/* * Copyright (C) 2009, 2010 Nicolas Bonnefon and other contributors * * This file is part of glogg. * * glogg is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * glogg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with glogg. If not, see . */ #include #include #include #include #include "menuactiontooltipbehavior.h" // It would be nice to only need action, and have action be the parent, // however implementation needs the parent menu (see showToolTip), and // since neither action nor parent is guaranteed to die before the other, // for memory-management purposes the parent will have to be specified // explicity (probably, the window owning the action and the menu). MenuActionToolTipBehavior::MenuActionToolTipBehavior(QAction *action, QMenu *parentMenu, QObject *parent = 0) : QObject(parent), action(action), parentMenu(parentMenu), toolTipDelayMs(1000), timerId(0), hoverPoint() { connect(action, SIGNAL(hovered()), this, SLOT(onActionHovered())); } int MenuActionToolTipBehavior::toolTipDelay() { return toolTipDelayMs; } void MenuActionToolTipBehavior::setToolTipDelay(int delayMs) { toolTipDelayMs = delayMs; } void MenuActionToolTipBehavior::timerEvent(QTimerEvent *event) { // Not ours, don't touch if (event->timerId() != timerId) { QObject::timerEvent(event); return; } killTimer(timerId); // interested in a single shot timerId = 0; // Has the mouse waited unmoved in one location for 'delay' ms? const QPoint &mousePos = QCursor::pos(); if (hoverPoint == mousePos) showToolTip(hoverPoint); } void MenuActionToolTipBehavior::onActionHovered() { const QPoint &mousePos = QCursor::pos(); // Hover is fired on keyboard focus over action in menu, ignore it const QPoint &relativeMousePos = parentMenu->mapFromGlobal(mousePos); if (!parentMenu->actionGeometry(action).contains(relativeMousePos)) { if (timerId != 0) { // once timer expires its check will fail anyway killTimer(timerId); timerId = 0; } QToolTip::hideText(); // there might be one currently shown return; } // Record location hoverPoint = mousePos; // Restart timer if (timerId != 0) killTimer(timerId); timerId = startTimer(toolTipDelayMs); } void MenuActionToolTipBehavior::showToolTip(const QPoint &position) { const QString &toolTip = action->toolTip(); // Show tooltip until mouse moves at all // NOTE: using action->parentWidget() which is the MainWindow, // does not work (tooltip is not cleared when upon leaving the // region). This is the only reason we need parentMenu here. Just // a wild guess: maybe it isn't cleared because it would be // cleared on a mouse move over the designated widget, but mouse // move doesn't happen over MainWindow, since the mouse is over // the menu even when out of the activeRegion. QPoint relativePos = parentMenu->mapFromGlobal(position); QRect activeRegion(relativePos.x(), relativePos.y(), 1, 1); QToolTip::showText(position, toolTip, parentMenu, activeRegion); }