Changeset View
Changeset View
Standalone View
Standalone View
ToolTips/tooltipmanager.cpp
Show All 16 Lines | |||||
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 "kcmtreeitem.h" | 22 | #include "kcmtreeitem.h" | ||
23 | #include "sidepanel.h" | 23 | #include "sidepanel.h" | ||
24 | 24 | | |||
25 | #include "ktooltip.h" | | |||
26 | | ||||
27 | #include <QRect> | 25 | #include <QRect> | ||
28 | #include <QLabel> | 26 | #include <QLabel> | ||
29 | #include <QTimer> | 27 | #include <QTimer> | ||
30 | #include <QScrollBar> | 28 | #include <QScrollBar> | ||
31 | #include <QGridLayout> | 29 | #include <QGridLayout> | ||
32 | #include <QApplication> | 30 | #include <QApplication> | ||
33 | #include <QDesktopWidget> | | |||
34 | #include <QAbstractItemView> | 31 | #include <QAbstractItemView> | ||
35 | 32 | | |||
36 | #include <QIcon> | 33 | #include <QIcon> | ||
37 | #include <KColorScheme> | 34 | #include <KColorScheme> | ||
35 | #include <KToolTipWidget> | ||||
38 | 36 | | |||
39 | class ToolTipManager::Private | 37 | class ToolTipManager::Private | ||
40 | { | 38 | { | ||
41 | public: | 39 | public: | ||
42 | Private() : | 40 | Private() : | ||
43 | view(0), | 41 | view(0), | ||
44 | timer(0) | 42 | timer(0), | ||
43 | delay(50) | ||||
45 | { } | 44 | { } | ||
46 | 45 | | |||
46 | KToolTipWidget *tooltip; | ||||
47 | QAbstractItemView* view; | 47 | QAbstractItemView* view; | ||
48 | QTimer* timer; | 48 | QTimer* timer; | ||
49 | QModelIndex item; | 49 | QModelIndex item; | ||
50 | QRect itemRect; | 50 | QRect itemRect; | ||
51 | int delay; | ||||
51 | }; | 52 | }; | ||
52 | 53 | | |||
53 | ToolTipManager::ToolTipManager(QAbstractItemView* parent) | 54 | ToolTipManager::ToolTipManager(QAbstractItemView* parent) | ||
54 | : QObject(parent) | 55 | : QObject(parent) | ||
55 | , d(new ToolTipManager::Private) | 56 | , d(new ToolTipManager::Private) | ||
56 | { | 57 | { | ||
57 | d->view = parent; | 58 | d->view = parent; | ||
59 | d->tooltip = new KToolTipWidget(d->view); | ||||
60 | d->tooltip->setHideDelay(0); | ||||
58 | 61 | | |||
59 | connect(parent, &QAbstractItemView::viewportEntered, this, &ToolTipManager::hideToolTip); | 62 | connect(parent, &QAbstractItemView::viewportEntered, this, &ToolTipManager::hideToolTip); | ||
60 | connect(parent, &QAbstractItemView::entered, this, &ToolTipManager::requestToolTip); | 63 | connect(parent, &QAbstractItemView::entered, this, &ToolTipManager::requestToolTip); | ||
61 | 64 | | |||
62 | d->timer = new QTimer(this); | 65 | d->timer = new QTimer(this); | ||
63 | d->timer->setSingleShot(true); | 66 | d->timer->setSingleShot(true); | ||
64 | connect(d->timer, &QTimer::timeout, this, &ToolTipManager::prepareToolTip); | 67 | connect(d->timer, &QTimer::timeout, this, &ToolTipManager::prepareToolTip); | ||
65 | 68 | | |||
Show All 29 Lines | 84 | { | |||
95 | return QObject::eventFilter(watched, event); | 98 | return QObject::eventFilter(watched, event); | ||
96 | } | 99 | } | ||
97 | 100 | | |||
98 | void ToolTipManager::requestToolTip(const QModelIndex& index) | 101 | void ToolTipManager::requestToolTip(const QModelIndex& index) | ||
99 | { | 102 | { | ||
100 | // only request a tooltip for the name column and when no selection or | 103 | // 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) | 104 | // drag & drop operation is done (indicated by the left mouse button) | ||
102 | if ( !(QApplication::mouseButtons() & Qt::LeftButton) ) { | 105 | if ( !(QApplication::mouseButtons() & Qt::LeftButton) ) { | ||
103 | KToolTip::hideTip(); | 106 | d->tooltip->hide(); | ||
104 | 107 | | |||
105 | d->itemRect = d->view->visualRect(index); | 108 | d->itemRect = d->view->visualRect(index); | ||
106 | const QPoint pos = d->view->viewport()->mapToGlobal(d->itemRect.topLeft()); | 109 | const QPoint pos = d->view->viewport()->mapToGlobal(d->itemRect.topLeft()); | ||
107 | d->itemRect.moveTo(pos); | 110 | d->itemRect.moveTo(pos); | ||
108 | d->item = index; | 111 | d->item = index; | ||
109 | d->timer->start(50); | 112 | d->timer->start(d->delay); | ||
110 | } else { | 113 | } else { | ||
111 | hideToolTip(); | 114 | hideToolTip(); | ||
112 | } | 115 | } | ||
113 | } | 116 | } | ||
114 | 117 | | |||
115 | void ToolTipManager::hideToolTip() | 118 | void ToolTipManager::hideToolTip() | ||
116 | { | 119 | { | ||
117 | d->timer->stop(); | 120 | d->timer->stop(); | ||
118 | KToolTip::hideTip(); | 121 | d->tooltip->hideLater(); | ||
119 | } | 122 | } | ||
120 | 123 | | |||
121 | void ToolTipManager::prepareToolTip() | 124 | void ToolTipManager::prepareToolTip() | ||
122 | { | 125 | { | ||
123 | showToolTip( d->item ); | 126 | showToolTip( d->item ); | ||
124 | } | 127 | } | ||
125 | 128 | | |||
126 | void ToolTipManager::showToolTip( const QModelIndex& menuItem ) | 129 | void ToolTipManager::showToolTip( const QModelIndex& menuItem ) | ||
127 | { | 130 | { | ||
128 | if (QApplication::mouseButtons() & Qt::LeftButton) { | 131 | if (QApplication::mouseButtons() & Qt::LeftButton) { | ||
129 | return; | 132 | return; | ||
130 | } | 133 | } | ||
131 | 134 | | |||
132 | QWidget * tip = createTipContent( menuItem ); | 135 | QWidget * tip = createTipContent( menuItem ); | ||
136 | connect(d->tooltip, &KToolTipWidget::hidden, tip, &QObject::deleteLater); | ||||
133 | 137 | | |||
134 | // calculate the x- and y-position of the tooltip | 138 | 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 bool hasRoomToLeft = (d->itemRect.left() - size.width() >= desktop.left()); | | |||
144 | const bool hasRoomToRight = (d->itemRect.right() + size.width() <= desktop.right()); | | |||
145 | const bool hasRoomAbove = (d->itemRect.top() - size.height() >= desktop.top()); | | |||
146 | const bool hasRoomBelow = (d->itemRect.bottom() + size.height() <= desktop.bottom()); | | |||
147 | if (!hasRoomAbove && !hasRoomBelow && !hasRoomToLeft && !hasRoomToRight) { | | |||
148 | delete tip; | | |||
149 | tip = 0; | | |||
150 | return; | | |||
151 | } | | |||
152 | | ||||
153 | int x = 0; | | |||
154 | int y = 0; | | |||
155 | if (hasRoomBelow || hasRoomAbove) { | | |||
156 | x = QCursor::pos().x() + 16; // TODO: use mouse pointer width instead of the magic value of 16 | | |||
157 | if (x + size.width() >= desktop.right()) { | | |||
158 | x = desktop.right() - size.width(); | | |||
159 | } | | |||
160 | y = hasRoomBelow ? d->itemRect.bottom() : d->itemRect.top() - size.height(); | | |||
161 | } else { | | |||
162 | Q_ASSERT(hasRoomToLeft || hasRoomToRight); | | |||
163 | x = hasRoomToRight ? d->itemRect.right() : d->itemRect.left() - size.width(); | | |||
164 | | ||||
165 | // Put the tooltip at the bottom of the screen. The x-coordinate has already | | |||
166 | // been adjusted, so that no overlapping with d->itemRect occurs. | | |||
167 | y = desktop.bottom() - size.height(); | | |||
168 | } | | |||
169 | | ||||
170 | // the ownership of tip is transferred to KToolTip | | |||
171 | KToolTip::showTip(QPoint(x, y), tip, d->view->nativeParentWidget()->windowHandle()); | | |||
172 | } | 139 | } | ||
173 | 140 | | |||
174 | QWidget * ToolTipManager::createTipContent( const QModelIndex& item ) | 141 | QWidget * ToolTipManager::createTipContent( const QModelIndex& item ) | ||
175 | { | 142 | { | ||
176 | QWidget * tipContent = new QWidget(); | 143 | QWidget * tipContent = new QWidget(); | ||
177 | QGridLayout* tipLayout = new QGridLayout(); | 144 | QGridLayout* tipLayout = new QGridLayout(); | ||
178 | 145 | | |||
179 | QLayout * primaryLine = generateToolTipLine( item, tipContent, QSize(32,32), true ); | 146 | QLayout * primaryLine = generateToolTipLine( item, tipContent, QSize(32,32), true ); | ||
▲ Show 20 Lines • Show All 48 Lines • Show Last 20 Lines |