OSDN Git Service

analyzer: use dockwidget also for the memcheck tool
authorhjk <qtc-committer@nokia.com>
Mon, 27 Jun 2011 13:43:15 +0000 (15:43 +0200)
committerhjk <qthjk@ovi.com>
Mon, 27 Jun 2011 14:16:41 +0000 (16:16 +0200)
Change-Id: I40d3a03e80627b4ff62ff84726dd6de3bcb1f5ea
Reviewed-on: http://codereview.qt.nokia.com/775
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: hjk <qthjk@ovi.com>
src/plugins/valgrind/memcheckerrorview.cpp
src/plugins/valgrind/memcheckerrorview.h
src/plugins/valgrind/memchecktool.cpp
src/plugins/valgrind/memchecktool.h

index e89595a..69957dd 100644 (file)
@@ -507,5 +507,35 @@ void MemcheckErrorView::suppressError()
     }
 }
 
+void MemcheckErrorView::goNext()
+{
+    setCurrentRow((currentRow() + 1) % rowCount());
+}
+
+void MemcheckErrorView::goBack()
+{
+    const int prevRow = currentRow() - 1;
+    setCurrentRow(prevRow >= 0 ? prevRow : rowCount() - 1);
+}
+
+int MemcheckErrorView::rowCount() const
+{
+    return model() ? model()->rowCount() : 0;
+}
+
+int MemcheckErrorView::currentRow() const
+{
+    const QModelIndex index = selectionModel()->currentIndex();
+    return index.row();
+}
+
+void MemcheckErrorView::setCurrentRow(int row)
+{
+    const QModelIndex index = model()->index(row, 0);
+    selectionModel()->setCurrentIndex(index,
+            QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows);
+    scrollTo(index);
+}
+
 } // namespace Internal
 } // namespace Valgrind
index d364536..f64bc5b 100644 (file)
@@ -99,20 +99,24 @@ public:
     QString defaultSuppressionFile() const;
     Analyzer::AnalyzerSettings *settings() const { return m_settings; }
 
-signals:
-    void resized();
-
 public slots:
     void settingsChanged(Analyzer::AnalyzerSettings *settings);
+    void goNext();
+    void goBack();
 
-private slots:
-    void suppressError();
+signals:
+    void resized();
 
-protected:
+private slots:
     void resizeEvent(QResizeEvent *e);
     void contextMenuEvent(QContextMenuEvent *e);
+    void suppressError();
+    void setCurrentRow(int row);
 
 private:
+    int rowCount() const;
+    int currentRow() const;
+
     QAction *m_copyAction;
     QAction *m_suppressAction;
     QString m_defaultSuppFile;
index 5388662..b391ca1 100644 (file)
@@ -40,7 +40,6 @@
 
 #include <analyzerbase/analyzermanager.h>
 #include <analyzerbase/analyzerconstants.h>
-#include <analyzerbase/ianalyzeroutputpaneadapter.h>
 
 #include <valgrind/xmlprotocol/errorlistmodel.h>
 #include <valgrind/xmlprotocol/stackmodel.h>
@@ -96,23 +95,6 @@ using namespace Valgrind::XmlProtocol;
 namespace Valgrind {
 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)
     : QSortFilterProxyModel(parent),
@@ -202,43 +184,41 @@ static void initKindFilterAction(QAction *action, const QList<int> &kinds)
     action->setData(data);
 }
 
-MemcheckTool::MemcheckTool(QObject *parent) :
-    Analyzer::IAnalyzerTool(parent),
-    m_settings(0),
-    m_errorModel(0),
-    m_errorProxyModel(0),
-    m_errorView(0),
-    m_filterProjectAction(new QAction(tr("External Errors"), this)),
-    m_suppressionSeparator(new QAction(tr("Suppressions"), this)),
-    m_outputPaneAdapter(0)
+MemcheckTool::MemcheckTool(QObject *parent)
+  : Analyzer::IAnalyzerTool(parent)
 {
+    m_settings = 0;
+    m_errorModel = 0;
+    m_errorProxyModel = 0;
+    m_errorView = 0;
+    m_filterMenu = 0;
     setObjectName(QLatin1String("MemcheckTool"));
-    connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
-            SIGNAL(updateRunActions()), SLOT(maybeActiveRunConfigurationChanged()));
+
+    m_filterProjectAction = new QAction(tr("External Errors"), this);
+    m_filterProjectAction->setToolTip(tr("Show issues originating outside currently opened projects."));
+    m_filterProjectAction->setCheckable(true);
+
+    m_suppressionSeparator = new QAction(tr("Suppressions"), this);
+    m_suppressionSeparator->setSeparator(true);
+    m_suppressionSeparator->setToolTip(tr("These suppression files were used in the last memory analyzer run."));
 
     QAction *a = new QAction(tr("Definite Memory Leaks"), this);
     initKindFilterAction(a, QList<int>() << Leak_DefinitelyLost << Leak_IndirectlyLost);
-    m_errorFilterActions << a;
+    m_errorFilterActions.append(a);
 
     a = new QAction(tr("Possible Memory Leaks"), this);
     initKindFilterAction(a, QList<int>() << Leak_PossiblyLost << Leak_StillReachable);
-    m_errorFilterActions << a;
+    m_errorFilterActions.append(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;
+    m_errorFilterActions.append(a);
 
-    a = new QAction(tr("Invalid Frees"), this);
+    a = new QAction(tr("Invalid Calls to \"free()\""), 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 were used in the last memory analyzer run."));
+    m_errorFilterActions.append(a);
 }
 
 void MemcheckTool::settingsDestroyed(QObject *settings)
@@ -247,8 +227,15 @@ void MemcheckTool::settingsDestroyed(QObject *settings)
     m_settings = AnalyzerGlobalSettings::instance();
 }
 
+void MemcheckTool::extensionsInitialized()
+{
+    //ensureWidgets(); // FIXME: Try to do that later.
+}
+
 void MemcheckTool::maybeActiveRunConfigurationChanged()
 {
+    ensureWidgets();
+
     AnalyzerSettings *settings = 0;
     ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance();
     if (ProjectExplorer::Project *project = pe->startupProject()) {
@@ -292,7 +279,6 @@ void MemcheckTool::maybeActiveRunConfigurationChanged()
     }
 
     m_filterProjectAction->setChecked(!memcheckSettings->filterExternalIssues());
-
     m_errorView->settingsChanged(m_settings);
 
     connect(memcheckSettings, SIGNAL(visibleErrorKindsChanged(QList<int>)),
@@ -365,61 +351,99 @@ private:
     QStringList m_projectFiles;
 };
 
-MemcheckErrorView *MemcheckTool::ensurePaneErrorView()
+void MemcheckTool::initializeDockWidgets()
 {
-    if (!m_errorView) {
-        m_errorView = new MemcheckErrorView;
-        m_errorView->setObjectName(QLatin1String("MemcheckErrorView"));
-        m_errorView->setFrameStyle(QFrame::NoFrame);
-        m_errorView->setAttribute(Qt::WA_MacShowFocusRect, false);
-        m_errorModel = new ErrorListModel(m_errorView);
-        m_frameFinder = new Internal::FrameFinder;
-        m_errorModel->setRelevantFrameFinder(QSharedPointer<Internal::FrameFinder>(m_frameFinder));
-        m_errorProxyModel = new MemcheckErrorFilterProxyModel(m_errorView);
-        m_errorProxyModel->setSourceModel(m_errorModel);
-        m_errorProxyModel->setDynamicSortFilter(true);
-        m_errorView->setModel(m_errorProxyModel);
-        m_errorView->setSelectionMode(QAbstractItemView::ExtendedSelection);
-        // make m_errorView->selectionModel()->selectedRows() return something
-        m_errorView->setSelectionBehavior(QAbstractItemView::SelectRows);
-        m_errorView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
-        m_errorView->setAutoScroll(false);
-        m_errorView->setObjectName("Valgrind.MemcheckTool.ErrorView");
-    }
-    return m_errorView;
+    ensureWidgets();
 }
 
-QWidget *MemcheckTool::createPaneToolBarWidget()
+void MemcheckTool::ensureWidgets()
 {
-    QWidget *toolbarWidget = new QWidget;
-    toolbarWidget->setObjectName(QLatin1String("MemCheckToolBarWidget"));
+    if (m_errorView)
+        return;
+
+    AnalyzerManager *am = AnalyzerManager::instance();
+    Utils::FancyMainWindow *mw = am->mainWindow();
+
+    m_errorView = new MemcheckErrorView;
+    m_errorView->setObjectName(QLatin1String("MemcheckErrorView"));
+    m_errorView->setFrameStyle(QFrame::NoFrame);
+    m_errorView->setAttribute(Qt::WA_MacShowFocusRect, false);
+    m_errorModel = new ErrorListModel(m_errorView);
+    m_frameFinder = new Internal::FrameFinder;
+    m_errorModel->setRelevantFrameFinder(QSharedPointer<Internal::FrameFinder>(m_frameFinder));
+    m_errorProxyModel = new MemcheckErrorFilterProxyModel(m_errorView);
+    m_errorProxyModel->setSourceModel(m_errorModel);
+    m_errorProxyModel->setDynamicSortFilter(true);
+    m_errorView->setModel(m_errorProxyModel);
+    m_errorView->setSelectionMode(QAbstractItemView::ExtendedSelection);
+    // make m_errorView->selectionModel()->selectedRows() return something
+    m_errorView->setSelectionBehavior(QAbstractItemView::SelectRows);
+    m_errorView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
+    m_errorView->setAutoScroll(false);
+    m_errorView->setObjectName("Valgrind.MemcheckTool.ErrorView");
+
+    QDockWidget *errorDock =
+        am->createDockWidget(this, tr("Memory Issues"), m_errorView,
+                             Qt::BottomDockWidgetArea);
+    mw->splitDockWidget(mw->toolBarDockWidget(), errorDock, Qt::Vertical);
+
+    connect(ProjectExplorer::ProjectExplorerPlugin::instance(),
+            SIGNAL(updateRunActions()), SLOT(maybeActiveRunConfigurationChanged()));
+}
+
+QWidget *MemcheckTool::createControlWidget()
+{
+    ensureWidgets();
+
+    QAction *action = 0;
     QHBoxLayout *layout = new QHBoxLayout;
+    QToolButton *button = 0;
+
     layout->setMargin(0);
     layout->setSpacing(0);
-    // filter
+
+    // Go to previous leak.
+    action = new QAction(this);
+    action->setDisabled(true);
+    action->setIcon(QIcon(QLatin1String(":core/images/prev.png")));
+    action->setToolTip(tr("Go to previous leak."));
+    connect(action, SIGNAL(triggered(bool)), m_errorView, SLOT(goBack()));
+    button = new QToolButton;
+    button->setDefaultAction(action);
+    layout->addWidget(button);
+    m_goBack = action;
+
+    // Go to next leak.
+    action = new QAction(this);
+    action->setDisabled(true);
+    action->setIcon(QIcon(QLatin1String(":core/images/next.png")));
+    action->setToolTip(tr("Go to next leak."));
+    connect(action, SIGNAL(triggered(bool)), m_errorView, SLOT(goNext()));
+    button = new QToolButton;
+    button->setDefaultAction(action);
+    layout->addWidget(button);
+    m_goNext = action;
+
     QToolButton *filterButton = new QToolButton;
     filterButton->setIcon(QIcon(Core::Constants::ICON_FILTER));
     filterButton->setText(tr("Error Filter"));
     filterButton->setPopupMode(QToolButton::InstantPopup);
-    QMenu *filterMenu = new QMenu(filterButton);
+
+    m_filterMenu = new QMenu(filterButton);
     foreach (QAction *filterAction, m_errorFilterActions)
-        filterMenu->addAction(filterAction);
-    filterMenu->addSeparator();
-    filterMenu->addAction(m_filterProjectAction);
-    filterMenu->addAction(m_suppressionSeparator);
-    connect(filterMenu, SIGNAL(triggered(QAction *)), SLOT(updateErrorFilter()));
-    filterButton->setMenu(filterMenu);
+        m_filterMenu->addAction(filterAction);
+    m_filterMenu->addSeparator();
+    m_filterMenu->addAction(m_filterProjectAction);
+    m_filterMenu->addAction(m_suppressionSeparator);
+    connect(m_filterMenu, SIGNAL(triggered(QAction *)), SLOT(updateErrorFilter()));
+    filterButton->setMenu(m_filterMenu);
     layout->addWidget(filterButton);
-    layout->addStretch();
-    toolbarWidget->setLayout(layout);
-    return toolbarWidget;
-}
 
-void MemcheckTool::initialize()
-{
-    ensurePaneErrorView();
-    // register shortcuts
-    maybeActiveRunConfigurationChanged();
+    layout->addStretch();
+    QWidget *widget = new QWidget;
+    widget->setObjectName(QLatin1String("MemCheckToolBarWidget"));
+    widget->setLayout(layout);
+    return widget;
 }
 
 IAnalyzerEngine *MemcheckTool::createEngine(const AnalyzerStartParameters &sp,
@@ -454,27 +478,16 @@ void MemcheckTool::engineStarting(const IAnalyzerEngine *engine)
 
     m_errorView->setDefaultSuppressionFile(dir + name + QLatin1String(".supp"));
 
-    QMenu *menu = filterMenu();
-    QTC_ASSERT(menu, return);
     foreach (const QString &file, mEngine->suppressionFiles()) {
-        QAction *action = menu->addAction(QFileInfo(file).fileName());
+        QAction *action = m_filterMenu->addAction(QFileInfo(file).fileName());
         action->setToolTip(file);
         action->setData(file);
         connect(action, SIGNAL(triggered(bool)),
                 this, SLOT(suppressionActionTriggered()));
-        m_suppressionActions << action;
+        m_suppressionActions.append(action);
     }
 }
 
-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()
 {
     QAction *action = qobject_cast<QAction *>(sender());
@@ -498,15 +511,17 @@ void MemcheckTool::internalParserError(const QString &errorString)
 
 void MemcheckTool::clearErrorView()
 {
+    ensureWidgets();
     m_errorModel->clear();
 
     qDeleteAll(m_suppressionActions);
     m_suppressionActions.clear();
-    QTC_ASSERT(filterMenu()->actions().last() == m_suppressionSeparator, qt_noop());
+    //QTC_ASSERT(filterMenu()->actions().last() == m_suppressionSeparator, qt_noop());
 }
 
 void MemcheckTool::updateErrorFilter()
 {
+    ensureWidgets();
     QTC_ASSERT(m_settings, return);
 
     AbstractMemcheckSettings *memcheckSettings = m_settings->subConfig<AbstractMemcheckSettings>();
@@ -527,16 +542,12 @@ void MemcheckTool::updateErrorFilter()
     memcheckSettings->setVisibleErrorKinds(errorKinds);
 }
 
-IAnalyzerOutputPaneAdapter *MemcheckTool::outputPaneAdapter()
-{
-    if (!m_outputPaneAdapter)
-        m_outputPaneAdapter = new MemCheckOutputPaneAdapter(this);
-    return m_outputPaneAdapter;
-}
-
 void MemcheckTool::finished()
 {
-    const QString msg = AnalyzerManager::msgToolFinished(displayName(), m_errorModel->rowCount());
+    const int n = m_errorModel->rowCount();
+    m_goBack->setEnabled(n > 0);
+    m_goNext->setEnabled(n > 0);
+    const QString msg = AnalyzerManager::msgToolFinished(displayName(), n);
     AnalyzerManager::instance()->showStatusMessage(msg);
 }
 
index 35262a9..273593a 100644 (file)
@@ -57,15 +57,13 @@ class Error;
 }
 }
 
-namespace Analyzer
-{
+namespace Analyzer {
 class AnalyzerSettings;
 }
 
 namespace Valgrind {
 namespace Internal {
 
-class MemCheckOutputPaneAdapter;
 class MemcheckErrorView;
 class FrameFinder;
 
@@ -99,21 +97,6 @@ public:
     QString displayName() const;
     ToolMode mode() const;
 
-    void initialize();
-    void extensionsInitialized() {}
-
-    Analyzer::IAnalyzerOutputPaneAdapter *outputPaneAdapter();
-    Analyzer::IAnalyzerEngine *createEngine(const Analyzer::AnalyzerStartParameters &sp,
-                               ProjectExplorer::RunConfiguration *runConfiguration = 0);
-
-    // For the output pane adapter.
-    MemcheckErrorView *ensurePaneErrorView();
-    QWidget *createPaneToolBarWidget();
-    void clearErrorView();
-
-    bool canRunRemotely() const;
-    bool needsOutputPane() const { return true; }
-
 private slots:
     void settingsDestroyed(QObject *settings);
     void maybeActiveRunConfigurationChanged();
@@ -127,9 +110,21 @@ private slots:
     void suppressionActionTriggered();
 
 private:
-    QMenu *filterMenu() const;
+    void ensureWidgets();
+    bool canRunRemotely() const;
+    bool needsOutputPane() const { return true; }
+    void initializeDockWidgets();
+    void initialize() {}
+    void extensionsInitialized();
+    QWidget *createControlWidget();
+
+    Analyzer::IAnalyzerEngine *createEngine(const Analyzer::AnalyzerStartParameters &sp,
+                               ProjectExplorer::RunConfiguration *runConfiguration = 0);
+
+    void clearErrorView();
 
     Analyzer::AnalyzerSettings *m_settings;
+    QMenu *m_filterMenu;
 
     FrameFinder *m_frameFinder;
     Valgrind::XmlProtocol::ErrorListModel *m_errorModel;
@@ -140,7 +135,8 @@ private:
     QAction *m_filterProjectAction;
     QList<QAction *> m_suppressionActions;
     QAction *m_suppressionSeparator;
-    MemCheckOutputPaneAdapter *m_outputPaneAdapter;
+    QAction *m_goBack;
+    QAction *m_goNext;
 };
 
 } // namespace Internal