mirror of
https://git.lyx.org/repos/lyx.git
synced 2024-12-22 05:16:21 +00:00
Line breaks in tooltips
* New function formatToolTip(QString):
Format text for display as a ToolTip, breaking at lines of a certain
width. Note: this function is expensive. Better call it in a delayed manner,
i.e. not to fill in a model (see for instance the function
ToolTipFormatter::eventFilter).
* Install a global event filter that formats tooltips on-the-fly
Inspired from
3793fa09ff
but much improved.
When is formatToolTip called automatically? Whenever the tooltip is not already
rich text beginning with <html>, and is defined by the following functions:
* QWidget::setToolTip(),
* QAbstractItemModel::setData(..., Qt::ToolTipRole),
* Inset::toolTip() (added in one of the subsequent patches)
In other words, tooltips can use Qt html and the tooltip will still be correctly
broken. Moreover, it is possible to specify an entirely custom tooltip (not
subject to automatic formatting) by giving it in its entirety, i.e. starting
with <html>.
This commit is contained in:
parent
489dca71cd
commit
059ca0f691
@ -14,6 +14,7 @@
|
||||
|
||||
#include "GuiApplication.h"
|
||||
|
||||
#include "ToolTipFormatter.h"
|
||||
#include "ColorCache.h"
|
||||
#include "ColorSet.h"
|
||||
#include "GuiClipboard.h"
|
||||
@ -1081,6 +1082,9 @@ GuiApplication::GuiApplication(int & argc, char ** argv)
|
||||
// This is clearly not enough in a time where we use threads for
|
||||
// document preview and/or export. 20 should be OK.
|
||||
QThreadPool::globalInstance()->setMaxThreadCount(20);
|
||||
|
||||
// make sure tooltips are formatted
|
||||
installEventFilter(new ToolTipFormatter(this));
|
||||
}
|
||||
|
||||
|
||||
|
@ -153,6 +153,7 @@ SOURCEFILES = \
|
||||
TocModel.cpp \
|
||||
TocWidget.cpp \
|
||||
Toolbars.cpp \
|
||||
ToolTipFormatter.cpp \
|
||||
Validator.cpp
|
||||
|
||||
NOMOCHEADER = \
|
||||
@ -259,6 +260,7 @@ MOCHEADER = \
|
||||
PanelStack.h \
|
||||
TocModel.h \
|
||||
TocWidget.h \
|
||||
ToolTipFormatter.h \
|
||||
Validator.h
|
||||
|
||||
UIFILES = \
|
||||
|
68
src/frontends/qt4/ToolTipFormatter.cpp
Normal file
68
src/frontends/qt4/ToolTipFormatter.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* \file ToolTipFormatter.cpp
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Guillaume Munch
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include "ToolTipFormatter.h"
|
||||
#include "qt_helpers.h"
|
||||
|
||||
#include <QAbstractItemView>
|
||||
#include <QTextDocument>
|
||||
#include <QTextLayout>
|
||||
#include <QToolTip>
|
||||
|
||||
|
||||
//#include "support/debug.h"
|
||||
//#include "support/lstrings.h"
|
||||
|
||||
|
||||
namespace lyx {
|
||||
namespace frontend {
|
||||
|
||||
|
||||
ToolTipFormatter::ToolTipFormatter(QObject * parent) : QObject(parent) {}
|
||||
|
||||
|
||||
bool ToolTipFormatter::eventFilter(QObject * o, QEvent * e)
|
||||
{
|
||||
if (e->type() != QEvent::ToolTip)
|
||||
return false;
|
||||
|
||||
// Format the tooltip of the widget being considered.
|
||||
QWidget * w = qobject_cast<QWidget *>(o);
|
||||
if (!w)
|
||||
return false;
|
||||
// Unchanged if empty or already formatted
|
||||
w->setToolTip(formatToolTip(w->toolTip()));
|
||||
|
||||
// Now, if the tooltip is for an item in a QListView or a QTreeView,
|
||||
// then the widget above was probably not the one with the tooltip.
|
||||
// Check if the parent is a QAbstractItemView.
|
||||
QAbstractItemView * iv = qobject_cast<QAbstractItemView *>(w->parent());
|
||||
if (!iv)
|
||||
return false;
|
||||
// In this case, the item is retrieved from the position of the QHelpEvent
|
||||
// on the screen.
|
||||
QPoint pos = static_cast<QHelpEvent *>(e)->pos();
|
||||
QModelIndex item = iv->indexAt(pos);
|
||||
QVariant data = iv->model()->data(item, Qt::ToolTipRole);
|
||||
if (data.isValid() && data.typeName() == toqstr("QString"))
|
||||
// Unchanged if empty or already formatted
|
||||
iv->model()->setData(item, formatToolTip(data.toString()),
|
||||
Qt::ToolTipRole);
|
||||
// We must let the tooltip event reach its destination.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
} // namespace frontend
|
||||
} // namespace lyx
|
||||
|
||||
#include "moc_ToolTipFormatter.cpp"
|
37
src/frontends/qt4/ToolTipFormatter.h
Normal file
37
src/frontends/qt4/ToolTipFormatter.h
Normal file
@ -0,0 +1,37 @@
|
||||
// -*- C++ -*-
|
||||
/**
|
||||
* \file ToolTipFormatter.h
|
||||
* This file is part of LyX, the document processor.
|
||||
* Licence details can be found in the file COPYING.
|
||||
*
|
||||
* \author Guillaume Munch
|
||||
*
|
||||
* Full author contact details are available in file CREDITS.
|
||||
*/
|
||||
|
||||
#ifndef TOOLTIPFORMATTER_H
|
||||
#define TOOLTIPFORMATTER_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class QEvent;
|
||||
|
||||
namespace lyx {
|
||||
namespace frontend {
|
||||
|
||||
|
||||
/// This event filter intercepts ToolTip events, to format any tooltip
|
||||
/// appropriately before display.
|
||||
class ToolTipFormatter : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
ToolTipFormatter(QObject * parent);
|
||||
protected:
|
||||
bool eventFilter(QObject * o, QEvent * e);
|
||||
};
|
||||
|
||||
|
||||
} // namespace frontend
|
||||
} // namespace lyx
|
||||
|
||||
#endif // TOOLTIPFORMATTER_H
|
@ -42,6 +42,9 @@
|
||||
#include <QLocale>
|
||||
#include <QPalette>
|
||||
#include <QSet>
|
||||
#include <QTextLayout>
|
||||
#include <QTextDocument>
|
||||
#include <QToolTip>
|
||||
|
||||
#include <algorithm>
|
||||
#include <fstream>
|
||||
@ -647,4 +650,37 @@ QString guiName(string const & type, BufferParams const & bp)
|
||||
}
|
||||
|
||||
|
||||
QString formatToolTip(QString text, int em)
|
||||
{
|
||||
// 1. QTooltip activates word wrapping only if mightBeRichText()
|
||||
// is true. So we convert the text to rich text.
|
||||
//
|
||||
// 2. The default width is way too small. Setting the width is tricky; first
|
||||
// one has to compute the ideal width, and then force it with special
|
||||
// html markup.
|
||||
|
||||
// do nothing if empty or already formatted
|
||||
if (text.isEmpty() || text.startsWith(QString("<html>")))
|
||||
return text;
|
||||
// Convert to rich text if it is not already
|
||||
if (!Qt::mightBeRichText(text))
|
||||
text = Qt::convertFromPlainText(text, Qt::WhiteSpaceNormal);
|
||||
// Compute desired width in pixels
|
||||
QFont const font = QToolTip::font();
|
||||
int const px_width = em * QFontMetrics(font).width("M");
|
||||
// Determine the ideal width of the tooltip
|
||||
QTextDocument td("");
|
||||
td.setHtml(text);
|
||||
td.setDefaultFont(QToolTip::font());
|
||||
td.setTextWidth(px_width);
|
||||
double best_width = td.idealWidth();
|
||||
// Set the line wrapping with appropriate width
|
||||
return QString("<html><body><table><tr>"
|
||||
"<td align=justify width=%1>%2</td>"
|
||||
"</tr></table></body></html>")
|
||||
.arg(QString::number(int(best_width) + 1), text);
|
||||
return text;
|
||||
}
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
@ -195,6 +195,24 @@ QString changeExtension(QString const & oldname, QString const & ext);
|
||||
/// parameter.
|
||||
QString guiName(std::string const & type, BufferParams const & bp);
|
||||
|
||||
/// Format \param text for display as a ToolTip, breaking at lines of \param
|
||||
/// width ems. Note: this function is expensive. Better call it in a delayed
|
||||
/// manner, i.e. not to fill in a model (see for instance the function
|
||||
/// ToolTipFormatter::eventFilter).
|
||||
///
|
||||
/// When is it called automatically? Whenever the tooltip is not already rich
|
||||
/// text beginning with <html>, and is defined by the following functions:
|
||||
/// - QWidget::setToolTip(),
|
||||
/// - QAbstractItemModel::setData(..., Qt::ToolTipRole),
|
||||
/// - Inset::toolTip()
|
||||
///
|
||||
/// In other words, tooltips can use Qt html, and the tooltip will still be
|
||||
/// correctly broken. Moreover, it is possible to specify an entirely custom
|
||||
/// tooltip (not subject to automatic formatting) by giving it in its entirety,
|
||||
/// i.e. starting with <html>.
|
||||
QString formatToolTip(QString text, int width = 30);
|
||||
|
||||
|
||||
} // namespace lyx
|
||||
|
||||
#endif // QTHELPERS_H
|
||||
|
Loading…
Reference in New Issue
Block a user