diff --git a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp index 9fcec8d6b5b..497af719930 100644 --- a/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp +++ b/src/plugins/clangcodemodel/clangdiagnostictooltipwidget.cpp @@ -474,9 +474,17 @@ QString ClangDiagnosticWidget::createText( const ClangDiagnosticWidget::Destination &destination) { const QString htmlText = WidgetFromDiagnostics(toHints(destination)).htmlText(diagnostics); + QTextDocument document; 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( diff --git a/src/plugins/clangcodemodel/clangtextmark.cpp b/src/plugins/clangcodemodel/clangtextmark.cpp index 0b66305d6e1..b8dc9a92a4d 100644 --- a/src/plugins/clangcodemodel/clangtextmark.cpp +++ b/src/plugins/clangcodemodel/clangtextmark.cpp @@ -33,7 +33,9 @@ #include #include +#include #include +#include #include #include @@ -64,7 +66,6 @@ static Core::Id categoryForSeverity(ClangBackEnd::DiagnosticSeverity severity) } // anonymous namespace - ClangTextMark::ClangTextMark(const FileName &fileName, const ClangBackEnd::DiagnosticContainer &diagnostic, const RemovedFromEditorHandler &removedHandler, @@ -86,6 +87,16 @@ ClangTextMark::ClangTextMark(const FileName &fileName, setColor(warning ? ::Utils::Theme::CodeModel_Warning_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) diff --git a/src/plugins/texteditor/textmark.cpp b/src/plugins/texteditor/textmark.cpp index 17c6268f85f..89951675646 100644 --- a/src/plugins/texteditor/textmark.cpp +++ b/src/plugins/texteditor/textmark.cpp @@ -31,9 +31,12 @@ #include #include #include +#include +#include #include #include +#include using namespace Core; using namespace Utils; @@ -88,6 +91,8 @@ TextMark::TextMark(const FileName &fileName, int lineNumber, Id category, double TextMark::~TextMark() { + qDeleteAll(m_actions); + m_actions.clear(); if (!m_fileName.isEmpty()) TextMarkRegistry::remove(this); if (m_baseTextDocument) @@ -269,14 +274,34 @@ void TextMark::addToToolTipLayout(QGridLayout *target) const { auto contentLayout = new QVBoxLayout; addToolTipContent(contentLayout); - if (contentLayout->count() > 0) { - const int row = target->rowCount(); - if (!m_icon.isNull()) { - auto iconLabel = new QLabel; - iconLabel->setPixmap(m_icon.pixmap(16, 16)); - target->addWidget(iconLabel, row, 0, Qt::AlignTop | Qt::AlignHCenter); + if (contentLayout->count() <= 0) + return; + + // Left column: text mark icon + const int row = target->rowCount(); + 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; } +QVector TextMark::actions() const +{ + return m_actions; +} + +void TextMark::setActions(const QVector &actions) +{ + m_actions = actions; +} + TextMarkRegistry::TextMarkRegistry(QObject *parent) : QObject(parent) { diff --git a/src/plugins/texteditor/textmark.h b/src/plugins/texteditor/textmark.h index 9275c254aeb..eeeb761eaf4 100644 --- a/src/plugins/texteditor/textmark.h +++ b/src/plugins/texteditor/textmark.h @@ -32,8 +32,10 @@ #include #include +#include QT_BEGIN_NAMESPACE +class QAction; class QGridLayout; class QLayout; class QPainter; @@ -122,6 +124,9 @@ public: QString toolTip() const { return m_toolTip; } void setToolTip(const QString &toolTip) { m_toolTip = toolTip; } + QVector actions() const; + void setActions(const QVector &actions); // Takes ownership + private: Q_DISABLE_COPY(TextMark) @@ -138,6 +143,7 @@ private: QString m_lineAnnotation; QString m_toolTip; QString m_defaultToolTip; + QVector m_actions; }; } // namespace TextEditor