diff --git a/src/plugins/analyzerbase/analyzermanager.cpp b/src/plugins/analyzerbase/analyzermanager.cpp index 27f4089fc8d..8ea59189e16 100644 --- a/src/plugins/analyzerbase/analyzermanager.cpp +++ b/src/plugins/analyzerbase/analyzermanager.cpp @@ -167,12 +167,11 @@ public: struct ToolDockWidgetData { - ToolDockWidgetData(Qt::DockWidgetArea a, QDockWidget *w, QDockWidget *t) : - area(a), widget(w), tabifyTo(t) {} + ToolDockWidgetData(Qt::DockWidgetArea a, QDockWidget *w) : + area(a), widget(w) {} Qt::DockWidgetArea area; QDockWidget *widget; - QDockWidget *tabifyTo; }; } // namespace Internal } // namespace Analyzer @@ -684,14 +683,13 @@ void AnalyzerManager::toolSelected(int idx) d->m_controlsWidget->setCurrentIndex(idx); 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 + if (firstTime) { + newTool->initializeDockWidgets(); d->m_defaultSettings.insert(newTool, d->m_mainWindow->saveSettings()); + } else { + foreach (const ToolDockWidgetData &widget, d->m_toolWidgets.value(newTool)) + d->addDock(newTool, widget.area, widget.widget); + } loadToolSettings(newTool); d->m_outputpane->setTool(newTool); @@ -744,8 +742,7 @@ void AnalyzerManager::addTool(IAnalyzerTool *tool) } QDockWidget *AnalyzerManager::createDockWidget(IAnalyzerTool *tool, const QString &title, - QWidget *widget, Qt::DockWidgetArea area, - QDockWidget *tabifyTo) + QWidget *widget, Qt::DockWidgetArea area) { QTC_ASSERT(!widget->objectName().isEmpty(), return 0;); @@ -753,7 +750,8 @@ QDockWidget *AnalyzerManager::createDockWidget(IAnalyzerTool *tool, const QStrin d->m_dockWidgets << AnalyzerManagerPrivate::DockPtr(dockWidget); dockWidget->setWindowTitle(title); - d->m_toolWidgets[tool].push_back(ToolDockWidgetData(area, dockWidget, tabifyTo)); + d->m_toolWidgets[tool].push_back(ToolDockWidgetData(area, dockWidget)); + d->addDock(tool, area, dockWidget); dockWidget->installEventFilter(d->m_resizeEventFilter); return dockWidget; } diff --git a/src/plugins/analyzerbase/analyzermanager.h b/src/plugins/analyzerbase/analyzermanager.h index 5cbe9dec6e4..e41cd71b8cd 100644 --- a/src/plugins/analyzerbase/analyzermanager.h +++ b/src/plugins/analyzerbase/analyzermanager.h @@ -89,8 +89,7 @@ public: // dockwidgets are registered to the main window QDockWidget *createDockWidget(IAnalyzerTool *tool, const QString &title, QWidget *widget, - Qt::DockWidgetArea area = Qt::TopDockWidgetArea, - QDockWidget *tabifyTo = 0); + Qt::DockWidgetArea area = Qt::TopDockWidgetArea); Utils::FancyMainWindow *mainWindow() const; diff --git a/src/plugins/analyzerbase/ianalyzertool.cpp b/src/plugins/analyzerbase/ianalyzertool.cpp index 540877ded78..40f51b6a3c3 100644 --- a/src/plugins/analyzerbase/ianalyzertool.cpp +++ b/src/plugins/analyzerbase/ianalyzertool.cpp @@ -54,6 +54,10 @@ IAnalyzerOutputPaneAdapter *IAnalyzerTool::outputPaneAdapter() return 0; } +void IAnalyzerTool::initializeDockWidgets() +{ +} + QWidget *IAnalyzerTool::createControlWidget() { return 0; diff --git a/src/plugins/analyzerbase/ianalyzertool.h b/src/plugins/analyzerbase/ianalyzertool.h index bc966893b6f..b05c99acdeb 100644 --- a/src/plugins/analyzerbase/ianalyzertool.h +++ b/src/plugins/analyzerbase/ianalyzertool.h @@ -97,6 +97,12 @@ public: /// gets called after all analyzation tools where initialized. virtual void extensionsInitialized() = 0; + /** + * Called to add all dock widgets if tool becomes active first time. + * \sa AnalzyerManager::createDockWidget + */ + virtual void initializeDockWidgets(); + virtual IAnalyzerOutputPaneAdapter *outputPaneAdapter(); /// subclass to return a control widget which will be shown /// in the output pane when this tool is selected diff --git a/src/plugins/callgrind/callgrindtool.cpp b/src/plugins/callgrind/callgrindtool.cpp index 60b66329bca..e8b5b23265e 100644 --- a/src/plugins/callgrind/callgrindtool.cpp +++ b/src/plugins/callgrind/callgrindtool.cpp @@ -163,21 +163,32 @@ void CallgrindTool::initialize(ExtensionSystem::IPlugin */*plugin*/) CallgrindWidgetHandler *handler = new CallgrindWidgetHandler(am->mainWindow()); m_callgrindWidgetHandler = handler; - QDockWidget *callersDock = am->createDockWidget(this, tr("Callers"), - handler->callersView(), Qt::BottomDockWidgetArea); - - 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*))); } +void CallgrindTool::initializeDockWidgets() +{ + AnalyzerManager *am = AnalyzerManager::instance(); + + QDockWidget *callersDock = + am->createDockWidget(this, tr("Callers"), + m_callgrindWidgetHandler->callersView(), + Qt::BottomDockWidgetArea); + + QDockWidget *calleesDock = + am->createDockWidget(this, tr("Callees"), + m_callgrindWidgetHandler->calleesView(), + Qt::BottomDockWidgetArea); + + QDockWidget *visDock = + am->createDockWidget(this, tr("Visualisation"), + m_callgrindWidgetHandler->visualisation(), Qt::LeftDockWidgetArea); + + am->mainWindow()->tabifyDockWidget(callersDock, calleesDock); + am->mainWindow()->tabifyDockWidget(calleesDock, visDock); +} + void CallgrindTool::extensionsInitialized() { Core::ICore *core = Core::ICore::instance(); diff --git a/src/plugins/callgrind/callgrindtool.h b/src/plugins/callgrind/callgrindtool.h index 8425abcdad0..6cee518729e 100644 --- a/src/plugins/callgrind/callgrindtool.h +++ b/src/plugins/callgrind/callgrindtool.h @@ -89,6 +89,7 @@ public: virtual void initialize(ExtensionSystem::IPlugin *plugin); virtual void extensionsInitialized(); + virtual void initializeDockWidgets(); virtual Analyzer::IAnalyzerOutputPaneAdapter *outputPaneAdapter(); virtual Analyzer::IAnalyzerEngine *createEngine(const Analyzer::AnalyzerStartParameters &sp, diff --git a/src/plugins/callgrind/callgrindwidgethandler.cpp b/src/plugins/callgrind/callgrindwidgethandler.cpp index 28d5f4b3275..84ce572a463 100644 --- a/src/plugins/callgrind/callgrindwidgethandler.cpp +++ b/src/plugins/callgrind/callgrindwidgethandler.cpp @@ -121,27 +121,20 @@ CallgrindWidgetHandler::CallgrindWidgetHandler(QWidget *parent) m_flatView->setObjectName("Valgrind.CallgrindWidgetHandler.FlatView"); connect(m_flatView, SIGNAL(activated(QModelIndex)), this, SLOT(dataFunctionSelected(QModelIndex))); +} - m_visualisation = new Visualisation(parent); +void CallgrindWidgetHandler::ensureDockWidgets() +{ + if (m_visualisation) + return; + QWidget *parenWidget = qobject_cast(parent()); + m_visualisation = new Visualisation(parenWidget); m_visualisation->setObjectName("Valgrind.CallgrindWidgetHandler.Visualisation"); m_visualisation->setModel(m_dataModel); connect(m_visualisation, SIGNAL(functionActivated(const Valgrind::Callgrind::Function*)), this, SLOT(visualisationFunctionSelected(const Valgrind::Callgrind::Function*))); - { - m_calleesView = new CostView(parent); - m_calleesView->sortByColumn(CallModel::CostColumn); - m_calleesView->setObjectName("Valgrind.CallgrindWidgetHandler.CalleesView"); - // enable sorting - QSortFilterProxyModel *calleeProxy = new QSortFilterProxyModel(m_calleesModel); - calleeProxy->setSourceModel(m_calleesModel); - m_calleesView->setModel(calleeProxy); - m_calleesView->hideColumn(CallModel::CallerColumn); - connect(m_calleesView, SIGNAL(activated(QModelIndex)), - this, SLOT(calleeFunctionSelected(QModelIndex))); - } - { - m_callersView = new CostView(parent); + m_callersView = new CostView(parenWidget); m_callersView->sortByColumn(CallModel::CostColumn); m_callersView->setObjectName("Valgrind.CallgrindWidgetHandler.CallersView"); // enable sorting @@ -151,7 +144,36 @@ CallgrindWidgetHandler::CallgrindWidgetHandler(QWidget *parent) m_callersView->hideColumn(CallModel::CalleeColumn); connect(m_callersView, SIGNAL(activated(QModelIndex)), this, SLOT(callerFunctionSelected(QModelIndex))); - } + + m_calleesView = new CostView(parenWidget); + m_calleesView->sortByColumn(CallModel::CostColumn); + m_calleesView->setObjectName("Valgrind.CallgrindWidgetHandler.CalleesView"); + // enable sorting + QSortFilterProxyModel *calleeProxy = new QSortFilterProxyModel(m_calleesModel); + calleeProxy->setSourceModel(m_calleesModel); + m_calleesView->setModel(calleeProxy); + m_calleesView->hideColumn(CallModel::CallerColumn); + connect(m_calleesView, SIGNAL(activated(QModelIndex)), + this, SLOT(calleeFunctionSelected(QModelIndex))); + updateCostFormat(); +} + +Visualisation *CallgrindWidgetHandler::visualisation() +{ + ensureDockWidgets(); + return m_visualisation; +} + +CostView *CallgrindWidgetHandler::callersView() +{ + ensureDockWidgets(); + return m_callersView; +} + +CostView *CallgrindWidgetHandler::calleesView() +{ + ensureDockWidgets(); + return m_calleesView; } void CallgrindWidgetHandler::populateActions(QLayout *layout) @@ -284,7 +306,7 @@ void CallgrindWidgetHandler::populateActions(QLayout *layout) CallgrindWidgetHandler::~CallgrindWidgetHandler() { - slotClear(); + doClear(false); } void CallgrindWidgetHandler::slotGoToOverview() @@ -294,7 +316,13 @@ void CallgrindWidgetHandler::slotGoToOverview() void CallgrindWidgetHandler::slotClear() { - setParseData(0); + doClear(true); +} + +void CallgrindWidgetHandler::doClear(bool clearParseData) +{ + if (clearParseData) // Crashed when done from destructor. + setParseData(0); // clear filters m_filterProjectCosts->setChecked(false); @@ -388,20 +416,27 @@ void CallgrindWidgetHandler::enableCycleDetection(bool enabled) m_cycleDetection->setChecked(enabled); } +// Following functions can be called with actions=0 or widgets=0 +// depending on initialization sequence (whether callgrind was current). +Callgrind::Internal::CostDelegate::CostFormat + CallgrindWidgetHandler::costFormat() const +{ + if (m_costRelativeToParent && m_costRelativeToParent->isChecked()) + return CostDelegate::FormatRelativeToParent; + if (m_costRelative && m_costRelative->isChecked()) + return CostDelegate::FormatRelative; + return CostDelegate::FormatAbsolute; +} + void CallgrindWidgetHandler::updateCostFormat() { - CostDelegate::CostFormat format = CostDelegate::FormatAbsolute; - - if (m_costRelativeToParent->isChecked()) - format = CostDelegate::FormatRelativeToParent; - else if (m_costRelative->isChecked()) - format = CostDelegate::FormatRelative; - // else = Absolute - - m_flatView->setCostFormat(format); - m_calleesView->setCostFormat(format); - m_callersView->setCostFormat(format); - + const CostDelegate::CostFormat format = costFormat(); + if (m_flatView) + m_flatView->setCostFormat(format); + if (m_calleesView) { + m_calleesView->setCostFormat(format); + m_callersView->setCostFormat(format); + } emit costFormatChanged(format); } diff --git a/src/plugins/callgrind/callgrindwidgethandler.h b/src/plugins/callgrind/callgrindwidgethandler.h index 350e399d20e..650890d50f3 100644 --- a/src/plugins/callgrind/callgrindwidgethandler.h +++ b/src/plugins/callgrind/callgrindwidgethandler.h @@ -84,12 +84,14 @@ public: Valgrind::Callgrind::DataModel *dataModel() const { return m_dataModel; } Valgrind::Callgrind::DataProxyModel *proxyModel() const { return m_dataProxy; } CostView *flatView() const { return m_flatView; } - Visualisation *visualisation() const { return m_visualisation; } + Visualisation *visualisation(); Valgrind::Callgrind::CallModel *callersModel() const { return m_callersModel; } - CostView *callersView() const { return m_callersView; } + CostView *callersView(); Valgrind::Callgrind::CallModel *calleesModel() const { return m_calleesModel; } - CostView *calleesView() const { return m_calleesView; } + CostView *calleesView(); + + Callgrind::Internal::CostDelegate::CostFormat costFormat() const; signals: void dumpRequested(); @@ -125,6 +127,8 @@ private slots: void visualisationFunctionSelected(const Valgrind::Callgrind::Function *function); private: + void ensureDockWidgets(); + void doClear(bool clearParseData); void updateEventCombo(); Valgrind::Callgrind::DataModel *m_dataModel;