From 580280af260c0fe261f8056495db8daf15c10b20 Mon Sep 17 00:00:00 2001 From: Lasse Holmstedt <lasse.holmstedt@nokia.com> Date: Tue, 9 Feb 2010 20:44:40 +0100 Subject: [PATCH] Changed QML Inspector from a separate global mode to a plugin. The new QML Inspector depends on DebuggerPlugin. Also added a dropdown menu into the debugger toolbar from which the user can select the used debugging language, e.g. C++ or QML. --- src/plugins/debugger/debugger.pro | 9 +- src/plugins/debugger/debuggerconstants.h | 2 +- src/plugins/debugger/debuggermainwindow.cpp | 60 +++ src/plugins/debugger/debuggermainwindow.h | 28 ++ src/plugins/debugger/debuggermanager.cpp | 123 +++--- src/plugins/debugger/debuggermanager.h | 6 +- src/plugins/debugger/debuggerplugin.cpp | 272 +++++-------- src/plugins/debugger/debuggerplugin.h | 8 +- src/plugins/debugger/debuggeruiswitcher.cpp | 381 ++++++++++++++++++ src/plugins/debugger/debuggeruiswitcher.h | 114 ++++++ src/plugins/debugger/gdb/gdbengine.cpp | 4 +- src/plugins/plugins.pro | 1 + .../qmlinspector/QmlInspector.pluginspec | 1 + .../qmlinspector/inspectoroutputpane.cpp | 2 + .../qmlinspector/inspectoroutputpane.h | 7 +- ...{qmlinspectormode.cpp => qmlinspector.cpp} | 258 +++++------- src/plugins/qmlinspector/qmlinspector.h | 98 ++++- src/plugins/qmlinspector/qmlinspector.pro | 11 +- .../qmlinspector/qmlinspector_global.h | 40 ++ .../qmlinspector/qmlinspectorconstants.h | 54 +++ src/plugins/qmlinspector/qmlinspectormode.h | 106 ----- .../qmlinspector/qmlinspectorplugin.cpp | 134 ++++-- src/plugins/qmlinspector/qmlinspectorplugin.h | 30 +- src/plugins/qmlprojectmanager/qmlproject.cpp | 31 +- src/plugins/qmlprojectmanager/qmlproject.h | 3 + 25 files changed, 1218 insertions(+), 565 deletions(-) create mode 100644 src/plugins/debugger/debuggermainwindow.cpp create mode 100644 src/plugins/debugger/debuggermainwindow.h create mode 100644 src/plugins/debugger/debuggeruiswitcher.cpp create mode 100644 src/plugins/debugger/debuggeruiswitcher.h rename src/plugins/qmlinspector/{qmlinspectormode.cpp => qmlinspector.cpp} (71%) create mode 100644 src/plugins/qmlinspector/qmlinspector_global.h create mode 100644 src/plugins/qmlinspector/qmlinspectorconstants.h delete mode 100644 src/plugins/qmlinspector/qmlinspectormode.h diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index d9e161749a3..7e1b1690ef2 100644 --- a/src/plugins/debugger/debugger.pro +++ b/src/plugins/debugger/debugger.pro @@ -43,7 +43,9 @@ HEADERS += breakhandler.h \ threadswindow.h \ watchhandler.h \ watchwindow.h \ - name_demangler.h + name_demangler.h \ + debuggeruiswitcher.h \ + debuggermainwindow.h SOURCES += breakhandler.cpp \ breakwindow.cpp \ breakwindow.h \ @@ -70,7 +72,10 @@ SOURCES += breakhandler.cpp \ threadswindow.cpp \ watchhandler.cpp \ watchwindow.cpp \ - name_demangler.cpp + name_demangler.cpp \ + debuggeruiswitcher.cpp \ + debuggermainwindow.cpp + FORMS += attachexternaldialog.ui \ attachcoredialog.ui \ breakbyfunction.ui \ diff --git a/src/plugins/debugger/debuggerconstants.h b/src/plugins/debugger/debuggerconstants.h index 9b6cdb636c7..5049ec011ce 100644 --- a/src/plugins/debugger/debuggerconstants.h +++ b/src/plugins/debugger/debuggerconstants.h @@ -38,7 +38,7 @@ namespace Constants { // modes and their priorities const char * const MODE_DEBUG = "Debugger.Mode.Debug"; const int P_MODE_DEBUG = 85; - +const char * const LANG_CPP = "C++"; // common actions const char * const INTERRUPT = "Debugger.Interrupt"; const char * const RESET = "Debugger.Reset"; diff --git a/src/plugins/debugger/debuggermainwindow.cpp b/src/plugins/debugger/debuggermainwindow.cpp new file mode 100644 index 00000000000..d35103acf22 --- /dev/null +++ b/src/plugins/debugger/debuggermainwindow.cpp @@ -0,0 +1,60 @@ +#include "debuggermainwindow.h" + +#include <QtCore/QCoreApplication> +#include <QtGui/QApplication> +#include <QtGui/QMenu> +#include <QtGui/QLayout> +#include <QtGui/QMainWindow> +#include <QtGui/QDockWidget> +#include <QtGui/QStyle> + +#include <QDebug> + +namespace Debugger { + +DebuggerMainWindow::DebuggerMainWindow(DebuggerUISwitcher *uiSwitcher, QWidget *parent) : + FancyMainWindow(parent), m_uiSwitcher(uiSwitcher) +{ + // TODO how to "append" style sheet? + // QString sheet; + // After setting it, all prev. style stuff seem to be ignored. + /* sheet = QLatin1String( + "Debugger--DebuggerMainWindow::separator {" + " background: black;" + " width: 1px;" + " height: 1px;" + "}" + ); + setStyleSheet(sheet); + */ +} + +DebuggerMainWindow::~DebuggerMainWindow() +{ + +} + +QMenu* DebuggerMainWindow::createPopupMenu() +{ + QMenu *menu = 0; + + QList<Internal::DebugToolWindow* > dockwidgets = m_uiSwitcher->m_dockWidgets; + + if (!dockwidgets.isEmpty()) { + menu = new QMenu(this); + + for (int i = 0; i < dockwidgets.size(); ++i) { + QDockWidget *dockWidget = dockwidgets.at(i)->m_dockWidget; + if (dockWidget->parentWidget() == this && + dockwidgets.at(i)->m_languageId == m_uiSwitcher->m_activeLanguage) { + + menu->addAction(dockWidget->toggleViewAction()); + } + } + menu->addSeparator(); + } + + return menu; +} + +} diff --git a/src/plugins/debugger/debuggermainwindow.h b/src/plugins/debugger/debuggermainwindow.h new file mode 100644 index 00000000000..8ebc099cccd --- /dev/null +++ b/src/plugins/debugger/debuggermainwindow.h @@ -0,0 +1,28 @@ +#ifndef DEBUGGERMAINWINDOW_H +#define DEBUGGERMAINWINDOW_H + +#include "debuggeruiswitcher.h" +#include <utils/fancymainwindow.h> + + +class QMenu; + +namespace Debugger { + +class DebuggerMainWindow : public Utils::FancyMainWindow +{ +public: + DebuggerMainWindow(DebuggerUISwitcher *uiSwitcher, QWidget *parent = 0); + ~DebuggerMainWindow(); + + +protected: + virtual QMenu *createPopupMenu(); + +private: + DebuggerUISwitcher *m_uiSwitcher; +}; + +} + +#endif // DEBUGGERMAINWINDOW_H diff --git a/src/plugins/debugger/debuggermanager.cpp b/src/plugins/debugger/debuggermanager.cpp index 06fad14ba01..f95c6c30c45 100644 --- a/src/plugins/debugger/debuggermanager.cpp +++ b/src/plugins/debugger/debuggermanager.cpp @@ -36,6 +36,8 @@ #include "idebuggerengine.h" #include "debuggerstringutils.h" #include "watchutils.h" +#include "debuggeruiswitcher.h" +#include "debuggermainwindow.h" #include "breakwindow.h" #include "debuggeroutputwindow.h" @@ -60,10 +62,10 @@ # include "shared/peutils.h" #endif +#include <coreplugin/minisplitter.h> #include <coreplugin/icore.h> #include <coreplugin/editormanager/editormanager.h> #include <utils/qtcassert.h> -#include <utils/fancymainwindow.h> #include <projectexplorer/toolchain.h> #include <cplusplus/CppDocument.h> #include <cpptools/cppmodelmanagerinterface.h> @@ -260,7 +262,7 @@ struct DebuggerManagerPrivate qint64 m_inferiorPid; /// Views - Utils::FancyMainWindow *m_mainWindow; + DebuggerMainWindow *m_mainWindow; QLabel *m_statusLabel; QDockWidget *m_breakDock; @@ -272,6 +274,7 @@ struct DebuggerManagerPrivate QDockWidget *m_stackDock; QDockWidget *m_threadsDock; QDockWidget *m_watchDock; + QList<QDockWidget *> m_dockWidgets; BreakHandler *m_breakHandler; ModulesHandler *m_modulesHandler; @@ -364,9 +367,7 @@ void DebuggerManager::init() d->m_watchersWindow = new WatchWindow(WatchWindow::WatchersType, this); d->m_statusTimer = new QTimer(this); - d->m_mainWindow = new Utils::FancyMainWindow; - d->m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); - d->m_mainWindow->setDocumentMode(true); + d->m_mainWindow = DebuggerUISwitcher::instance()->mainWindow(); // Snapshots d->m_snapshotHandler = new SnapshotHandler; @@ -545,30 +546,32 @@ void DebuggerManager::init() connect(theDebuggerAction(OperateByInstruction), SIGNAL(triggered()), this, SLOT(operateByInstructionTriggered())); + DebuggerUISwitcher *uiSwitcher = DebuggerUISwitcher::instance(); + d->m_breakDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_breakWindow); + d->m_modulesDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_modulesWindow, + Qt::TopDockWidgetArea, false); - d->m_breakDock = d->m_mainWindow->addDockForWidget(d->m_breakWindow); - - d->m_modulesDock = d->m_mainWindow->addDockForWidget(d->m_modulesWindow); connect(d->m_modulesDock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(reloadModules()), Qt::QueuedConnection); - d->m_registerDock = d->m_mainWindow->addDockForWidget(d->m_registerWindow); + d->m_registerDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_registerWindow, + Qt::TopDockWidgetArea, false); connect(d->m_registerDock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(reloadRegisters()), Qt::QueuedConnection); - d->m_outputDock = d->m_mainWindow->addDockForWidget(d->m_outputWindow); - - d->m_snapshotDock = d->m_mainWindow->addDockForWidget(d->m_snapshotWindow); + d->m_outputDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_outputWindow, + Qt::TopDockWidgetArea, false); - d->m_stackDock = d->m_mainWindow->addDockForWidget(d->m_stackWindow); - - d->m_sourceFilesDock = d->m_mainWindow->addDockForWidget(d->m_sourceFilesWindow); + d->m_snapshotDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_snapshotWindow); + d->m_stackDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_stackWindow); + d->m_sourceFilesDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_sourceFilesWindow, + Qt::TopDockWidgetArea, false); connect(d->m_sourceFilesDock->toggleViewAction(), SIGNAL(toggled(bool)), this, SLOT(reloadSourceFiles()), Qt::QueuedConnection); - d->m_threadsDock = d->m_mainWindow->addDockForWidget(d->m_threadsWindow); + d->m_threadsDock = uiSwitcher->createDockWidget(LANG_CPP, d->m_threadsWindow); - QSplitter *localsAndWatchers = new QSplitter(Qt::Vertical, 0); + QSplitter *localsAndWatchers = new Core::MiniSplitter(Qt::Vertical); localsAndWatchers->setWindowTitle(d->m_localsWindow->windowTitle()); localsAndWatchers->addWidget(d->m_localsWindow); localsAndWatchers->addWidget(d->m_watchersWindow); @@ -576,7 +579,10 @@ void DebuggerManager::init() localsAndWatchers->setStretchFactor(0, 3); localsAndWatchers->setStretchFactor(1, 1); localsAndWatchers->setStretchFactor(2, 1); - d->m_watchDock = d->m_mainWindow->addDockForWidget(localsAndWatchers); + d->m_watchDock = DebuggerUISwitcher::instance()->createDockWidget(LANG_CPP, localsAndWatchers); + d->m_dockWidgets << d->m_breakDock << d->m_modulesDock << d->m_registerDock + << d->m_outputDock << d->m_stackDock << d->m_sourceFilesDock + << d->m_threadsDock << d->m_watchDock; setState(DebuggerNotReady); } @@ -607,11 +613,6 @@ DebuggerManagerActions DebuggerManager::debuggerManagerActions() const return d->m_actions; } -Utils::FancyMainWindow *DebuggerManager::mainWindow() const -{ - return d->m_mainWindow; -} - QLabel *DebuggerManager::statusLabel() const { return d->m_statusLabel; @@ -681,45 +682,51 @@ QWidget *DebuggerManager::threadsWindow() const void DebuggerManager::createNewDock(QWidget *widget) { - QDockWidget *dockWidget = new QDockWidget(widget->windowTitle(), d->m_mainWindow); + QDockWidget *dockWidget = DebuggerUISwitcher::instance()->createDockWidget(LANG_CPP, widget); + dockWidget->setWindowTitle(widget->windowTitle()); dockWidget->setObjectName(widget->windowTitle()); dockWidget->setFeatures(QDockWidget::DockWidgetClosable); - dockWidget->setWidget(widget); - d->m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget); + //dockWidget->setWidget(widget); + //d->m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget); dockWidget->show(); } -void DebuggerManager::setSimpleDockWidgetArrangement() +void DebuggerManager::setSimpleDockWidgetArrangement(const QString &activeLanguage) { - d->m_mainWindow->setTrackingEnabled(false); - QList<QDockWidget *> dockWidgets = d->m_mainWindow->dockWidgets(); - foreach (QDockWidget *dockWidget, dockWidgets) { - dockWidget->setFloating(false); - d->m_mainWindow->removeDockWidget(dockWidget); - } - - foreach (QDockWidget *dockWidget, dockWidgets) { - if (dockWidget == d->m_outputDock) - d->m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget); - else - d->m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget); - dockWidget->show(); - } + if (activeLanguage == LANG_CPP || !activeLanguage.length()) { + d->m_mainWindow->setTrackingEnabled(false); + QList<QDockWidget *> dockWidgets = d->m_mainWindow->dockWidgets(); + foreach (QDockWidget *dockWidget, dockWidgets) { + if (d->m_dockWidgets.contains(dockWidget)) { + dockWidget->setFloating(false); + d->m_mainWindow->removeDockWidget(dockWidget); + } + } - d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_breakDock); - d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_modulesDock); - d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_registerDock); - d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_threadsDock); - d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_sourceFilesDock); - d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_snapshotDock); + foreach (QDockWidget *dockWidget, dockWidgets) { + if (d->m_dockWidgets.contains(dockWidget)) { + if (dockWidget == d->m_outputDock) + d->m_mainWindow->addDockWidget(Qt::TopDockWidgetArea, dockWidget); + else + d->m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget); + dockWidget->show(); + } + } - // They following views are rarely used in ordinary debugging. Hiding them - // saves cycles since the corresponding information won't be retrieved. - d->m_sourceFilesDock->hide(); - d->m_registerDock->hide(); - d->m_modulesDock->hide(); - d->m_outputDock->hide(); - d->m_mainWindow->setTrackingEnabled(true); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_breakDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_modulesDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_registerDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_threadsDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_sourceFilesDock); + d->m_mainWindow->tabifyDockWidget(d->m_watchDock, d->m_snapshotDock); + // They following views are rarely used in ordinary debugging. Hiding them + // saves cycles since the corresponding information won't be retrieved. + d->m_sourceFilesDock->hide(); + d->m_registerDock->hide(); + d->m_modulesDock->hide(); + d->m_outputDock->hide(); + d->m_mainWindow->setTrackingEnabled(true); + } } QAbstractItemModel *DebuggerManager::threadsModel() @@ -1235,7 +1242,7 @@ void DebuggerManager::saveSessionData() void DebuggerManager::dumpLog() { - QString fileName = QFileDialog::getSaveFileName(mainWindow(), + QString fileName = QFileDialog::getSaveFileName(d->m_mainWindow, tr("Save Debugger Log"), QDir::tempPath()); if (fileName.isEmpty()) return; @@ -1562,7 +1569,7 @@ QStringList DebuggerManager::qtDumperLibraryLocations() const void DebuggerManager::showQtDumperLibraryWarning(const QString &details) { - QMessageBox dialog(mainWindow()); + QMessageBox dialog(d->m_mainWindow); QPushButton *qtPref = dialog.addButton(tr("Open Qt preferences"), QMessageBox::ActionRole); QPushButton *helperOff = dialog.addButton(tr("Turn off helper usage"), @@ -1623,7 +1630,7 @@ QMessageBox *DebuggerManager::showMessageBox(int icon, const QString &title, const QString &text, int buttons) { QMessageBox *mb = new QMessageBox(QMessageBox::Icon(icon), - title, text, QMessageBox::StandardButtons(buttons), mainWindow()); + title, text, QMessageBox::StandardButtons(buttons), d->m_mainWindow); mb->setAttribute(Qt::WA_DeleteOnClose); mb->show(); return mb; @@ -1735,7 +1742,7 @@ void DebuggerManager::setState(DebuggerState state, bool forced) const bool stopped = state == InferiorStopped; if (stopped) - QApplication::alert(mainWindow(), 3000); + QApplication::alert(d->m_mainWindow, 3000); const bool actionsEnabled = debuggerActionsEnabled(); const unsigned engineCapabilities = debuggerCapabilities(); diff --git a/src/plugins/debugger/debuggermanager.h b/src/plugins/debugger/debuggermanager.h index 55f03a055f6..03379797e97 100644 --- a/src/plugins/debugger/debuggermanager.h +++ b/src/plugins/debugger/debuggermanager.h @@ -53,9 +53,6 @@ QT_END_NAMESPACE namespace Core { class IOptionsPage; } -namespace Utils { -class FancyMainWindow; -} namespace TextEditor { class ITextEditor; @@ -180,7 +177,6 @@ public: DebuggerState state() const; QList<Core::IOptionsPage*> initializeEngines(unsigned enabledTypeFlags); - Utils::FancyMainWindow *mainWindow() const; QLabel *statusLabel() const; Internal::IDebuggerEngine *currentEngine() const; @@ -208,7 +204,7 @@ public slots: void startNewDebugger(const DebuggerStartParametersPtr &sp); void exitDebugger(); - void setSimpleDockWidgetArrangement(); + void setSimpleDockWidgetArrangement(const QString &activeLanguage); void setBusyCursor(bool on); void queryCurrentTextEditor(QString *fileName, int *lineNumber, QObject **ed); diff --git a/src/plugins/debugger/debuggerplugin.cpp b/src/plugins/debugger/debuggerplugin.cpp index 67788f74ed9..85885e6d783 100644 --- a/src/plugins/debugger/debuggerplugin.cpp +++ b/src/plugins/debugger/debuggerplugin.cpp @@ -36,6 +36,8 @@ #include "debuggermanager.h" #include "debuggerrunner.h" #include "debuggerstringutils.h" +#include "debuggeruiswitcher.h" +#include "debuggermainwindow.h" #include "ui_commonoptionspage.h" #include "ui_dumperoptionpage.h" @@ -76,7 +78,6 @@ #include <utils/qtcassert.h> #include <utils/styledbar.h> -#include <utils/fancymainwindow.h> #include <QtCore/QDebug> #include <QtCore/QObject> @@ -97,6 +98,7 @@ #include <climits> using namespace Core; +using namespace Debugger; using namespace Debugger::Constants; using namespace Debugger::Internal; using namespace ProjectExplorer; @@ -259,7 +261,8 @@ bool DebuggerListener::coreAboutToClose() " state (%1) can leave the target in an inconsistent state." " Would you still like to terminate it?") .arg(QLatin1String(DebuggerManager::stateName(mgr->state()))); - QMessageBox::StandardButton answer = QMessageBox::question(mgr->mainWindow(), title, question, + QMessageBox::StandardButton answer = QMessageBox::question(DebuggerUISwitcher::instance()->mainWindow(), + title, question, QMessageBox::Yes|QMessageBox::No, QMessageBox::Yes); if (answer != QMessageBox::Yes) return false; @@ -520,8 +523,7 @@ DebuggerPlugin::DebuggerPlugin() m_debugMode(0), m_locationMark(0), m_gdbRunningContext(0), - m_cmdLineEnabledEngines(AllEngineTypes), - m_toggleLockedAction(0) + m_cmdLineEnabledEngines(AllEngineTypes) {} DebuggerPlugin::~DebuggerPlugin() @@ -534,9 +536,12 @@ void DebuggerPlugin::shutdown() m_manager->shutdown(); writeSettings(); + + if (m_uiSwitcher) + m_uiSwitcher->shutdown(); + delete DebuggerSettings::instance(); - //qDebug() << "DebuggerPlugin::~DebuggerPlugin"; removeObject(m_debugMode); // FIXME: when using the line below, BreakWindow etc gets deleted twice. @@ -550,6 +555,10 @@ void DebuggerPlugin::shutdown() removeObject(m_manager); delete m_manager; m_manager = 0; + + removeObject(m_uiSwitcher); + delete m_uiSwitcher; + m_uiSwitcher = 0; } static QString msgParameterMissing(const QString &a) @@ -657,6 +666,13 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess errorMessage->clear(); } + // Debug mode setup + m_debugMode = new DebugMode(this); + //addAutoReleasedObject(m_debugMode); + m_uiSwitcher = new DebuggerUISwitcher(m_debugMode, this); + ExtensionSystem::PluginManager::instance()->addObject(m_uiSwitcher); + m_uiSwitcher->addLanguage(LANG_CPP); + m_manager = new DebuggerManager; ExtensionSystem::PluginManager::instance()->addObject(m_manager); const QList<Core::IOptionsPage *> engineOptionPages = @@ -688,6 +704,16 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess m_gdbRunningContext = uidm->uniqueIdentifier(Constants::GDBRUNNING); + // register factory of DebuggerRunControl + m_debuggerRunControlFactory = new DebuggerRunControlFactory(m_manager); + addAutoReleasedObject(m_debuggerRunControlFactory); + + QList<int> context; + context.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER)); + context.append(uidm->uniqueIdentifier(Debugger::Constants::C_GDBDEBUGGER)); + context.append(uidm->uniqueIdentifier(Core::Constants::C_NAVIGATION_PANE)); + m_debugMode->setContext(context); + //Core::ActionContainer *mcppcontext = // am->actionContainer(CppEditor::Constants::M_CONTEXT); @@ -706,26 +732,26 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess m_attachCoreAction->setText(tr("Attach to Core...")); connect(m_attachCoreAction, SIGNAL(triggered()), this, SLOT(attachCore())); - m_startRemoteAction = new QAction(this); m_startRemoteAction->setText(tr("Start and Attach to Remote Application...")); connect(m_startRemoteAction, SIGNAL(triggered()), this, SLOT(startRemoteApplication())); - m_detachAction = new QAction(this); m_detachAction->setText(tr("Detach Debugger")); connect(m_detachAction, SIGNAL(triggered()), m_manager, SLOT(detachDebugger())); - Core::ActionContainer *mdebug = - am->actionContainer(ProjectExplorer::Constants::M_DEBUG); + // Core::ActionContainer *mdebug = + // am->actionContainer(ProjectExplorer::Constants::M_DEBUG); + + Core::Command *cmd = 0; + const DebuggerManagerActions actions = m_manager->debuggerManagerActions(); + Core::ActionContainer *mstart = am->actionContainer(ProjectExplorer::Constants::M_DEBUG_STARTDEBUGGING); - Core::Command *cmd = 0; - const DebuggerManagerActions actions = m_manager->debuggerManagerActions(); cmd = am->registerAction(actions.continueAction, ProjectExplorer::Constants::DEBUG, QList<int>() << m_gdbRunningContext); mstart->addAction(cmd, Core::Constants::G_DEFAULT_ONE); @@ -748,7 +774,7 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess cmd = am->registerAction(m_detachAction, Constants::DETACH, globalcontext); - mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); + m_uiSwitcher->addMenuAction(cmd, Core::Constants::G_DEFAULT_ONE); cmd = am->registerAction(actions.stopAction, Constants::INTERRUPT, globalcontext); @@ -756,86 +782,86 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess cmd->setAttribute(Core::Command::CA_UpdateIcon); cmd->setDefaultKeySequence(QKeySequence(Constants::INTERRUPT_KEY)); cmd->setDefaultText(tr("Stop Debugger/Interrupt Debugger")); - mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); + m_uiSwitcher->addMenuAction(cmd, Core::Constants::G_DEFAULT_ONE); cmd = am->registerAction(actions.resetAction, Constants::RESET, globalcontext); cmd->setAttribute(Core::Command::CA_UpdateText); //cmd->setDefaultKeySequence(QKeySequence(Constants::RESET_KEY)); cmd->setDefaultText(tr("Reset Debugger")); - mdebug->addAction(cmd, Core::Constants::G_DEFAULT_ONE); + m_uiSwitcher->addMenuAction(cmd, Core::Constants::G_DEFAULT_ONE); QAction *sep = new QAction(this); sep->setSeparator(true); cmd = am->registerAction(sep, QLatin1String("Debugger.Sep.Step"), globalcontext); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.nextAction, Constants::NEXT, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::NEXT_KEY)); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.stepAction, Constants::STEP, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::STEP_KEY)); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.stepOutAction, Constants::STEPOUT, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::STEPOUT_KEY)); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.runToLineAction1, Constants::RUN_TO_LINE1, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_LINE_KEY)); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.runToFunctionAction, Constants::RUN_TO_FUNCTION, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::RUN_TO_FUNCTION_KEY)); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.jumpToLineAction1, Constants::JUMP_TO_LINE1, debuggercontext); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); #ifdef USE_REVERSE_DEBUGGING cmd = am->registerAction(actions.reverseDirectionAction, Constants::REVERSE, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::REVERSE_KEY)); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); #endif sep = new QAction(this); sep->setSeparator(true); cmd = am->registerAction(sep, QLatin1String("Debugger.Sep.Break"), globalcontext); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.snapshotAction, Constants::SNAPSHOT, debuggercontext); cmd->setDefaultKeySequence(QKeySequence(Constants::SNAPSHOT_KEY)); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(theDebuggerAction(OperateByInstruction), Constants::OPERATE_BY_INSTRUCTION, debuggercontext); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.breakAction, Constants::TOGGLE_BREAK, cppeditorcontext); cmd->setDefaultKeySequence(QKeySequence(Constants::TOGGLE_BREAK_KEY)); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); //mcppcontext->addAction(cmd); sep = new QAction(this); sep->setSeparator(true); cmd = am->registerAction(sep, QLatin1String("Debugger.Sep.Watch"), globalcontext); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); cmd = am->registerAction(actions.watchAction1, Constants::ADD_TO_WATCH1, cppeditorcontext); cmd->action()->setEnabled(true); //cmd->setDefaultKeySequence(QKeySequence(tr("ALT+D,ALT+W"))); - mdebug->addAction(cmd); + m_uiSwitcher->addMenuAction(cmd); // Editor context menu ActionContainer *editorContextMenu = @@ -863,35 +889,6 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess editorContextMenu->addAction(cmd); cmd->setAttribute(Command::CA_Hide); - // Views menu - cmd = am->registerAction(sep, QLatin1String("Debugger.Sep.Views"), globalcontext); - mdebug->addAction(cmd); - ActionContainer *viewsMenu = am->createMenu(Constants::M_DEBUG_VIEWS); - QMenu *m = viewsMenu->menu(); - m->setEnabled(true); - m->setTitle(tr("&Views")); - mdebug->addMenu(viewsMenu, Core::Constants::G_DEFAULT_THREE); - - m_toggleLockedAction = new QAction(tr("Locked"), this); - m_toggleLockedAction->setCheckable(true); - m_toggleLockedAction->setChecked(true); - connect(m_toggleLockedAction, SIGNAL(toggled(bool)), - m_manager->mainWindow(), SLOT(setLocked(bool))); - foreach (QDockWidget *dockWidget, m_manager->mainWindow()->dockWidgets()) { - cmd = am->registerAction(dockWidget->toggleViewAction(), - "Debugger." + dockWidget->objectName(), debuggercontext); - viewsMenu->addAction(cmd); - //m->addAction(dockWidget->toggleViewAction()); - } - m->addSeparator(); - m->addAction(m_toggleLockedAction); - m->addSeparator(); - - QAction *resetToSimpleAction = - viewsMenu->menu()->addAction(tr("Reset to default layout")); - connect(resetToSimpleAction, SIGNAL(triggered()), - m_manager, SLOT(setSimpleDockWidgetArrangement())); - // FIXME: addAutoReleasedObject(new CommonOptionsPage); addAutoReleasedObject(new DebuggingHelperOptionPage); @@ -900,92 +897,13 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess addAutoReleasedObject(new DebuggerListener); m_locationMark = 0; - - // - // Debug mode setup - // - m_debugMode = new DebugMode(this); - //addAutoReleasedObject(m_debugMode); - - // register factory of DebuggerRunControl - m_debuggerRunControlFactory = new DebuggerRunControlFactory(m_manager); - addAutoReleasedObject(m_debuggerRunControlFactory); - - QList<int> context; - context.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER)); - context.append(uidm->uniqueIdentifier(Debugger::Constants::C_GDBDEBUGGER)); - context.append(uidm->uniqueIdentifier(Core::Constants::C_NAVIGATION_PANE)); - m_debugMode->setContext(context); - - QBoxLayout *editorHolderLayout = new QVBoxLayout; - editorHolderLayout->setMargin(0); - editorHolderLayout->setSpacing(0); - - QWidget *editorAndFindWidget = new QWidget; - editorAndFindWidget->setLayout(editorHolderLayout); - editorHolderLayout->addWidget(new EditorManagerPlaceHolder(m_debugMode)); - editorHolderLayout->addWidget(new FindToolBarPlaceHolder(editorAndFindWidget)); - - MiniSplitter *rightPaneSplitter = new MiniSplitter; - rightPaneSplitter->addWidget(editorAndFindWidget); - rightPaneSplitter->addWidget(new RightPanePlaceHolder(m_debugMode)); - rightPaneSplitter->setStretchFactor(0, 1); - rightPaneSplitter->setStretchFactor(1, 0); - - QWidget *centralWidget = new QWidget; - - m_manager->mainWindow()->setCentralWidget(centralWidget); - - MiniSplitter *splitter = new MiniSplitter; - splitter->addWidget(m_manager->mainWindow()); - splitter->addWidget(new OutputPanePlaceHolder(m_debugMode, splitter)); - splitter->setStretchFactor(0, 10); - splitter->setStretchFactor(1, 0); - splitter->setOrientation(Qt::Vertical); - - MiniSplitter *splitter2 = new MiniSplitter; - splitter2->addWidget(new NavigationWidgetPlaceHolder(m_debugMode)); - splitter2->addWidget(splitter); - splitter2->setStretchFactor(0, 0); - splitter2->setStretchFactor(1, 1); - - m_debugMode->setWidget(splitter2); - - Utils::StyledBar *debugToolBar = new Utils::StyledBar; - debugToolBar->setProperty("topBorder", true); - QHBoxLayout *debugToolBarLayout = new QHBoxLayout(debugToolBar); - debugToolBarLayout->setMargin(0); - debugToolBarLayout->setSpacing(0); - debugToolBarLayout->addWidget(toolButton(am->command(ProjectExplorer::Constants::DEBUG)->action())); - debugToolBarLayout->addWidget(toolButton(am->command(Constants::INTERRUPT)->action())); - debugToolBarLayout->addWidget(toolButton(am->command(Constants::NEXT)->action())); - debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEP)->action())); - debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEPOUT)->action())); - debugToolBarLayout->addWidget(toolButton(am->command(Constants::OPERATE_BY_INSTRUCTION)->action())); - debugToolBarLayout->addWidget(toolButton(am->command(Constants::SNAPSHOT)->action())); -#ifdef USE_REVERSE_DEBUGGING - debugToolBarLayout->addWidget(new Utils::StyledSeparator); - debugToolBarLayout->addWidget(toolButton(am->command(Constants::REVERSE)->action())); -#endif - debugToolBarLayout->addWidget(new Utils::StyledSeparator); - debugToolBarLayout->addWidget(new QLabel(tr("Threads:"))); - - QComboBox *threadBox = new QComboBox; - threadBox->setModel(m_manager->threadsModel()); - connect(threadBox, SIGNAL(activated(int)), - m_manager->threadsWindow(), SIGNAL(threadSelected(int))); - debugToolBarLayout->addWidget(threadBox); - debugToolBarLayout->addWidget(m_manager->statusLabel(), 10); - - QBoxLayout *toolBarAddingLayout = new QVBoxLayout(centralWidget); - toolBarAddingLayout->setMargin(0); - toolBarAddingLayout->setSpacing(0); - toolBarAddingLayout->addWidget(rightPaneSplitter); - toolBarAddingLayout->addWidget(debugToolBar); - - m_manager->setSimpleDockWidgetArrangement(); + m_manager->setSimpleDockWidgetArrangement(LANG_CPP); readSettings(); + m_uiSwitcher->setToolbar(LANG_CPP, createToolbar()); + connect(m_uiSwitcher, SIGNAL(dockArranged(QString)), m_manager, + SLOT(setSimpleDockWidgetArrangement(QString))); + connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)), this, SLOT(onModeChanged(Core::IMode*))); m_debugMode->widget()->setFocusProxy(EditorManager::instance()); @@ -1042,6 +960,38 @@ bool DebuggerPlugin::initialize(const QStringList &arguments, QString *errorMess return true; } +QWidget *DebuggerPlugin::createToolbar() const +{ + Core::ActionManager *am = ICore::instance()->actionManager(); + + QWidget *toolbarContainer = new QWidget; + QHBoxLayout *debugToolBarLayout = new QHBoxLayout(toolbarContainer); + + debugToolBarLayout->setMargin(0); + debugToolBarLayout->setSpacing(0); + debugToolBarLayout->addWidget(toolButton(am->command(ProjectExplorer::Constants::DEBUG)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::INTERRUPT)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::NEXT)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEP)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::STEPOUT)->action())); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::OPERATE_BY_INSTRUCTION)->action())); +#ifdef USE_REVERSE_DEBUGGING + debugToolBarLayout->addWidget(new Utils::StyledSeparator); + debugToolBarLayout->addWidget(toolButton(am->command(Constants::REVERSE)->action())); +#endif + debugToolBarLayout->addWidget(new Utils::StyledSeparator); + debugToolBarLayout->addWidget(new QLabel(tr("Threads:"))); + + QComboBox *threadBox = new QComboBox; + threadBox->setModel(m_manager->threadsModel()); + connect(threadBox, SIGNAL(activated(int)), + m_manager->threadsWindow(), SIGNAL(threadSelected(int))); + debugToolBarLayout->addWidget(threadBox); + debugToolBarLayout->addWidget(m_manager->statusLabel(), 10); + + return toolbarContainer; +} + void DebuggerPlugin::extensionsInitialized() { // time gdb -i mi -ex 'debuggerplugin.cpp:800' -ex r -ex q bin/qtcreator.bin @@ -1051,6 +1001,9 @@ void DebuggerPlugin::extensionsInitialized() m_manager->runTest(QString::fromLocal8Bit(env)); if (m_attachRemoteParameters.attachPid || !m_attachRemoteParameters.attachCore.isEmpty()) QTimer::singleShot(0, this, SLOT(attachCmdLine())); + + readSettings(); + m_uiSwitcher->initialize(); } void DebuggerPlugin::attachCmdLine() @@ -1284,33 +1237,14 @@ void DebuggerPlugin::handleStateChanged(int state) void DebuggerPlugin::writeSettings() const { - QTC_ASSERT(m_manager, return); - QTC_ASSERT(m_manager->mainWindow(), return); - QSettings *s = settings(); DebuggerSettings::instance()->writeSettings(s); - s->beginGroup(QLatin1String("DebugMode")); - m_manager->mainWindow()->saveSettings(s); - s->endGroup(); } void DebuggerPlugin::readSettings() { QSettings *s = settings(); DebuggerSettings::instance()->readSettings(s); - - QString defaultCommand("gdb"); -#ifdef Q_OS_WIN - defaultCommand.append(".exe"); -#endif - //QString defaultScript = ICore::instance()->resourcePath() + - // QLatin1String("/gdb/qt4macros"); - QString defaultScript; - - s->beginGroup(QLatin1String("DebugMode")); - m_manager->mainWindow()->restoreSettings(s); - m_toggleLockedAction->setChecked(m_manager->mainWindow()->isLocked()); - s->endGroup(); } void DebuggerPlugin::onModeChanged(IMode *mode) @@ -1323,8 +1257,14 @@ void DebuggerPlugin::onModeChanged(IMode *mode) return; EditorManager *editorManager = EditorManager::instance(); - if (editorManager->currentEditor()) + if (editorManager->currentEditor()) { editorManager->currentEditor()->widget()->setFocus(); + + if (editorManager->currentEditor()->id() == CppEditor::Constants::C_CPPEDITOR) { + m_uiSwitcher->setActiveLanguage(Debugger::Constants::LANG_CPP); + } + + } } void DebuggerPlugin::showSettingsDialog() @@ -1337,7 +1277,7 @@ void DebuggerPlugin::showSettingsDialog() void DebuggerPlugin::startExternalApplication() { const DebuggerStartParametersPtr sp(new DebuggerStartParameters); - StartExternalDialog dlg(m_manager->mainWindow()); + StartExternalDialog dlg(m_uiSwitcher->mainWindow()); dlg.setExecutableFile( configValue(_("LastExternalExecutableFile")).toString()); dlg.setExecutableArguments( @@ -1363,7 +1303,7 @@ void DebuggerPlugin::startExternalApplication() void DebuggerPlugin::attachExternalApplication() { - AttachExternalDialog dlg(m_manager->mainWindow()); + AttachExternalDialog dlg(m_uiSwitcher->mainWindow()); if (dlg.exec() == QDialog::Accepted) attachExternalApplication(dlg.attachPID()); } @@ -1371,7 +1311,7 @@ void DebuggerPlugin::attachExternalApplication() void DebuggerPlugin::attachExternalApplication(qint64 pid, const QString &crashParameter) { if (pid == 0) { - QMessageBox::warning(m_manager->mainWindow(), tr("Warning"), tr("Cannot attach to PID 0")); + QMessageBox::warning(m_uiSwitcher->mainWindow(), tr("Warning"), tr("Cannot attach to PID 0")); return; } const DebuggerStartParametersPtr sp(new DebuggerStartParameters); @@ -1384,7 +1324,7 @@ void DebuggerPlugin::attachExternalApplication(qint64 pid, const QString &crashP void DebuggerPlugin::attachCore() { - AttachCoreDialog dlg(m_manager->mainWindow()); + AttachCoreDialog dlg(m_uiSwitcher->mainWindow()); dlg.setExecutableFile( configValue(_("LastExternalExecutableFile")).toString()); dlg.setCoreFile( @@ -1412,7 +1352,7 @@ void DebuggerPlugin::attachCore(const QString &core, const QString &exe) void DebuggerPlugin::startRemoteApplication() { const DebuggerStartParametersPtr sp(new DebuggerStartParameters); - StartRemoteDialog dlg(m_manager->mainWindow()); + StartRemoteDialog dlg(m_uiSwitcher->mainWindow()); QStringList arches; arches.append(_("i386:x86-64:intel")); arches.append(_("i386")); diff --git a/src/plugins/debugger/debuggerplugin.h b/src/plugins/debugger/debuggerplugin.h index db064b20b2a..ea15577f7e4 100644 --- a/src/plugins/debugger/debuggerplugin.h +++ b/src/plugins/debugger/debuggerplugin.h @@ -40,6 +40,7 @@ class QAction; class QCursor; class QMenu; class QPoint; +class QComboBox; QT_END_NAMESPACE namespace Core { @@ -54,7 +55,9 @@ class BaseTextMark; } namespace Debugger { + class DebuggerManager; +class DebuggerUISwitcher; namespace Internal { @@ -122,12 +125,14 @@ private: void writeSettings() const; void attachExternalApplication(qint64 pid, const QString &crashParameter = QString()); void attachCore(const QString &core, const QString &exeFileName); + QWidget *createToolbar() const; friend class Debugger::DebuggerManager; friend class GdbOptionPage; friend class DebuggingHelperOptionPage; friend class Debugger::Internal::DebugMode; // FIXME: Just a hack now so that it can access the views + DebuggerUISwitcher *m_uiSwitcher; DebuggerManager *m_manager; DebugMode *m_debugMode; DebuggerRunControlFactory *m_debuggerRunControlFactory; @@ -138,13 +143,12 @@ private: AttachRemoteParameters m_attachRemoteParameters; unsigned m_cmdLineEnabledEngines; - QAction *m_toggleLockedAction; - QAction *m_startExternalAction; QAction *m_startRemoteAction; QAction *m_attachExternalAction; QAction *m_attachCoreAction; QAction *m_detachAction; + QComboBox *m_langBox; }; } // namespace Internal diff --git a/src/plugins/debugger/debuggeruiswitcher.cpp b/src/plugins/debugger/debuggeruiswitcher.cpp new file mode 100644 index 00000000000..a972b61734a --- /dev/null +++ b/src/plugins/debugger/debuggeruiswitcher.cpp @@ -0,0 +1,381 @@ +#include "debuggeruiswitcher.h" +#include "debuggermainwindow.h" + +#include <debugger/debuggerconstants.h> +#include <utils/styledbar.h> +#include <coreplugin/modemanager.h> +#include <coreplugin/uniqueidmanager.h> +#include <coreplugin/coreconstants.h> +#include <coreplugin/icore.h> +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/actionmanager/actionmanager.h> +#include <coreplugin/findplaceholder.h> +#include <coreplugin/minisplitter.h> +#include <coreplugin/rightpane.h> +#include <coreplugin/outputpane.h> +#include <coreplugin/navigationwidget.h> +#include <coreplugin/actionmanager/actioncontainer.h> +#include <coreplugin/actionmanager/actioncontainer_p.h> +#include <projectexplorer/projectexplorerconstants.h> + +#include <QtCore/QSettings> + +#include <QtGui/QStackedWidget> +#include <QtGui/QComboBox> +#include <QtGui/QHBoxLayout> +#include <QtGui/QLabel> +#include <QtGui/QDockWidget> + +#include <QDebug> + +namespace Debugger { + +using namespace Debugger::Internal; + +DebuggerUISwitcher *DebuggerUISwitcher::m_instance = 0; + +DebuggerUISwitcher::DebuggerUISwitcher(Core::BaseMode *mode, QObject* parent) : QObject(parent), + m_model(new QStandardItemModel(this)), + m_toolbarStack(new QStackedWidget), + m_langBox(new QComboBox), + m_activeLanguage(-1), + m_isActiveMode(false), + m_changingUI(false), + m_toggleLockedAction(0), + m_viewsMenu(0), + m_debugMenu(0) +{ + mode->setWidget(createContents(mode)); + + Core::ICore *core = Core::ICore::instance(); + Core::ActionManager *am = core->actionManager(); + + connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)), + SLOT(modeChanged(Core::IMode*))); + + m_debugMenu = am->actionContainer(ProjectExplorer::Constants::M_DEBUG); + m_viewsMenu = am->createMenu(Debugger::Constants::M_DEBUG_VIEWS); + + m_instance = this; +} + +DebuggerUISwitcher::~DebuggerUISwitcher() +{ + qDeleteAll(m_dockWidgets); + m_dockWidgets.clear(); +} + +void DebuggerUISwitcher::addMenuAction(Core::Command *command, const QString &group) +{ + m_debugMenu->addAction(command, group); +} + +void DebuggerUISwitcher::setActiveLanguage(const QString &langName) +{ + QModelIndex idx = modelIndexForLanguage(langName); + if (!idx.isValid()) + return; + + changeDebuggerUI(idx.row()); +} + + +void DebuggerUISwitcher::modeChanged(Core::IMode *mode) +{ + m_isActiveMode = (mode->id() == Debugger::Constants::MODE_DEBUG); + hideInactiveWidgets(); +} + +void DebuggerUISwitcher::hideInactiveWidgets() +{ + if (!m_isActiveMode) { + // hide all the debugger windows if mode is different + foreach(Internal::DebugToolWindow *window, m_dockWidgets) { + if (window->m_languageId == m_activeLanguage && + window->m_dockWidget->isVisible()) + { + window->m_dockWidget->hide(); + } + } + } else { + // bring them back + foreach(Internal::DebugToolWindow *window, m_dockWidgets) { + if (window->m_languageId == m_activeLanguage && + window->m_visible && + !window->m_dockWidget->isVisible()) + { + window->m_dockWidget->show(); + } + } + } +} + +void DebuggerUISwitcher::createViewsMenuItems() +{ + Core::ICore *core = Core::ICore::instance(); + Core::ActionManager *am = core->actionManager(); + + QList<int> globalcontext; + globalcontext << Core::Constants::C_GLOBAL_ID; + + Core::Command *cmd = 0; + + m_toggleLockedAction = new QAction(tr("Locked"), this); + m_toggleLockedAction->setCheckable(true); + m_toggleLockedAction->setChecked(true); + connect(m_toggleLockedAction, SIGNAL(toggled(bool)), + m_mainWindow, SLOT(setLocked(bool))); + + QAction *sep = new QAction(this); + sep->setSeparator(true); + cmd = am->registerAction(sep, QLatin1String("Debugger.Sep.Views"), globalcontext); + m_debugMenu->addAction(cmd); + + QMenu *m = m_viewsMenu->menu(); + m->setEnabled(true); + m->setTitle(tr("&Views")); + m_debugMenu->addMenu(m_viewsMenu, Core::Constants::G_DEFAULT_THREE); + + m->addSeparator(); + m->addAction(m_toggleLockedAction); + m->addSeparator(); + + QAction *resetToSimpleAction = m_viewsMenu->menu()->addAction(tr("Reset to default layout")); + connect(resetToSimpleAction, SIGNAL(triggered()), + SLOT(resetDebuggerLayout())); + +} + +DebuggerUISwitcher *DebuggerUISwitcher::instance() +{ + return m_instance; +} + +void DebuggerUISwitcher::addLanguage(const QString &langName) +{ + QStandardItem* item = new QStandardItem(langName); + + m_model->appendRow(item); +} + +void DebuggerUISwitcher::changeDebuggerUI(int langId) +{ + if (m_changingUI) + return; + m_changingUI = true; + + // id + QModelIndex idx = m_model->index(langId, 0); + if (langId != m_activeLanguage) { + m_langBox->setCurrentIndex(langId); + m_activeLanguage = langId; + + m_toolbarStack->setCurrentIndex(m_model->data(idx, StackIndexRole).toInt()); + + foreach (DebugToolWindow *window, m_dockWidgets) { + if (window->m_languageId != langId) { + // visibleTo must be used because during init, debugger is not visible, + // although visibility is explicitly set through both default layout and + // QSettings. + window->m_visible = window->m_dockWidget->isVisibleTo(m_mainWindow); + window->m_dockWidget->hide(); + } else { + if (window->m_visible) { + window->m_dockWidget->show(); + } + } + } + + foreach (ViewsMenuItems menuitem, m_viewsMenuItems) { + if (menuitem.first == langId) { + menuitem.second->setVisible(true); + } else { + menuitem.second->setVisible(false); + } + } + emit languageChanged(idx.data().toString()); + } + + m_changingUI = false; +} + +QModelIndex DebuggerUISwitcher::modelIndexForLanguage(const QString& languageName) +{ + QList<QStandardItem*> items = m_model->findItems(languageName); + if (items.length() != 1) + return QModelIndex(); + + return m_model->indexFromItem(items.at(0)); +} + +void DebuggerUISwitcher::setToolbar(const QString &langName, QWidget *widget) +{ + QModelIndex modelIdx = modelIndexForLanguage(langName); + if (!modelIdx.isValid()) + return; + + int stackIdx = m_toolbarStack->addWidget(widget); + m_model->setData(modelIdx, stackIdx, StackIndexRole); + +} + +DebuggerMainWindow *DebuggerUISwitcher::mainWindow() const +{ + return m_mainWindow; +} + +QWidget *DebuggerUISwitcher::createMainWindow(Core::BaseMode *mode) +{ + m_mainWindow = new DebuggerMainWindow(this); + m_mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); + m_mainWindow->setDocumentMode(true); + + QBoxLayout *editorHolderLayout = new QVBoxLayout; + editorHolderLayout->setMargin(0); + editorHolderLayout->setSpacing(0); + + QWidget *editorAndFindWidget = new QWidget; + editorAndFindWidget->setLayout(editorHolderLayout); + editorHolderLayout->addWidget(new Core::EditorManagerPlaceHolder(mode)); + editorHolderLayout->addWidget(new Core::FindToolBarPlaceHolder(editorAndFindWidget)); + + Core::MiniSplitter *documentAndRightPane = new Core::MiniSplitter; + documentAndRightPane->addWidget(editorAndFindWidget); + documentAndRightPane->addWidget(new Core::RightPanePlaceHolder(mode)); + documentAndRightPane->setStretchFactor(0, 1); + documentAndRightPane->setStretchFactor(1, 0); + + Utils::StyledBar *debugToolBar = new Utils::StyledBar; + debugToolBar->setProperty("topBorder", true); + QHBoxLayout *debugToolBarLayout = new QHBoxLayout(debugToolBar); + debugToolBarLayout->setMargin(0); + debugToolBarLayout->setSpacing(0); + debugToolBarLayout->addWidget(m_toolbarStack); + debugToolBarLayout->addStretch(); + + m_langBox = new QComboBox; + m_langBox->setModel(m_model); + debugToolBarLayout->addWidget(m_langBox); + + QWidget *centralWidget = new QWidget; + m_mainWindow->setCentralWidget(centralWidget); + + QVBoxLayout *centralLayout = new QVBoxLayout(centralWidget); + centralWidget->setLayout(centralLayout); + centralLayout->setMargin(0); + centralLayout->setSpacing(0); + centralLayout->addWidget(documentAndRightPane); + centralLayout->addWidget(debugToolBar); + centralLayout->setStretch(0, 1); + centralLayout->setStretch(1, 0); + + return m_mainWindow; +} + + +/*! + Keep track of dock widgets so they can be shown/hidden for different languages +*/ +QDockWidget *DebuggerUISwitcher::createDockWidget(const QString &langName, QWidget *widget, + Qt::DockWidgetArea area, bool visibleByDefault) +{ + QDockWidget *dockWidget = m_mainWindow->addDockForWidget(widget); + m_mainWindow->addDockWidget(area, dockWidget); + DebugToolWindow *window = new DebugToolWindow; + window->m_languageId = modelIndexForLanguage(langName).row(); + window->m_dockWidget = dockWidget; + + window->m_visible = visibleByDefault; + m_dockWidgets.append(window); + + if (modelIndexForLanguage(langName).row() != m_activeLanguage) + dockWidget->hide(); + + QList<int> debuggercontext; + debuggercontext << Core::ICore::instance()->uniqueIDManager()->uniqueIdentifier(Debugger::Constants::C_GDBDEBUGGER); + + Core::ActionManager *am = Core::ICore::instance()->actionManager(); + Core::Command *cmd = am->registerAction(dockWidget->toggleViewAction(), + "Debugger." + dockWidget->objectName(), debuggercontext); + m_viewsMenu->addAction(cmd); + + m_viewsMenuItems.append(qMakePair(modelIndexForLanguage(langName).row(), cmd->action())); + + return dockWidget; +} + +QWidget *DebuggerUISwitcher::createContents(Core::BaseMode *mode) +{ + // right-side window with editor, output etc. + Core::MiniSplitter *mainWindowSplitter = new Core::MiniSplitter; + mainWindowSplitter->addWidget(createMainWindow(mode)); + mainWindowSplitter->addWidget(new Core::OutputPanePlaceHolder(mode, mainWindowSplitter)); + mainWindowSplitter->setStretchFactor(0, 10); + mainWindowSplitter->setStretchFactor(1, 0); + mainWindowSplitter->setOrientation(Qt::Vertical); + + // navigation + right-side window + Core::MiniSplitter *splitter = new Core::MiniSplitter; + splitter->addWidget(new Core::NavigationWidgetPlaceHolder(mode)); + splitter->addWidget(mainWindowSplitter); + splitter->setStretchFactor(0, 0); + splitter->setStretchFactor(1, 1); + return splitter; +} + +void DebuggerUISwitcher::shutdown() +{ + writeSettings(); +} + +void DebuggerUISwitcher::writeSettings() const +{ + QSettings *s = Core::ICore::instance()->settings(); + s->beginGroup(QLatin1String("DebugMode")); + + foreach(Internal::DebugToolWindow *toolWindow, m_dockWidgets) { + bool visible = toolWindow->m_visible; + if (toolWindow->m_languageId == m_activeLanguage) { + visible = toolWindow->m_dockWidget->isVisibleTo(m_mainWindow); + } + toolWindow->m_dockWidget->setVisible(visible); + } + + m_mainWindow->saveSettings(s); + s->endGroup(); +} + +void DebuggerUISwitcher::readSettings() +{ + QSettings *s = Core::ICore::instance()->settings(); + s->beginGroup(QLatin1String("DebugMode")); + m_mainWindow->restoreSettings(s); + m_toggleLockedAction->setChecked(m_mainWindow->isLocked()); + s->endGroup(); + + foreach(Internal::DebugToolWindow *toolWindow, m_dockWidgets) { + toolWindow->m_visible = toolWindow->m_dockWidget->isVisibleTo(m_mainWindow); + } +} + +void DebuggerUISwitcher::initialize() +{ + createViewsMenuItems(); + + emit dockArranged(QString()); + readSettings(); + + if (m_activeLanguage == -1) { + changeDebuggerUI(0); + } + hideInactiveWidgets(); + + connect(m_langBox, SIGNAL(currentIndexChanged(int)), SLOT(changeDebuggerUI(int))); +} + +void DebuggerUISwitcher::resetDebuggerLayout() +{ + emit dockArranged(m_model->index(m_activeLanguage, 0).data().toString()); +} + +} diff --git a/src/plugins/debugger/debuggeruiswitcher.h b/src/plugins/debugger/debuggeruiswitcher.h new file mode 100644 index 00000000000..85e09af9d66 --- /dev/null +++ b/src/plugins/debugger/debuggeruiswitcher.h @@ -0,0 +1,114 @@ +#ifndef DEBUGGERUISWITCHER_H +#define DEBUGGERUISWITCHER_H + +#include "debugger_global.h" + +#include <coreplugin/basemode.h> +#include <QtCore/QObject> +#include <QtGui/QStandardItemModel> +#include <QtCore/QList> + +namespace Core { + class ActionContainer; + class Command; +} + +class QAction; +class QDockWidget; +class QStackedWidget; +class QComboBox; + +namespace Debugger { + class DebuggerMainWindow; +namespace Internal { +class DebugToolWindow { +public: + DebugToolWindow() : m_visible(false) {} + QDockWidget* m_dockWidget; + int m_languageId; + bool m_visible; +}; +} +} + +namespace Debugger { +class DEBUGGER_EXPORT DebuggerUISwitcher : public QObject +{ + Q_OBJECT +public: + DebuggerUISwitcher(Core::BaseMode *mode, QObject *parent = 0); + ~DebuggerUISwitcher(); + + static DebuggerUISwitcher *instance(); + + // debuggable languages are registered with this function + void addLanguage(const QString &langName); + + // debugger toolbars are registered with this function + void setToolbar(const QString &langName, QWidget *widget); + + // menu actions are registered with this function + void addMenuAction(Core::Command *command, + const QString &group = QString()); + + void setActiveLanguage(const QString &langName); + + // called when all dependent plugins have loaded + void initialize(); + + void shutdown(); + + // dockwidgets are registered to the main window + QDockWidget *createDockWidget(const QString &langName, QWidget *widget, + Qt::DockWidgetArea area = Qt::TopDockWidgetArea, + bool visibleByDefault = true); + + DebuggerMainWindow *mainWindow() const; + +signals: + void languageChanged(const QString &langName); + // emit when dock needs to be reset + void dockArranged(const QString &activeLanguage); + +private slots: + void modeChanged(Core::IMode *mode); + void changeDebuggerUI(int langId); + void resetDebuggerLayout(); + +private: + void hideInactiveWidgets(); + void createViewsMenuItems(); + void readSettings(); + void writeSettings() const; + QModelIndex modelIndexForLanguage(const QString &langName); + QWidget *createContents(Core::BaseMode *mode); + QWidget *createMainWindow(Core::BaseMode *mode); + + // first: language id, second: menu item + typedef QPair<int, QAction* > ViewsMenuItems; + QList< ViewsMenuItems > m_viewsMenuItems; + QList< Internal::DebugToolWindow* > m_dockWidgets; + QStandardItemModel *m_model; + QStackedWidget *m_toolbarStack; + QComboBox *m_langBox; + DebuggerMainWindow *m_mainWindow; + + int m_activeLanguage; + bool m_isActiveMode; + bool m_changingUI; + + QAction *m_toggleLockedAction; + + const static int StackIndexRole = Qt::UserRole + 11; + + Core::ActionContainer *m_viewsMenu; + Core::ActionContainer *m_debugMenu; + + static DebuggerUISwitcher *m_instance; + + friend class DebuggerMainWindow; +}; + +} + +#endif // DEBUGGERUISWITCHER_H diff --git a/src/plugins/debugger/gdb/gdbengine.cpp b/src/plugins/debugger/gdb/gdbengine.cpp index a82d09fb662..13c659836dd 100644 --- a/src/plugins/debugger/gdb/gdbengine.cpp +++ b/src/plugins/debugger/gdb/gdbengine.cpp @@ -33,6 +33,8 @@ #include "gdboptionspage.h" #include "trkoptions.h" #include "trkoptionspage.h" +#include "debugger/debuggeruiswitcher.h" +#include "debugger/debuggermainwindow.h" #include "attachgdbadapter.h" #include "coregdbadapter.h" @@ -210,7 +212,7 @@ DebuggerStartMode GdbEngine::startMode() const QMainWindow *GdbEngine::mainWindow() const { - return m_manager->mainWindow(); + return DebuggerUISwitcher::instance()->mainWindow(); } GdbEngine::~GdbEngine() diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index ef18ea0df46..982990817c8 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -189,6 +189,7 @@ plugin_qmlinspector.depends += plugin_projectexplorer plugin_qmlinspector.depends += plugin_coreplugin plugin_qmlinspector.depends += plugin_texteditor plugin_qmlinspector.depends += plugin_qmlprojectmanager +plugin_qmlinspector.depends += plugin_debugger plugin_mercurial.subdir = mercurial plugin_mercurial.depends = plugin_texteditor diff --git a/src/plugins/qmlinspector/QmlInspector.pluginspec b/src/plugins/qmlinspector/QmlInspector.pluginspec index 9ad51d42309..0afdc90147c 100644 --- a/src/plugins/qmlinspector/QmlInspector.pluginspec +++ b/src/plugins/qmlinspector/QmlInspector.pluginspec @@ -24,5 +24,6 @@ will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> <dependency name="CppTools" version="1.3.80"/> <dependency name="CppEditor" version="1.3.80"/> <dependency name="Help" version="1.3.80"/> + <dependency name="Debugger" version="1.3.80"/> </dependencyList> </plugin> diff --git a/src/plugins/qmlinspector/inspectoroutputpane.cpp b/src/plugins/qmlinspector/inspectoroutputpane.cpp index 84b0a1cd57c..333c63eb5d4 100644 --- a/src/plugins/qmlinspector/inspectoroutputpane.cpp +++ b/src/plugins/qmlinspector/inspectoroutputpane.cpp @@ -30,6 +30,8 @@ #include <QtGui/qtextedit.h> +using namespace Qml; + InspectorOutputPane::InspectorOutputPane(QObject *parent) : Core::IOutputPane(parent), m_textEdit(new QTextEdit) diff --git a/src/plugins/qmlinspector/inspectoroutputpane.h b/src/plugins/qmlinspector/inspectoroutputpane.h index 873aa54155c..e1add1ff032 100644 --- a/src/plugins/qmlinspector/inspectoroutputpane.h +++ b/src/plugins/qmlinspector/inspectoroutputpane.h @@ -33,12 +33,11 @@ #include <QtCore/QObject> -QT_BEGIN_NAMESPACE - class QTextEdit; - class RunControl; +namespace Qml { + class InspectorOutputPane : public Core::IOutputPane { Q_OBJECT @@ -76,7 +75,7 @@ private: QTextEdit *m_textEdit; }; -QT_END_NAMESPACE +} #endif diff --git a/src/plugins/qmlinspector/qmlinspectormode.cpp b/src/plugins/qmlinspector/qmlinspector.cpp similarity index 71% rename from src/plugins/qmlinspector/qmlinspectormode.cpp rename to src/plugins/qmlinspector/qmlinspector.cpp index c4e568c6648..764c4adb63b 100644 --- a/src/plugins/qmlinspector/qmlinspectormode.cpp +++ b/src/plugins/qmlinspector/qmlinspector.cpp @@ -26,8 +26,11 @@ ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ +#include "qmlinspectorconstants.h" #include "qmlinspector.h" -#include "qmlinspectormode.h" +#include "debugger/debuggermainwindow.h" + +#include <debugger/debuggeruiswitcher.h> #include "components/objectpropertiesview.h" #include "components/objecttree.h" @@ -52,7 +55,6 @@ #include <coreplugin/uniqueidmanager.h> #include <coreplugin/editormanager/editormanager.h> -#include <coreplugin/actionmanager/actionmanager.h> #include <texteditor/itexteditor.h> @@ -66,6 +68,8 @@ #include <QtCore/QStringList> #include <QtCore/QtPlugin> +#include <QtCore/QTimer> + #include <QtCore/QDebug> #include <QtGui/qtoolbutton.h> @@ -80,9 +84,9 @@ #include <QtNetwork/QHostAddress> +using namespace Qml; -QT_BEGIN_NAMESPACE - +namespace Qml { class EngineSpinBox : public QSpinBox { @@ -107,6 +111,8 @@ private: QList<EngineInfo> m_engines; }; +} + EngineSpinBox::EngineSpinBox(QWidget *parent) : QSpinBox(parent) { @@ -152,8 +158,8 @@ int EngineSpinBox::valueFromText(const QString &text) const } -QmlInspectorMode::QmlInspectorMode(QObject *parent) - : Core::BaseMode(parent), +QmlInspector::QmlInspector(QObject *parent) + : QObject(parent), m_conn(0), m_client(0), m_engineQuery(0), @@ -161,17 +167,13 @@ QmlInspectorMode::QmlInspectorMode(QObject *parent) { m_watchTableModel = new WatchTableModel(0, this); - setWidget(createModeWindow()); - - setDisplayName(tr("QML Inspect")); - setIcon(QIcon(":/qmlinspector/images/logo.png")); - setId(QLatin1String("QML_INSPECT_MODE")); + initWidgets(); } -void QmlInspectorMode::connectToViewer() +bool QmlInspector::connectToViewer() { if (m_conn && m_conn->state() != QAbstractSocket::UnconnectedState) - return; + return false; delete m_client; m_client = 0; @@ -183,17 +185,17 @@ void QmlInspectorMode::connectToViewer() ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::instance()->currentProject(); if (!project) { emit statusMessage(tr("No active project, debugging canceled.")); - return; + return false; } QmlProjectManager::QmlRunConfiguration* config = qobject_cast<QmlProjectManager::QmlRunConfiguration*>(project->activeTarget()->activeRunConfiguration()); if (!config) { emit statusMessage(tr("Cannot find project run configuration, debugging canceled.")); - return; + return false; } - QHostAddress host = QHostAddress::LocalHost; + QString host = config->debugServerAddress(); quint16 port = quint16(config->debugServerPort()); m_conn = new QmlDebugConnection(this); @@ -202,16 +204,21 @@ void QmlInspectorMode::connectToViewer() connect(m_conn, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(connectionError())); - emit statusMessage(tr("[Inspector] set to connect to debug server %1:%2").arg(host.toString()).arg(port)); + emit statusMessage(tr("[Inspector] set to connect to debug server %1:%2").arg(host).arg(port)); m_conn->connectToHost(host, port); + // blocks until connected; if no connection is available, will fail immediately + if (m_conn->waitForConnected()) + return true; + + return false; } -void QmlInspectorMode::disconnectFromViewer() +void QmlInspector::disconnectFromViewer() { m_conn->disconnectFromHost(); } -void QmlInspectorMode::connectionStateChanged() +void QmlInspector::connectionStateChanged() { switch (m_conn->state()) { case QAbstractSocket::UnconnectedState: @@ -260,35 +267,27 @@ void QmlInspectorMode::connectionStateChanged() } } -void QmlInspectorMode::connectionError() +void QmlInspector::connectionError() { emit statusMessage(tr("[Inspector] error: (%1) %2", "%1=error code, %2=error message") .arg(m_conn->error()).arg(m_conn->errorString())); } -QToolButton *QmlInspectorMode::createToolButton(QAction *action) +void QmlInspector::initWidgets() { - QToolButton *button = new QToolButton; - button->setDefaultAction(action); - return button; -} - -QWidget *QmlInspectorMode::createMainView() -{ - initWidgets(); - - Utils::FancyMainWindow *mainWindow = new Utils::FancyMainWindow; - mainWindow->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); - mainWindow->setDocumentMode(true); + m_objectTreeWidget = new ObjectTree; + m_propertiesWidget = new ObjectPropertiesView; + m_watchTableView = new WatchTableView(m_watchTableModel); + m_frameRateWidget = new CanvasFrameRate; + m_expressionWidget = new ExpressionQueryWidget(ExpressionQueryWidget::ShellMode); - QBoxLayout *editorHolderLayout = new QVBoxLayout; - editorHolderLayout->setMargin(0); - editorHolderLayout->setSpacing(0); + m_engineSpinBox = new EngineSpinBox; + m_engineSpinBox->setEnabled(false); + connect(m_engineSpinBox, SIGNAL(valueChanged(int)), + SLOT(queryEngineContext(int))); - QWidget *editorAndFindWidget = new QWidget; - editorAndFindWidget->setLayout(editorHolderLayout); - editorHolderLayout->addWidget(new Core::EditorManagerPlaceHolder(this)); - editorHolderLayout->addWidget(new Core::FindToolBarPlaceHolder(editorAndFindWidget)); + // FancyMainWindow uses widgets' window titles for tab labels + m_frameRateWidget->setWindowTitle(tr("Frame rate")); Utils::StyledBar *treeOptionBar = new Utils::StyledBar; QHBoxLayout *treeOptionBarLayout = new QHBoxLayout(treeOptionBar); @@ -298,121 +297,13 @@ QWidget *QmlInspectorMode::createMainView() treeOptionBarLayout->addWidget(m_engineSpinBox); QWidget *treeWindow = new QWidget; + treeWindow->setWindowTitle(tr("Object Tree")); QVBoxLayout *treeWindowLayout = new QVBoxLayout(treeWindow); treeWindowLayout->setMargin(0); treeWindowLayout->setSpacing(0); treeWindowLayout->addWidget(treeOptionBar); treeWindowLayout->addWidget(m_objectTreeWidget); - Core::MiniSplitter *documentAndTree = new Core::MiniSplitter; - documentAndTree->addWidget(editorAndFindWidget); - documentAndTree->addWidget(new Core::RightPanePlaceHolder(this)); - documentAndTree->addWidget(treeWindow); - documentAndTree->setStretchFactor(0, 2); - documentAndTree->setStretchFactor(1, 0); - documentAndTree->setStretchFactor(2, 0); - - Utils::StyledBar *configBar = new Utils::StyledBar; - configBar->setProperty("topBorder", true); - - QHBoxLayout *configBarLayout = new QHBoxLayout(configBar); - configBarLayout->setMargin(0); - configBarLayout->setSpacing(5); - - Core::ICore *core = Core::ICore::instance(); - Core::ActionManager *am = core->actionManager(); - configBarLayout->addWidget(createToolButton(am->command(ProjectExplorer::Constants::DEBUG)->action())); - configBarLayout->addWidget(createToolButton(am->command(ProjectExplorer::Constants::STOP)->action())); - - configBarLayout->addStretch(); - - QWidget *widgetAboveTabs = new QWidget; - QVBoxLayout *widgetAboveTabsLayout = new QVBoxLayout(widgetAboveTabs); - widgetAboveTabsLayout->setMargin(0); - widgetAboveTabsLayout->setSpacing(0); - widgetAboveTabsLayout->addWidget(documentAndTree); - widgetAboveTabsLayout->addWidget(configBar); - - Core::MiniSplitter *mainSplitter = new Core::MiniSplitter(Qt::Vertical); - mainSplitter->addWidget(widgetAboveTabs); - mainSplitter->addWidget(createBottomWindow()); - mainSplitter->setStretchFactor(0, 3); - mainSplitter->setStretchFactor(1, 1); - - QWidget *centralWidget = new QWidget; - QVBoxLayout *centralLayout = new QVBoxLayout(centralWidget); - centralLayout->setMargin(0); - centralLayout->setSpacing(0); - centralLayout->addWidget(mainSplitter); - - mainWindow->setCentralWidget(centralWidget); - - return mainWindow; -} - -QWidget *QmlInspectorMode::createBottomWindow() -{ - Utils::FancyMainWindow *win = new Utils::FancyMainWindow; - win->setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North); - win->setDocumentMode(true); - win->setTrackingEnabled(true); - - Core::MiniSplitter *leftSplitter = new Core::MiniSplitter(Qt::Vertical); - leftSplitter->addWidget(m_propertiesWidget); - leftSplitter->addWidget(m_expressionWidget); - leftSplitter->setStretchFactor(0, 2); - leftSplitter->setStretchFactor(1, 1); - - Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Horizontal); - propSplitter->addWidget(leftSplitter); - propSplitter->addWidget(m_watchTableView); - propSplitter->setStretchFactor(0, 2); - propSplitter->setStretchFactor(1, 1); - propSplitter->setWindowTitle(tr("Properties and Watchers")); - - QDockWidget *propertiesDock = win->addDockForWidget(propSplitter); - win->addDockWidget(Qt::TopDockWidgetArea, propertiesDock); - - QDockWidget *frameRateDock = win->addDockForWidget(m_frameRateWidget); - win->addDockWidget(Qt::TopDockWidgetArea, frameRateDock); - - // stack the dock widgets as tabs - win->tabifyDockWidget(frameRateDock, propertiesDock); - - return win; -} - -QWidget *QmlInspectorMode::createModeWindow() -{ - // right-side window with editor, output etc. - Core::MiniSplitter *mainWindowSplitter = new Core::MiniSplitter; - mainWindowSplitter->addWidget(createMainView()); - mainWindowSplitter->addWidget(new Core::OutputPanePlaceHolder(this, mainWindowSplitter)); - mainWindowSplitter->setStretchFactor(0, 10); - mainWindowSplitter->setStretchFactor(1, 0); - mainWindowSplitter->setOrientation(Qt::Vertical); - - // navigation + right-side window - Core::MiniSplitter *splitter = new Core::MiniSplitter; - splitter->addWidget(new Core::NavigationWidgetPlaceHolder(this)); - splitter->addWidget(mainWindowSplitter); - splitter->setStretchFactor(0, 0); - splitter->setStretchFactor(1, 1); - return splitter; -} - -void QmlInspectorMode::initWidgets() -{ - m_objectTreeWidget = new ObjectTree; - m_propertiesWidget = new ObjectPropertiesView; - m_watchTableView = new WatchTableView(m_watchTableModel); - m_frameRateWidget = new CanvasFrameRate; - m_expressionWidget = new ExpressionQueryWidget(ExpressionQueryWidget::ShellMode); - - // FancyMainWindow uses widgets' window titles for tab labels - m_objectTreeWidget->setWindowTitle(tr("Object Tree")); - m_frameRateWidget->setWindowTitle(tr("Frame rate")); - m_watchTableView->setModel(m_watchTableModel); WatchTableHeaderView *header = new WatchTableHeaderView(m_watchTableModel); m_watchTableView->setHorizontalHeader(header); @@ -441,13 +332,59 @@ void QmlInspectorMode::initWidgets() connect(m_objectTreeWidget, SIGNAL(currentObjectChanged(QmlDebugObjectReference)), m_expressionWidget, SLOT(setCurrentObject(QmlDebugObjectReference))); - m_engineSpinBox = new EngineSpinBox; - m_engineSpinBox->setEnabled(false); - connect(m_engineSpinBox, SIGNAL(valueChanged(int)), - SLOT(queryEngineContext(int))); + + Core::MiniSplitter *leftSplitter = new Core::MiniSplitter(Qt::Vertical); + leftSplitter->addWidget(m_propertiesWidget); + leftSplitter->addWidget(m_expressionWidget); + leftSplitter->setStretchFactor(0, 2); + leftSplitter->setStretchFactor(1, 1); + + Core::MiniSplitter *propSplitter = new Core::MiniSplitter(Qt::Horizontal); + propSplitter->addWidget(leftSplitter); + propSplitter->addWidget(m_watchTableView); + propSplitter->setStretchFactor(0, 2); + propSplitter->setStretchFactor(1, 1); + propSplitter->setWindowTitle(tr("Properties and Watchers")); + + m_objectTreeDock = Debugger::DebuggerUISwitcher::instance()->createDockWidget(Qml::Constants::LANG_QML, + treeWindow, Qt::BottomDockWidgetArea); + m_frameRateDock = Debugger::DebuggerUISwitcher::instance()->createDockWidget(Qml::Constants::LANG_QML, + m_frameRateWidget, Qt::BottomDockWidgetArea); + m_propertyWatcherDock = Debugger::DebuggerUISwitcher::instance()->createDockWidget(Qml::Constants::LANG_QML, + propSplitter, Qt::BottomDockWidgetArea); + m_dockWidgets << m_objectTreeDock << m_frameRateDock << m_propertyWatcherDock; } -void QmlInspectorMode::reloadEngines() +void QmlInspector::setSimpleDockWidgetArrangement() +{ + Debugger::DebuggerMainWindow *mainWindow = Debugger::DebuggerUISwitcher::instance()->mainWindow(); + + mainWindow->setTrackingEnabled(false); + QList<QDockWidget *> dockWidgets = mainWindow->dockWidgets(); + foreach (QDockWidget *dockWidget, dockWidgets) { + if (m_dockWidgets.contains(dockWidget)) { + dockWidget->setFloating(false); + mainWindow->removeDockWidget(dockWidget); + } + } + + foreach (QDockWidget *dockWidget, dockWidgets) { + if (m_dockWidgets.contains(dockWidget)) { + if (dockWidget == m_objectTreeDock) + mainWindow->addDockWidget(Qt::RightDockWidgetArea, dockWidget); + else + mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dockWidget); + dockWidget->show(); + // dockwidget is not actually visible during init because debugger is + // not visible, either. we can use isVisibleTo(), though. + } + } + + mainWindow->tabifyDockWidget(m_frameRateDock, m_propertyWatcherDock); + mainWindow->setTrackingEnabled(true); +} + +void QmlInspector::reloadEngines() { if (m_engineQuery) { emit statusMessage("[Inspector] Waiting for response to previous engine query"); @@ -464,7 +401,7 @@ void QmlInspectorMode::reloadEngines() this, SLOT(enginesChanged())); } -void QmlInspectorMode::enginesChanged() +void QmlInspector::enginesChanged() { m_engineSpinBox->clearEngines(); @@ -485,7 +422,7 @@ void QmlInspectorMode::enginesChanged() } } -void QmlInspectorMode::queryEngineContext(int id) +void QmlInspector::queryEngineContext(int id) { if (id < 0) return; @@ -503,7 +440,7 @@ void QmlInspectorMode::queryEngineContext(int id) this, SLOT(contextChanged())); } -void QmlInspectorMode::contextChanged() +void QmlInspector::contextChanged() { //dump(m_contextQuery->rootContext(), 0); @@ -513,7 +450,7 @@ void QmlInspectorMode::contextChanged() delete m_contextQuery; m_contextQuery = 0; } -void QmlInspectorMode::treeObjectActivated(const QmlDebugObjectReference &obj) +void QmlInspector::treeObjectActivated(const QmlDebugObjectReference &obj) { QmlDebugFileReference source = obj.source(); QString fileName = source.url().toLocalFile(); @@ -531,7 +468,4 @@ void QmlInspectorMode::treeObjectActivated(const QmlDebugObjectReference &obj) } } -QT_END_NAMESPACE - -#include "qmlinspectormode.moc" - +#include "qmlinspector.moc" diff --git a/src/plugins/qmlinspector/qmlinspector.h b/src/plugins/qmlinspector/qmlinspector.h index e680a017444..d9a8eddde92 100644 --- a/src/plugins/qmlinspector/qmlinspector.h +++ b/src/plugins/qmlinspector/qmlinspector.h @@ -26,28 +26,92 @@ ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ -#ifndef QMLINSPECTOR_H -#define QMLINSPECTOR_H +#ifndef QMLINSPECTORMODE_H +#define QMLINSPECTORMODE_H -#include <QString> +#include "qmlinspector_global.h" +#include <coreplugin/basemode.h> -namespace QmlInspector { - namespace Constants { - const char * const RUN = "QmlInspector.Run"; - const char * const STOP = "QmlInspector.Stop"; +#include <QtGui/QAction> +#include <QtCore/QObject> - const char * const C_INSPECTOR = "QmlInspector"; - }; +QT_BEGIN_NAMESPACE - class StartParameters - { - public: - StartParameters() : port(0) {} - ~StartParameters() {} +class QDockWidget; +class QToolButton; +class QLineEdit; +class QSpinBox; +class QLabel; + +class QmlEngineDebug; +class QmlDebugConnection; +class QmlDebugEnginesQuery; +class QmlDebugRootContextQuery; +class QmlDebugObjectReference; +class ObjectTree; +class WatchTableModel; +class WatchTableView; +class ObjectPropertiesView; +class CanvasFrameRate; +class ExpressionQueryWidget; + + +namespace Qml { + class EngineSpinBox; + +class QMLINSPECTOR_EXPORT QmlInspector : public QObject +{ + Q_OBJECT + +public: + QmlInspector(QObject *parent = 0); + + bool connectToViewer(); // using host, port from widgets + +signals: + void statusMessage(const QString &text); + +public slots: + void disconnectFromViewer(); + void setSimpleDockWidgetArrangement(); + +private slots: + void connectionStateChanged(); + void connectionError(); + void reloadEngines(); + void enginesChanged(); + void queryEngineContext(int); + void contextChanged(); + void treeObjectActivated(const QmlDebugObjectReference &obj); + +private: + + void initWidgets(); + + QmlDebugConnection *m_conn; + QmlEngineDebug *m_client; + + QmlDebugEnginesQuery *m_engineQuery; + QmlDebugRootContextQuery *m_contextQuery; + + ObjectTree *m_objectTreeWidget; + ObjectPropertiesView *m_propertiesWidget; + WatchTableModel *m_watchTableModel; + WatchTableView *m_watchTableView; + CanvasFrameRate *m_frameRateWidget; + ExpressionQueryWidget *m_expressionWidget; + + EngineSpinBox *m_engineSpinBox; + + QDockWidget *m_objectTreeDock; + QDockWidget *m_frameRateDock; + QDockWidget *m_propertyWatcherDock; + QList<QDockWidget*> m_dockWidgets; - QString address; - quint16 port; - }; }; +} + +QT_END_NAMESPACE + #endif diff --git a/src/plugins/qmlinspector/qmlinspector.pro b/src/plugins/qmlinspector/qmlinspector.pro index 0a2807f8fff..e382eb75d10 100644 --- a/src/plugins/qmlinspector/qmlinspector.pro +++ b/src/plugins/qmlinspector/qmlinspector.pro @@ -6,13 +6,16 @@ DEPENDPATH += . include(components/qmldebugger.pri) +DEFINES += QMLINSPECTOR_LIBRARY + HEADERS += qmlinspectorplugin.h \ + qmlinspectorconstants.h \ qmlinspector.h \ - qmlinspectormode.h \ - inspectoroutputpane.h + inspectoroutputpane.h \ + qmlinspector_global.h SOURCES += qmlinspectorplugin.cpp \ - qmlinspectormode.cpp \ + qmlinspector.cpp \ inspectoroutputpane.cpp OTHER_FILES += QmlInspector.pluginspec @@ -23,4 +26,4 @@ include(../../plugins/projectexplorer/projectexplorer.pri) include(../../plugins/qmlprojectmanager/qmlprojectmanager.pri) include(../../plugins/coreplugin/coreplugin.pri) include(../../plugins/texteditor/texteditor.pri) - +include(../../plugins/debugger/debugger.pri) diff --git a/src/plugins/qmlinspector/qmlinspector_global.h b/src/plugins/qmlinspector/qmlinspector_global.h new file mode 100644 index 00000000000..c89baceb84a --- /dev/null +++ b/src/plugins/qmlinspector/qmlinspector_global.h @@ -0,0 +1,40 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ +#ifndef QMLINSPECTOR_GLOBAL_H +#define QMLINSPECTOR_GLOBAL_H + +#include <QtCore/QtGlobal> + +#if defined(QMLINSPECTOR_LIBRARY) +# define QMLINSPECTOR_EXPORT Q_DECL_EXPORT +#else +# define QMLINSPECTOR_EXPORT Q_DECL_IMPORT +#endif + +#endif // QMLINSPECTOR_GLOBAL_H diff --git a/src/plugins/qmlinspector/qmlinspectorconstants.h b/src/plugins/qmlinspector/qmlinspectorconstants.h new file mode 100644 index 00000000000..ed8fb633a4d --- /dev/null +++ b/src/plugins/qmlinspector/qmlinspectorconstants.h @@ -0,0 +1,54 @@ +/************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** Commercial Usage +** +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at http://qt.nokia.com/contact. +** +**************************************************************************/ +#ifndef QMLINSPECTORCONSTANTS_H +#define QMLINSPECTORCONSTANTS_H + +#include <QString> + +namespace Qml { + namespace Constants { + const char * const RUN = "QmlInspector.Run"; + const char * const STOP = "QmlInspector.Stop"; + + const char * const C_INSPECTOR = "QmlInspector"; + const char * const LANG_QML = "QML"; + }; + + class StartParameters + { + public: + StartParameters() : port(0) {} + ~StartParameters() {} + + QString address; + quint16 port; + }; +}; + +#endif diff --git a/src/plugins/qmlinspector/qmlinspectormode.h b/src/plugins/qmlinspector/qmlinspectormode.h deleted file mode 100644 index 9ee90d61045..00000000000 --- a/src/plugins/qmlinspector/qmlinspectormode.h +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************************** -** -** This file is part of Qt Creator -** -** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). -** -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** Commercial Usage -** -** Licensees holding valid Qt Commercial licenses may use this file in -** accordance with the Qt Commercial License Agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and Nokia. -** -** GNU Lesser General Public License Usage -** -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 2.1 requirements -** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** If you are unsure which license is appropriate for your use, please -** contact the sales department at http://qt.nokia.com/contact. -** -**************************************************************************/ -#ifndef QMLINSPECTORMODE_H -#define QMLINSPECTORMODE_H - -#include <coreplugin/basemode.h> - -#include <QtGui/QAction> -#include <QtCore/QObject> - -QT_BEGIN_NAMESPACE - -class QToolButton; -class QLineEdit; -class QSpinBox; -class QLabel; - -class QmlEngineDebug; -class QmlDebugConnection; -class QmlDebugEnginesQuery; -class QmlDebugRootContextQuery; -class QmlDebugObjectReference; -class ObjectTree; -class WatchTableModel; -class WatchTableView; -class ObjectPropertiesView; -class CanvasFrameRate; -class ExpressionQueryWidget; -class EngineSpinBox; - - -class QmlInspectorMode : public Core::BaseMode -{ - Q_OBJECT - -public: - QmlInspectorMode(QObject *parent = 0); - -signals: - void statusMessage(const QString &text); - -public slots: - void connectToViewer(); // using host, port from widgets - void disconnectFromViewer(); - -private slots: - void connectionStateChanged(); - void connectionError(); - void reloadEngines(); - void enginesChanged(); - void queryEngineContext(int); - void contextChanged(); - void treeObjectActivated(const QmlDebugObjectReference &obj); - -private: - QWidget *createModeWindow(); - QWidget *createMainView(); - void initWidgets(); - QWidget *createBottomWindow(); - QToolButton *createToolButton(QAction *action); - - QmlDebugConnection *m_conn; - QmlEngineDebug *m_client; - - QmlDebugEnginesQuery *m_engineQuery; - QmlDebugRootContextQuery *m_contextQuery; - - ObjectTree *m_objectTreeWidget; - ObjectPropertiesView *m_propertiesWidget; - WatchTableModel *m_watchTableModel; - WatchTableView *m_watchTableView; - CanvasFrameRate *m_frameRateWidget; - ExpressionQueryWidget *m_expressionWidget; - - EngineSpinBox *m_engineSpinBox; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/qmlinspector/qmlinspectorplugin.cpp b/src/plugins/qmlinspector/qmlinspectorplugin.cpp index 518a5f45d2c..c99d42895f6 100644 --- a/src/plugins/qmlinspector/qmlinspectorplugin.cpp +++ b/src/plugins/qmlinspector/qmlinspectorplugin.cpp @@ -26,16 +26,25 @@ ** contact the sales department at http://qt.nokia.com/contact. ** **************************************************************************/ +#include "qmlinspectorconstants.h" #include "qmlinspector.h" -#include "qmlinspectormode.h" #include "inspectoroutputpane.h" #include "qmlinspectorplugin.h" +#include <debugger/debuggeruiswitcher.h> +#include <debugger/debuggerconstants.h> + +#include <qmlprojectmanager/qmlproject.h> +#include <qmljseditor/qmljseditorconstants.h> + #include <private/qmldebug_p.h> #include <private/qmldebugclient_p.h> -#include <coreplugin/icore.h> #include <coreplugin/modemanager.h> +#include <coreplugin/editormanager/ieditor.h> +#include <coreplugin/editormanager/editormanager.h> +#include <extensionsystem/pluginmanager.h> +#include <coreplugin/icore.h> #include <projectexplorer/runconfiguration.h> #include <projectexplorer/projectexplorer.h> @@ -44,19 +53,34 @@ #include <coreplugin/coreconstants.h> #include <coreplugin/uniqueidmanager.h> +#include <coreplugin/actionmanager/actionmanager.h> #include <extensionsystem/pluginmanager.h> #include <QtCore/QStringList> #include <QtCore/QtPlugin> +#include <QtCore/QTimer> + +#include <QtGui/QHBoxLayout> +#include <QtGui/QToolButton> + #include <QtCore/QDebug> -QT_BEGIN_NAMESPACE +using namespace Qml; + +static QToolButton *createToolButton(QAction *action) +{ + QToolButton *button = new QToolButton; + button->setDefaultAction(action); + return button; +} QmlInspectorPlugin::QmlInspectorPlugin() - : m_inspectMode(0) + : m_inspector(0), m_connectionTimer(new QTimer(this)), + m_connectionAttempts(0) { + m_connectionTimer->setInterval(75); } QmlInspectorPlugin::~QmlInspectorPlugin() @@ -65,13 +89,13 @@ QmlInspectorPlugin::~QmlInspectorPlugin() void QmlInspectorPlugin::shutdown() { - removeObject(m_inspectMode); - delete m_inspectMode; - m_inspectMode = 0; - removeObject(m_outputPane); delete m_outputPane; m_outputPane = 0; + + removeObject(m_inspector); + delete m_inspector; + m_inspector = 0; } bool QmlInspectorPlugin::initialize(const QStringList &arguments, QString *errorString) @@ -79,42 +103,100 @@ bool QmlInspectorPlugin::initialize(const QStringList &arguments, QString *error Q_UNUSED(arguments); Q_UNUSED(errorString); - Core::ICore *core = Core::ICore::instance(); - Core::UniqueIDManager *uidm = core->uniqueIDManager(); + connect(Core::ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)), + SLOT(prepareDebugger(Core::IMode*))); + + ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); + Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>(); + uiSwitcher->addLanguage(Qml::Constants::LANG_QML); - QList<int> context; - context.append(uidm->uniqueIdentifier(QmlInspector::Constants::C_INSPECTOR)); - context.append(uidm->uniqueIdentifier(Core::Constants::C_EDITORMANAGER)); - context.append(uidm->uniqueIdentifier(Core::Constants::C_NAVIGATION_PANE)); + m_inspector = new QmlInspector; + addObject(m_inspector); - m_inspectMode = new QmlInspectorMode(this); - m_inspectMode->setContext(context); - addObject(m_inspectMode); + connect(m_connectionTimer, SIGNAL(timeout()), SLOT(pollInspector())); m_outputPane = new InspectorOutputPane; addObject(m_outputPane); - connect(m_inspectMode, SIGNAL(statusMessage(QString)), + connect(m_inspector, SIGNAL(statusMessage(QString)), m_outputPane, SLOT(addInspectorStatus(QString))); - connect(core->modeManager(), SIGNAL(currentModeChanged(Core::IMode*)), - SLOT(currentModeChanged(Core::IMode*))); - return true; } void QmlInspectorPlugin::extensionsInitialized() { + ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); + Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>(); + //connect(uiSwitcher, SIGNAL(languageChanged(QString)), SLOT(activateDebugger(QString))); + connect(uiSwitcher, SIGNAL(dockArranged(QString)), SLOT(setDockWidgetArrangement(QString))); + + ProjectExplorer::ProjectExplorerPlugin *pex = ProjectExplorer::ProjectExplorerPlugin::instance(); + if (pex) { + connect(pex, SIGNAL(aboutToExecuteProject(ProjectExplorer::Project*)), + SLOT(activateDebuggerForProject(ProjectExplorer::Project*))); + } + + QWidget *configBar = new QWidget; + configBar->setProperty("topBorder", true); + + QHBoxLayout *configBarLayout = new QHBoxLayout(configBar); + configBarLayout->setMargin(0); + configBarLayout->setSpacing(5); + + Core::ICore *core = Core::ICore::instance(); + Core::ActionManager *am = core->actionManager(); + configBarLayout->addWidget(createToolButton(am->command(ProjectExplorer::Constants::DEBUG)->action())); + configBarLayout->addWidget(createToolButton(am->command(ProjectExplorer::Constants::STOP)->action())); + + configBarLayout->addStretch(); + + uiSwitcher->setToolbar(Qml::Constants::LANG_QML, configBar); +} + +void QmlInspectorPlugin::activateDebugger(const QString &langName) +{ + if (langName == Qml::Constants::LANG_QML) { + m_inspector->connectToViewer(); + } } -void QmlInspectorPlugin::currentModeChanged(Core::IMode *mode) +void QmlInspectorPlugin::activateDebuggerForProject(ProjectExplorer::Project *project) +{ + QmlProjectManager::QmlProject *qmlproj = qobject_cast<QmlProjectManager::QmlProject*>(project); + if (qmlproj) + m_connectionTimer->start(); + +} +void QmlInspectorPlugin::pollInspector() { - if (mode == m_inspectMode) - m_inspectMode->connectToViewer(); + ++m_connectionAttempts; + if (m_inspector->connectToViewer() || m_connectionAttempts == MaxConnectionAttempts) { + m_connectionTimer->stop(); + m_connectionAttempts = 0; + } } +void QmlInspectorPlugin::prepareDebugger(Core::IMode *mode) +{ + if (mode->id() != Debugger::Constants::MODE_DEBUG) + return; -Q_EXPORT_PLUGIN(QmlInspectorPlugin) + Core::EditorManager *editorManager = Core::EditorManager::instance(); -QT_END_NAMESPACE + if (editorManager->currentEditor() && + editorManager->currentEditor()->id() == QmlJSEditor::Constants::C_QMLJSEDITOR_ID) { + ExtensionSystem::PluginManager *pluginManager = ExtensionSystem::PluginManager::instance(); + Debugger::DebuggerUISwitcher *uiSwitcher = pluginManager->getObject<Debugger::DebuggerUISwitcher>(); + uiSwitcher->setActiveLanguage(Qml::Constants::LANG_QML); + } +} +void QmlInspectorPlugin::setDockWidgetArrangement(const QString &activeLanguage) +{ + if (activeLanguage == Qml::Constants::LANG_QML || activeLanguage.isEmpty()) + m_inspector->setSimpleDockWidgetArrangement(); +} + + +Q_EXPORT_PLUGIN(QmlInspectorPlugin) diff --git a/src/plugins/qmlinspector/qmlinspectorplugin.h b/src/plugins/qmlinspector/qmlinspectorplugin.h index ccec2f9b7c5..240092e2b2a 100644 --- a/src/plugins/qmlinspector/qmlinspectorplugin.h +++ b/src/plugins/qmlinspector/qmlinspectorplugin.h @@ -33,19 +33,24 @@ #include <QtCore/QObject> #include <QtCore/QPointer> - -QT_BEGIN_NAMESPACE +#include <QtCore/QTimer> class QStringList; -class QmlInspectorMode; -class InspectorOutputPane; +namespace ProjectExplorer { + class Project; +} -namespace Core -{ +namespace Core { class IMode; } +namespace Qml { + class QmlInspector; + class InspectorOutputPane; + +const int MaxConnectionAttempts = 20; + class QmlInspectorPlugin : public ExtensionSystem::IPlugin { Q_OBJECT @@ -58,14 +63,23 @@ public: virtual void extensionsInitialized(); virtual void shutdown(); +public slots: + void activateDebugger(const QString &langName); + void activateDebuggerForProject(ProjectExplorer::Project *project); + void setDockWidgetArrangement(const QString &activeLanguage); + private slots: - void currentModeChanged(Core::IMode *mode); + void pollInspector(); + void prepareDebugger(Core::IMode *mode); private: - QmlInspectorMode *m_inspectMode; + QmlInspector *m_inspector; InspectorOutputPane *m_outputPane; + QTimer *m_connectionTimer; + int m_connectionAttempts; }; +} QT_END_NAMESPACE diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index 8ff1071ee53..e6809c25a53 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -31,6 +31,10 @@ #include "qmlprojectconstants.h" #include "qmltarget.h" +#include "qmlinspector/qmlinspector.h" +#include "qmlinspector/qmlinspectorconstants.h" + +#include <debugger/debuggeruiswitcher.h> #include <projectexplorer/toolchain.h> #include <projectexplorer/persistentsettings.h> #include <projectexplorer/projectexplorerconstants.h> @@ -40,7 +44,6 @@ #include <coreplugin/icore.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/ieditor.h> -#include <coreplugin/modemanager.h> #include <qmljseditor/qmlmodelmanagerinterface.h> @@ -73,6 +76,7 @@ const char * const QML_RC_DISPLAY_NAME(QT_TRANSLATE_NOOP("QmlProjectManager::Int const char * const QML_VIEWER_KEY("QmlProjectManager.QmlRunConfiguration.QmlViewer"); const char * const QML_VIEWER_ARGUMENTS_KEY("QmlProjectManager.QmlRunConfiguration.QmlViewerArguments"); const char * const QML_MAINSCRIPT_KEY("QmlProjectManager.QmlRunConfiguration.MainScript"); +const char * const QML_DEBUG_SERVER_ADDRESS_KEY("QmlProjectManager.QmlRunConfiguration.DebugServerAddress"); const char * const QML_DEBUG_SERVER_PORT_KEY("QmlProjectManager.QmlRunConfiguration.DebugServerPort"); const int DEFAULT_DEBUG_SERVER_PORT(3768); @@ -369,6 +373,7 @@ void QmlProjectFile::modified(ReloadBehavior *) QmlRunConfiguration::QmlRunConfiguration(QmlTarget *parent) : ProjectExplorer::RunConfiguration(parent, QLatin1String(QML_RC_ID)), + m_debugServerAddress("127.0.0.1"), m_debugServerPort(DEFAULT_DEBUG_SERVER_PORT) { ctor(); @@ -379,6 +384,7 @@ QmlRunConfiguration::QmlRunConfiguration(QmlTarget *parent, QmlRunConfiguration m_scriptFile(source->m_scriptFile), m_qmlViewerCustomPath(source->m_qmlViewerCustomPath), m_qmlViewerArgs(source->m_qmlViewerArgs), + m_debugServerAddress(source->m_debugServerAddress), m_debugServerPort(source->m_debugServerPort) { ctor(); @@ -437,6 +443,11 @@ QString QmlRunConfiguration::workingDirectory() const return projectFile.absolutePath(); } +QString QmlRunConfiguration::debugServerAddress() const +{ + return m_debugServerAddress; +} + uint QmlRunConfiguration::debugServerPort() const { return m_debugServerPort; @@ -483,6 +494,10 @@ QWidget *QmlRunConfiguration::configurationWidget() qmlViewerArgs->setText(m_qmlViewerArgs); connect(qmlViewerArgs, SIGNAL(textChanged(QString)), this, SLOT(onQmlViewerArgsChanged())); + QLineEdit *debugServer = new QLineEdit; + debugServer->setText(m_debugServerAddress); + connect(debugServer, SIGNAL(textChanged(QString)), this, SLOT(onDebugServerAddressChanged())); + QSpinBox *debugPort = new QSpinBox; debugPort->setMinimum(1024); // valid registered/dynamic/free ports according to http://www.iana.org/assignments/port-numbers debugPort->setMaximum(65535); @@ -492,6 +507,7 @@ QWidget *QmlRunConfiguration::configurationWidget() form->addRow(tr("QML Viewer"), qmlViewer); form->addRow(tr("QML Viewer arguments:"), qmlViewerArgs); form->addRow(tr("Main QML File:"), combo); + form->addRow(tr("Debugging Address:"), debugServer); form->addRow(tr("Debugging Port:"), debugPort); return config; @@ -527,6 +543,12 @@ void QmlRunConfiguration::onQmlViewerArgsChanged() m_qmlViewerArgs = lineEdit->text(); } +void QmlRunConfiguration::onDebugServerAddressChanged() +{ + if (QLineEdit *lineEdit = qobject_cast<QLineEdit*>(sender())) + m_debugServerAddress = lineEdit->text(); +} + void QmlRunConfiguration::onDebugServerPortChanged() { if (QSpinBox *spinBox = qobject_cast<QSpinBox*>(sender())) { @@ -541,6 +563,7 @@ QVariantMap QmlRunConfiguration::toMap() const map.insert(QLatin1String(QML_VIEWER_KEY), m_qmlViewerCustomPath); map.insert(QLatin1String(QML_VIEWER_ARGUMENTS_KEY), m_qmlViewerArgs); map.insert(QLatin1String(QML_MAINSCRIPT_KEY), m_scriptFile); + map.insert(QLatin1String(QML_DEBUG_SERVER_ADDRESS_KEY), m_debugServerAddress); map.insert(QLatin1String(QML_DEBUG_SERVER_PORT_KEY), m_debugServerPort); return map; } @@ -550,6 +573,7 @@ bool QmlRunConfiguration::fromMap(const QVariantMap &map) m_qmlViewerCustomPath = map.value(QLatin1String(QML_VIEWER_KEY)).toString(); m_qmlViewerArgs = map.value(QLatin1String(QML_VIEWER_ARGUMENTS_KEY)).toString(); m_scriptFile = map.value(QLatin1String(QML_MAINSCRIPT_KEY), tr("<Current File>")).toString(); + m_debugServerAddress = map.value(QLatin1String(QML_DEBUG_SERVER_ADDRESS_KEY)).toString(); m_debugServerPort = map.value(QLatin1String(QML_DEBUG_SERVER_PORT_KEY), DEFAULT_DEBUG_SERVER_PORT).toUInt(); return RunConfiguration::fromMap(map); @@ -662,6 +686,7 @@ QmlRunControl::~QmlRunControl() void QmlRunControl::start() { m_applicationLauncher.start(ApplicationLauncher::Gui, m_executable, m_commandLineArguments); + emit started(); emit addToOutputWindow(this, tr("Starting %1 %2").arg(QDir::toNativeSeparators(m_executable), m_commandLineArguments.join(QLatin1String(" ")))); @@ -691,8 +716,8 @@ void QmlRunControl::slotError(const QString &err) void QmlRunControl::slotAddToOutputWindow(const QString &line) { if (m_debugMode && line.startsWith("QmlDebugServer: Waiting for connection")) { - Core::ICore *core = Core::ICore::instance(); - core->modeManager()->activateMode(QLatin1String("QML_INSPECT_MODE")); + Debugger::DebuggerUISwitcher *uiSwitcher = Debugger::DebuggerUISwitcher::instance(); + uiSwitcher->setActiveLanguage(Qml::Constants::LANG_QML); } emit addToOutputWindowInline(this, line); diff --git a/src/plugins/qmlprojectmanager/qmlproject.h b/src/plugins/qmlprojectmanager/qmlproject.h index cd9edd84f92..e8913891750 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.h +++ b/src/plugins/qmlprojectmanager/qmlproject.h @@ -226,6 +226,7 @@ public: QString viewerPath() const; QStringList viewerArguments() const; QString workingDirectory() const; + QString debugServerAddress() const; uint debugServerPort() const; // RunConfiguration @@ -238,6 +239,7 @@ private slots: void setMainScript(const QString &scriptFile); void onQmlViewerChanged(); void onQmlViewerArgsChanged(); + void onDebugServerAddressChanged(); void onDebugServerPortChanged(); protected: @@ -251,6 +253,7 @@ private: QString m_qmlViewerCustomPath; QString m_qmlViewerDefaultPath; QString m_qmlViewerArgs; + QString m_debugServerAddress; uint m_debugServerPort; }; -- GitLab