forked from qt-creator/qt-creator
Remove 'Analyze' mode.
- Introduce a shared analysis output pane using a stacked widgets, layouts for the tools' output panes and toolbar widgets. - Introduce IAnalyzerOutputPaneAdapter interface returned by IAnalyzerTool to manage them. - Remove mode and its mainwindow contents (depending on enum constants should use cases for it occur). Reviewed-by: con
This commit is contained in:
@@ -18,7 +18,8 @@ SOURCES += \
|
|||||||
analyzermanager.cpp \
|
analyzermanager.cpp \
|
||||||
analyzersettings.cpp \
|
analyzersettings.cpp \
|
||||||
analyzeroptionspage.cpp \
|
analyzeroptionspage.cpp \
|
||||||
analyzerrunconfigwidget.cpp
|
analyzerrunconfigwidget.cpp \
|
||||||
|
analyzeroutputpane.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
ianalyzerengine.h \
|
ianalyzerengine.h \
|
||||||
@@ -30,7 +31,8 @@ HEADERS += \
|
|||||||
analyzermanager.h \
|
analyzermanager.h \
|
||||||
analyzersettings.h \
|
analyzersettings.h \
|
||||||
analyzeroptionspage.h \
|
analyzeroptionspage.h \
|
||||||
analyzerrunconfigwidget.h
|
analyzerrunconfigwidget.h \
|
||||||
|
analyzeroutputpane.h
|
||||||
|
|
||||||
RESOURCES += \
|
RESOURCES += \
|
||||||
analyzerbase.qrc
|
analyzerbase.qrc
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
#include "analyzerplugin.h"
|
#include "analyzerplugin.h"
|
||||||
#include "analyzerruncontrol.h"
|
#include "analyzerruncontrol.h"
|
||||||
#include "analyzeroptionspage.h"
|
#include "analyzeroptionspage.h"
|
||||||
|
#include "analyzeroutputpane.h"
|
||||||
|
|
||||||
#include <coreplugin/actionmanager/command.h>
|
#include <coreplugin/actionmanager/command.h>
|
||||||
#include <coreplugin/findplaceholder.h>
|
#include <coreplugin/findplaceholder.h>
|
||||||
@@ -94,6 +95,11 @@ using namespace Core;
|
|||||||
using namespace Analyzer;
|
using namespace Analyzer;
|
||||||
using namespace Analyzer::Internal;
|
using namespace Analyzer::Internal;
|
||||||
|
|
||||||
|
// A separate 'Analzye' mode is not used in Qt Creator 2.2.
|
||||||
|
// Consider re-introducing it if a real use case for a separate main window with docks
|
||||||
|
// appears.
|
||||||
|
enum { useAnalyzeMode = 0 };
|
||||||
|
|
||||||
namespace Analyzer {
|
namespace Analyzer {
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
|
||||||
@@ -183,14 +189,15 @@ public:
|
|||||||
void delayedInit();
|
void delayedInit();
|
||||||
|
|
||||||
void setupActions();
|
void setupActions();
|
||||||
QWidget *createContents();
|
QWidget *createModeContents();
|
||||||
QWidget *createMainWindow();
|
QWidget *createModeMainWindow();
|
||||||
|
|
||||||
void addDock(IAnalyzerTool *tool, Qt::DockWidgetArea area, QDockWidget *dockWidget);
|
void addDock(IAnalyzerTool *tool, Qt::DockWidgetArea area, QDockWidget *dockWidget);
|
||||||
void startTool();
|
void startTool();
|
||||||
|
|
||||||
AnalyzerManager *q;
|
AnalyzerManager *q;
|
||||||
AnalyzerMode *m_mode;
|
AnalyzerMode *m_mode;
|
||||||
|
AnalyzerOutputPane *m_outputpane;
|
||||||
AnalyzerRunControlFactory *m_runControlFactory;
|
AnalyzerRunControlFactory *m_runControlFactory;
|
||||||
ProjectExplorer::RunControl *m_currentRunControl;
|
ProjectExplorer::RunControl *m_currentRunControl;
|
||||||
Utils::FancyMainWindow *m_mainWindow;
|
Utils::FancyMainWindow *m_mainWindow;
|
||||||
@@ -200,14 +207,11 @@ public:
|
|||||||
QAction *m_stopAction;
|
QAction *m_stopAction;
|
||||||
QMenu *m_menu;
|
QMenu *m_menu;
|
||||||
QComboBox *m_toolBox;
|
QComboBox *m_toolBox;
|
||||||
Utils::StyledSeparator *m_toolBoxSeparator;
|
|
||||||
ActionContainer *m_viewsMenu;
|
ActionContainer *m_viewsMenu;
|
||||||
typedef QPair<Qt::DockWidgetArea, QDockWidget*> ToolWidgetPair;
|
typedef QPair<Qt::DockWidgetArea, QDockWidget*> ToolWidgetPair;
|
||||||
typedef QList<ToolWidgetPair> ToolWidgetPairList;
|
typedef QList<ToolWidgetPair> ToolWidgetPairList;
|
||||||
QMap<IAnalyzerTool*, ToolWidgetPairList> m_toolWidgets;
|
QMap<IAnalyzerTool*, ToolWidgetPairList> m_toolWidgets;
|
||||||
DockWidgetEventFilter *m_resizeEventFilter;
|
DockWidgetEventFilter *m_resizeEventFilter;
|
||||||
QMap<IAnalyzerTool*, QWidget*> m_toolToolbarWidgets;
|
|
||||||
QStackedWidget *m_toolbarStackedWidget;
|
|
||||||
QMap<IAnalyzerTool *, QSettings *> m_defaultSettings;
|
QMap<IAnalyzerTool *, QSettings *> m_defaultSettings;
|
||||||
|
|
||||||
// list of dock widgets to prevent memory leak
|
// list of dock widgets to prevent memory leak
|
||||||
@@ -220,6 +224,7 @@ public:
|
|||||||
AnalyzerManager::AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager *qq):
|
AnalyzerManager::AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager *qq):
|
||||||
q(qq),
|
q(qq),
|
||||||
m_mode(0),
|
m_mode(0),
|
||||||
|
m_outputpane(0),
|
||||||
m_runControlFactory(0),
|
m_runControlFactory(0),
|
||||||
m_currentRunControl(0),
|
m_currentRunControl(0),
|
||||||
m_mainWindow(0),
|
m_mainWindow(0),
|
||||||
@@ -227,18 +232,20 @@ AnalyzerManager::AnalyzerManagerPrivate::AnalyzerManagerPrivate(AnalyzerManager
|
|||||||
m_startAction(0),
|
m_startAction(0),
|
||||||
m_stopAction(0),
|
m_stopAction(0),
|
||||||
m_menu(0),
|
m_menu(0),
|
||||||
m_toolBox(0),
|
m_toolBox(new QComboBox),
|
||||||
m_toolBoxSeparator(0),
|
|
||||||
m_viewsMenu(0),
|
m_viewsMenu(0),
|
||||||
m_resizeEventFilter(new DockWidgetEventFilter(qq)),
|
m_resizeEventFilter(new DockWidgetEventFilter(qq)),
|
||||||
m_toolbarStackedWidget(0),
|
|
||||||
m_initialized(false)
|
m_initialized(false)
|
||||||
{
|
{
|
||||||
|
m_toolBox->setObjectName(QLatin1String("AnalyzerManagerToolBox"));
|
||||||
m_runControlFactory = new AnalyzerRunControlFactory();
|
m_runControlFactory = new AnalyzerRunControlFactory();
|
||||||
AnalyzerPlugin::instance()->addAutoReleasedObject(m_runControlFactory);
|
AnalyzerPlugin::instance()->addAutoReleasedObject(m_runControlFactory);
|
||||||
connect(m_runControlFactory, SIGNAL(runControlCreated(Analyzer::Internal::AnalyzerRunControl *)),
|
connect(m_runControlFactory, SIGNAL(runControlCreated(Analyzer::Internal::AnalyzerRunControl *)),
|
||||||
q, SLOT(runControlCreated(Analyzer::Internal::AnalyzerRunControl *)));
|
q, SLOT(runControlCreated(Analyzer::Internal::AnalyzerRunControl *)));
|
||||||
|
|
||||||
|
connect(m_toolBox, SIGNAL(currentIndexChanged(int)),
|
||||||
|
q, SLOT(toolSelected(int)));
|
||||||
|
|
||||||
setupActions();
|
setupActions();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,17 +302,20 @@ void AnalyzerManager::AnalyzerManagerPrivate::delayedInit()
|
|||||||
if (m_initialized)
|
if (m_initialized)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (useAnalyzeMode) {
|
||||||
m_mode = new AnalyzerMode(q);
|
m_mode = new AnalyzerMode(q);
|
||||||
m_mode->setWidget(createContents());
|
m_mode->setWidget(createModeContents());
|
||||||
AnalyzerPlugin::instance()->addAutoReleasedObject(m_mode);
|
AnalyzerPlugin::instance()->addAutoReleasedObject(m_mode);
|
||||||
|
}
|
||||||
m_initialized = true;
|
m_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *AnalyzerManager::AnalyzerManagerPrivate::createContents()
|
QWidget *AnalyzerManager::AnalyzerManagerPrivate::createModeContents()
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(useAnalyzeMode, return 0; )
|
||||||
// right-side window with editor, output etc.
|
// right-side window with editor, output etc.
|
||||||
MiniSplitter *mainWindowSplitter = new MiniSplitter;
|
MiniSplitter *mainWindowSplitter = new MiniSplitter;
|
||||||
mainWindowSplitter->addWidget(createMainWindow());
|
mainWindowSplitter->addWidget(createModeMainWindow());
|
||||||
mainWindowSplitter->addWidget(new OutputPanePlaceHolder(m_mode, mainWindowSplitter));
|
mainWindowSplitter->addWidget(new OutputPanePlaceHolder(m_mode, mainWindowSplitter));
|
||||||
mainWindowSplitter->setStretchFactor(0, 10);
|
mainWindowSplitter->setStretchFactor(0, 10);
|
||||||
mainWindowSplitter->setStretchFactor(1, 0);
|
mainWindowSplitter->setStretchFactor(1, 0);
|
||||||
@@ -327,9 +337,19 @@ static QToolButton *toolButton(QAction *action)
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
QWidget *AnalyzerManager::AnalyzerManagerPrivate::createMainWindow()
|
QWidgetList AnalyzerManager::outputPaneToolBarWidgets() const
|
||||||
{
|
{
|
||||||
|
QWidgetList result;
|
||||||
|
result << toolButton(d->m_startAction) << toolButton(d->m_stopAction)
|
||||||
|
<< new Utils::StyledSeparator << d->m_toolBox;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *AnalyzerManager::AnalyzerManagerPrivate::createModeMainWindow()
|
||||||
|
{
|
||||||
|
QTC_ASSERT(useAnalyzeMode, return 0; )
|
||||||
m_mainWindow = new Utils::FancyMainWindow();
|
m_mainWindow = new Utils::FancyMainWindow();
|
||||||
|
m_mainWindow->setObjectName(QLatin1String("AnalyzerManagerMainWindow"));
|
||||||
connect(m_mainWindow, SIGNAL(resetLayout()),
|
connect(m_mainWindow, SIGNAL(resetLayout()),
|
||||||
q, SLOT(resetLayout()));
|
q, SLOT(resetLayout()));
|
||||||
m_mainWindow->setDocumentMode(true);
|
m_mainWindow->setDocumentMode(true);
|
||||||
@@ -352,35 +372,6 @@ QWidget *AnalyzerManager::AnalyzerManagerPrivate::createMainWindow()
|
|||||||
documentAndRightPane->setStretchFactor(0, 1);
|
documentAndRightPane->setStretchFactor(0, 1);
|
||||||
documentAndRightPane->setStretchFactor(1, 0);
|
documentAndRightPane->setStretchFactor(1, 0);
|
||||||
|
|
||||||
Utils::StyledBar *analyzeToolBar = new Utils::StyledBar;
|
|
||||||
analyzeToolBar->setProperty("topBorder", true);
|
|
||||||
QHBoxLayout *analyzeToolBarLayout = new QHBoxLayout(analyzeToolBar);
|
|
||||||
analyzeToolBarLayout->setMargin(0);
|
|
||||||
analyzeToolBarLayout->setSpacing(0);
|
|
||||||
QToolButton *startButton = toolButton(m_startAction);
|
|
||||||
analyzeToolBarLayout->addWidget(startButton);
|
|
||||||
analyzeToolBarLayout->addWidget(toolButton(m_stopAction));
|
|
||||||
analyzeToolBarLayout->addWidget(new Utils::StyledSeparator);
|
|
||||||
m_toolBox = new QComboBox;
|
|
||||||
connect(m_toolBox, SIGNAL(currentIndexChanged(int)),
|
|
||||||
q, SLOT(toolSelected(int)));
|
|
||||||
analyzeToolBarLayout->addWidget(m_toolBox);
|
|
||||||
m_toolBoxSeparator = new Utils::StyledSeparator;
|
|
||||||
analyzeToolBarLayout->addWidget(m_toolBoxSeparator);
|
|
||||||
m_toolbarStackedWidget = new QStackedWidget;
|
|
||||||
analyzeToolBarLayout->addWidget(m_toolbarStackedWidget);
|
|
||||||
analyzeToolBarLayout->addStretch();
|
|
||||||
|
|
||||||
QDockWidget *dock = new QDockWidget(tr("Analyzer Toolbar"));
|
|
||||||
dock->setObjectName(QLatin1String("Analyzer Toolbar"));
|
|
||||||
dock->setWidget(analyzeToolBar);
|
|
||||||
dock->setFeatures(QDockWidget::NoDockWidgetFeatures);
|
|
||||||
dock->setProperty("managed_dockwidget", QLatin1String("true"));
|
|
||||||
dock->setAllowedAreas(Qt::BottomDockWidgetArea);
|
|
||||||
// hide title bar
|
|
||||||
dock->setTitleBarWidget(new QWidget(dock));
|
|
||||||
m_mainWindow->addDockWidget(Qt::BottomDockWidgetArea, dock);
|
|
||||||
m_mainWindow->setToolBarDockWidget(dock);
|
|
||||||
|
|
||||||
QWidget *centralWidget = new QWidget;
|
QWidget *centralWidget = new QWidget;
|
||||||
m_mainWindow->setCentralWidget(centralWidget);
|
m_mainWindow->setCentralWidget(centralWidget);
|
||||||
@@ -399,7 +390,7 @@ QWidget *AnalyzerManager::AnalyzerManagerPrivate::createMainWindow()
|
|||||||
void AnalyzerManager::AnalyzerManagerPrivate::addDock(IAnalyzerTool *tool, Qt::DockWidgetArea area,
|
void AnalyzerManager::AnalyzerManagerPrivate::addDock(IAnalyzerTool *tool, Qt::DockWidgetArea area,
|
||||||
QDockWidget *dockWidget)
|
QDockWidget *dockWidget)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(tool == q->currentTool(), return)
|
QTC_ASSERT(useAnalyzeMode && tool == q->currentTool(), return)
|
||||||
|
|
||||||
dockWidget->setParent(m_mainWindow);
|
dockWidget->setParent(m_mainWindow);
|
||||||
m_mainWindow->addDockWidget(area, dockWidget);
|
m_mainWindow->addDockWidget(area, dockWidget);
|
||||||
@@ -448,9 +439,10 @@ bool buildTypeAcceppted(IAnalyzerTool::ToolMode toolMode,
|
|||||||
|
|
||||||
void AnalyzerManager::AnalyzerManagerPrivate::startTool()
|
void AnalyzerManager::AnalyzerManagerPrivate::startTool()
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!m_currentRunControl, return);
|
QTC_ASSERT(!m_currentRunControl && q->currentTool(), return);
|
||||||
|
|
||||||
// make sure our mode is shown
|
// make sure our mode is shown
|
||||||
|
m_outputpane->popup();
|
||||||
|
if (m_mode)
|
||||||
ModeManager::instance()->activateMode(m_mode->id());
|
ModeManager::instance()->activateMode(m_mode->id());
|
||||||
|
|
||||||
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
|
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||||
@@ -520,12 +512,14 @@ void AnalyzerManager::AnalyzerManagerPrivate::startTool()
|
|||||||
// AnalyzerManager ////////////////////////////////////////////////////
|
// AnalyzerManager ////////////////////////////////////////////////////
|
||||||
AnalyzerManager *AnalyzerManager::m_instance = 0;
|
AnalyzerManager *AnalyzerManager::m_instance = 0;
|
||||||
|
|
||||||
AnalyzerManager::AnalyzerManager(QObject *parent) :
|
AnalyzerManager::AnalyzerManager(Internal::AnalyzerOutputPane *op, QObject *parent) :
|
||||||
QObject(parent),
|
QObject(parent),
|
||||||
d(new AnalyzerManagerPrivate(this))
|
d(new AnalyzerManagerPrivate(this))
|
||||||
{
|
{
|
||||||
m_instance = this;
|
m_instance = this;
|
||||||
|
d->m_outputpane = op;
|
||||||
|
|
||||||
|
if (useAnalyzeMode)
|
||||||
connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
|
connect(ModeManager::instance(), SIGNAL(currentModeChanged(Core::IMode*)),
|
||||||
this, SLOT(modeChanged(Core::IMode*)));
|
this, SLOT(modeChanged(Core::IMode*)));
|
||||||
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
|
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||||
@@ -545,6 +539,7 @@ bool AnalyzerManager::isInitialized() const
|
|||||||
|
|
||||||
void AnalyzerManager::shutdown()
|
void AnalyzerManager::shutdown()
|
||||||
{
|
{
|
||||||
|
if (useAnalyzeMode)
|
||||||
saveToolSettings(currentTool());
|
saveToolSettings(currentTool());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -555,6 +550,7 @@ AnalyzerManager * AnalyzerManager::instance()
|
|||||||
|
|
||||||
void AnalyzerManager::modeChanged(IMode *mode)
|
void AnalyzerManager::modeChanged(IMode *mode)
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(d->m_mainWindow, return; )
|
||||||
const bool makeVisible = mode->id() == Constants::MODE_ANALYZE;
|
const bool makeVisible = mode->id() == Constants::MODE_ANALYZE;
|
||||||
if (!makeVisible)
|
if (!makeVisible)
|
||||||
return;
|
return;
|
||||||
@@ -576,7 +572,7 @@ void AnalyzerManager::toolSelected(int idx)
|
|||||||
selectingTool = true;
|
selectingTool = true;
|
||||||
|
|
||||||
IAnalyzerTool *oldTool = currentTool();
|
IAnalyzerTool *oldTool = currentTool();
|
||||||
if (oldTool) {
|
if (useAnalyzeMode && oldTool != 0) {
|
||||||
saveToolSettings(oldTool);
|
saveToolSettings(oldTool);
|
||||||
|
|
||||||
ActionManager *am = ICore::instance()->actionManager();
|
ActionManager *am = ICore::instance()->actionManager();
|
||||||
@@ -599,13 +595,13 @@ void AnalyzerManager::toolSelected(int idx)
|
|||||||
|
|
||||||
IAnalyzerTool *newTool = currentTool();
|
IAnalyzerTool *newTool = currentTool();
|
||||||
|
|
||||||
if (QWidget *toolbarWidget = d->m_toolToolbarWidgets.value(newTool))
|
if (useAnalyzeMode) {
|
||||||
d->m_toolbarStackedWidget->setCurrentWidget(toolbarWidget);
|
|
||||||
|
|
||||||
foreach (const AnalyzerManagerPrivate::ToolWidgetPair &widget, d->m_toolWidgets.value(newTool)) {
|
foreach (const AnalyzerManagerPrivate::ToolWidgetPair &widget, d->m_toolWidgets.value(newTool)) {
|
||||||
d->addDock(newTool, widget.first, widget.second);
|
d->addDock(newTool, widget.first, widget.second);
|
||||||
}
|
}
|
||||||
loadToolSettings(newTool);
|
loadToolSettings(newTool);
|
||||||
|
}
|
||||||
|
d->m_outputpane->setTool(newTool);
|
||||||
|
|
||||||
selectingTool = false;
|
selectingTool = false;
|
||||||
}
|
}
|
||||||
@@ -628,33 +624,23 @@ void AnalyzerManager::addTool(IAnalyzerTool *tool)
|
|||||||
d->m_toolGroup->setVisible(d->m_toolGroup->actions().count() > 1);
|
d->m_toolGroup->setVisible(d->m_toolGroup->actions().count() > 1);
|
||||||
d->m_tools.append(tool);
|
d->m_tools.append(tool);
|
||||||
d->m_toolBox->addItem(tool->displayName());
|
d->m_toolBox->addItem(tool->displayName());
|
||||||
d->m_toolBox->setVisible(d->m_toolBox->count() > 1);
|
d->m_toolBox->setEnabled(d->m_toolBox->count() > 1);
|
||||||
d->m_toolBoxSeparator->setVisible(d->m_toolBox->isVisible());
|
|
||||||
|
|
||||||
if (currentTool() != tool)
|
if (currentTool() != tool)
|
||||||
selectTool(tool); // the first tool gets selected automatically due to signal emission from toolbox
|
selectTool(tool); // the first tool gets selected automatically due to signal emission from toolbox
|
||||||
tool->initialize(plugin);
|
tool->initialize(plugin);
|
||||||
|
|
||||||
|
if (useAnalyzeMode) {
|
||||||
QSettings *defaultSettings = new QSettings(this);
|
QSettings *defaultSettings = new QSettings(this);
|
||||||
d->m_defaultSettings[tool] = defaultSettings;
|
d->m_defaultSettings[tool] = defaultSettings;
|
||||||
d->m_mainWindow->saveSettings(defaultSettings);
|
d->m_mainWindow->saveSettings(defaultSettings);
|
||||||
|
|
||||||
loadToolSettings(tool);
|
loadToolSettings(tool);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnalyzerManager::setToolbar(IAnalyzerTool *tool, QWidget *widget)
|
|
||||||
{
|
|
||||||
d->m_toolToolbarWidgets[tool] = widget;
|
|
||||||
d->m_toolbarStackedWidget->addWidget(widget);
|
|
||||||
|
|
||||||
if (currentTool() == tool)
|
|
||||||
d->m_toolbarStackedWidget->setCurrentWidget(widget);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QDockWidget *AnalyzerManager::createDockWidget(IAnalyzerTool *tool, const QString &title,
|
QDockWidget *AnalyzerManager::createDockWidget(IAnalyzerTool *tool, const QString &title,
|
||||||
QWidget *widget, Qt::DockWidgetArea area)
|
QWidget *widget, Qt::DockWidgetArea area)
|
||||||
{
|
{
|
||||||
QTC_ASSERT(!widget->objectName().isEmpty(), qt_noop());
|
QTC_ASSERT(useAnalyzeMode && !widget->objectName().isEmpty(), return 0;);
|
||||||
|
|
||||||
QDockWidget *dockWidget = d->m_mainWindow->addDockForWidget(widget);
|
QDockWidget *dockWidget = d->m_mainWindow->addDockForWidget(widget);
|
||||||
d->m_dockWidgets << AnalyzerManagerPrivate::DockPtr(dockWidget);
|
d->m_dockWidgets << AnalyzerManagerPrivate::DockPtr(dockWidget);
|
||||||
@@ -727,6 +713,7 @@ void AnalyzerManager::resetLayout()
|
|||||||
|
|
||||||
void AnalyzerManager::loadToolSettings(IAnalyzerTool *tool)
|
void AnalyzerManager::loadToolSettings(IAnalyzerTool *tool)
|
||||||
{
|
{
|
||||||
|
QTC_ASSERT(d->m_mainWindow, return; )
|
||||||
QSettings *settings = Core::ICore::instance()->settings();
|
QSettings *settings = Core::ICore::instance()->settings();
|
||||||
settings->beginGroup(QLatin1String("AnalyzerViewSettings_") + tool->id());
|
settings->beginGroup(QLatin1String("AnalyzerViewSettings_") + tool->id());
|
||||||
if (settings->value("ToolSettingsSaved", false).toBool()) {
|
if (settings->value("ToolSettingsSaved", false).toBool()) {
|
||||||
@@ -739,6 +726,7 @@ void AnalyzerManager::saveToolSettings(IAnalyzerTool *tool)
|
|||||||
{
|
{
|
||||||
if (!tool)
|
if (!tool)
|
||||||
return; // no active tool, do nothing
|
return; // no active tool, do nothing
|
||||||
|
QTC_ASSERT(d->m_mainWindow, return ; )
|
||||||
|
|
||||||
QSettings *settings = Core::ICore::instance()->settings();
|
QSettings *settings = Core::ICore::instance()->settings();
|
||||||
settings->beginGroup(QLatin1String("AnalyzerViewSettings_") + tool->id());
|
settings->beginGroup(QLatin1String("AnalyzerViewSettings_") + tool->id());
|
||||||
@@ -751,7 +739,8 @@ void AnalyzerManager::updateRunActions()
|
|||||||
{
|
{
|
||||||
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
|
ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
|
||||||
ProjectExplorer::Project *project = pe->startupProject();
|
ProjectExplorer::Project *project = pe->startupProject();
|
||||||
bool startEnabled = !d->m_currentRunControl && pe->canRun(project, Constants::MODE_ANALYZE);
|
bool startEnabled = !d->m_currentRunControl && pe->canRun(project, Constants::MODE_ANALYZE)
|
||||||
|
&& currentTool();
|
||||||
d->m_startAction->setEnabled(startEnabled);
|
d->m_startAction->setEnabled(startEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ namespace Analyzer {
|
|||||||
class IAnalyzerTool;
|
class IAnalyzerTool;
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
class AnalyzerRunControl;
|
class AnalyzerRunControl;
|
||||||
|
class AnalyzerOutputPane;
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|
||||||
class ANALYZER_EXPORT AnalyzerManager : public QObject
|
class ANALYZER_EXPORT AnalyzerManager : public QObject
|
||||||
@@ -64,7 +65,7 @@ class ANALYZER_EXPORT AnalyzerManager : public QObject
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AnalyzerManager(QObject *parent = 0);
|
explicit AnalyzerManager(Internal::AnalyzerOutputPane *op, QObject *parent = 0);
|
||||||
~AnalyzerManager();
|
~AnalyzerManager();
|
||||||
|
|
||||||
static AnalyzerManager *instance();
|
static AnalyzerManager *instance();
|
||||||
@@ -83,19 +84,12 @@ public:
|
|||||||
QDockWidget *createDockWidget(IAnalyzerTool *tool, const QString &title, QWidget *widget,
|
QDockWidget *createDockWidget(IAnalyzerTool *tool, const QString &title, QWidget *widget,
|
||||||
Qt::DockWidgetArea area = Qt::TopDockWidgetArea);
|
Qt::DockWidgetArea area = Qt::TopDockWidgetArea);
|
||||||
|
|
||||||
/**
|
|
||||||
* Add the given @p widget into this mode's toolbar.
|
|
||||||
*
|
|
||||||
* It will be shown whenever this tool is selected by the user.
|
|
||||||
*
|
|
||||||
* @Note The manager will take ownership of @p widget.
|
|
||||||
*/
|
|
||||||
void setToolbar(Analyzer::IAnalyzerTool *tool, QWidget *widget);
|
|
||||||
|
|
||||||
Utils::FancyMainWindow *mainWindow() const;
|
Utils::FancyMainWindow *mainWindow() const;
|
||||||
|
|
||||||
void selectTool(IAnalyzerTool *tool);
|
void selectTool(IAnalyzerTool *tool);
|
||||||
|
|
||||||
|
QList<QWidget *> outputPaneToolBarWidgets() const;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void startTool();
|
void startTool();
|
||||||
void stopTool();
|
void stopTool();
|
||||||
|
|||||||
318
src/plugins/analyzerbase/analyzeroutputpane.cpp
Normal file
318
src/plugins/analyzerbase/analyzeroutputpane.cpp
Normal file
@@ -0,0 +1,318 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** No Commercial Usage
|
||||||
|
**
|
||||||
|
** This file contains pre-release code and may not be distributed.
|
||||||
|
** You may use this file in accordance with the terms and conditions
|
||||||
|
** contained in the Technology Preview License Agreement accompanying
|
||||||
|
** this package.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#include "analyzeroutputpane.h"
|
||||||
|
#include "analyzermanager.h"
|
||||||
|
#include "ianalyzertool.h"
|
||||||
|
|
||||||
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/styledbar.h>
|
||||||
|
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
#include <QtCore/QDebug>
|
||||||
|
|
||||||
|
#include <QtGui/QWidget>
|
||||||
|
#include <QtGui/QStackedLayout>
|
||||||
|
#include <QtGui/QLabel>
|
||||||
|
#include <QtGui/QStackedWidget>
|
||||||
|
|
||||||
|
static const char dummyWidgetPropertyC[] = "dummyWidget";
|
||||||
|
|
||||||
|
enum { debug = 0 };
|
||||||
|
enum { dummyIndex = 0 };
|
||||||
|
|
||||||
|
namespace Analyzer {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
static inline QWidget *createDummyWidget()
|
||||||
|
{
|
||||||
|
QWidget *widget = new QWidget;
|
||||||
|
widget->setProperty(dummyWidgetPropertyC, QVariant(true));
|
||||||
|
return widget;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class AnalyzerPane::Internal::AnalyzerOutputPane
|
||||||
|
|
||||||
|
\brief Common analysis output pane managing several tools.
|
||||||
|
|
||||||
|
Output pane for all tools derived from IAnalyzerTool.
|
||||||
|
The IAnalyzerOutputPaneAdapter (unless 0) provides
|
||||||
|
\list
|
||||||
|
\i Pane widget
|
||||||
|
\i Optional toolbar widget
|
||||||
|
\endlist
|
||||||
|
|
||||||
|
Both are inserted into a pane stacked layout and a stacked toolbar widget respectively.
|
||||||
|
|
||||||
|
The indexes of the stacked widgets/layouts and the adapter list go in sync
|
||||||
|
(dummy widgets on the toolbar are used to achieve this).
|
||||||
|
Dummy widgets that are shown in case there is no tool with an output pane
|
||||||
|
are added at index 0 to the stacks (usage of index 0 is to avoid using
|
||||||
|
QStackedWidget::insert() when adding adapters, which causes flicker).
|
||||||
|
|
||||||
|
Besides the tool-specific toolbar widget, the start/stop buttons and the combo
|
||||||
|
box of the AnalyzerManager are shown in the toolbar.
|
||||||
|
|
||||||
|
The initialization is a bit tricky here, as the sequence of calls to
|
||||||
|
setTool(), outputWindow()/toolBarWidgets() is basically undefined. The pane widget
|
||||||
|
should be created on the correct parent when outputWindow()
|
||||||
|
is called, tools will typically be added before.
|
||||||
|
|
||||||
|
\sa AnalyzerPane::Internal::IAnalyzerOutputPaneAdapter
|
||||||
|
*/
|
||||||
|
|
||||||
|
AnalyzerOutputPane::AnalyzerOutputPane(QObject *parent) :
|
||||||
|
Core::IOutputPane(parent),
|
||||||
|
m_paneWidget(0),
|
||||||
|
m_paneStackedLayout(0),
|
||||||
|
m_toolbarStackedWidget(0),
|
||||||
|
m_toolBarSeparator(0)
|
||||||
|
{
|
||||||
|
setObjectName(QLatin1String("AnalyzerOutputPane"));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::clearTool()
|
||||||
|
{
|
||||||
|
// No tool. Show dummy label, which is the last widget.
|
||||||
|
if (m_paneWidget) {
|
||||||
|
m_paneStackedLayout->setCurrentIndex(dummyIndex);
|
||||||
|
m_toolbarStackedWidget->setCurrentIndex(dummyIndex);
|
||||||
|
emit navigateStateChanged();
|
||||||
|
}
|
||||||
|
hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
int AnalyzerOutputPane::currentIndex() const
|
||||||
|
{
|
||||||
|
return m_paneStackedLayout ? m_paneStackedLayout->currentIndex() : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
IAnalyzerOutputPaneAdapter *AnalyzerOutputPane::currentAdapter() const
|
||||||
|
{
|
||||||
|
const int index = currentIndex(); // Rule out leading dummy widget
|
||||||
|
if (index != dummyIndex && index < m_adapters.size())
|
||||||
|
return m_adapters.at(index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::setCurrentIndex(int i)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(isInitialized(), return )
|
||||||
|
|
||||||
|
if (i != currentIndex()) {
|
||||||
|
// Show up pane widget and optional toolbar widget. Hide
|
||||||
|
// the toolbar if the toolbar widget is a dummy.
|
||||||
|
m_paneStackedLayout->setCurrentIndex(i);
|
||||||
|
m_toolbarStackedWidget->setCurrentIndex(i);
|
||||||
|
const bool hasToolBarWidget = !m_toolbarStackedWidget->currentWidget()->property(dummyWidgetPropertyC).toBool();
|
||||||
|
m_toolbarStackedWidget->setVisible(hasToolBarWidget);
|
||||||
|
m_toolBarSeparator->setVisible(hasToolBarWidget);
|
||||||
|
navigateStateChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::add(IAnalyzerOutputPaneAdapter *adapter)
|
||||||
|
{
|
||||||
|
if (m_adapters.isEmpty())
|
||||||
|
m_adapters.push_back(0); // Index for leading dummy widgets.
|
||||||
|
m_adapters.push_back(adapter);
|
||||||
|
connect(adapter, SIGNAL(navigationStatusChanged()), this, SLOT(slotNavigationStatusChanged()));
|
||||||
|
connect(adapter, SIGNAL(popup(bool)), this, SLOT(slotPopup(bool)));
|
||||||
|
if (isInitialized())
|
||||||
|
addToWidgets(adapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::addToWidgets(IAnalyzerOutputPaneAdapter *adapter)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_paneWidget, return; )
|
||||||
|
QWidget *toolPaneWidget = adapter->paneWidget();
|
||||||
|
QTC_ASSERT(toolPaneWidget, return; )
|
||||||
|
m_paneStackedLayout->addWidget(toolPaneWidget);
|
||||||
|
QWidget *toolBarWidget = adapter->toolBarWidget(); // Might be 0
|
||||||
|
m_toolbarStackedWidget->addWidget(toolBarWidget ? toolBarWidget : createDummyWidget());
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::setTool(IAnalyzerTool *t)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
qDebug() << "AnalyzerOutputPane::setTool" << t;
|
||||||
|
// No tool. show dummy label.
|
||||||
|
IAnalyzerOutputPaneAdapter *adapter = t ? t->outputPaneAdapter() :
|
||||||
|
static_cast<IAnalyzerOutputPaneAdapter *>(0);
|
||||||
|
// Re-show or add.
|
||||||
|
if (adapter) {
|
||||||
|
int index = m_adapters.indexOf(adapter);
|
||||||
|
if (index == -1) {
|
||||||
|
index = m_adapters.size();
|
||||||
|
add(adapter);
|
||||||
|
}
|
||||||
|
if (isInitialized()) {
|
||||||
|
popup(false);
|
||||||
|
setCurrentIndex(index);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
clearTool();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget * AnalyzerOutputPane::outputWidget(QWidget *parent)
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
qDebug() << "AnalyzerOutputPane::outputWidget";
|
||||||
|
// Delayed creation of main pane widget. Add a trailing dummy widget
|
||||||
|
// and add all adapters.
|
||||||
|
if (!isInitialized())
|
||||||
|
createWidgets(parent);
|
||||||
|
return m_paneWidget;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::createWidgets(QWidget *paneParent)
|
||||||
|
{
|
||||||
|
// Create pane and toolbar stack with leading dummy widget.
|
||||||
|
m_paneWidget = new QWidget(paneParent);
|
||||||
|
m_paneStackedLayout = new QStackedLayout(m_paneWidget);
|
||||||
|
m_paneWidget->setObjectName(objectName() + QLatin1String("Widget"));
|
||||||
|
m_paneStackedLayout->addWidget(new QLabel(tr("No current analysis tool")));
|
||||||
|
|
||||||
|
m_toolbarStackedWidget = new QStackedWidget;
|
||||||
|
m_toolBarSeparator = new Utils::StyledSeparator;
|
||||||
|
m_toolbarStackedWidget->setObjectName(objectName() + QLatin1String("ToolBarStackedWidget"));
|
||||||
|
|
||||||
|
// Add adapters added before.
|
||||||
|
const int adapterCount = m_adapters.size();
|
||||||
|
const int firstAdapter = dummyIndex + 1;
|
||||||
|
for (int i = firstAdapter; i < adapterCount; i++)
|
||||||
|
addToWidgets(m_adapters.at(i));
|
||||||
|
// Make last one current
|
||||||
|
if (adapterCount > firstAdapter)
|
||||||
|
setCurrentIndex(firstAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidgetList AnalyzerOutputPane::toolBarWidgets() const
|
||||||
|
{
|
||||||
|
if (debug)
|
||||||
|
qDebug() << "AnalyzerOutputPane::toolBarWidget";
|
||||||
|
QTC_ASSERT(isInitialized(), return QWidgetList(); )
|
||||||
|
|
||||||
|
QWidgetList list = AnalyzerManager::instance()->outputPaneToolBarWidgets();
|
||||||
|
list << m_toolBarSeparator << m_toolbarStackedWidget;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AnalyzerOutputPane::displayName() const
|
||||||
|
{
|
||||||
|
return tr("Analysis");
|
||||||
|
}
|
||||||
|
|
||||||
|
int AnalyzerOutputPane::priorityInStatusBar() const
|
||||||
|
{
|
||||||
|
return -1; // Not visible in status bar.
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::clearContents()
|
||||||
|
{
|
||||||
|
if (IAnalyzerOutputPaneAdapter *adapter = currentAdapter())
|
||||||
|
adapter->clearContents();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::visibilityChanged(bool v)
|
||||||
|
{
|
||||||
|
Q_UNUSED(v)
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::setFocus()
|
||||||
|
{
|
||||||
|
if (IAnalyzerOutputPaneAdapter *adapter = currentAdapter())
|
||||||
|
adapter->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnalyzerOutputPane::hasFocus()
|
||||||
|
{
|
||||||
|
const IAnalyzerOutputPaneAdapter *adapter = currentAdapter();
|
||||||
|
return adapter ? adapter->hasFocus() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnalyzerOutputPane::canFocus()
|
||||||
|
{
|
||||||
|
const IAnalyzerOutputPaneAdapter *adapter = currentAdapter();
|
||||||
|
return adapter ? adapter->canFocus() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnalyzerOutputPane::canNavigate()
|
||||||
|
{
|
||||||
|
const IAnalyzerOutputPaneAdapter *adapter = currentAdapter();
|
||||||
|
return adapter ? adapter->canNavigate() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnalyzerOutputPane::canNext()
|
||||||
|
{
|
||||||
|
const IAnalyzerOutputPaneAdapter *adapter = currentAdapter();
|
||||||
|
return adapter ? adapter->canNext() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AnalyzerOutputPane::canPrevious()
|
||||||
|
{
|
||||||
|
const IAnalyzerOutputPaneAdapter *adapter = currentAdapter();
|
||||||
|
return adapter ? adapter->canPrevious() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::goToNext()
|
||||||
|
{
|
||||||
|
if (IAnalyzerOutputPaneAdapter *adapter = currentAdapter())
|
||||||
|
adapter->goToNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::goToPrev()
|
||||||
|
{
|
||||||
|
if (IAnalyzerOutputPaneAdapter *adapter = currentAdapter())
|
||||||
|
adapter->goToPrev();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::slotPopup(bool withFocus)
|
||||||
|
{
|
||||||
|
popup(withFocus);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnalyzerOutputPane::slotNavigationStatusChanged()
|
||||||
|
{
|
||||||
|
IAnalyzerOutputPaneAdapter *adapter = qobject_cast<IAnalyzerOutputPaneAdapter *>(sender());
|
||||||
|
const int index = m_adapters.indexOf(adapter);
|
||||||
|
QTC_ASSERT(adapter != 0 && index != -1, return; )
|
||||||
|
// Forward navigation status if it is the current pane.
|
||||||
|
if (index == currentIndex())
|
||||||
|
navigateStateChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Analyzer
|
||||||
101
src/plugins/analyzerbase/analyzeroutputpane.h
Normal file
101
src/plugins/analyzerbase/analyzeroutputpane.h
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
**
|
||||||
|
** This file is part of Qt Creator
|
||||||
|
**
|
||||||
|
** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||||
|
**
|
||||||
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||||
|
**
|
||||||
|
** No Commercial Usage
|
||||||
|
**
|
||||||
|
** This file contains pre-release code and may not be distributed.
|
||||||
|
** You may use this file in accordance with the terms and conditions
|
||||||
|
** contained in the Technology Preview License Agreement accompanying
|
||||||
|
** this package.
|
||||||
|
**
|
||||||
|
** 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.
|
||||||
|
**
|
||||||
|
** In addition, as a special exception, Nokia gives you certain additional
|
||||||
|
** rights. These rights are described in the Nokia Qt LGPL Exception
|
||||||
|
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||||
|
**
|
||||||
|
** If you have questions regarding the use of this file, please contact
|
||||||
|
** Nokia at qt-info@nokia.com.
|
||||||
|
**
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#ifndef ANALYZEROUTPUTPANE_H
|
||||||
|
#define ANALYZEROUTPUTPANE_H
|
||||||
|
|
||||||
|
#include <coreplugin/ioutputpane.h>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QStackedLayout)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QStackedWidget)
|
||||||
|
|
||||||
|
namespace Utils {
|
||||||
|
class StyledSeparator;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Analyzer {
|
||||||
|
class IAnalyzerTool;
|
||||||
|
class IAnalyzerOutputPaneAdapter;
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
class AnalyzerOutputPane : public Core::IOutputPane
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit AnalyzerOutputPane(QObject *parent = 0);
|
||||||
|
|
||||||
|
void setTool(IAnalyzerTool *t);
|
||||||
|
// IOutputPane
|
||||||
|
virtual QWidget *outputWidget(QWidget *parent);
|
||||||
|
virtual QList<QWidget*> toolBarWidgets() const;
|
||||||
|
virtual QString displayName() const;
|
||||||
|
|
||||||
|
virtual int priorityInStatusBar() const;
|
||||||
|
|
||||||
|
virtual void clearContents();
|
||||||
|
virtual void visibilityChanged(bool visible);
|
||||||
|
|
||||||
|
virtual void setFocus();
|
||||||
|
virtual bool hasFocus();
|
||||||
|
virtual bool canFocus();
|
||||||
|
virtual bool canNavigate();
|
||||||
|
virtual bool canNext();
|
||||||
|
virtual bool canPrevious();
|
||||||
|
virtual void goToNext();
|
||||||
|
virtual void goToPrev();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void slotPopup(bool withFocus);
|
||||||
|
void slotNavigationStatusChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void clearTool();
|
||||||
|
inline int currentIndex() const;
|
||||||
|
inline IAnalyzerOutputPaneAdapter *currentAdapter() const;
|
||||||
|
void setCurrentIndex(int );
|
||||||
|
void add(IAnalyzerOutputPaneAdapter *adapter);
|
||||||
|
void addToWidgets(IAnalyzerOutputPaneAdapter *adapter);
|
||||||
|
void createWidgets(QWidget *paneParent);
|
||||||
|
bool isInitialized() const { return m_paneWidget != 0; }
|
||||||
|
|
||||||
|
QWidget *m_paneWidget;
|
||||||
|
QStackedLayout *m_paneStackedLayout;
|
||||||
|
QList<IAnalyzerOutputPaneAdapter *> m_adapters;
|
||||||
|
QStackedWidget *m_toolbarStackedWidget;
|
||||||
|
Utils::StyledSeparator *m_toolBarSeparator;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Analyzer
|
||||||
|
|
||||||
|
#endif // ANALYZEROUTPUTPANE_H
|
||||||
@@ -36,6 +36,7 @@
|
|||||||
#include "analyzerplugin.h"
|
#include "analyzerplugin.h"
|
||||||
#include "analyzerconstants.h"
|
#include "analyzerconstants.h"
|
||||||
#include "analyzermanager.h"
|
#include "analyzermanager.h"
|
||||||
|
#include "analyzeroutputpane.h"
|
||||||
|
|
||||||
#include <coreplugin/imode.h>
|
#include <coreplugin/imode.h>
|
||||||
#include <coreplugin/coreconstants.h>
|
#include <coreplugin/coreconstants.h>
|
||||||
@@ -76,7 +77,9 @@ void AnalyzerPlugin::AnalyzerPluginPrivate::initialize(const QStringList &argume
|
|||||||
{
|
{
|
||||||
Q_UNUSED(arguments)
|
Q_UNUSED(arguments)
|
||||||
Q_UNUSED(errorString)
|
Q_UNUSED(errorString)
|
||||||
m_manager = new AnalyzerManager(q);
|
AnalyzerOutputPane *outputPane = new AnalyzerOutputPane;
|
||||||
|
q->addAutoReleasedObject(outputPane);
|
||||||
|
m_manager = new AnalyzerManager(outputPane, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -34,14 +34,158 @@
|
|||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
|
|
||||||
#include "ianalyzertool.h"
|
#include "ianalyzertool.h"
|
||||||
|
#include "analyzeroutputpane.h"
|
||||||
|
|
||||||
using namespace Analyzer;
|
#include <utils/qtcassert.h>
|
||||||
|
|
||||||
|
#include <QtGui/QAbstractItemView>
|
||||||
|
#include <QtGui/QItemSelectionModel>
|
||||||
|
#include <QtCore/QAbstractItemModel>
|
||||||
|
#include <QtCore/QModelIndex>
|
||||||
|
|
||||||
|
namespace Analyzer {
|
||||||
|
|
||||||
IAnalyzerTool::IAnalyzerTool(QObject *parent) :
|
IAnalyzerTool::IAnalyzerTool(QObject *parent) :
|
||||||
QObject(parent)
|
QObject(parent)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class Analyzer::IAnalyzerOutputPaneAdapter
|
||||||
|
|
||||||
|
\brief Adapter for handling multiple tools in the common 'Analysis' output pane.
|
||||||
|
|
||||||
|
Provides the tool-specific output pane widget and optionally, a widget to be
|
||||||
|
inserted into into the toolbar. Ownership of them is taken by the output pane.
|
||||||
|
Forwards navigation calls issued by the output pane.
|
||||||
|
*/
|
||||||
|
|
||||||
|
IAnalyzerOutputPaneAdapter::IAnalyzerOutputPaneAdapter(QObject *parent) :
|
||||||
|
QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
IAnalyzerOutputPaneAdapter::~IAnalyzerOutputPaneAdapter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class Analyzer::ListItemViewOutputPaneAdapter
|
||||||
|
|
||||||
|
\brief Utility class implementing wrap-around navigation for flat lists.
|
||||||
|
|
||||||
|
Provides an optional mechanism to pop up automatically in case errors show up.
|
||||||
|
*/
|
||||||
|
|
||||||
|
ListItemViewOutputPaneAdapter::ListItemViewOutputPaneAdapter(QObject *parent) :
|
||||||
|
IAnalyzerOutputPaneAdapter(parent), m_listView(0), m_showOnRowsInserted(true)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItemViewOutputPaneAdapter::connectNavigationSignals(QAbstractItemModel *model)
|
||||||
|
{
|
||||||
|
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||||
|
this, SIGNAL(navigationStatusChanged()));
|
||||||
|
connect(model, SIGNAL(rowsInserted(QModelIndex,int,int)),
|
||||||
|
this, SLOT(slotRowsInserted()));
|
||||||
|
connect(model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
|
||||||
|
this, SIGNAL(navigationStatusChanged()));
|
||||||
|
connect(model, SIGNAL(modelReset()),
|
||||||
|
this, SIGNAL(navigationStatusChanged()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItemViewOutputPaneAdapter::slotRowsInserted()
|
||||||
|
{
|
||||||
|
if (m_showOnRowsInserted && !m_listView->isVisible())
|
||||||
|
emit popup(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QWidget *ListItemViewOutputPaneAdapter::paneWidget()
|
||||||
|
{
|
||||||
|
if (!m_listView) {
|
||||||
|
m_listView = createItemView();
|
||||||
|
if (QAbstractItemModel *model = m_listView->model())
|
||||||
|
connectNavigationSignals(model);
|
||||||
|
}
|
||||||
|
return m_listView;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItemViewOutputPaneAdapter::setFocus()
|
||||||
|
{
|
||||||
|
if (m_listView)
|
||||||
|
m_listView->setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListItemViewOutputPaneAdapter::hasFocus() const
|
||||||
|
{
|
||||||
|
return m_listView ? m_listView->hasFocus() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListItemViewOutputPaneAdapter::canFocus() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListItemViewOutputPaneAdapter::canNavigate() const
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListItemViewOutputPaneAdapter::canNext() const
|
||||||
|
{
|
||||||
|
return rowCount() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListItemViewOutputPaneAdapter::canPrevious() const
|
||||||
|
{
|
||||||
|
return rowCount() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItemViewOutputPaneAdapter::goToNext()
|
||||||
|
{
|
||||||
|
setCurrentRow((currentRow() + 1) % rowCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItemViewOutputPaneAdapter::goToPrev()
|
||||||
|
{
|
||||||
|
const int prevRow = currentRow() - 1;
|
||||||
|
setCurrentRow(prevRow >= 0 ? prevRow : rowCount() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ListItemViewOutputPaneAdapter::showOnRowsInserted() const
|
||||||
|
{
|
||||||
|
return m_showOnRowsInserted;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItemViewOutputPaneAdapter::setShowOnRowsInserted(bool v)
|
||||||
|
{
|
||||||
|
m_showOnRowsInserted = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ListItemViewOutputPaneAdapter::currentRow() const
|
||||||
|
{
|
||||||
|
if (m_listView) {
|
||||||
|
const QModelIndex index = m_listView->selectionModel()->currentIndex();
|
||||||
|
if (index.isValid())
|
||||||
|
return index.row();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ListItemViewOutputPaneAdapter::setCurrentRow(int r)
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_listView, return; )
|
||||||
|
const QModelIndex index = m_listView->model()->index(r, 0);
|
||||||
|
m_listView->selectionModel()->setCurrentIndex(index, QItemSelectionModel::ClearAndSelect|QItemSelectionModel::Current);
|
||||||
|
m_listView->scrollTo(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ListItemViewOutputPaneAdapter::rowCount() const
|
||||||
|
{
|
||||||
|
return m_listView ? m_listView->model()->rowCount() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -------------IAnalyzerTool
|
||||||
QString IAnalyzerTool::modeString()
|
QString IAnalyzerTool::modeString()
|
||||||
{
|
{
|
||||||
switch (mode()) {
|
switch (mode()) {
|
||||||
@@ -54,3 +198,10 @@ QString IAnalyzerTool::modeString()
|
|||||||
}
|
}
|
||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IAnalyzerOutputPaneAdapter *IAnalyzerTool::outputPaneAdapter()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Analyzer
|
||||||
|
|||||||
@@ -40,6 +40,9 @@
|
|||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QAbstractItemView)
|
||||||
|
QT_FORWARD_DECLARE_CLASS(QAbstractItemModel)
|
||||||
|
|
||||||
namespace ProjectExplorer {
|
namespace ProjectExplorer {
|
||||||
class RunConfiguration;
|
class RunConfiguration;
|
||||||
}
|
}
|
||||||
@@ -49,9 +52,66 @@ class IPlugin;
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace Analyzer {
|
namespace Analyzer {
|
||||||
|
|
||||||
class IAnalyzerEngine;
|
class IAnalyzerEngine;
|
||||||
|
|
||||||
|
class ANALYZER_EXPORT IAnalyzerOutputPaneAdapter : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit IAnalyzerOutputPaneAdapter(QObject *parent = 0);
|
||||||
|
virtual ~IAnalyzerOutputPaneAdapter();
|
||||||
|
|
||||||
|
virtual QWidget *toolBarWidget() = 0;
|
||||||
|
virtual QWidget *paneWidget() = 0;
|
||||||
|
virtual void clearContents() = 0;
|
||||||
|
virtual void setFocus() = 0;
|
||||||
|
virtual bool hasFocus() const = 0;
|
||||||
|
virtual bool canFocus() const = 0;
|
||||||
|
virtual bool canNavigate() const = 0;
|
||||||
|
virtual bool canNext() const = 0;
|
||||||
|
virtual bool canPrevious() const = 0;
|
||||||
|
virtual void goToNext() = 0;
|
||||||
|
virtual void goToPrev() = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void popup(bool withFocus);
|
||||||
|
void navigationStatusChanged();
|
||||||
|
};
|
||||||
|
|
||||||
|
class ANALYZER_EXPORT ListItemViewOutputPaneAdapter : public IAnalyzerOutputPaneAdapter
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ListItemViewOutputPaneAdapter(QObject *parent = 0);
|
||||||
|
|
||||||
|
virtual QWidget *paneWidget();
|
||||||
|
virtual void setFocus();
|
||||||
|
virtual bool hasFocus() const;
|
||||||
|
virtual bool canFocus() const;
|
||||||
|
virtual bool canNavigate() const;
|
||||||
|
virtual bool canNext() const;
|
||||||
|
virtual bool canPrevious() const;
|
||||||
|
virtual void goToNext();
|
||||||
|
virtual void goToPrev();
|
||||||
|
|
||||||
|
bool showOnRowsInserted() const;
|
||||||
|
void setShowOnRowsInserted(bool v);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int currentRow() const;
|
||||||
|
void setCurrentRow(int);
|
||||||
|
int rowCount() const;
|
||||||
|
void connectNavigationSignals(QAbstractItemModel *);
|
||||||
|
virtual QAbstractItemView *createItemView() = 0;
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void slotRowsInserted();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QAbstractItemView *m_listView;
|
||||||
|
bool m_showOnRowsInserted;
|
||||||
|
};
|
||||||
|
|
||||||
class ANALYZER_EXPORT IAnalyzerTool : public QObject
|
class ANALYZER_EXPORT IAnalyzerTool : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@@ -78,6 +138,8 @@ public:
|
|||||||
|
|
||||||
virtual void initialize(ExtensionSystem::IPlugin *plugin) = 0;
|
virtual void initialize(ExtensionSystem::IPlugin *plugin) = 0;
|
||||||
|
|
||||||
|
virtual IAnalyzerOutputPaneAdapter *outputPaneAdapter();
|
||||||
|
|
||||||
virtual IAnalyzerEngine *createEngine(ProjectExplorer::RunConfiguration *runConfiguration) = 0;
|
virtual IAnalyzerEngine *createEngine(ProjectExplorer::RunConfiguration *runConfiguration) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,6 @@ bool MemcheckPlugin::initialize(const QStringList &/*arguments*/, QString */*err
|
|||||||
AnalyzerGlobalSettings::instance()->registerSubConfigFactory(new MemcheckConfigFactory);
|
AnalyzerGlobalSettings::instance()->registerSubConfigFactory(new MemcheckConfigFactory);
|
||||||
|
|
||||||
AnalyzerManager::instance()->addTool(new MemcheckTool(this));
|
AnalyzerManager::instance()->addTool(new MemcheckTool(this));
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -91,10 +91,29 @@
|
|||||||
#include <QtGui/QCheckBox>
|
#include <QtGui/QCheckBox>
|
||||||
#include <utils/stylehelper.h>
|
#include <utils/stylehelper.h>
|
||||||
|
|
||||||
using namespace Analyzer;
|
|
||||||
using namespace Analyzer::Internal;
|
|
||||||
using namespace Valgrind::XmlProtocol;
|
using namespace Valgrind::XmlProtocol;
|
||||||
|
|
||||||
|
namespace Analyzer {
|
||||||
|
namespace Internal {
|
||||||
|
|
||||||
|
// Adapter for output pane.
|
||||||
|
class MemCheckOutputPaneAdapter : public Analyzer::ListItemViewOutputPaneAdapter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit MemCheckOutputPaneAdapter(MemcheckTool *mct) :
|
||||||
|
ListItemViewOutputPaneAdapter(mct), m_tool(mct) {}
|
||||||
|
|
||||||
|
virtual QWidget *toolBarWidget() { return m_tool->createPaneToolBarWidget(); }
|
||||||
|
virtual void clearContents() { m_tool->clearErrorView(); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual QAbstractItemView *createItemView() { return m_tool->ensurePaneErrorView(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
MemcheckTool *m_tool;
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---------------------------- MemcheckErrorFilterProxyModel
|
||||||
MemcheckErrorFilterProxyModel::MemcheckErrorFilterProxyModel(QObject *parent)
|
MemcheckErrorFilterProxyModel::MemcheckErrorFilterProxyModel(QObject *parent)
|
||||||
: QSortFilterProxyModel(parent),
|
: QSortFilterProxyModel(parent),
|
||||||
m_filterExternalIssues(false)
|
m_filterExternalIssues(false)
|
||||||
@@ -174,19 +193,52 @@ bool MemcheckErrorFilterProxyModel::filterAcceptsRow(int sourceRow, const QModel
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void initKindFilterAction(QAction *action, const QList<int> &kinds)
|
||||||
|
{
|
||||||
|
action->setCheckable(true);
|
||||||
|
QVariantList data;
|
||||||
|
foreach (int kind, kinds)
|
||||||
|
data << kind;
|
||||||
|
action->setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
MemcheckTool::MemcheckTool(QObject *parent) :
|
MemcheckTool::MemcheckTool(QObject *parent) :
|
||||||
Analyzer::IAnalyzerTool(parent),
|
Analyzer::IAnalyzerTool(parent),
|
||||||
m_settings(0),
|
m_settings(0),
|
||||||
m_errorModel(0),
|
m_errorModel(0),
|
||||||
m_errorProxyModel(0),
|
m_errorProxyModel(0),
|
||||||
m_errorView(0),
|
m_errorView(0),
|
||||||
m_prevAction(0),
|
m_filterProjectAction(new QAction(tr("External Errors"), this)),
|
||||||
m_nextAction(0),
|
m_suppressionSeparator(new QAction(tr("Suppressions"), this)),
|
||||||
m_clearAction(0),
|
m_outputPaneAdapter(0)
|
||||||
m_filterProjectAction(0)
|
|
||||||
{
|
{
|
||||||
|
setObjectName(QLatin1String("MemcheckTool"));
|
||||||
connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
|
connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
|
||||||
SIGNAL(updateRunActions()), SLOT(maybeActiveRunConfigurationChanged()));
|
SIGNAL(updateRunActions()), SLOT(maybeActiveRunConfigurationChanged()));
|
||||||
|
|
||||||
|
QAction *a = new QAction(tr("Definite Memory Leaks"), this);
|
||||||
|
initKindFilterAction(a, QList<int>() << Leak_DefinitelyLost << Leak_IndirectlyLost);
|
||||||
|
m_errorFilterActions << a;
|
||||||
|
|
||||||
|
a = new QAction(tr("Possible Memory Leaks"), this);
|
||||||
|
initKindFilterAction(a, QList<int>() << Leak_PossiblyLost << Leak_StillReachable);
|
||||||
|
m_errorFilterActions << a;
|
||||||
|
|
||||||
|
a = new QAction(tr("Use of Uninitialized Memory"), this);
|
||||||
|
initKindFilterAction(a, QList<int>() << InvalidRead << InvalidWrite << InvalidJump << Overlap
|
||||||
|
<< InvalidMemPool << UninitCondition << UninitValue
|
||||||
|
<< SyscallParam << ClientCheck);
|
||||||
|
m_errorFilterActions << a;
|
||||||
|
|
||||||
|
a = new QAction(tr("Invalid Frees"), this);
|
||||||
|
initKindFilterAction(a, QList<int>() << InvalidFree << MismatchedFree);
|
||||||
|
m_errorFilterActions << a;
|
||||||
|
|
||||||
|
m_filterProjectAction->setToolTip(tr("Show issues originating outside currently opened projects."));
|
||||||
|
m_filterProjectAction->setCheckable(true);
|
||||||
|
|
||||||
|
m_suppressionSeparator->setSeparator(true);
|
||||||
|
m_suppressionSeparator->setToolTip(tr("These suppression files where used in the last memory analyzer run."));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemcheckTool::settingsDestroyed(QObject *settings)
|
void MemcheckTool::settingsDestroyed(QObject *settings)
|
||||||
@@ -267,8 +319,6 @@ IAnalyzerTool::ToolMode MemcheckTool::mode() const
|
|||||||
return DebugMode;
|
return DebugMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Analyzer {
|
|
||||||
namespace Internal {
|
|
||||||
class FrameFinder : public ErrorListModel::RelevantFrameFinder {
|
class FrameFinder : public ErrorListModel::RelevantFrameFinder {
|
||||||
public:
|
public:
|
||||||
Frame findRelevant(const Error &error) const {
|
Frame findRelevant(const Error &error) const {
|
||||||
@@ -310,28 +360,17 @@ public:
|
|||||||
private:
|
private:
|
||||||
QStringList m_projectFiles;
|
QStringList m_projectFiles;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void initKindFilterAction(QAction *action, const QList<int> &kinds)
|
MemcheckErrorView *MemcheckTool::ensurePaneErrorView()
|
||||||
{
|
{
|
||||||
action->setCheckable(true);
|
if (!m_errorView) {
|
||||||
QVariantList data;
|
|
||||||
foreach (int kind, kinds)
|
|
||||||
data << kind;
|
|
||||||
action->setData(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemcheckTool::initialize(ExtensionSystem::IPlugin */*plugin*/)
|
|
||||||
{
|
|
||||||
AnalyzerManager *am = AnalyzerManager::instance();
|
|
||||||
|
|
||||||
m_errorView = new MemcheckErrorView;
|
m_errorView = new MemcheckErrorView;
|
||||||
|
m_errorView->setObjectName(QLatin1String("MemcheckErrorView"));
|
||||||
m_errorView->setFrameStyle(QFrame::NoFrame);
|
m_errorView->setFrameStyle(QFrame::NoFrame);
|
||||||
m_errorView->setAttribute(Qt::WA_MacShowFocusRect, false);
|
m_errorView->setAttribute(Qt::WA_MacShowFocusRect, false);
|
||||||
m_errorModel = new ErrorListModel(m_errorView);
|
m_errorModel = new ErrorListModel(m_errorView);
|
||||||
m_frameFinder = new FrameFinder;
|
m_frameFinder = new Internal::FrameFinder;
|
||||||
m_errorModel->setRelevantFrameFinder(QSharedPointer<FrameFinder>(m_frameFinder));
|
m_errorModel->setRelevantFrameFinder(QSharedPointer<Internal::FrameFinder>(m_frameFinder));
|
||||||
m_errorProxyModel = new MemcheckErrorFilterProxyModel(m_errorView);
|
m_errorProxyModel = new MemcheckErrorFilterProxyModel(m_errorView);
|
||||||
m_errorProxyModel->setSourceModel(m_errorModel);
|
m_errorProxyModel->setSourceModel(m_errorModel);
|
||||||
m_errorProxyModel->setDynamicSortFilter(true);
|
m_errorProxyModel->setDynamicSortFilter(true);
|
||||||
@@ -342,98 +381,40 @@ void MemcheckTool::initialize(ExtensionSystem::IPlugin */*plugin*/)
|
|||||||
m_errorView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
m_errorView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
m_errorView->setAutoScroll(false);
|
m_errorView->setAutoScroll(false);
|
||||||
m_errorView->setObjectName("Valgrind.MemcheckTool.ErrorView");
|
m_errorView->setObjectName("Valgrind.MemcheckTool.ErrorView");
|
||||||
|
}
|
||||||
|
return m_errorView;
|
||||||
|
}
|
||||||
|
|
||||||
am->createDockWidget(this, tr("Memory Errors"), m_errorView, Qt::BottomDockWidgetArea);
|
QWidget *MemcheckTool::createPaneToolBarWidget()
|
||||||
|
{
|
||||||
|
QWidget *toolbarWidget = new QWidget;
|
||||||
|
toolbarWidget->setObjectName(QLatin1String("MemCheckToolBarWidget"));
|
||||||
QHBoxLayout *layout = new QHBoxLayout;
|
QHBoxLayout *layout = new QHBoxLayout;
|
||||||
layout->setMargin(0);
|
layout->setMargin(0);
|
||||||
layout->setSpacing(0);
|
layout->setSpacing(0);
|
||||||
|
|
||||||
{ // clear / next / prev
|
|
||||||
QToolButton *button = 0;
|
|
||||||
|
|
||||||
m_clearAction = new QAction(this);
|
|
||||||
m_clearAction->setIcon(QIcon(Core::Constants::ICON_CLEAN_PANE));
|
|
||||||
m_clearAction->setText(tr("Clear"));
|
|
||||||
connect(m_clearAction, SIGNAL(triggered()), this, SLOT(slotClear()));
|
|
||||||
button = new QToolButton;
|
|
||||||
button->setDefaultAction(m_clearAction);
|
|
||||||
layout->addWidget(button);
|
|
||||||
|
|
||||||
m_prevAction = new QAction(this);
|
|
||||||
m_prevAction->setIcon(QIcon(QLatin1String(Core::Constants::ICON_PREV)));
|
|
||||||
m_prevAction->setText(tr("Previous Item"));
|
|
||||||
connect(m_prevAction, SIGNAL(triggered()), this, SLOT(slotPrev()));
|
|
||||||
button = new QToolButton;
|
|
||||||
button->setDefaultAction(m_prevAction);
|
|
||||||
layout->addWidget(button);
|
|
||||||
|
|
||||||
m_nextAction = new QAction(this);
|
|
||||||
m_nextAction->setIcon(QIcon(QLatin1String(Core::Constants::ICON_NEXT)));
|
|
||||||
m_nextAction->setText(tr("Next Item"));
|
|
||||||
connect(m_nextAction, SIGNAL(triggered()), this, SLOT(slotNext()));
|
|
||||||
button = new QToolButton;
|
|
||||||
button->setDefaultAction(m_nextAction);
|
|
||||||
layout->addWidget(button);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
// filter
|
// filter
|
||||||
QToolButton *filterButton = new QToolButton;
|
QToolButton *filterButton = new QToolButton;
|
||||||
filterButton->setIcon(QIcon(Core::Constants::ICON_FILTER));
|
filterButton->setIcon(QIcon(Core::Constants::ICON_FILTER));
|
||||||
filterButton->setText(tr("Error Filter"));
|
filterButton->setText(tr("Error Filter"));
|
||||||
filterButton->setPopupMode(QToolButton::InstantPopup);
|
filterButton->setPopupMode(QToolButton::InstantPopup);
|
||||||
QMenu *filterMenu = new QMenu(filterButton);
|
QMenu *filterMenu = new QMenu(filterButton);
|
||||||
|
foreach (QAction *filterAction, m_errorFilterActions)
|
||||||
QAction *a = filterMenu->addAction(tr("Definite Memory Leaks"));
|
filterMenu->addAction(filterAction);
|
||||||
initKindFilterAction(a, QList<int>() << Leak_DefinitelyLost << Leak_IndirectlyLost);
|
|
||||||
m_errorFilterActions << a;
|
|
||||||
|
|
||||||
a = filterMenu->addAction(tr("Possible Memory Leaks"));
|
|
||||||
initKindFilterAction(a, QList<int>() << Leak_PossiblyLost << Leak_StillReachable);
|
|
||||||
m_errorFilterActions << a;
|
|
||||||
|
|
||||||
a = filterMenu->addAction(tr("Use of Uninitialized Memory"));
|
|
||||||
initKindFilterAction(a, QList<int>() << InvalidRead << InvalidWrite << InvalidJump << Overlap
|
|
||||||
<< InvalidMemPool << UninitCondition << UninitValue
|
|
||||||
<< SyscallParam << ClientCheck);
|
|
||||||
m_errorFilterActions << a;
|
|
||||||
|
|
||||||
a = filterMenu->addAction(tr("Invalid Frees"));
|
|
||||||
initKindFilterAction(a, QList<int>() << InvalidFree << MismatchedFree);
|
|
||||||
m_errorFilterActions << a;
|
|
||||||
|
|
||||||
filterMenu->addSeparator();
|
filterMenu->addSeparator();
|
||||||
|
filterMenu->addAction(m_filterProjectAction);
|
||||||
m_filterProjectAction = filterMenu->addAction(tr("External Errors"));
|
filterMenu->addAction(m_suppressionSeparator);
|
||||||
m_filterProjectAction->setToolTip(tr("Show issues originating outside currently opened projects."));
|
|
||||||
m_filterProjectAction->setCheckable(true);
|
|
||||||
|
|
||||||
m_suppressionSeparator = filterMenu->addSeparator();
|
|
||||||
m_suppressionSeparator->setText(tr("Suppressions"));
|
|
||||||
m_suppressionSeparator->setToolTip(tr("These suppression files where used in the last memory analyzer run."));
|
|
||||||
|
|
||||||
connect(filterMenu, SIGNAL(triggered(QAction *)), SLOT(updateErrorFilter()));
|
connect(filterMenu, SIGNAL(triggered(QAction *)), SLOT(updateErrorFilter()));
|
||||||
filterButton->setMenu(filterMenu);
|
filterButton->setMenu(filterMenu);
|
||||||
layout->addWidget(filterButton);
|
layout->addWidget(filterButton);
|
||||||
|
layout->addStretch();
|
||||||
|
toolbarWidget->setLayout(layout);
|
||||||
|
return toolbarWidget;
|
||||||
}
|
}
|
||||||
|
|
||||||
layout->addStretch();
|
void MemcheckTool::initialize(ExtensionSystem::IPlugin */*plugin*/)
|
||||||
QWidget *toolbar = new QWidget;
|
{
|
||||||
toolbar->setLayout(layout);
|
ensurePaneErrorView();
|
||||||
am->setToolbar(this, toolbar);
|
|
||||||
|
|
||||||
// register shortcuts
|
// register shortcuts
|
||||||
Core::ActionManager *actionManager = Core::ICore::instance()->actionManager();
|
|
||||||
const Core::Context analyzeContext(Constants::C_ANALYZEMODE);
|
|
||||||
|
|
||||||
Core::Command *cmd;
|
|
||||||
|
|
||||||
cmd = actionManager->registerAction(m_prevAction, "Analyzer.MemcheckTool.previtem", analyzeContext);
|
|
||||||
cmd->setDefaultKeySequence(QKeySequence("Shift+F10"));
|
|
||||||
|
|
||||||
cmd = actionManager->registerAction(m_nextAction, "Analyzer.MemcheckTool.nextitem", analyzeContext);
|
|
||||||
cmd->setDefaultKeySequence(QKeySequence("F10"));
|
|
||||||
|
|
||||||
maybeActiveRunConfigurationChanged();
|
maybeActiveRunConfigurationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,7 +435,7 @@ IAnalyzerEngine *MemcheckTool::createEngine(ProjectExplorer::RunConfiguration *r
|
|||||||
|
|
||||||
void MemcheckTool::engineStarting(const IAnalyzerEngine *engine)
|
void MemcheckTool::engineStarting(const IAnalyzerEngine *engine)
|
||||||
{
|
{
|
||||||
slotClear();
|
clearErrorView();
|
||||||
|
|
||||||
const QString dir = engine->runConfiguration()->target()->project()->projectDirectory();
|
const QString dir = engine->runConfiguration()->target()->project()->projectDirectory();
|
||||||
const MemcheckEngine *mEngine = dynamic_cast<const MemcheckEngine*>(engine);
|
const MemcheckEngine *mEngine = dynamic_cast<const MemcheckEngine*>(engine);
|
||||||
@@ -463,7 +444,7 @@ void MemcheckTool::engineStarting(const IAnalyzerEngine *engine)
|
|||||||
|
|
||||||
m_errorView->setDefaultSuppressionFile(dir + QDir::separator() + name + QLatin1String(".supp"));
|
m_errorView->setDefaultSuppressionFile(dir + QDir::separator() + name + QLatin1String(".supp"));
|
||||||
|
|
||||||
QMenu *menu = qobject_cast<QMenu*>(m_suppressionSeparator->parentWidget());
|
QMenu *menu = filterMenu();
|
||||||
QTC_ASSERT(menu, return);
|
QTC_ASSERT(menu, return);
|
||||||
foreach(const QString &file, mEngine->suppressionFiles()) {
|
foreach(const QString &file, mEngine->suppressionFiles()) {
|
||||||
QAction *action = menu->addAction(QFileInfo(file).fileName());
|
QAction *action = menu->addAction(QFileInfo(file).fileName());
|
||||||
@@ -475,6 +456,15 @@ void MemcheckTool::engineStarting(const IAnalyzerEngine *engine)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMenu *MemcheckTool::filterMenu() const
|
||||||
|
{
|
||||||
|
QTC_ASSERT(m_suppressionSeparator, return 0; )
|
||||||
|
foreach (QWidget *w, m_suppressionSeparator->associatedWidgets())
|
||||||
|
if (QMenu *menu = qobject_cast<QMenu*>(w))
|
||||||
|
return menu;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void MemcheckTool::suppressionActionTriggered()
|
void MemcheckTool::suppressionActionTriggered()
|
||||||
{
|
{
|
||||||
QAction *action = qobject_cast<QAction*>(sender());
|
QAction *action = qobject_cast<QAction*>(sender());
|
||||||
@@ -495,48 +485,13 @@ void MemcheckTool::internalParserError(const QString &errorString)
|
|||||||
QMessageBox::critical(m_errorView, tr("Internal Error"), tr("Error occurred parsing valgrind output: %1").arg(errorString));
|
QMessageBox::critical(m_errorView, tr("Internal Error"), tr("Error occurred parsing valgrind output: %1").arg(errorString));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemcheckTool::slotNext()
|
void MemcheckTool::clearErrorView()
|
||||||
{
|
|
||||||
QModelIndex current = m_errorView->selectionModel()->currentIndex();
|
|
||||||
if (!current.isValid()) {
|
|
||||||
if (!m_errorView->model()->rowCount())
|
|
||||||
return;
|
|
||||||
|
|
||||||
current = m_errorView->model()->index(0, 0);
|
|
||||||
} else if (current.row() < m_errorView->model()->rowCount(current.parent()) - 1) {
|
|
||||||
current = m_errorView->model()->index(current.row() + 1, 0);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_errorView->selectionModel()->setCurrentIndex(current, QItemSelectionModel::ClearAndSelect);
|
|
||||||
m_errorView->scrollTo(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemcheckTool::slotPrev()
|
|
||||||
{
|
|
||||||
QModelIndex current = m_errorView->selectionModel()->currentIndex();
|
|
||||||
if (!current.isValid()) {
|
|
||||||
if (!m_errorView->model()->rowCount())
|
|
||||||
return;
|
|
||||||
current = m_errorView->model()->index(m_errorView->model()->rowCount() - 1, 0);
|
|
||||||
} else if (current.row() > 0) {
|
|
||||||
current = m_errorView->model()->index(current.row() - 1, 0);
|
|
||||||
} else {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_errorView->selectionModel()->setCurrentIndex(current, QItemSelectionModel::ClearAndSelect);
|
|
||||||
m_errorView->scrollTo(current);
|
|
||||||
}
|
|
||||||
|
|
||||||
void MemcheckTool::slotClear()
|
|
||||||
{
|
{
|
||||||
m_errorModel->clear();
|
m_errorModel->clear();
|
||||||
|
|
||||||
qDeleteAll(m_suppressionActions);
|
qDeleteAll(m_suppressionActions);
|
||||||
m_suppressionActions.clear();
|
m_suppressionActions.clear();
|
||||||
QTC_ASSERT(m_suppressionSeparator->parentWidget()->actions().last() == m_suppressionSeparator, qt_noop());
|
QTC_ASSERT(filterMenu()->actions().last() == m_suppressionSeparator, qt_noop());
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemcheckTool::updateErrorFilter()
|
void MemcheckTool::updateErrorFilter()
|
||||||
@@ -560,3 +515,13 @@ void MemcheckTool::updateErrorFilter()
|
|||||||
}
|
}
|
||||||
memcheckSettings->setVisibleErrorKinds(errorKinds);
|
memcheckSettings->setVisibleErrorKinds(errorKinds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IAnalyzerOutputPaneAdapter *MemcheckTool::outputPaneAdapter()
|
||||||
|
{
|
||||||
|
if (!m_outputPaneAdapter)
|
||||||
|
m_outputPaneAdapter = new MemCheckOutputPaneAdapter(this);
|
||||||
|
return m_outputPaneAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Internal
|
||||||
|
} // namespace Analyzer
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ class QModelIndex;
|
|||||||
class QAction;
|
class QAction;
|
||||||
class QSpinBox;
|
class QSpinBox;
|
||||||
class QCheckBox;
|
class QCheckBox;
|
||||||
|
class QMenu;
|
||||||
QT_END_NAMESPACE
|
QT_END_NAMESPACE
|
||||||
|
|
||||||
namespace Valgrind {
|
namespace Valgrind {
|
||||||
@@ -58,11 +59,9 @@ class Error;
|
|||||||
}
|
}
|
||||||
|
|
||||||
namespace Analyzer {
|
namespace Analyzer {
|
||||||
|
|
||||||
class AnalyzerSettings;
|
class AnalyzerSettings;
|
||||||
|
|
||||||
namespace Internal {
|
namespace Internal {
|
||||||
|
class MemCheckOutputPaneAdapter;
|
||||||
class MemcheckErrorView;
|
class MemcheckErrorView;
|
||||||
class FrameFinder;
|
class FrameFinder;
|
||||||
|
|
||||||
@@ -95,8 +94,14 @@ public:
|
|||||||
|
|
||||||
void initialize(ExtensionSystem::IPlugin *plugin);
|
void initialize(ExtensionSystem::IPlugin *plugin);
|
||||||
|
|
||||||
|
virtual IAnalyzerOutputPaneAdapter *outputPaneAdapter();
|
||||||
IAnalyzerEngine *createEngine(ProjectExplorer::RunConfiguration *runConfiguration);
|
IAnalyzerEngine *createEngine(ProjectExplorer::RunConfiguration *runConfiguration);
|
||||||
|
|
||||||
|
// For the output pane adapter.
|
||||||
|
MemcheckErrorView *ensurePaneErrorView();
|
||||||
|
QWidget *createPaneToolBarWidget();
|
||||||
|
void clearErrorView();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void settingsDestroyed(QObject *settings);
|
void settingsDestroyed(QObject *settings);
|
||||||
void maybeActiveRunConfigurationChanged();
|
void maybeActiveRunConfigurationChanged();
|
||||||
@@ -104,13 +109,9 @@ private slots:
|
|||||||
void engineStarting(const IAnalyzerEngine *engine);
|
void engineStarting(const IAnalyzerEngine *engine);
|
||||||
void parserError(const Valgrind::XmlProtocol::Error &error);
|
void parserError(const Valgrind::XmlProtocol::Error &error);
|
||||||
void internalParserError(const QString &errorString);
|
void internalParserError(const QString &errorString);
|
||||||
|
|
||||||
void slotNext();
|
|
||||||
void slotPrev();
|
|
||||||
void slotClear();
|
|
||||||
|
|
||||||
void updateErrorFilter();
|
void updateErrorFilter();
|
||||||
void suppressionActionTriggered();
|
void suppressionActionTriggered();
|
||||||
|
QMenu *filterMenu() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AnalyzerSettings *m_settings;
|
AnalyzerSettings *m_settings;
|
||||||
@@ -120,13 +121,11 @@ private:
|
|||||||
MemcheckErrorFilterProxyModel *m_errorProxyModel;
|
MemcheckErrorFilterProxyModel *m_errorProxyModel;
|
||||||
MemcheckErrorView *m_errorView;
|
MemcheckErrorView *m_errorView;
|
||||||
|
|
||||||
QAction *m_prevAction;
|
|
||||||
QAction *m_nextAction;
|
|
||||||
QAction *m_clearAction;
|
|
||||||
QList<QAction *> m_errorFilterActions;
|
QList<QAction *> m_errorFilterActions;
|
||||||
QAction *m_filterProjectAction;
|
QAction *m_filterProjectAction;
|
||||||
QList<QAction *> m_suppressionActions;
|
QList<QAction *> m_suppressionActions;
|
||||||
QAction *m_suppressionSeparator;
|
QAction *m_suppressionSeparator;
|
||||||
|
MemCheckOutputPaneAdapter *m_outputPaneAdapter;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Internal
|
} // namespace Internal
|
||||||
|
|||||||
Reference in New Issue
Block a user