Skip to content

Commit b8a5e30

Browse files
committed
Merge pull request #1090 from laanwj/2012_04_wraptooltips
Allow Qt to wrap long tooltips (fixes #1063)
2 parents f93727a + 3793fa0 commit b8a5e30

File tree

5 files changed

+57
-3
lines changed

5 files changed

+57
-3
lines changed

src/qt/bitcoin.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "walletmodel.h"
77
#include "optionsmodel.h"
88
#include "guiutil.h"
9+
#include "guiconstants.h"
910

1011
#include "init.h"
1112
#include "ui_interface.h"
@@ -164,6 +165,9 @@ int main(int argc, char *argv[])
164165
Q_INIT_RESOURCE(bitcoin);
165166
QApplication app(argc, argv);
166167

168+
// Install global event filter that makes sure that long tooltips can be word-wrapped
169+
app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
170+
167171
// Command-line options take precedence:
168172
ParseParameters(argc, argv);
169173

src/qt/bitcoingui.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,22 +563,25 @@ void BitcoinGUI::setNumBlocks(int count)
563563
// Set icon state: spinning if catching up, tick otherwise
564564
if(secs < 90*60 && count >= nTotalBlocks)
565565
{
566-
tooltip = tr("Up to date") + QString(".\n") + tooltip;
566+
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
567567
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
568568
}
569569
else
570570
{
571-
tooltip = tr("Catching up...") + QString("\n") + tooltip;
571+
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
572572
labelBlocksIcon->setMovie(syncIconMovie);
573573
syncIconMovie->start();
574574
}
575575

576576
if(!text.isEmpty())
577577
{
578-
tooltip += QString("\n");
578+
tooltip += QString("<br>");
579579
tooltip += tr("Last received block was generated %1.").arg(text);
580580
}
581581

582+
// Don't word-wrap this (fixed-width) tooltip
583+
tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
584+
582585
labelBlocksIcon->setToolTip(tooltip);
583586
progressBarLabel->setToolTip(tooltip);
584587
progressBar->setToolTip(tooltip);

src/qt/guiconstants.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,9 @@ static const int STATUSBAR_ICONSIZE = 16;
2020
/* Transaction list -- bare address (without label) */
2121
#define COLOR_BAREADDRESS QColor(140, 140, 140)
2222

23+
/* Tooltips longer than this (in characters) are converted into rich text,
24+
so that they can be word-wrapped.
25+
*/
26+
static const int TOOLTIP_WRAP_THRESHOLD = 80;
27+
2328
#endif // GUICONSTANTS_H

src/qt/guiutil.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,5 +214,29 @@ bool isObscured(QWidget *w)
214214
&& checkPoint(QPoint(w->width()/2, w->height()/2), w));
215215
}
216216

217+
ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent):
218+
size_threshold(size_threshold), QObject(parent)
219+
{
220+
221+
}
222+
223+
bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
224+
{
225+
if(evt->type() == QEvent::ToolTipChange)
226+
{
227+
QWidget *widget = static_cast<QWidget*>(obj);
228+
QString tooltip = widget->toolTip();
229+
if(!Qt::mightBeRichText(tooltip) && tooltip.size() > size_threshold)
230+
{
231+
// Prefix <qt/> to make sure Qt detects this as rich text
232+
// Escape the current message as HTML and replace \n by <br>
233+
tooltip = "<qt/>" + HtmlEscape(tooltip, true);
234+
widget->setToolTip(tooltip);
235+
return true;
236+
}
237+
}
238+
return QObject::eventFilter(obj, evt);
239+
}
240+
217241
} // namespace GUIUtil
218242

src/qt/guiutil.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define GUIUTIL_H
33

44
#include <QString>
5+
#include <QObject>
56

67
QT_BEGIN_NAMESPACE
78
class QFont;
@@ -69,6 +70,23 @@ namespace GUIUtil
6970
// Determine whether a widget is hidden behind other windows
7071
bool isObscured(QWidget *w);
7172

73+
/** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text
74+
representation if needed. This assures that Qt can word-wrap long tooltip messages.
75+
Tooltips longer than the provided size threshold (in characters) are wrapped.
76+
*/
77+
class ToolTipToRichTextFilter: public QObject
78+
{
79+
Q_OBJECT
80+
public:
81+
ToolTipToRichTextFilter(int size_threshold, QObject *parent);
82+
83+
protected:
84+
bool eventFilter(QObject *obj, QEvent *evt);
85+
86+
private:
87+
int size_threshold;
88+
};
89+
7290
} // namespace GUIUtil
7391

7492
#endif // GUIUTIL_H

0 commit comments

Comments
 (0)