25#include <QCoreApplication>
29#include <QGraphicsView>
30#include <QGraphicsSceneHoverEvent>
33#include <kwindowsystem.h>
37#include <QtGui/QX11Info>
50#include "plasma/private/tooltip_p.h"
51#include "plasma/private/dialogshadows_p.h"
56class ToolTipManagerPrivate
59 ToolTipManagerPrivate(ToolTipManager *manager)
61 shadow(new DialogShadows(q,
"widgets/tooltip")),
63 showTimer(new QTimer(manager)),
64 hideTimer(new QTimer(manager)),
66 state(ToolTipManager::Activated),
73 ~ToolTipManagerPrivate()
75 if (!QCoreApplication::closingDown()) {
76 shadow->removeWindow(tipWidget);
82 void resetShownState();
87 void onWidgetDestroyed(
QObject *
object);
91 void toolTipHovered(
bool);
92 void createTipWidget();
96 DialogShadows *shadow;
100 QHash<QGraphicsWidget *, ToolTipContent> tooltips;
104 bool delayedHide : 1;
109class ToolTipManagerSingleton
112 ToolTipManagerSingleton()
117K_GLOBAL_STATIC(ToolTipManagerSingleton, privateInstance)
121 return &privateInstance->
self;
124ToolTipManager::ToolTipManager(
QObject *parent)
126 d(new ToolTipManagerPrivate(this)),
129 d->showTimer->setSingleShot(
true);
130 connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip()));
132 d->hideTimer->setSingleShot(
true);
133 connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState()));
136ToolTipManager::~ToolTipManager()
143 if (!d->tooltips.contains(widget)) {
147 d->delayedHide =
false;
148 d->hideTimer->stop();
149 d->showTimer->stop();
152 if (defaultDelay < 0) {
159 d->currentWidget = widget;
164 d->showTimer->start(200);
166 d->showTimer->start(qMax(qreal(200), delay));
172 return d->currentWidget == widget && d->tipWidget && d->tipWidget->isVisible();
175void ToolTipManagerPrivate::doDelayedHide()
180 if (isShown && clickable) {
182 hideTimer->start(1000);
184 hideTimer->start(250);
190 if (d->currentWidget != widget) {
194 d->currentWidget = 0;
195 d->showTimer->stop();
196 d->delayedHide =
false;
202 if (d->state ==
Deactivated || d->tooltips.contains(widget)) {
208 widget->installEventFilter(
this);
209 connect(widget, SIGNAL(destroyed(
QObject*)),
this, SLOT(onWidgetDestroyed(
QObject*)));
214 if (!d->tooltips.contains(widget)) {
218 if (widget == d->currentWidget) {
219 d->currentWidget = 0;
220 d->showTimer->stop();
221 d->delayedHide =
false;
225 widget->removeEventFilter(
this);
226 d->removeWidget(widget);
236 d->tooltips.insert(widget, data);
238 if (d->currentWidget == widget && d->tipWidget && d->tipWidget->isVisible()) {
245 if (d->delayedHide) {
247 d->hideTimer->start(3000);
249 d->hideTimer->stop();
254 d->tipWidget->setContent(widget, data);
255 d->tipWidget->prepareShowing();
259 Corona *corona = qobject_cast<Corona *>(referenceWidget->scene());
266 d->tipWidget->moveTo(corona->
popupPosition(referenceWidget, d->tipWidget->size(), Qt::AlignCenter));
288 d->resetShownState();
298void ToolTipManagerPrivate::createTipWidget()
304 tipWidget =
new ToolTip(0);
305 shadow->addWindow(tipWidget);
307 QObject::connect(tipWidget, SIGNAL(activateWindowByWId(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)),
308 q, SIGNAL(windowPreviewActivated(WId,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)));
309 QObject::connect(tipWidget, SIGNAL(linkActivated(QString,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)),
310 q, SIGNAL(linkActivated(QString,Qt::MouseButtons,Qt::KeyboardModifiers,QPoint)));
311 QObject::connect(tipWidget, SIGNAL(hovered(
bool)), q, SLOT(toolTipHovered(
bool)));
314void ToolTipManagerPrivate::hideTipWidget()
318 shadow->removeWindow(tipWidget);
319 tipWidget->deleteLater();
324void ToolTipManagerPrivate::onWidgetDestroyed(
QObject *
object)
338 removeWidget(w,
false);
341void ToolTipManagerPrivate::removeWidget(
QGraphicsWidget *w,
bool canSafelyAccess)
343 if (currentWidget == w && currentWidget) {
350 if (w && canSafelyAccess) {
351 QObject::disconnect(q, 0, w, 0);
357void ToolTipManagerPrivate::clearTips()
362void ToolTipManagerPrivate::resetShownState()
364 if (!tipWidget || !tipWidget->isVisible() || delayedHide) {
374void ToolTipManagerPrivate::showToolTip()
376 if (state != ToolTipManager::Activated ||
378 QApplication::activePopupWidget() ||
379 QApplication::activeModalWidget()) {
383 PopupApplet *popup = qobject_cast<PopupApplet*>(currentWidget);
384 if (popup && popup->isPopupShowing()) {
388 if (currentWidget->metaObject()->indexOfMethod(
"toolTipAboutToShow()") != -1) {
394 QMetaObject::invokeMethod(temp,
"toolTipAboutToShow");
395 currentWidget = temp;
398 QHash<QGraphicsWidget *, ToolTipContent>::const_iterator tooltip = tooltips.constFind(currentWidget);
400 if (tooltip == tooltips.constEnd() || tooltip.value().isEmpty()) {
403 hideTimer->start(250);
411 Containment *c =
dynamic_cast<Containment *
>(currentWidget->topLevelItem());
417 clickable = tooltip.value().isClickable();
418 tipWidget->setContent(currentWidget, tooltip.value());
419 tipWidget->prepareShowing();
420 QGraphicsWidget *referenceWidget = tooltip.value().graphicsWidget() ? tooltip.value().graphicsWidget() : currentWidget;
421 Corona *corona = qobject_cast<Corona *>(referenceWidget->scene());
424 corona = q->m_corona;
428 tipWidget->moveTo(corona->popupPosition(referenceWidget, tipWidget->size(), Qt::AlignCenter));
433 delayedHide = tooltip.value().autohide();
436 hideTimer->start(3000);
442void ToolTipManagerPrivate::toolTipHovered(
bool hovered)
451 hideTimer->start(500);
455bool ToolTipManager::eventFilter(
QObject *watched, QEvent *event)
459 return QObject::eventFilter(watched, event);
462 switch (event->type()) {
463 case QEvent::GraphicsSceneHoverMove:
474 QGraphicsSceneHoverEvent *me =
static_cast<QGraphicsSceneHoverEvent *
>(event);
476 if (!d->currentWidget || (me->pos() == me->lastPos())) {
481 case QEvent::GraphicsSceneHoverEnter:
484 if (!d->tooltips.contains(widget)) {
492 case QEvent::GraphicsSceneHoverLeave:
493 if (d->currentWidget == widget) {
498 case QEvent::GraphicsSceneMousePress:
499 if (d->currentWidget == widget) {
504 case QEvent::GraphicsSceneWheel:
509 return QObject::eventFilter(watched, event);
514#include "tooltipmanager.moc"
A QGraphicsScene for Plasma::Applets.
QPoint popupPosition(const QGraphicsItem *item, const QSize &size)
Recommended position for a popup window like a menu or a tooltip given its size.
static Theme * defaultTheme()
Singleton pattern accessor.
QGraphicsWidget * graphicsWidget() const
the graphicsWidget used for positioning the tooltip, if any
bool isInstantPopup() const
Whether or not the tooltip should popup instantly when the widget is hovered, defaults to false.
bool autohide() const
Whether or not to autohide the tooltip, defaults to true.
Namespace for everything in libplasma.
Direction locationToDirection(Location location)
Converts a location to a direction.