diff options
Diffstat (limited to 'src/plugins/debugger')
-rw-r--r-- | src/plugins/debugger/debugger.pro | 9 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerconstants.h | 2 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermainwindow.cpp | 60 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermainwindow.h | 28 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermanager.cpp | 123 | ||||
-rw-r--r-- | src/plugins/debugger/debuggermanager.h | 6 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerplugin.cpp | 272 | ||||
-rw-r--r-- | src/plugins/debugger/debuggerplugin.h | 8 | ||||
-rw-r--r-- | src/plugins/debugger/debuggeruiswitcher.cpp | 381 | ||||
-rw-r--r-- | src/plugins/debugger/debuggeruiswitcher.h | 114 | ||||
-rw-r--r-- | src/plugins/debugger/gdb/gdbengine.cpp | 4 |
11 files changed, 772 insertions, 235 deletions
diff --git a/src/plugins/debugger/debugger.pro b/src/plugins/debugger/debugger.pro index d9e161749a..7e1b1690ef 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 9b6cdb636c..5049ec011c 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 0000000000..d35103acf2 --- /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 0000000000..8ebc099ccc --- /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 06fad14ba0..f95c6c30c4 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 55f03a055f..03379797e9 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 67788f74ed..85885e6d78 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 db064b20b2..ea15577f7e 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 0000000000..a972b61734 --- /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 0000000000..85e09af9d6 --- /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 a82d09fb66..13c659836d 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() |