summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2014-11-14 13:39:59 +0100
committerNikolai Kosjar <nikolai.kosjar@theqtcompany.com>2014-11-25 12:41:45 +0200
commit30b77eb0325669fa39331b1aef261c94c22a4c73 (patch)
tree445f0ac8f3f1093680197e9f07243b4f7fdea4a8
parent802a7d653ca98115b10f873fbc578bafb99590ae (diff)
downloadqt-creator-30b77eb0325669fa39331b1aef261c94c22a4c73.tar.gz
DiagnosticView: Add copy action to context menu
Task-number: QCE-22 Change-Id: I22a71bd99689e4eaece3b2595b28e0d434a52453 Reviewed-by: Riitta-Leena Miettinen <riitta-leena.miettinen@digia.com> Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp99
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h13
-rw-r--r--plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp3
3 files changed, 98 insertions, 17 deletions
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp
index 6d00968c86..0c0a872de3 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.cpp
@@ -21,12 +21,19 @@
#include "clangstaticanalyzerlogfilereader.h"
#include "clangstaticanalyzerutils.h"
+#include <coreplugin/coreconstants.h>
+
#include <utils/qtcassert.h>
+#include <QAction>
+#include <QApplication>
+#include <QClipboard>
+#include <QContextMenuEvent>
#include <QCoreApplication>
#include <QDebug>
#include <QFileInfo>
#include <QLabel>
+#include <QMenu>
#include <QVBoxLayout>
using namespace Analyzer;
@@ -90,29 +97,32 @@ QLabel *createExplainingStepLabel(const QFont &font, bool useAlternateRowPalette
}
QString createLocationString(const ClangStaticAnalyzer::Internal::Location &location,
- bool withMarkup)
+ bool withMarkup, bool withAbsolutePath)
{
const QString filePath = location.filePath;
- const QString fileName = QFileInfo(filePath).fileName();
const QString lineNumber = QString::number(location.line);
const QString columnNumber = QString::number(location.column - 1);
- const QString fileNameAndLine = fileName + QLatin1Char(':') + lineNumber;
+ const QString fileAndLine = (withAbsolutePath ? filePath : QFileInfo(filePath).fileName())
+ + QLatin1Char(':') + lineNumber;
if (withMarkup) {
return QLatin1String("in <a href=\"file://")
+ filePath + QLatin1Char(':') + lineNumber + QLatin1Char(':') + columnNumber
+ QLatin1String("\">")
- + fileNameAndLine
+ + fileAndLine
+ QLatin1String("</a>");
} else {
- return QLatin1String("in ") + fileNameAndLine;
+ return QLatin1String("in ") + fileAndLine;
}
}
-QString createExplainingStepNumberString(int number)
+QString createExplainingStepNumberString(int number, bool withMarkup)
{
const int fieldWidth = 2;
- return QString::fromLatin1("<code style='white-space:pre'>%1:</code>").arg(number, fieldWidth);
+ const QString result = QString::fromLatin1("%1:").arg(number, fieldWidth);
+ return withMarkup
+ ? QLatin1String("<code style='white-space:pre'>") + result + QLatin1String("</code>")
+ : result;
}
QString createExplainingStepToolTipString(const ClangStaticAnalyzer::Internal::ExplainingStep &step)
@@ -154,6 +164,17 @@ QString createExplainingStepToolTipString(const ClangStaticAnalyzer::Internal::E
return html;
}
+QString createExplainingStepString(
+ const ClangStaticAnalyzer::Internal::ExplainingStep &explainingStep,
+ int number, bool withMarkup, bool withAbsolutePath)
+{
+ return createExplainingStepNumberString(number, withMarkup)
+ + QLatin1Char(' ')
+ + explainingStep.extendedMessage
+ + QLatin1Char(' ')
+ + createLocationString(explainingStep.location, withMarkup, withAbsolutePath);
+}
+
} // anonymous namespace
namespace ClangStaticAnalyzer {
@@ -172,13 +193,36 @@ DetailedErrorDelegate::SummaryLineInfo ClangStaticAnalyzerDiagnosticDelegate::su
DetailedErrorDelegate::SummaryLineInfo info;
info.errorText = diagnostic.description;
- info.errorLocation = createLocationString(diagnostic.location, /*withMarkup=*/ false);
+ info.errorLocation = createLocationString(diagnostic.location,
+ /*withMarkup=*/ false,
+ /*withAbsolutePath=*/ false);
return info;
}
void ClangStaticAnalyzerDiagnosticDelegate::copy()
{
- qDebug() << Q_FUNC_INFO;
+ QTC_ASSERT(m_detailsIndex.isValid(), return);
+
+ const Diagnostic diagnostic = m_detailsIndex.data(Qt::UserRole).value<Diagnostic>();
+ QTC_ASSERT(diagnostic.isValid(), return);
+
+ // Create summary
+ QString clipboardText = diagnostic.category + QLatin1String(": ") + diagnostic.type;
+ if (diagnostic.type != diagnostic.description)
+ clipboardText += QLatin1String(": ") + diagnostic.description;
+ clipboardText += QLatin1Char('\n');
+
+ // Create explaining steps
+ int explainingStepNumber = 1;
+ foreach (const ExplainingStep &explainingStep, diagnostic.explainingSteps) {
+ clipboardText += createExplainingStepString(explainingStep,
+ explainingStepNumber++,
+ /*withMarkup=*/ false,
+ /*withAbsolutePath=*/ true) + QLatin1Char('\n');
+ }
+
+ clipboardText.chop(1); // Remove \n
+ QApplication::clipboard()->setText(clipboardText);
}
QWidget *ClangStaticAnalyzerDiagnosticDelegate::createDetailsWidget(const QFont &font,
@@ -201,12 +245,10 @@ QWidget *ClangStaticAnalyzerDiagnosticDelegate::createDetailsWidget(const QFont
// Add labels for explaining steps
int explainingStepNumber = 1;
foreach (const ExplainingStep &explainingStep, diagnostic.explainingSteps) {
- const QString text = createExplainingStepNumberString(explainingStepNumber++)
- + QLatin1Char(' ')
- + explainingStep.extendedMessage
- + QLatin1Char(' ')
- + createLocationString(explainingStep.location, /*withMarkup=*/ true);
-
+ const QString text = createExplainingStepString(explainingStep,
+ explainingStepNumber++,
+ /*withMarkup=*/ true,
+ /*withAbsolutePath=*/ false);
QLabel *label = createExplainingStepLabel(font, explainingStepNumber % 2 == 0);
label->setParent(widget);
label->setText(text);
@@ -222,5 +264,32 @@ QWidget *ClangStaticAnalyzerDiagnosticDelegate::createDetailsWidget(const QFont
return widget;
}
+ClangStaticAnalyzerDiagnosticView::ClangStaticAnalyzerDiagnosticView(QWidget *parent)
+ : Analyzer::DetailedErrorView(parent)
+{
+ ClangStaticAnalyzerDiagnosticDelegate *delegate
+ = new ClangStaticAnalyzerDiagnosticDelegate(this);
+ 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, &ClangStaticAnalyzerDiagnosticDelegate::copy);
+ addAction(m_copyAction);
+}
+
+void ClangStaticAnalyzerDiagnosticView::contextMenuEvent(QContextMenuEvent *e)
+{
+ if (selectionModel()->selectedRows().isEmpty())
+ return;
+
+ QMenu menu;
+ menu.addAction(m_copyAction);
+ menu.exec(e->globalPos());
+}
+
} // namespace Internal
} // namespace ClangStaticAnalyzer
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h
index 551aff3e72..5830a05a50 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzerdiagnosticview.h
@@ -24,6 +24,19 @@
namespace ClangStaticAnalyzer {
namespace Internal {
+class ClangStaticAnalyzerDiagnosticView : public Analyzer::DetailedErrorView
+{
+ Q_OBJECT
+
+public:
+ ClangStaticAnalyzerDiagnosticView(QWidget *parent = 0);
+
+private:
+ void contextMenuEvent(QContextMenuEvent *e);
+
+ QAction *m_copyAction;
+};
+
class ClangStaticAnalyzerDiagnosticDelegate : public Analyzer::DetailedErrorDelegate
{
public:
diff --git a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
index 4da16b98f3..ffec5af1a7 100644
--- a/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
+++ b/plugins/clangstaticanalyzer/clangstaticanalyzertool.cpp
@@ -70,8 +70,7 @@ QWidget *ClangStaticAnalyzerTool::createWidgets()
//
// Diagnostic View
//
- m_diagnosticView = new DetailedErrorView;
- m_diagnosticView->setItemDelegate(new ClangStaticAnalyzerDiagnosticDelegate(m_diagnosticView));
+ m_diagnosticView = new ClangStaticAnalyzerDiagnosticView;
m_diagnosticView->setObjectName(QLatin1String("ClangStaticAnalyzerIssuesView"));
m_diagnosticView->setFrameStyle(QFrame::NoFrame);
m_diagnosticView->setAttribute(Qt::WA_MacShowFocusRect, false);