Analyzer: Put more common code into the DetailedError* base classes.

Namely:
    - The "copy" action and the corresponding "slot".
    - The context menu.
Plus an infrastructure for adding new common and custom actions.

Change-Id: I4bf8b28b4ad60b4022abbfc0b401c3b832b94560
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
This commit is contained in:
Christian Kandeler
2015-02-11 16:12:58 +01:00
parent 875d889082
commit d9408156d1
4 changed files with 78 additions and 44 deletions

View File

@@ -30,10 +30,14 @@
#include "detailederrorview.h" #include "detailederrorview.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QApplication>
#include <QClipboard>
#include <QContextMenuEvent>
#include <QFontMetrics> #include <QFontMetrics>
#include <QPainter> #include <QPainter>
#include <QScrollBar> #include <QScrollBar>
@@ -216,6 +220,11 @@ void DetailedErrorDelegate::openLinkInEditor(const QString &link)
Core::EditorManager::openEditorAt(path, qMax(line, 0), qMax(column, 0)); Core::EditorManager::openEditorAt(path, qMax(line, 0), qMax(column, 0));
} }
void DetailedErrorDelegate::copyToClipboard()
{
QApplication::clipboard()->setText(textualRepresentation());
}
DetailedErrorView::DetailedErrorView(QWidget *parent) DetailedErrorView::DetailedErrorView(QWidget *parent)
: QListView(parent) : QListView(parent)
{ {
@@ -232,6 +241,14 @@ void DetailedErrorView::setItemDelegate(QAbstractItemDelegate *delegate)
DetailedErrorDelegate *myDelegate = qobject_cast<DetailedErrorDelegate *>(itemDelegate()); DetailedErrorDelegate *myDelegate = qobject_cast<DetailedErrorDelegate *>(itemDelegate());
connect(this, &DetailedErrorView::resized, myDelegate, &DetailedErrorDelegate::onViewResized); connect(this, &DetailedErrorView::resized, myDelegate, &DetailedErrorDelegate::onViewResized);
m_copyAction = new QAction(this);
m_copyAction->setText(tr("Copy"));
m_copyAction->setIcon(QIcon(QLatin1String(Core::Constants::ICON_COPY)));
m_copyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C));
m_copyAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
connect(m_copyAction, &QAction::triggered, myDelegate, &DetailedErrorDelegate::copyToClipboard);
addAction(m_copyAction);
} }
void DetailedErrorView::setModel(QAbstractItemModel *model) void DetailedErrorView::setModel(QAbstractItemModel *model)
@@ -253,6 +270,21 @@ void DetailedErrorView::resizeEvent(QResizeEvent *e)
QListView::resizeEvent(e); QListView::resizeEvent(e);
} }
void DetailedErrorView::contextMenuEvent(QContextMenuEvent *e)
{
if (selectionModel()->selectedRows().isEmpty())
return;
QMenu menu;
menu.addActions(commonActions());
const QList<QAction *> custom = customActions();
if (!custom.isEmpty()) {
menu.addSeparator();
menu.addActions(custom);
}
menu.exec(e->globalPos());
}
void DetailedErrorView::updateGeometries() void DetailedErrorView::updateGeometries()
{ {
if (model()) { if (model()) {
@@ -284,6 +316,18 @@ int DetailedErrorView::rowCount() const
return model() ? model()->rowCount() : 0; return model() ? model()->rowCount() : 0;
} }
QList<QAction *> DetailedErrorView::commonActions() const
{
QList<QAction *> actions;
actions << m_copyAction;
return actions;
}
QList<QAction *> DetailedErrorView::customActions() const
{
return QList<QAction *>();
}
int DetailedErrorView::currentRow() const int DetailedErrorView::currentRow() const
{ {
const QModelIndex index = selectionModel()->currentIndex(); const QModelIndex index = selectionModel()->currentIndex();

View File

@@ -55,7 +55,7 @@ public:
explicit DetailedErrorDelegate(QListView *parent); explicit DetailedErrorDelegate(QListView *parent);
virtual SummaryLineInfo summaryInfo(const QModelIndex &index) const = 0; virtual SummaryLineInfo summaryInfo(const QModelIndex &index) const = 0;
virtual void copy() = 0; void copyToClipboard();
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const; QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
void paint(QPainter *painter, const QStyleOptionViewItem &option, void paint(QPainter *painter, const QStyleOptionViewItem &option,
@@ -77,6 +77,7 @@ private:
// the constness of this function is a necessary lie because it is called from paint() const. // the constness of this function is a necessary lie because it is called from paint() const.
virtual QWidget *createDetailsWidget(const QFont &font, const QModelIndex &errorIndex, virtual QWidget *createDetailsWidget(const QFont &font, const QModelIndex &errorIndex,
QWidget *parent) const = 0; QWidget *parent) const = 0;
virtual QString textualRepresentation() const = 0;
static const int s_itemMargin = 2; static const int s_itemMargin = 2;
mutable QWidget *m_detailsWidget; mutable QWidget *m_detailsWidget;
@@ -109,10 +110,16 @@ protected:
void resizeEvent(QResizeEvent *e); void resizeEvent(QResizeEvent *e);
private: private:
void contextMenuEvent(QContextMenuEvent *e) Q_DECL_OVERRIDE;
int currentRow() const; int currentRow() const;
void setCurrentRow(int row); void setCurrentRow(int row);
int rowCount() const; int rowCount() const;
QList<QAction *> commonActions() const;
virtual QList<QAction *> customActions() const;
QAction *m_copyAction;
}; };
} // namespace Analyzer } // namespace Analyzer

View File

@@ -41,7 +41,6 @@
#include "xmlprotocol/modelhelpers.h" #include "xmlprotocol/modelhelpers.h"
#include "xmlprotocol/suppression.h" #include "xmlprotocol/suppression.h"
#include <coreplugin/coreconstants.h>
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <projectexplorer/project.h> #include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
@@ -52,12 +51,7 @@
#include <QDebug> #include <QDebug>
#include <QAction> #include <QAction>
#include <QApplication>
#include <QClipboard>
#include <QContextMenuEvent>
#include <QLabel> #include <QLabel>
#include <QListView>
#include <QMenu>
#include <QPainter> #include <QPainter>
#include <QScrollBar> #include <QScrollBar>
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
@@ -77,13 +71,12 @@ class MemcheckErrorDelegate : public Analyzer::DetailedErrorDelegate
public: public:
explicit MemcheckErrorDelegate(QListView *parent); explicit MemcheckErrorDelegate(QListView *parent);
void copy();
SummaryLineInfo summaryInfo(const QModelIndex &index) const; SummaryLineInfo summaryInfo(const QModelIndex &index) const;
private: private:
QWidget *createDetailsWidget(const QFont &font, const QModelIndex &errorIndex, QWidget *createDetailsWidget(const QFont &font, const QModelIndex &errorIndex,
QWidget *parent) const; QWidget *parent) const;
QString textualRepresentation() const Q_DECL_OVERRIDE;
}; };
static QString makeFrameName(const Frame &frame, const QString &relativeTo, static QString makeFrameName(const Frame &frame, const QString &relativeTo,
@@ -261,9 +254,9 @@ Analyzer::DetailedErrorDelegate::SummaryLineInfo MemcheckErrorDelegate::summaryI
return info; return info;
} }
void MemcheckErrorDelegate::copy() QString MemcheckErrorDelegate::textualRepresentation() const
{ {
QTC_ASSERT(m_detailsIndex.isValid(), return); QTC_ASSERT(m_detailsIndex.isValid(), return QString());
QString content; QString content;
QTextStream stream(&content); QTextStream stream(&content);
@@ -283,7 +276,7 @@ void MemcheckErrorDelegate::copy()
} }
stream.flush(); stream.flush();
QApplication::clipboard()->setText(content); return content;
} }
MemcheckErrorView::MemcheckErrorView(QWidget *parent) MemcheckErrorView::MemcheckErrorView(QWidget *parent)
@@ -293,14 +286,6 @@ MemcheckErrorView::MemcheckErrorView(QWidget *parent)
MemcheckErrorDelegate *delegate = new MemcheckErrorDelegate(this); MemcheckErrorDelegate *delegate = new MemcheckErrorDelegate(this);
setItemDelegate(delegate); setItemDelegate(delegate);
m_copyAction = new QAction(this);
m_copyAction->setText(tr("Copy"));
m_copyAction->setIcon(QIcon(QLatin1String(Core::Constants::ICON_COPY)));
m_copyAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_C));
m_copyAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
connect(m_copyAction, &QAction::triggered, delegate, &MemcheckErrorDelegate::copy);
addAction(m_copyAction);
m_suppressAction = new QAction(this); m_suppressAction = new QAction(this);
m_suppressAction->setText(tr("Suppress Error")); m_suppressAction->setText(tr("Suppress Error"));
m_suppressAction->setIcon(QIcon(QLatin1String(":/qmldesigner/images/eye_crossed.png"))); m_suppressAction->setIcon(QIcon(QLatin1String(":/qmldesigner/images/eye_crossed.png")));
@@ -332,32 +317,30 @@ void MemcheckErrorView::settingsChanged(ValgrindBaseSettings *settings)
m_settings = settings; m_settings = settings;
} }
void MemcheckErrorView::contextMenuEvent(QContextMenuEvent *e)
{
const QModelIndexList indizes = selectionModel()->selectedRows();
if (indizes.isEmpty())
return;
QList<Error> errors;
foreach (const QModelIndex &index, indizes) {
Error error = model()->data(index, ErrorListModel::ErrorRole).value<Error>();
if (!error.suppression().isNull())
errors << error;
}
QMenu menu;
menu.addAction(m_copyAction);
menu.addSeparator();
menu.addAction(m_suppressAction);
m_suppressAction->setEnabled(!errors.isEmpty());
menu.exec(e->globalPos());
}
void MemcheckErrorView::suppressError() void MemcheckErrorView::suppressError()
{ {
SuppressionDialog::maybeShow(this); SuppressionDialog::maybeShow(this);
} }
QList<QAction *> MemcheckErrorView::customActions() const
{
QList<QAction *> actions;
const QModelIndexList indizes = selectionModel()->selectedRows();
QTC_ASSERT(!indizes.isEmpty(), return actions);
bool hasErrors = false;
foreach (const QModelIndex &index, indizes) {
Error error = model()->data(index, ErrorListModel::ErrorRole).value<Error>();
if (!error.suppression().isNull()) {
hasErrors = true;
break;
}
}
m_suppressAction->setEnabled(hasErrors);
actions << m_suppressAction;
return actions;
}
} // namespace Internal } // namespace Internal
} // namespace Valgrind } // namespace Valgrind

View File

@@ -57,11 +57,11 @@ public slots:
void settingsChanged(ValgrindBaseSettings *settings); void settingsChanged(ValgrindBaseSettings *settings);
private slots: private slots:
void contextMenuEvent(QContextMenuEvent *e);
void suppressError(); void suppressError();
private: private:
QAction *m_copyAction; QList<QAction *> customActions() const Q_DECL_OVERRIDE;
QAction *m_suppressAction; QAction *m_suppressAction;
QString m_defaultSuppFile; QString m_defaultSuppFile;
ValgrindBaseSettings *m_settings; ValgrindBaseSettings *m_settings;