Clang: Add tooltip action to copy to clipboard

...as selecting text in the tooltip was difficult and eventually got
disabled due to other problems - see
d58c0a9ac8.

This adds support for actions in TextMarks. They are displayed as
QToolButtons in a dedicated column in the tooltip.

Change-Id: I84ee3c3e4af573a80953786881d1333b00e4200c
Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Nikolai Kosjar
2019-01-28 09:32:11 +01:00
parent 966f4ea6a9
commit 0df7468e51
4 changed files with 69 additions and 9 deletions

View File

@@ -474,9 +474,17 @@ QString ClangDiagnosticWidget::createText(
const ClangDiagnosticWidget::Destination &destination) const ClangDiagnosticWidget::Destination &destination)
{ {
const QString htmlText = WidgetFromDiagnostics(toHints(destination)).htmlText(diagnostics); const QString htmlText = WidgetFromDiagnostics(toHints(destination)).htmlText(diagnostics);
QTextDocument document; QTextDocument document;
document.setHtml(htmlText); document.setHtml(htmlText);
return document.toPlainText(); QString text = document.toPlainText();
if (text.startsWith('\n'))
text = text.mid(1);
if (text.endsWith('\n'))
text.chop(1);
return text;
} }
QWidget *ClangDiagnosticWidget::createWidget( QWidget *ClangDiagnosticWidget::createWidget(

View File

@@ -33,7 +33,9 @@
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
#include <QAction>
#include <QApplication> #include <QApplication>
#include <QClipboard>
#include <QLayout> #include <QLayout>
#include <QString> #include <QString>
@@ -64,7 +66,6 @@ static Core::Id categoryForSeverity(ClangBackEnd::DiagnosticSeverity severity)
} // anonymous namespace } // anonymous namespace
ClangTextMark::ClangTextMark(const FileName &fileName, ClangTextMark::ClangTextMark(const FileName &fileName,
const ClangBackEnd::DiagnosticContainer &diagnostic, const ClangBackEnd::DiagnosticContainer &diagnostic,
const RemovedFromEditorHandler &removedHandler, const RemovedFromEditorHandler &removedHandler,
@@ -86,6 +87,16 @@ ClangTextMark::ClangTextMark(const FileName &fileName,
setColor(warning ? ::Utils::Theme::CodeModel_Warning_TextMarkColor setColor(warning ? ::Utils::Theme::CodeModel_Warning_TextMarkColor
: ::Utils::Theme::CodeModel_Error_TextMarkColor); : ::Utils::Theme::CodeModel_Error_TextMarkColor);
} }
QAction *action = new QAction();
action->setIcon(QIcon::fromTheme("edit-copy", ::Utils::Icons::COPY.icon()));
QObject::connect(action, &QAction::triggered, [diagnostic]() {
using namespace ClangCodeModel::Internal;
const QString text = ClangDiagnosticWidget::createText({diagnostic},
ClangDiagnosticWidget::InfoBar);
QApplication::clipboard()->setText(text, QClipboard::Clipboard);
});
setActions({action});
} }
void ClangTextMark::updateIcon(bool valid) void ClangTextMark::updateIcon(bool valid)

View File

@@ -31,9 +31,12 @@
#include <coreplugin/editormanager/editormanager.h> #include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/documentmanager.h> #include <coreplugin/documentmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/tooltip/tooltip.h>
#include <QAction>
#include <QGridLayout> #include <QGridLayout>
#include <QPainter> #include <QPainter>
#include <QToolButton>
using namespace Core; using namespace Core;
using namespace Utils; using namespace Utils;
@@ -88,6 +91,8 @@ TextMark::TextMark(const FileName &fileName, int lineNumber, Id category, double
TextMark::~TextMark() TextMark::~TextMark()
{ {
qDeleteAll(m_actions);
m_actions.clear();
if (!m_fileName.isEmpty()) if (!m_fileName.isEmpty())
TextMarkRegistry::remove(this); TextMarkRegistry::remove(this);
if (m_baseTextDocument) if (m_baseTextDocument)
@@ -269,14 +274,34 @@ void TextMark::addToToolTipLayout(QGridLayout *target) const
{ {
auto contentLayout = new QVBoxLayout; auto contentLayout = new QVBoxLayout;
addToolTipContent(contentLayout); addToolTipContent(contentLayout);
if (contentLayout->count() > 0) { if (contentLayout->count() <= 0)
const int row = target->rowCount(); return;
if (!m_icon.isNull()) {
auto iconLabel = new QLabel; // Left column: text mark icon
iconLabel->setPixmap(m_icon.pixmap(16, 16)); const int row = target->rowCount();
target->addWidget(iconLabel, row, 0, Qt::AlignTop | Qt::AlignHCenter); if (!m_icon.isNull()) {
auto iconLabel = new QLabel;
iconLabel->setPixmap(m_icon.pixmap(16, 16));
target->addWidget(iconLabel, row, 0, Qt::AlignTop | Qt::AlignHCenter);
}
// Middle column: tooltip content
target->addLayout(contentLayout, row, 1);
// Right column: action icons/button
if (!m_actions.isEmpty()) {
auto actionsLayout = new QHBoxLayout;
for (QAction *action : m_actions) {
QTC_ASSERT(!action->icon().isNull(), continue);
auto button = new QToolButton;
button->setIcon(action->icon());
QObject::connect(button, &QToolButton::clicked, action, &QAction::triggered);
QObject::connect(button, &QToolButton::clicked, []() {
Utils::ToolTip::hideImmediately();
});
actionsLayout->addWidget(button, 0, Qt::AlignTop | Qt::AlignRight);
} }
target->addLayout(contentLayout, row, 1); target->addLayout(actionsLayout, row, 2);
} }
} }
@@ -311,6 +336,16 @@ void TextMark::setColor(const Theme::Color &color)
m_color = color; m_color = color;
} }
QVector<QAction *> TextMark::actions() const
{
return m_actions;
}
void TextMark::setActions(const QVector<QAction *> &actions)
{
m_actions = actions;
}
TextMarkRegistry::TextMarkRegistry(QObject *parent) TextMarkRegistry::TextMarkRegistry(QObject *parent)
: QObject(parent) : QObject(parent)
{ {

View File

@@ -32,8 +32,10 @@
#include <utils/fileutils.h> #include <utils/fileutils.h>
#include <QIcon> #include <QIcon>
#include <QVector>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
class QAction;
class QGridLayout; class QGridLayout;
class QLayout; class QLayout;
class QPainter; class QPainter;
@@ -122,6 +124,9 @@ public:
QString toolTip() const { return m_toolTip; } QString toolTip() const { return m_toolTip; }
void setToolTip(const QString &toolTip) { m_toolTip = toolTip; } void setToolTip(const QString &toolTip) { m_toolTip = toolTip; }
QVector<QAction *> actions() const;
void setActions(const QVector<QAction *> &actions); // Takes ownership
private: private:
Q_DISABLE_COPY(TextMark) Q_DISABLE_COPY(TextMark)
@@ -138,6 +143,7 @@ private:
QString m_lineAnnotation; QString m_lineAnnotation;
QString m_toolTip; QString m_toolTip;
QString m_defaultToolTip; QString m_defaultToolTip;
QVector<QAction *> m_actions;
}; };
} // namespace TextEditor } // namespace TextEditor