Plasma
tooltipmanager.cpp
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "tooltipmanager.h"
00023
00024
00025 #include <QCoreApplication>
00026 #include <QLabel>
00027 #include <QTimer>
00028 #include <QGridLayout>
00029 #include <QGraphicsView>
00030
00031
00032 #include <kwindowsystem.h>
00033
00034
00035 #ifdef Q_WS_X11
00036 #include <QtGui/QX11Info>
00037 #include <X11/Xlib.h>
00038 #include <fixx11h.h>
00039 #endif
00040
00041
00042 #include "plasma/applet.h"
00043 #include "plasma/containment.h"
00044 #include "plasma/corona.h"
00045 #include "plasma/framesvg.h"
00046 #include "plasma/popupapplet.h"
00047 #include "plasma/theme.h"
00048 #include "plasma/view.h"
00049 #include "plasma/private/tooltip_p.h"
00050
00051 namespace Plasma
00052 {
00053
00054 class ToolTipManagerPrivate
00055 {
00056 public :
00057 ToolTipManagerPrivate()
00058 : currentWidget(0),
00059 showTimer(0),
00060 hideTimer(0),
00061 tipWidget(new ToolTip(0)),
00062 state(ToolTipManager::Activated),
00063 isShown(false),
00064 delayedHide(false)
00065 {
00066
00067 }
00068
00069 ~ToolTipManagerPrivate()
00070 {
00071 if (!QCoreApplication::closingDown()) {
00072 delete tipWidget;
00073 }
00074 }
00075
00076 void showToolTip();
00077 void resetShownState();
00078
00082 void onWidgetDestroyed(QObject * object);
00083 void removeWidget(QGraphicsWidget *w);
00084 void clearTips();
00085 void doDelayedHide();
00086
00087 QGraphicsWidget *currentWidget;
00088 QTimer *showTimer;
00089 QTimer *hideTimer;
00090 QHash<QGraphicsWidget *, ToolTipContent> tooltips;
00091 ToolTip *tipWidget;
00092 ToolTipManager::State state;
00093 bool isShown : 1;
00094 bool delayedHide : 1;
00095 };
00096
00097
00098 class ToolTipManagerSingleton
00099 {
00100 public:
00101 ToolTipManagerSingleton()
00102 {
00103 }
00104 ToolTipManager self;
00105 };
00106 K_GLOBAL_STATIC(ToolTipManagerSingleton, privateInstance)
00107
00108 ToolTipManager *ToolTipManager::self()
00109 {
00110 return &privateInstance->self;
00111 }
00112
00113 ToolTipManager::ToolTipManager(QObject *parent)
00114 : QObject(parent),
00115 d(new ToolTipManagerPrivate)
00116 {
00117 d->showTimer = new QTimer(this);
00118 d->showTimer->setSingleShot(true);
00119 d->hideTimer = new QTimer(this);
00120 d->hideTimer->setSingleShot(true);
00121
00122 connect(d->showTimer, SIGNAL(timeout()), SLOT(showToolTip()));
00123 connect(d->hideTimer, SIGNAL(timeout()), SLOT(resetShownState()));
00124 }
00125
00126 ToolTipManager::~ToolTipManager()
00127 {
00128 delete d;
00129 }
00130
00131 void ToolTipManager::show(QGraphicsWidget *widget)
00132 {
00133 if (!d->tooltips.contains(widget)) {
00134 return;
00135 }
00136
00137 d->hideTimer->stop();
00138 d->delayedHide = false;
00139 d->showTimer->stop();
00140 d->currentWidget = widget;
00141
00142 if (d->isShown) {
00143
00144
00145 d->showTimer->start(200);
00146 } else {
00147 d->showTimer->start(700);
00148 }
00149 }
00150
00151 bool ToolTipManager::isVisible(QGraphicsWidget *widget) const
00152 {
00153 return d->currentWidget == widget && d->tipWidget->isVisible();
00154 }
00155
00156 void ToolTipManagerPrivate::doDelayedHide()
00157 {
00158 showTimer->stop();
00159 delayedHide = true;
00160 hideTimer->start(250);
00161 }
00162
00163 void ToolTipManager::hide(QGraphicsWidget *widget)
00164 {
00165 if (d->currentWidget != widget) {
00166 return;
00167 }
00168
00169 d->currentWidget = 0;
00170 d->showTimer->stop();
00171 d->delayedHide = false;
00172 d->tipWidget->hide();
00173 }
00174
00175 void ToolTipManager::registerWidget(QGraphicsWidget *widget)
00176 {
00177 if (d->state == Deactivated || d->tooltips.contains(widget)) {
00178 return;
00179 }
00180
00181
00182 d->tooltips.insert(widget, ToolTipContent());
00183 widget->installEventFilter(this);
00184 connect(widget, SIGNAL(destroyed(QObject*)), this, SLOT(onWidgetDestroyed(QObject*)));
00185 }
00186
00187 void ToolTipManager::unregisterWidget(QGraphicsWidget *widget)
00188 {
00189 if (!d->tooltips.contains(widget)) {
00190 return;
00191 }
00192
00193 widget->removeEventFilter(this);
00194 d->removeWidget(widget);
00195 }
00196
00197 void ToolTipManager::setContent(QGraphicsWidget *widget, const ToolTipContent &data)
00198 {
00199 if (d->state == Deactivated) {
00200 return;
00201 }
00202
00203 registerWidget(widget);
00204 d->tooltips[widget] = data;
00205
00206 if (d->currentWidget == widget) {
00207 if (data.isEmpty()) {
00208 hide(widget);
00209 } else {
00210 d->delayedHide = data.autohide();
00211 if (d->delayedHide) {
00212
00213 d->hideTimer->start(3000);
00214 } else {
00215 d->hideTimer->stop();
00216 }
00217 }
00218
00219 d->tipWidget->setContent(widget, data);
00220 d->tipWidget->prepareShowing();
00221 d->tipWidget->moveTo(m_corona->popupPosition(d->currentWidget, d->tipWidget->size()));
00222 }
00223 }
00224
00225 void ToolTipManager::clearContent(QGraphicsWidget *widget)
00226 {
00227 setContent(widget, ToolTipContent());
00228 }
00229
00230 void ToolTipManager::setState(ToolTipManager::State state)
00231 {
00232 d->state = state;
00233
00234 switch (state) {
00235 case Activated:
00236 break;
00237 case Deactivated:
00238 d->clearTips();
00239
00240 case Inhibited:
00241 d->resetShownState();
00242 break;
00243 }
00244 }
00245
00246 ToolTipManager::State ToolTipManager::state() const
00247 {
00248 return d->state;
00249 }
00250
00251 void ToolTipManagerPrivate::onWidgetDestroyed(QObject *object)
00252 {
00253 if (!object) {
00254 return;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264 QGraphicsWidget *w = static_cast<QGraphicsWidget*>(object);
00265 removeWidget(w);
00266 }
00267
00268 void ToolTipManagerPrivate::removeWidget(QGraphicsWidget *w)
00269 {
00270
00271 if (currentWidget == w) {
00272 currentWidget = 0;
00273 showTimer->stop();
00274 tipWidget->setContent(0, ToolTipContent());
00275 tipWidget->hide();
00276 delayedHide = false;
00277 }
00278
00279 tooltips.remove(w);
00280 }
00281
00282 void ToolTipManagerPrivate::clearTips()
00283 {
00284 tooltips.clear();
00285 }
00286
00287 void ToolTipManagerPrivate::resetShownState()
00288 {
00289 if (currentWidget) {
00290 if (!tipWidget->isVisible() || delayedHide) {
00291
00292 delayedHide = false;
00293 isShown = false;
00294 currentWidget = 0;
00295 tipWidget->hide();
00296 }
00297 }
00298 }
00299
00300 void ToolTipManagerPrivate::showToolTip()
00301 {
00302 if (state != ToolTipManager::Activated ||
00303 !currentWidget ||
00304 QApplication::activePopupWidget() ||
00305 QApplication::activeModalWidget()) {
00306 return;
00307 }
00308
00309 PopupApplet *popup = qobject_cast<PopupApplet*>(currentWidget);
00310 if (popup && popup->isPopupShowing()) {
00311 return;
00312 }
00313
00314 QMetaObject::invokeMethod(currentWidget, "toolTipAboutToShow");
00315 QHash<QGraphicsWidget *, ToolTipContent>::const_iterator tooltip = tooltips.constFind(currentWidget);
00316
00317 if (tooltip == tooltips.constEnd() || tooltip.value().isEmpty()) {
00318 return;
00319 }
00320
00321 Containment *c = dynamic_cast<Containment *>(currentWidget->topLevelItem());
00322
00323 if (c) {
00324 tipWidget->setDirection(Plasma::locationToDirection(c->location()));
00325 }
00326
00327 tipWidget->setContent(currentWidget, tooltip.value());
00328 tipWidget->prepareShowing();
00329 tipWidget->moveTo(ToolTipManager::self()->m_corona->popupPosition(currentWidget, tipWidget->size()));
00330 tipWidget->show();
00331 isShown = true;
00332
00333 delayedHide = tooltip.value().autohide();
00334 if (delayedHide) {
00335
00336 hideTimer->start(3000);
00337 } else {
00338 hideTimer->stop();
00339 }
00340 }
00341
00342 bool ToolTipManager::eventFilter(QObject *watched, QEvent *event)
00343 {
00344 QGraphicsWidget * widget = dynamic_cast<QGraphicsWidget *>(watched);
00345 if (d->state != Activated || !widget) {
00346 return QObject::eventFilter(watched, event);
00347 }
00348
00349 switch (event->type()) {
00350 case QEvent::GraphicsSceneHoverMove:
00351
00352
00353 if (Plasma::ToolTipManager::self()->isVisible(widget)) {
00354 break;
00355 }
00356
00357
00358
00359
00360 if (!d->currentWidget) {
00361 break;
00362 }
00363
00364 case QEvent::GraphicsSceneHoverEnter:
00365 {
00366
00367 if (!d->tooltips.contains(widget)) {
00368 break;
00369 }
00370
00371
00372
00373
00374 QGraphicsView *parentView = viewFor(widget);
00375 if (parentView) {
00376 show(widget);
00377 }
00378
00379 break;
00380 }
00381
00382 case QEvent::GraphicsSceneHoverLeave:
00383 d->doDelayedHide();
00384 break;
00385
00386 case QEvent::GraphicsSceneMousePress:
00387 case QEvent::GraphicsSceneWheel:
00388 hide(widget);
00389
00390 default:
00391 break;
00392 }
00393
00394 return QObject::eventFilter(watched, event);
00395 }
00396
00397 }
00398
00399 #include "tooltipmanager.moc"
00400