Allow Qt to wrap long tooltips (fixes #1063)
Implemented without having to touch any translation: by listening for QEvent::ToolTipChange events, then rewriting the tooltips to prefix `<qt/>` if it is not yet rich text.
This commit is contained in:
parent
4c9183e8bb
commit
3793fa09ff
5 changed files with 57 additions and 3 deletions
|
@ -6,6 +6,7 @@
|
||||||
#include "walletmodel.h"
|
#include "walletmodel.h"
|
||||||
#include "optionsmodel.h"
|
#include "optionsmodel.h"
|
||||||
#include "guiutil.h"
|
#include "guiutil.h"
|
||||||
|
#include "guiconstants.h"
|
||||||
|
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
#include "ui_interface.h"
|
#include "ui_interface.h"
|
||||||
|
@ -164,6 +165,9 @@ int main(int argc, char *argv[])
|
||||||
Q_INIT_RESOURCE(bitcoin);
|
Q_INIT_RESOURCE(bitcoin);
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
|
// Install global event filter that makes sure that long tooltips can be word-wrapped
|
||||||
|
app.installEventFilter(new GUIUtil::ToolTipToRichTextFilter(TOOLTIP_WRAP_THRESHOLD, &app));
|
||||||
|
|
||||||
// Command-line options take precedence:
|
// Command-line options take precedence:
|
||||||
ParseParameters(argc, argv);
|
ParseParameters(argc, argv);
|
||||||
|
|
||||||
|
|
|
@ -551,22 +551,25 @@ void BitcoinGUI::setNumBlocks(int count)
|
||||||
// Set icon state: spinning if catching up, tick otherwise
|
// Set icon state: spinning if catching up, tick otherwise
|
||||||
if(secs < 90*60 && count >= nTotalBlocks)
|
if(secs < 90*60 && count >= nTotalBlocks)
|
||||||
{
|
{
|
||||||
tooltip = tr("Up to date") + QString(".\n") + tooltip;
|
tooltip = tr("Up to date") + QString(".<br>") + tooltip;
|
||||||
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
|
labelBlocksIcon->setPixmap(QIcon(":/icons/synced").pixmap(STATUSBAR_ICONSIZE, STATUSBAR_ICONSIZE));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
tooltip = tr("Catching up...") + QString("\n") + tooltip;
|
tooltip = tr("Catching up...") + QString("<br>") + tooltip;
|
||||||
labelBlocksIcon->setMovie(syncIconMovie);
|
labelBlocksIcon->setMovie(syncIconMovie);
|
||||||
syncIconMovie->start();
|
syncIconMovie->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!text.isEmpty())
|
if(!text.isEmpty())
|
||||||
{
|
{
|
||||||
tooltip += QString("\n");
|
tooltip += QString("<br>");
|
||||||
tooltip += tr("Last received block was generated %1.").arg(text);
|
tooltip += tr("Last received block was generated %1.").arg(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Don't word-wrap this (fixed-width) tooltip
|
||||||
|
tooltip = QString("<nobr>") + tooltip + QString("</nobr>");
|
||||||
|
|
||||||
labelBlocksIcon->setToolTip(tooltip);
|
labelBlocksIcon->setToolTip(tooltip);
|
||||||
progressBarLabel->setToolTip(tooltip);
|
progressBarLabel->setToolTip(tooltip);
|
||||||
progressBar->setToolTip(tooltip);
|
progressBar->setToolTip(tooltip);
|
||||||
|
|
|
@ -20,4 +20,9 @@ static const int STATUSBAR_ICONSIZE = 16;
|
||||||
/* Transaction list -- bare address (without label) */
|
/* Transaction list -- bare address (without label) */
|
||||||
#define COLOR_BAREADDRESS QColor(140, 140, 140)
|
#define COLOR_BAREADDRESS QColor(140, 140, 140)
|
||||||
|
|
||||||
|
/* Tooltips longer than this (in characters) are converted into rich text,
|
||||||
|
so that they can be word-wrapped.
|
||||||
|
*/
|
||||||
|
static const int TOOLTIP_WRAP_THRESHOLD = 80;
|
||||||
|
|
||||||
#endif // GUICONSTANTS_H
|
#endif // GUICONSTANTS_H
|
||||||
|
|
|
@ -214,5 +214,29 @@ bool isObscured(QWidget *w)
|
||||||
&& checkPoint(QPoint(w->width()/2, w->height()/2), w));
|
&& checkPoint(QPoint(w->width()/2, w->height()/2), w));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ToolTipToRichTextFilter::ToolTipToRichTextFilter(int size_threshold, QObject *parent):
|
||||||
|
size_threshold(size_threshold), QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToolTipToRichTextFilter::eventFilter(QObject *obj, QEvent *evt)
|
||||||
|
{
|
||||||
|
if(evt->type() == QEvent::ToolTipChange)
|
||||||
|
{
|
||||||
|
QWidget *widget = static_cast<QWidget*>(obj);
|
||||||
|
QString tooltip = widget->toolTip();
|
||||||
|
if(!Qt::mightBeRichText(tooltip) && tooltip.size() > size_threshold)
|
||||||
|
{
|
||||||
|
// Prefix <qt/> to make sure Qt detects this as rich text
|
||||||
|
// Escape the current message as HTML and replace \n by <br>
|
||||||
|
tooltip = "<qt/>" + HtmlEscape(tooltip, true);
|
||||||
|
widget->setToolTip(tooltip);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QObject::eventFilter(obj, evt);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace GUIUtil
|
} // namespace GUIUtil
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define GUIUTIL_H
|
#define GUIUTIL_H
|
||||||
|
|
||||||
#include <QString>
|
#include <QString>
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
class QFont;
|
class QFont;
|
||||||
|
@ -69,6 +70,23 @@ namespace GUIUtil
|
||||||
// Determine whether a widget is hidden behind other windows
|
// Determine whether a widget is hidden behind other windows
|
||||||
bool isObscured(QWidget *w);
|
bool isObscured(QWidget *w);
|
||||||
|
|
||||||
|
/** Qt event filter that intercepts ToolTipChange events, and replaces the tooltip with a rich text
|
||||||
|
representation if needed. This assures that Qt can word-wrap long tooltip messages.
|
||||||
|
Tooltips longer than the provided size threshold (in characters) are wrapped.
|
||||||
|
*/
|
||||||
|
class ToolTipToRichTextFilter: public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
ToolTipToRichTextFilter(int size_threshold, QObject *parent);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
bool eventFilter(QObject *obj, QEvent *evt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
int size_threshold;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace GUIUtil
|
} // namespace GUIUtil
|
||||||
|
|
||||||
#endif // GUIUTIL_H
|
#endif // GUIUTIL_H
|
||||||
|
|
Loading…
Reference in a new issue