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