diff --git a/src/plugins/analyzerbase/analyzermanager.cpp b/src/plugins/analyzerbase/analyzermanager.cpp index 9607645311b8a01b4da625c3142ec84fd424cb63..ee77d45f13a79f8efb7bb2b0e263b3c2368ffbed 100644 --- a/src/plugins/analyzerbase/analyzermanager.cpp +++ b/src/plugins/analyzerbase/analyzermanager.cpp @@ -165,6 +165,15 @@ public: } }; +struct ToolDockWidgetData +{ + ToolDockWidgetData(Qt::DockWidgetArea a, QDockWidget *w, QDockWidget *t) : + area(a), widget(w), tabifyTo(t) {} + + Qt::DockWidgetArea area; + QDockWidget *widget; + QDockWidget *tabifyTo; +}; } // namespace Internal } // namespace Analyzer @@ -212,12 +221,11 @@ public: QStackedWidget *m_controlsWidget; ActionContainer *m_viewsMenu; Utils::StatusLabel *m_statusLabel; - typedef QPair<Qt::DockWidgetArea, QDockWidget *> ToolWidgetPair; - typedef QList<ToolWidgetPair> ToolWidgetPairList; - QMap<IAnalyzerTool *, ToolWidgetPairList> m_toolWidgets; + typedef QMap<IAnalyzerTool *, FancyMainWindowSettings> MainWindowSettingsMap; + QMap<IAnalyzerTool *, QList<ToolDockWidgetData> > m_toolWidgets; DockWidgetEventFilter *m_resizeEventFilter; - QMap<IAnalyzerTool *, FancyMainWindowSettings> m_defaultSettings; + MainWindowSettingsMap m_defaultSettings; // list of dock widgets to prevent memory leak typedef QWeakPointer<QDockWidget> DockPtr; @@ -225,6 +233,7 @@ public: bool m_restartOnStop; bool m_initialized; + IAnalyzerTool *m_currentTool; }; AnalyzerManager::AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager *qq): @@ -245,7 +254,8 @@ AnalyzerManager::AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager m_statusLabel(new Utils::StatusLabel), m_resizeEventFilter(new DockWidgetEventFilter(qq)), m_restartOnStop(false), - m_initialized(false) + m_initialized(false), + m_currentTool(0) { m_toolBox->setObjectName(QLatin1String("AnalyzerManagerToolBox")); m_runControlFactory = new AnalyzerRunControlFactory(); @@ -640,37 +650,49 @@ void AnalyzerManager::selectTool(IAnalyzerTool *tool) void AnalyzerManager::toolSelected(int idx) { static bool selectingTool = false; - if (selectingTool) + + IAnalyzerTool *oldTool = currentTool(); + IAnalyzerTool *newTool = d->m_tools.at(idx); + + if (selectingTool || oldTool == newTool) return; + selectingTool = true; - IAnalyzerTool *oldTool = currentTool(); if (oldTool != 0) { saveToolSettings(oldTool); ActionManager *am = ICore::instance()->actionManager(); - foreach(const AnalyzerManagerPrivate::ToolWidgetPair &widget, d->m_toolWidgets.value(oldTool)) { - QAction *toggleViewAction = widget.second->toggleViewAction(); - am->unregisterAction(toggleViewAction, QString("Analyzer." + widget.second->objectName())); - d->m_mainWindow->removeDockWidget(widget.second); + foreach (const ToolDockWidgetData &widget, d->m_toolWidgets.value(oldTool)) { + QAction *toggleViewAction = widget.widget->toggleViewAction(); + am->unregisterAction(toggleViewAction, QString("Analyzer." + widget.widget->objectName())); + d->m_mainWindow->removeDockWidget(widget.widget); ///NOTE: QMainWindow (and FancyMainWindow) just look at @c findChildren<QDockWidget*>() ///if we don't do this, all kind of havoc might happen, including: ///- improper saveState/restoreState ///- improper list of qdockwidgets in popup menu ///- ... - widget.second->setParent(0); + widget.widget->setParent(0); } } + d->m_currentTool = newTool; + d->m_toolGroup->actions().at(idx)->setChecked(true); d->m_toolBox->setCurrentIndex(idx); d->m_controlsWidget->setCurrentIndex(idx); - IAnalyzerTool *newTool = currentTool(); - foreach (const AnalyzerManagerPrivate::ToolWidgetPair &widget, d->m_toolWidgets.value(newTool)) { - d->addDock(newTool, widget.first, widget.second); + const bool firstTime = !d->m_defaultSettings.contains(newTool); + foreach (const ToolDockWidgetData &widget, d->m_toolWidgets.value(newTool)) { + d->addDock(newTool, widget.area, widget.widget); + if (firstTime && widget.tabifyTo) + d->m_mainWindow->tabifyDockWidget(widget.tabifyTo, widget.widget); } + + if (firstTime) // Save default settings first time + d->m_defaultSettings.insert(newTool, d->m_mainWindow->saveSettings()); + loadToolSettings(newTool); d->m_outputpane->setTool(newTool); @@ -694,6 +716,7 @@ void AnalyzerManager::addTool(IAnalyzerTool *tool) QAction *action = new QAction(tool->displayName(), d->m_toolGroup); action->setData(d->m_tools.count()); action->setCheckable(true); + action->setChecked(false); ActionManager *am = Core::ICore::instance()->actionManager(); @@ -703,24 +726,26 @@ void AnalyzerManager::addTool(IAnalyzerTool *tool) d->m_toolGroup->setVisible(d->m_toolGroup->actions().count() > 1); d->m_tools.append(tool); + + const bool blocked = d->m_toolBox->blockSignals(true); // Do not make current. d->m_toolBox->addItem(tool->displayName()); + d->m_toolBox->blockSignals(blocked); + // Populate output pane + d->m_outputpane->setTool(tool); // populate controls widget QWidget *controlWidget = tool->createControlWidget(); // might be 0 d->m_controlsWidget->addWidget(controlWidget ? controlWidget : AnalyzerUtils::createDummyWidget()); d->m_toolBox->setEnabled(d->m_toolBox->count() > 1); - if (currentTool() != tool) - selectTool(tool); // the first tool gets selected automatically due to signal emission from toolbox tool->initialize(plugin); - d->m_defaultSettings.insert(tool, d->m_mainWindow->saveSettings()); - loadToolSettings(tool); } QDockWidget *AnalyzerManager::createDockWidget(IAnalyzerTool *tool, const QString &title, - QWidget *widget, Qt::DockWidgetArea area) + QWidget *widget, Qt::DockWidgetArea area, + QDockWidget *tabifyTo) { QTC_ASSERT(!widget->objectName().isEmpty(), return 0;); @@ -728,19 +753,14 @@ QDockWidget *AnalyzerManager::createDockWidget(IAnalyzerTool *tool, const QStrin d->m_dockWidgets << AnalyzerManagerPrivate::DockPtr(dockWidget); dockWidget->setWindowTitle(title); - d->m_toolWidgets[tool] << qMakePair(area, dockWidget); + d->m_toolWidgets[tool].push_back(ToolDockWidgetData(area, dockWidget, tabifyTo)); dockWidget->installEventFilter(d->m_resizeEventFilter); - - d->addDock(tool, area, dockWidget); - return dockWidget; } IAnalyzerTool *AnalyzerManager::currentTool() const { - if (const QAction *ca = d->m_toolGroup->checkedAction()) - return d->m_tools.value(ca->data().toInt()); - return 0; + return d->m_currentTool; } QList<IAnalyzerTool *> AnalyzerManager::tools() const diff --git a/src/plugins/analyzerbase/analyzermanager.h b/src/plugins/analyzerbase/analyzermanager.h index 3d2463fe5ee53879cb60ff52f8dac5c2f3f0d97e..db39828337489262521dd72ca3db009298926b4b 100644 --- a/src/plugins/analyzerbase/analyzermanager.h +++ b/src/plugins/analyzerbase/analyzermanager.h @@ -89,7 +89,8 @@ public: // dockwidgets are registered to the main window QDockWidget *createDockWidget(IAnalyzerTool *tool, const QString &title, QWidget *widget, - Qt::DockWidgetArea area = Qt::TopDockWidgetArea); + Qt::DockWidgetArea area = Qt::TopDockWidgetArea, + QDockWidget *tabifyTo = 0); Utils::FancyMainWindow *mainWindow() const; diff --git a/src/plugins/analyzerbase/analyzerplugin.cpp b/src/plugins/analyzerbase/analyzerplugin.cpp index fb399641c6896034623ebb682f7dcf98676384fa..6a8da8b38a9e701c71dfd8b8e888c40fd2b13be8 100644 --- a/src/plugins/analyzerbase/analyzerplugin.cpp +++ b/src/plugins/analyzerbase/analyzerplugin.cpp @@ -129,19 +129,24 @@ void AnalyzerPlugin::extensionsInitialized() // plugins that depend on it are completely initialized." // notify tools about the extensions initialized state - foreach(IAnalyzerTool *tool, d->m_manager->tools()) { + const QList<IAnalyzerTool *> tools = d->m_manager->tools(); + if (tools.isEmpty()) + return; + + const QSettings *settings = Core::ICore::instance()->settings(); + const QString lastActiveToolId = settings->value(QLatin1String(lastActiveToolC), QString()).toString(); + IAnalyzerTool *lastActiveTool = 0; + + foreach (IAnalyzerTool *tool, tools) { tool->extensionsInitialized(); + if (tool->id() == lastActiveToolId) + lastActiveTool = tool; } - // load the last active tool - QSettings *settings = Core::ICore::instance()->settings(); - const QString lastActiveTool = settings->value(lastActiveToolC, QString()).toString(); - foreach(IAnalyzerTool *tool, d->m_manager->tools()) { - if (tool->id() == lastActiveTool) { - d->m_manager->selectTool(tool); - break; - } - } + if (!lastActiveTool) + lastActiveTool = tools.back(); + if (lastActiveTool) + d->m_manager->selectTool(lastActiveTool); } ExtensionSystem::IPlugin::ShutdownFlag AnalyzerPlugin::aboutToShutdown() diff --git a/src/plugins/callgrind/callgrindtool.cpp b/src/plugins/callgrind/callgrindtool.cpp index 32c1ffe3a6426d30b6f1aebcbea755c95f0d570a..a0fe5751493e8d38bb1ffa9851d171423f5fdfab 100644 --- a/src/plugins/callgrind/callgrindtool.cpp +++ b/src/plugins/callgrind/callgrindtool.cpp @@ -164,16 +164,16 @@ void CallgrindTool::initialize(ExtensionSystem::IPlugin */*plugin*/) CallgrindWidgetHandler *handler = new CallgrindWidgetHandler(am->mainWindow()); m_callgrindWidgetHandler = handler; - QDockWidget *visDock = am->createDockWidget(this, tr("Visualisation"), - handler->visualisation(), Qt::LeftDockWidgetArea); - - QDockWidget *calleesDock = am->createDockWidget(this, tr("Callees"), - handler->calleesView(), Qt::BottomDockWidgetArea); QDockWidget *callersDock = am->createDockWidget(this, tr("Callers"), handler->callersView(), Qt::BottomDockWidgetArea); - am->mainWindow()->tabifyDockWidget(callersDock, calleesDock); - am->mainWindow()->tabifyDockWidget(calleesDock, visDock); + QDockWidget *calleesDock = am->createDockWidget(this, tr("Callees"), + handler->calleesView(), Qt::BottomDockWidgetArea, + callersDock); + + am->createDockWidget(this, tr("Visualisation"), + handler->visualisation(), Qt::LeftDockWidgetArea, + calleesDock); connect(m_callgrindWidgetHandler, SIGNAL(functionSelected(const Valgrind::Callgrind::Function*)), this, SLOT(slotFunctionSelected(const Valgrind::Callgrind::Function*)));