Help: Avoid double lookup for help tooltips

Save the HelpItem directly in the tooltip instead of the help ID which
would need to be looked up again.

Change-Id: I107e82e89d9ea26cad9d6532ad4c687d1ac8f1ec
Reviewed-by: David Schulz <david.schulz@qt.io>
This commit is contained in:
Eike Ziller
2019-01-29 11:43:43 +01:00
parent 4e8c2c4b13
commit 32429e11c9
9 changed files with 67 additions and 57 deletions

View File

@@ -53,15 +53,15 @@ TipLabel::TipLabel(QWidget *parent) :
{ {
} }
void TipLabel::setHelpId(const QString &id) void TipLabel::setContextHelp(const QVariant &help)
{ {
m_helpId = id; m_contextHelp = help;
update(); update();
} }
QString TipLabel::helpId() const QVariant TipLabel::contextHelp() const
{ {
return m_helpId; return m_contextHelp;
} }
const QMetaObject *TipLabel::metaObject() const const QMetaObject *TipLabel::metaObject() const
@@ -113,9 +113,9 @@ bool ColorTip::canHandleContentReplacement(int typeId) const
return typeId == ToolTip::ColorContent; return typeId == ToolTip::ColorContent;
} }
bool ColorTip::equals(int typeId, const QVariant &other, const QString &otherHelpId) const bool ColorTip::equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const
{ {
return typeId == ToolTip::ColorContent && otherHelpId == helpId() && other == m_color; return typeId == ToolTip::ColorContent && otherContextHelp == contextHelp() && other == m_color;
} }
void ColorTip::paintEvent(QPaintEvent *event) void ColorTip::paintEvent(QPaintEvent *event)
@@ -165,7 +165,7 @@ bool TextTip::isInteractive() const
void TextTip::configure(const QPoint &pos, QWidget *w) void TextTip::configure(const QPoint &pos, QWidget *w)
{ {
if (helpId().isEmpty()) if (contextHelp().isNull())
setText(m_text); setText(m_text);
else else
setText(QString::fromLatin1("<table><tr><td valign=middle>%1</td><td>&nbsp;&nbsp;" setText(QString::fromLatin1("<table><tr><td valign=middle>%1</td><td>&nbsp;&nbsp;"
@@ -201,9 +201,10 @@ int TextTip::showTime() const
return 10000 + 40 * qMax(0, m_text.size() - 100); return 10000 + 40 * qMax(0, m_text.size() - 100);
} }
bool TextTip::equals(int typeId, const QVariant &other, const QString &otherHelpId) const bool TextTip::equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const
{ {
return typeId == ToolTip::TextContent && otherHelpId == helpId() && other.toString() == m_text; return typeId == ToolTip::TextContent && otherContextHelp == contextHelp()
&& other.toString() == m_text;
} }
void TextTip::paintEvent(QPaintEvent *event) void TextTip::paintEvent(QPaintEvent *event)
@@ -280,9 +281,9 @@ bool WidgetTip::canHandleContentReplacement(int typeId) const
return false; return false;
} }
bool WidgetTip::equals(int typeId, const QVariant &other, const QString &otherHelpId) const bool WidgetTip::equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const
{ {
return typeId == ToolTip::WidgetContent && otherHelpId == helpId() return typeId == ToolTip::WidgetContent && otherContextHelp == contextHelp()
&& other.value<QWidget *>() == m_widget; && other.value<QWidget *>() == m_widget;
} }

View File

@@ -46,15 +46,15 @@ public:
virtual int showTime() const = 0; virtual int showTime() const = 0;
virtual void configure(const QPoint &pos, QWidget *w) = 0; virtual void configure(const QPoint &pos, QWidget *w) = 0;
virtual bool canHandleContentReplacement(int typeId) const = 0; virtual bool canHandleContentReplacement(int typeId) const = 0;
virtual bool equals(int typeId, const QVariant &other, const QString &helpId) const = 0; virtual bool equals(int typeId, const QVariant &other, const QVariant &contextHelp) const = 0;
virtual void setHelpId(const QString &id); virtual void setContextHelp(const QVariant &help);
virtual QString helpId() const; virtual QVariant contextHelp() const;
protected: protected:
const QMetaObject *metaObject() const override; const QMetaObject *metaObject() const override;
private: private:
QString m_helpId; QVariant m_contextHelp;
}; };
class TextTip : public TipLabel class TextTip : public TipLabel
@@ -67,7 +67,7 @@ public:
void configure(const QPoint &pos, QWidget *w) override; void configure(const QPoint &pos, QWidget *w) override;
bool canHandleContentReplacement(int typeId) const override; bool canHandleContentReplacement(int typeId) const override;
int showTime() const override; int showTime() const override;
bool equals(int typeId, const QVariant &other, const QString &otherHelpId) const override; bool equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const override;
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override; void resizeEvent(QResizeEvent *event) override;
@@ -84,7 +84,7 @@ public:
void configure(const QPoint &pos, QWidget *w) override; void configure(const QPoint &pos, QWidget *w) override;
bool canHandleContentReplacement(int typeId) const override; bool canHandleContentReplacement(int typeId) const override;
int showTime() const override { return 4000; } int showTime() const override { return 4000; }
bool equals(int typeId, const QVariant &other, const QString &otherHelpId) const override; bool equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const override;
void paintEvent(QPaintEvent *event) override; void paintEvent(QPaintEvent *event) override;
private: private:
@@ -104,7 +104,7 @@ public:
void configure(const QPoint &pos, QWidget *w) override; void configure(const QPoint &pos, QWidget *w) override;
bool canHandleContentReplacement(int typeId) const override; bool canHandleContentReplacement(int typeId) const override;
int showTime() const override { return 30000; } int showTime() const override { return 30000; }
bool equals(int typeId, const QVariant &other, const QString &otherHelpId) const override; bool equals(int typeId, const QVariant &other, const QVariant &otherContextHelp) const override;
bool isInteractive() const override { return true; } bool isInteractive() const override { return true; }
private: private:

View File

@@ -62,36 +62,36 @@ ToolTip *ToolTip::instance()
return &tooltip; return &tooltip;
} }
void ToolTip::show(const QPoint &pos, const QString &content, QWidget *w, const QString &helpId, const QRect &rect) void ToolTip::show(const QPoint &pos, const QString &content, QWidget *w, const QVariant &contextHelp, const QRect &rect)
{ {
if (content.isEmpty()) if (content.isEmpty())
instance()->hideTipWithDelay(); instance()->hideTipWithDelay();
else else
instance()->showInternal(pos, QVariant(content), TextContent, w, helpId, rect); instance()->showInternal(pos, QVariant(content), TextContent, w, contextHelp, rect);
} }
void ToolTip::show(const QPoint &pos, const QColor &color, QWidget *w, const QString &helpId, const QRect &rect) void ToolTip::show(const QPoint &pos, const QColor &color, QWidget *w, const QVariant &contextHelp, const QRect &rect)
{ {
if (!color.isValid()) if (!color.isValid())
instance()->hideTipWithDelay(); instance()->hideTipWithDelay();
else else
instance()->showInternal(pos, QVariant(color), ColorContent, w, helpId, rect); instance()->showInternal(pos, QVariant(color), ColorContent, w, contextHelp, rect);
} }
void ToolTip::show(const QPoint &pos, QWidget *content, QWidget *w, const QString &helpId, const QRect &rect) void ToolTip::show(const QPoint &pos, QWidget *content, QWidget *w, const QVariant &contextHelp, const QRect &rect)
{ {
if (!content) if (!content)
instance()->hideTipWithDelay(); instance()->hideTipWithDelay();
else else
instance()->showInternal(pos, QVariant::fromValue(content), WidgetContent, w, helpId, rect); instance()->showInternal(pos, QVariant::fromValue(content), WidgetContent, w, contextHelp, rect);
} }
void ToolTip::show(const QPoint &pos, QLayout *content, QWidget *w, const QString &helpId, const QRect &rect) void ToolTip::show(const QPoint &pos, QLayout *content, QWidget *w, const QVariant &contextHelp, const QRect &rect)
{ {
if (content && content->count()) { if (content && content->count()) {
auto tooltipWidget = new FakeToolTip; auto tooltipWidget = new FakeToolTip;
tooltipWidget->setLayout(content); tooltipWidget->setLayout(content);
instance()->showInternal(pos, QVariant::fromValue(tooltipWidget), WidgetContent, w, helpId, rect); instance()->showInternal(pos, QVariant::fromValue(tooltipWidget), WidgetContent, w, contextHelp, rect);
} else { } else {
instance()->hideTipWithDelay(); instance()->hideTipWithDelay();
} }
@@ -118,15 +118,15 @@ bool ToolTip::pinToolTip(QWidget *w, QWidget *parent)
return false; return false;
} }
QString ToolTip::contextHelpId() QVariant ToolTip::contextHelp()
{ {
return instance()->m_tip ? instance()->m_tip->helpId() : QString(); return instance()->m_tip ? instance()->m_tip->contextHelp() : QVariant();
} }
bool ToolTip::acceptShow(const QVariant &content, bool ToolTip::acceptShow(const QVariant &content,
int typeId, int typeId,
const QPoint &pos, const QPoint &pos,
QWidget *w, const QString &helpId, QWidget *w, const QVariant &contextHelp,
const QRect &rect) const QRect &rect)
{ {
if (isVisible()) { if (isVisible()) {
@@ -135,9 +135,9 @@ bool ToolTip::acceptShow(const QVariant &content,
QPoint localPos = pos; QPoint localPos = pos;
if (w) if (w)
localPos = w->mapFromGlobal(pos); localPos = w->mapFromGlobal(pos);
if (tipChanged(localPos, content, typeId, w, helpId)) { if (tipChanged(localPos, content, typeId, w, contextHelp)) {
m_tip->setContent(content); m_tip->setContent(content);
m_tip->setHelpId(helpId); m_tip->setContextHelp(contextHelp);
setUp(pos, w, rect); setUp(pos, w, rect);
} }
return false; return false;
@@ -169,9 +169,9 @@ void ToolTip::setUp(const QPoint &pos, QWidget *w, const QRect &rect)
} }
bool ToolTip::tipChanged(const QPoint &pos, const QVariant &content, int typeId, QWidget *w, bool ToolTip::tipChanged(const QPoint &pos, const QVariant &content, int typeId, QWidget *w,
const QString &helpId) const const QVariant &contextHelp) const
{ {
if (!m_tip->equals(typeId, content, helpId) || m_widget != w) if (!m_tip->equals(typeId, content, contextHelp) || m_widget != w)
return true; return true;
if (!m_rect.isNull()) if (!m_rect.isNull())
return !m_rect.contains(pos); return !m_rect.contains(pos);
@@ -243,9 +243,9 @@ void ToolTip::hideTipImmediately()
} }
void ToolTip::showInternal(const QPoint &pos, const QVariant &content, void ToolTip::showInternal(const QPoint &pos, const QVariant &content,
int typeId, QWidget *w, const QString &helpId, const QRect &rect) int typeId, QWidget *w, const QVariant &contextHelp, const QRect &rect)
{ {
if (acceptShow(content, typeId, pos, w, helpId, rect)) { if (acceptShow(content, typeId, pos, w, contextHelp, rect)) {
QWidget *target = nullptr; QWidget *target = nullptr;
if (HostOsInfo::isWindowsHost()) if (HostOsInfo::isWindowsHost())
target = QApplication::desktop()->screen(Internal::screenNumber(pos, w)); target = QApplication::desktop()->screen(Internal::screenNumber(pos, w));
@@ -264,7 +264,7 @@ void ToolTip::showInternal(const QPoint &pos, const QVariant &content,
break; break;
} }
m_tip->setContent(content); m_tip->setContent(content);
m_tip->setHelpId(helpId); m_tip->setContextHelp(contextHelp);
setUp(pos, w, rect); setUp(pos, w, rect);
qApp->installEventFilter(this); qApp->installEventFilter(this);
showTip(); showTip();

View File

@@ -32,6 +32,7 @@
#include <QPointer> #include <QPointer>
#include <QTimer> #include <QTimer>
#include <QRect> #include <QRect>
#include <QVariant>
/* /*
* In its current form QToolTip is not extensible. So this is an attempt to provide a more * In its current form QToolTip is not extensible. So this is an attempt to provide a more
@@ -72,13 +73,13 @@ public:
static ToolTip *instance(); static ToolTip *instance();
static void show(const QPoint &pos, const QString &content, QWidget *w = nullptr, static void show(const QPoint &pos, const QString &content, QWidget *w = nullptr,
const QString &helpId = QString(), const QRect &rect = QRect()); const QVariant &contextHelp = {}, const QRect &rect = QRect());
static void show(const QPoint &pos, const QColor &color, QWidget *w = nullptr, static void show(const QPoint &pos, const QColor &color, QWidget *w = nullptr,
const QString &helpId = QString(), const QRect &rect = QRect()); const QVariant &contextHelp = {}, const QRect &rect = QRect());
static void show(const QPoint &pos, QWidget *content, QWidget *w = nullptr, static void show(const QPoint &pos, QWidget *content, QWidget *w = nullptr,
const QString &helpId = QString(), const QRect &rect = QRect()); const QVariant &contextHelp = {}, const QRect &rect = QRect());
static void show(const QPoint &pos, QLayout *content, QWidget *w = nullptr, static void show(const QPoint &pos, QLayout *content, QWidget *w = nullptr,
const QString &helpId = QString(), const QRect &rect = QRect()); const QVariant &contextHelp = {}, const QRect &rect = QRect());
static void move(const QPoint &pos, QWidget *w); static void move(const QPoint &pos, QWidget *w);
static void hide(); static void hide();
static void hideImmediately(); static void hideImmediately();
@@ -90,7 +91,7 @@ public:
// using WidgetContent // using WidgetContent
static bool pinToolTip(QWidget *w, QWidget *parent); static bool pinToolTip(QWidget *w, QWidget *parent);
static QString contextHelpId(); static QVariant contextHelp();
signals: signals:
void shown(); void shown();
@@ -98,13 +99,13 @@ signals:
private: private:
void showInternal(const QPoint &pos, const QVariant &content, int typeId, QWidget *w, void showInternal(const QPoint &pos, const QVariant &content, int typeId, QWidget *w,
const QString &helpId, const QRect &rect); const QVariant &contextHelp, const QRect &rect);
void hideTipImmediately(); void hideTipImmediately();
bool acceptShow(const QVariant &content, int typeId, const QPoint &pos, QWidget *w, bool acceptShow(const QVariant &content, int typeId, const QPoint &pos, QWidget *w,
const QString &helpId, const QRect &rect); const QVariant &contextHelp, const QRect &rect);
void setUp(const QPoint &pos, QWidget *w, const QRect &rect); void setUp(const QPoint &pos, QWidget *w, const QRect &rect);
bool tipChanged(const QPoint &pos, const QVariant &content, int typeId, QWidget *w, bool tipChanged(const QPoint &pos, const QVariant &content, int typeId, QWidget *w,
const QString &helpId) const; const QVariant &contextHelp) const;
void setTipRect(QWidget *w, const QRect &rect); void setTipRect(QWidget *w, const QRect &rect);
void placeTip(const QPoint &pos, QWidget *w); void placeTip(const QPoint &pos, QWidget *w);
void showTip(); void showTip();
@@ -115,7 +116,7 @@ private:
QRect m_rect; QRect m_rect;
QTimer m_showTimer; QTimer m_showTimer;
QTimer m_hideDelayTimer; QTimer m_hideDelayTimer;
QString m_helpId; QVariant m_contextHelp;
}; };
} // namespace Utils } // namespace Utils

View File

@@ -75,7 +75,7 @@ static bool editorDocumentProcessorHasDiagnosticAt(TextEditorWidget *editorWidge
static void processWithEditorDocumentProcessor(TextEditorWidget *editorWidget, static void processWithEditorDocumentProcessor(TextEditorWidget *editorWidget,
const QPoint &point, const QPoint &point,
int position, int position,
const QString &helpId) const Core::HelpItem &helpItem)
{ {
if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) { if (CppTools::BaseEditorDocumentProcessor *processor = editorDocumentProcessor(editorWidget)) {
int line, column; int line, column;
@@ -84,7 +84,7 @@ static void processWithEditorDocumentProcessor(TextEditorWidget *editorWidget,
layout->setContentsMargins(0, 0, 0, 0); layout->setContentsMargins(0, 0, 0, 0);
layout->setSpacing(2); layout->setSpacing(2);
processor->addDiagnosticToolTipToLayout(line, column, layout); processor->addDiagnosticToolTipToLayout(line, column, layout);
Utils::ToolTip::show(point, layout, editorWidget, helpId); Utils::ToolTip::show(point, layout, editorWidget, qVariantFromValue(helpItem));
} }
} }
} }
@@ -283,9 +283,10 @@ void ClangHoverHandler::operateTooltip(TextEditor::TextEditorWidget *editorWidge
const QPoint &point) const QPoint &point)
{ {
if (priority() == Priority_Diagnostic) { if (priority() == Priority_Diagnostic) {
const Core::HelpItem helpItem = lastHelpItemIdentified(); processWithEditorDocumentProcessor(editorWidget,
const QString helpId = helpItem.isValid() ? helpItem.helpId() : QString(); point,
processWithEditorDocumentProcessor(editorWidget, point, m_cursorPosition, helpId); m_cursorPosition,
lastHelpItemIdentified());
return; return;
} }

View File

@@ -32,6 +32,7 @@
#include <QMap> #include <QMap>
#include <QString> #include <QString>
#include <QUrl> #include <QUrl>
#include <QVariant>
namespace Core { namespace Core {
@@ -89,3 +90,5 @@ private:
}; };
} // namespace Core } // namespace Core
Q_DECLARE_METATYPE(Core::HelpItem)

View File

@@ -647,12 +647,15 @@ static QUrl findBestLink(const QMap<QString, QUrl> &links)
void HelpPluginPrivate::requestContextHelp() void HelpPluginPrivate::requestContextHelp()
{ {
// Find out what to show // Find out what to show
QString contextHelpId = Utils::ToolTip::contextHelpId(); const QVariant tipHelpValue = Utils::ToolTip::contextHelp();
const HelpItem tipHelp = tipHelpValue.canConvert<HelpItem>()
? tipHelpValue.value<HelpItem>()
: HelpItem(tipHelpValue.toString());
IContext *context = ICore::currentContextObject(); IContext *context = ICore::currentContextObject();
if (contextHelpId.isEmpty() && context) if (!tipHelp.isValid() && context)
context->contextHelp([this](const HelpItem &item) { showContextHelp(item); }); context->contextHelp([this](const HelpItem &item) { showContextHelp(item); });
else else
showContextHelp(contextHelpId); showContextHelp(tipHelp);
} }
void HelpPluginPrivate::showContextHelp(const HelpItem &contextHelp) void HelpPluginPrivate::showContextHelp(const HelpItem &contextHelp)

View File

@@ -159,9 +159,10 @@ void BaseHoverHandler::operateTooltip(TextEditorWidget *editorWidget, const QPoi
if (m_toolTip.isEmpty()) if (m_toolTip.isEmpty())
Utils::ToolTip::hide(); Utils::ToolTip::hide();
else else
Utils::ToolTip::show(point, m_toolTip, editorWidget, m_lastHelpItemIdentified.isValid() Utils::ToolTip::show(point,
? m_lastHelpItemIdentified.helpId() m_toolTip,
: QString()); editorWidget,
qVariantFromValue(m_lastHelpItemIdentified));
} }
} // namespace TextEditor } // namespace TextEditor

View File

@@ -3565,7 +3565,7 @@ bool TextEditorWidget::viewportEvent(QEvent *event)
RefactorMarker refactorMarker = d->m_refactorOverlay->markerAt(pos); RefactorMarker refactorMarker = d->m_refactorOverlay->markerAt(pos);
if (refactorMarker.isValid() && !refactorMarker.tooltip.isEmpty()) { if (refactorMarker.isValid() && !refactorMarker.tooltip.isEmpty()) {
ToolTip::show(he->globalPos(), refactorMarker.tooltip, ToolTip::show(he->globalPos(), refactorMarker.tooltip,
viewport(), QString(), refactorMarker.rect); viewport(), {}, refactorMarker.rect);
return true; return true;
} }