25 #include <QCoreApplication>
28 #include <QGridLayout>
29 #include <QGraphicsView>
30 #include <QGraphicsSceneHoverEvent>
33 #include <kwindowsystem.h>
37 #include <QtGui/QX11Info>
50 #include "plasma/private/tooltip_p.h"
55 class ToolTipManagerPrivate
58 ToolTipManagerPrivate(ToolTipManager *manager)
61 showTimer(new QTimer(manager)),
62 hideTimer(new QTimer(manager)),
64 state(ToolTipManager::Activated),
71 ~ToolTipManagerPrivate()
73 if (!QCoreApplication::closingDown()) {
79 void resetShownState();
84 void onWidgetDestroyed(
QObject *
object);
88 void toolTipHovered(
bool);
89 void createTipWidget();
96 QHash<QGraphicsWidget *, ToolTipContent> tooltips;
100 bool delayedHide : 1;
105 class ToolTipManagerSingleton
108 ToolTipManagerSingleton()
113 K_GLOBAL_STATIC(ToolTipManagerSingleton, privateInstance)
117 return &privateInstance->
self;
120 ToolTipManager::ToolTipManager(
QObject *parent)
122 d(new ToolTipManagerPrivate(this)),
125 d->showTimer->setSingleShot(
true);
126 connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip()));
128 d->hideTimer->setSingleShot(
true);
129 connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState()));
132 ToolTipManager::~ToolTipManager()
139 if (!d->tooltips.contains(widget)) {
143 d->delayedHide =
false;
144 d->hideTimer->stop();
145 d->showTimer->stop();
148 if (defaultDelay < 0) {
155 d->currentWidget = widget;
160 d->showTimer->start(200);
162 d->showTimer->start(qMax(qreal(200), delay));
168 return d->currentWidget == widget && d->tipWidget && d->tipWidget->isVisible();
171 void ToolTipManagerPrivate::doDelayedHide()
176 if (isShown && clickable) {
178 hideTimer->start(1000);
180 hideTimer->start(250);
186 if (d->currentWidget != widget) {
190 d->currentWidget = 0;
191 d->showTimer->stop();
192 d->delayedHide =
false;
198 if (d->state ==
Deactivated || d->tooltips.contains(widget)) {
204 widget->installEventFilter(
this);
205 connect(widget, SIGNAL(destroyed(
QObject*)),
this, SLOT(onWidgetDestroyed(
QObject*)));
210 if (!d->tooltips.contains(widget)) {
214 if (widget == d->currentWidget) {
215 d->currentWidget = 0;
216 d->showTimer->stop();
217 d->delayedHide =
false;
221 widget->removeEventFilter(
this);
222 d->removeWidget(widget);
232 d->tooltips.insert(widget, data);
234 if (d->currentWidget == widget && d->tipWidget && d->tipWidget->isVisible()) {
241 if (d->delayedHide) {
243 d->hideTimer->start(3000);
245 d->hideTimer->stop();
250 d->tipWidget->setContent(widget, data);
251 d->tipWidget->prepareShowing();
255 Corona *corona = qobject_cast<
Corona *>(referenceWidget->scene());
262 d->tipWidget->moveTo(corona->
popupPosition(referenceWidget, d->tipWidget->size(), Qt::AlignCenter));
284 d->resetShownState();
294 void ToolTipManagerPrivate::createTipWidget()
300 tipWidget =
new ToolTip(0);
301 QObject::connect(tipWidget, SIGNAL(activateWindowByWId(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)),
302 q, SIGNAL(windowPreviewActivated(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)));
303 QObject::connect(tipWidget, SIGNAL(linkActivated(QString,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)),
304 q, SIGNAL(linkActivated(QString,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)));
305 QObject::connect(tipWidget, SIGNAL(hovered(
bool)), q, SLOT(toolTipHovered(
bool)));
308 void ToolTipManagerPrivate::hideTipWidget()
312 tipWidget->deleteLater();
317 void ToolTipManagerPrivate::onWidgetDestroyed(
QObject *
object)
331 removeWidget(w,
false);
334 void ToolTipManagerPrivate::removeWidget(
QGraphicsWidget *w,
bool canSafelyAccess)
336 if (currentWidget == w && currentWidget) {
343 if (w && canSafelyAccess) {
344 QObject::disconnect(q, 0, w, 0);
350 void ToolTipManagerPrivate::clearTips()
355 void ToolTipManagerPrivate::resetShownState()
357 if (!tipWidget || !tipWidget->isVisible() || delayedHide) {
367 void ToolTipManagerPrivate::showToolTip()
371 QApplication::activePopupWidget() ||
372 QApplication::activeModalWidget()) {
376 PopupApplet *popup = qobject_cast<PopupApplet*>(currentWidget);
377 if (popup && popup->isPopupShowing()) {
381 if (currentWidget->metaObject()->indexOfMethod(
"toolTipAboutToShow()") != -1) {
387 QMetaObject::invokeMethod(temp,
"toolTipAboutToShow");
388 currentWidget = temp;
391 QHash<QGraphicsWidget *, ToolTipContent>::const_iterator tooltip = tooltips.constFind(currentWidget);
393 if (tooltip == tooltips.constEnd() || tooltip.value().isEmpty()) {
396 hideTimer->start(250);
404 Containment *c =
dynamic_cast<Containment *
>(currentWidget->topLevelItem());
410 clickable = tooltip.value().isClickable();
411 tipWidget->setContent(currentWidget, tooltip.value());
412 tipWidget->prepareShowing();
413 QGraphicsWidget *referenceWidget = tooltip.value().graphicsWidget() ? tooltip.value().graphicsWidget() : currentWidget;
414 Corona *corona = qobject_cast<Corona *>(referenceWidget->scene());
417 corona = q->m_corona;
421 tipWidget->moveTo(corona->popupPosition(referenceWidget, tipWidget->size(), Qt::AlignCenter));
426 delayedHide = tooltip.value().autohide();
429 hideTimer->start(3000);
435 void ToolTipManagerPrivate::toolTipHovered(
bool hovered)
444 hideTimer->start(500);
448 bool ToolTipManager::eventFilter(
QObject *watched, QEvent *event)
452 return QObject::eventFilter(watched, event);
455 switch (event->type()) {
456 case QEvent::GraphicsSceneHoverMove:
467 QGraphicsSceneHoverEvent *me =
static_cast<QGraphicsSceneHoverEvent *
>(event);
469 if (!d->currentWidget || (me->pos() == me->lastPos())) {
474 case QEvent::GraphicsSceneHoverEnter:
477 if (!d->tooltips.contains(widget)) {
485 case QEvent::GraphicsSceneHoverLeave:
486 if (d->currentWidget == widget) {
491 case QEvent::GraphicsSceneMousePress:
492 if (d->currentWidget == widget) {
497 case QEvent::GraphicsSceneWheel:
502 return QObject::eventFilter(watched, event);
507 #include "tooltipmanager.moc"