Changeset View
Changeset View
Standalone View
Standalone View
app/ToolTips/tooltipmanager.cpp
Show All 15 Lines | |||||
16 | * Free Software Foundation, Inc., * | 16 | * Free Software Foundation, Inc., * | ||
17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * | 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * | ||
18 | *******************************************************************************/ | 18 | *******************************************************************************/ | ||
19 | 19 | | |||
20 | #include "tooltipmanager.h" | 20 | #include "tooltipmanager.h" | ||
21 | 21 | | |||
22 | #include "MenuItem.h" | 22 | #include "MenuItem.h" | ||
23 | 23 | | |||
24 | #include "ktooltip.h" | | |||
25 | | ||||
26 | #include <QRect> | 24 | #include <QRect> | ||
27 | #include <QLabel> | 25 | #include <QLabel> | ||
28 | #include <QTimer> | 26 | #include <QTimer> | ||
29 | #include <QScrollBar> | 27 | #include <QScrollBar> | ||
30 | #include <QGridLayout> | 28 | #include <QGridLayout> | ||
31 | #include <QApplication> | 29 | #include <QApplication> | ||
32 | #include <QDesktopWidget> | | |||
33 | #include <QAbstractItemView> | 30 | #include <QAbstractItemView> | ||
34 | 31 | | |||
35 | #include <KIconLoader> | 32 | #include <KIconLoader> | ||
36 | #include <KColorScheme> | 33 | #include <KColorScheme> | ||
37 | #include <KLocalizedString> | 34 | #include <KLocalizedString> | ||
35 | #include <KToolTipWidget> | ||||
38 | 36 | | |||
39 | class ToolTipManager::Private | 37 | class ToolTipManager::Private | ||
40 | { | 38 | { | ||
41 | public: | 39 | public: | ||
42 | Private() : | 40 | Private() : | ||
41 | tooltip(0), | ||||
43 | view(0), | 42 | view(0), | ||
44 | timer(0) | 43 | timer(0), | ||
44 | delay(300) | ||||
45 | { } | 45 | { } | ||
46 | 46 | | |||
47 | KToolTipWidget *tooltip; | ||||
47 | QAbstractItemView* view; | 48 | QAbstractItemView* view; | ||
48 | QTimer* timer; | 49 | QTimer* timer; | ||
49 | QModelIndex item; | 50 | QModelIndex item; | ||
50 | QRect itemRect; | 51 | QRect itemRect; | ||
52 | int delay; | ||||
51 | }; | 53 | }; | ||
52 | 54 | | |||
53 | ToolTipManager::ToolTipManager(QAbstractItemView* parent) | 55 | ToolTipManager::ToolTipManager(QAbstractItemView* parent) | ||
54 | : QObject(parent) | 56 | : QObject(parent) | ||
55 | , d(new ToolTipManager::Private) | 57 | , d(new ToolTipManager::Private) | ||
56 | { | 58 | { | ||
57 | d->view = parent; | 59 | d->view = parent; | ||
60 | d->tooltip = new KToolTipWidget(d->view); | ||||
61 | d->tooltip->setHideDelay(0); | ||||
58 | 62 | | |||
59 | connect(parent, &QAbstractItemView::viewportEntered, this, &ToolTipManager::hideToolTip); | 63 | connect(parent, &QAbstractItemView::viewportEntered, this, &ToolTipManager::hideToolTip); | ||
60 | connect(parent, &QAbstractItemView::entered, this, &ToolTipManager::requestToolTip); | 64 | connect(parent, &QAbstractItemView::entered, this, &ToolTipManager::requestToolTip); | ||
61 | 65 | | |||
62 | d->timer = new QTimer(this); | 66 | d->timer = new QTimer(this); | ||
63 | d->timer->setSingleShot(true); | 67 | d->timer->setSingleShot(true); | ||
64 | connect(d->timer, &QTimer::timeout, this, &ToolTipManager::prepareToolTip); | 68 | connect(d->timer, &QTimer::timeout, this, &ToolTipManager::prepareToolTip); | ||
65 | 69 | | |||
66 | // When the mousewheel is used, the items don't get a hovered indication | 70 | // When the mousewheel is used, the items don't get a hovered indication | ||
67 | // (Qt-issue #200665). To assure that the tooltip still gets hidden, | 71 | // (Qt-issue #200665). To assure that the tooltip still gets hidden, | ||
68 | // the scrollbars are observed. | 72 | // the scrollbars are observed. | ||
69 | connect(parent->horizontalScrollBar(), &QAbstractSlider::valueChanged, this, &ToolTipManager::hideToolTip); | 73 | connect(parent->horizontalScrollBar(), &QAbstractSlider::valueChanged, this, &ToolTipManager::hideToolTip); | ||
70 | connect(parent->verticalScrollBar(), &QAbstractSlider::valueChanged, this, &ToolTipManager::hideToolTip); | 74 | connect(parent->verticalScrollBar(), &QAbstractSlider::valueChanged, this, &ToolTipManager::hideToolTip); | ||
71 | | ||||
72 | d->view->viewport()->installEventFilter(this); | | |||
73 | } | 75 | } | ||
74 | 76 | | |||
75 | ToolTipManager::~ToolTipManager() | 77 | ToolTipManager::~ToolTipManager() | ||
76 | { | 78 | { | ||
77 | delete d; | 79 | delete d; | ||
78 | } | 80 | } | ||
79 | 81 | | |||
80 | bool ToolTipManager::eventFilter(QObject* watched, QEvent* event) | | |||
81 | { | | |||
82 | if ( watched == d->view->viewport() ) { | | |||
83 | switch ( event->type() ) { | | |||
84 | case QEvent::Leave: | | |||
85 | case QEvent::MouseButtonPress: | | |||
86 | hideToolTip(); | | |||
87 | break; | | |||
88 | case QEvent::ToolTip: | | |||
89 | return true; | | |||
90 | default: | | |||
91 | break; | | |||
92 | } | | |||
93 | } | | |||
94 | | ||||
95 | return QObject::eventFilter(watched, event); | | |||
96 | } | | |||
97 | | ||||
98 | void ToolTipManager::requestToolTip(const QModelIndex& index) | 82 | void ToolTipManager::requestToolTip(const QModelIndex& index) | ||
99 | { | 83 | { | ||
100 | // only request a tooltip for the name column and when no selection or | 84 | // only request a tooltip for the name column and when no selection or | ||
101 | // drag & drop operation is done (indicated by the left mouse button) | 85 | // drag & drop operation is done (indicated by the left mouse button) | ||
102 | if ( !(QApplication::mouseButtons() & Qt::LeftButton) ) { | 86 | if ( !(QApplication::mouseButtons() & Qt::LeftButton) ) { | ||
103 | KToolTip::hideTip(); | 87 | d->tooltip->hide(); | ||
104 | 88 | | |||
105 | d->itemRect = d->view->visualRect(index); | 89 | d->itemRect = d->view->visualRect(index); | ||
106 | const QPoint pos = d->view->viewport()->mapToGlobal(d->itemRect.topLeft()); | 90 | const QPoint pos = d->view->viewport()->mapToGlobal(d->itemRect.topLeft()); | ||
107 | d->itemRect.moveTo(pos); | 91 | d->itemRect.moveTo(pos); | ||
108 | d->item = index; | 92 | d->item = index; | ||
109 | d->timer->start(300); | 93 | d->timer->start(d->delay); | ||
110 | } else { | 94 | } else { | ||
111 | hideToolTip(); | 95 | hideToolTip(); | ||
112 | } | 96 | } | ||
113 | } | 97 | } | ||
114 | 98 | | |||
115 | void ToolTipManager::hideToolTip() | 99 | void ToolTipManager::hideToolTip() | ||
116 | { | 100 | { | ||
117 | d->timer->stop(); | 101 | d->timer->stop(); | ||
118 | KToolTip::hideTip(); | 102 | d->tooltip->hideLater(); | ||
119 | } | 103 | } | ||
120 | 104 | | |||
121 | void ToolTipManager::prepareToolTip() | 105 | void ToolTipManager::prepareToolTip() | ||
122 | { | 106 | { | ||
123 | showToolTip( d->item ); | 107 | showToolTip( d->item ); | ||
124 | } | 108 | } | ||
125 | 109 | | |||
126 | void ToolTipManager::showToolTip( QModelIndex menuItem ) | 110 | void ToolTipManager::showToolTip( QModelIndex menuItem ) | ||
127 | { | 111 | { | ||
128 | if (QApplication::mouseButtons() & Qt::LeftButton) { | 112 | if (QApplication::mouseButtons() & Qt::LeftButton) { | ||
129 | return; | 113 | return; | ||
130 | } | 114 | } | ||
131 | 115 | | |||
132 | QWidget * tip = createTipContent( menuItem ); | 116 | QWidget * tip = createTipContent( menuItem ); | ||
133 | 117 | | |||
134 | // calculate the x- and y-position of the tooltip | 118 | d->tooltip->showBelow(d->itemRect, tip, d->view->nativeParentWidget()->windowHandle()); | ||
135 | const QSize size = tip->sizeHint(); | | |||
136 | const QRect desktop = QApplication::desktop()->screenGeometry( d->itemRect.bottomRight() ); | | |||
137 | | ||||
138 | // d->itemRect defines the area of the item, where the tooltip should be | | |||
139 | // shown. Per default the tooltip is shown in the bottom right corner. | | |||
140 | // If the tooltip content exceeds the desktop borders, it must be assured that: | | |||
141 | // - the content is fully visible | | |||
142 | // - the content is not drawn inside d->itemRect | | |||
143 | const int margin = 3; | | |||
144 | const bool hasRoomToLeft = (d->itemRect.left() - size.width() - margin >= desktop.left()); | | |||
145 | const bool hasRoomToRight = (d->itemRect.right() + size.width() + margin <= desktop.right()); | | |||
146 | const bool hasRoomAbove = (d->itemRect.top() - size.height() - margin >= desktop.top()); | | |||
147 | const bool hasRoomBelow = (d->itemRect.bottom() + size.height() + margin <= desktop.bottom()); | | |||
148 | if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) { | | |||
149 | delete tip; | | |||
150 | tip = 0; | | |||
151 | return; | | |||
152 | } | | |||
153 | | ||||
154 | int x = 0; | | |||
155 | int y = 0; | | |||
156 | if (hasRoomBelow || hasRoomAbove) { | | |||
157 | x = qMax(desktop.left(), d->itemRect.center().x() - size.width() / 2); | | |||
158 | if (x + size.width() / 2 >= desktop.right()) { | | |||
159 | x = desktop.right() - size.width(); | | |||
160 | } | | |||
161 | | ||||
162 | y = hasRoomBelow ? d->itemRect.bottom() + margin : d->itemRect.top() - size.height() - margin; | | |||
163 | } else { | | |||
164 | Q_ASSERT(hasRoomToLeft || hasRoomToRight); | | |||
165 | x = hasRoomToRight ? d->itemRect.right() + margin : d->itemRect.left() - size.width() - margin; | | |||
166 | 119 | | |||
167 | // Put the tooltip at the bottom of the screen. The x-coordinate has already | 120 | connect(d->tooltip, &KToolTipWidget::hidden, tip, &QObject::deleteLater); | ||
168 | // been adjusted, so that no overlapping with d->itemRect occurs. | | |||
169 | y = desktop.bottom() - size.height(); | | |||
170 | } | | |||
171 | 121 | | |||
172 | // the ownership of tip is transferred to KToolTip | | |||
173 | KToolTip::showTip(QPoint(x, y), tip, d->view->nativeParentWidget()->windowHandle()); | | |||
174 | } | 122 | } | ||
175 | 123 | | |||
176 | QWidget * ToolTipManager::createTipContent( QModelIndex item ) | 124 | QWidget * ToolTipManager::createTipContent( QModelIndex item ) | ||
177 | { | 125 | { | ||
178 | const QSize dialogIconSize = QSize(IconSize(KIconLoader::Dialog), IconSize(KIconLoader::Dialog)); | 126 | const QSize dialogIconSize = QSize(IconSize(KIconLoader::Dialog), IconSize(KIconLoader::Dialog)); | ||
179 | const QSize toolbarIconSize = QSize(IconSize(KIconLoader::MainToolbar), IconSize(KIconLoader::MainToolbar)); | 127 | const QSize toolbarIconSize = QSize(IconSize(KIconLoader::MainToolbar), IconSize(KIconLoader::MainToolbar)); | ||
180 | 128 | | |||
181 | QWidget * tipContent = new QWidget(); | 129 | QWidget * tipContent = new QWidget(); | ||
▲ Show 20 Lines • Show All 66 Lines • Show Last 20 Lines |