File indexing completed on 2024-05-12 16:02:30

0001 /*
0002   SPDX-FileCopyrightText: 2006 Gábor Lehel <illissius@gmail.com>
0003 
0004   SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 #include "KoItemToolTip.h"
0007 
0008 #include <QApplication>
0009 #include <QBasicTimer>
0010 #include <QDesktopWidget>
0011 #include <QModelIndex>
0012 #include <QPainter>
0013 #include <QPaintEvent>
0014 #include <QPersistentModelIndex>
0015 #include <QStyleOptionViewItem>
0016 #include <QTextDocument>
0017 #include <QTimerEvent>
0018 #include <QToolTip>
0019 
0020 class Q_DECL_HIDDEN KoItemToolTip::Private
0021 {
0022     public:
0023         QTextDocument *document;
0024         QPersistentModelIndex index;
0025         QPoint pos;
0026         QBasicTimer timer;
0027 
0028         Private(): document(0) { }
0029 };
0030 
0031 KoItemToolTip::KoItemToolTip()
0032     : d(new Private)
0033 {
0034     d->document = new QTextDocument(this);
0035     setWindowFlags(Qt::FramelessWindowHint  | Qt::ToolTip
0036                   | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
0037     QApplication::instance()->installEventFilter(this);
0038 }
0039 
0040 KoItemToolTip::~KoItemToolTip()
0041 {
0042     delete d;
0043 }
0044 
0045 void KoItemToolTip::showTip(QWidget *widget, const QPoint &pos, const QStyleOptionViewItem &option, const QModelIndex &index)
0046 {
0047     QTextDocument *doc = createDocument(index);
0048 
0049     QPoint p = (isVisible() && index == d->index) ? d->pos : pos;
0050 
0051     if (!isVisible() || index != d->index || doc->toHtml() != d->document->toHtml())
0052     {
0053         d->pos = p;
0054         d->index = index;
0055         delete d->document;
0056         d->document = doc;
0057         updatePosition(widget, p, option);
0058         if (!isVisible())
0059             show();
0060         else
0061             update();
0062         d->timer.start(10000, this);
0063     }
0064     else
0065         delete doc;
0066 }
0067 
0068 void KoItemToolTip::updatePosition(QWidget *widget, const QPoint &pos, const QStyleOptionViewItem &option)
0069 {
0070     const QRect drect = QApplication::desktop()->availableGeometry(widget);
0071     const QSize size = sizeHint();
0072     const int width = size.width(), height = size.height();
0073     const QPoint gpos = widget->mapToGlobal(pos);
0074     const QRect irect(widget->mapToGlobal(option.rect.topLeft()), option.rect.size());
0075 
0076     int y = gpos.y() + 20;
0077     if (y + height > drect.bottom())
0078         y = qMax(drect.top(), irect.top() - height);
0079 
0080     int x;
0081     if (gpos.x() + width < drect.right())
0082         x = gpos.x();
0083     else
0084         x = qMax(drect.left(), gpos.x() - width);
0085 
0086     move(x, y);
0087 
0088     resize(sizeHint());
0089  }
0090 
0091 QSize KoItemToolTip::sizeHint() const
0092 {
0093     return d->document->size().toSize();
0094 }
0095 
0096 void KoItemToolTip::paintEvent(QPaintEvent*)
0097 {
0098     QPainter p(this);
0099     d->document->drawContents(&p, rect());
0100     p.drawRect(0, 0, width() - 1, height() - 1);
0101 }
0102 
0103 void KoItemToolTip::timerEvent(QTimerEvent *e)
0104 {
0105     if (e->timerId() == d->timer.timerId()) {
0106         hide();
0107     }
0108 }
0109 
0110 bool KoItemToolTip::eventFilter(QObject *object, QEvent *event)
0111 {
0112     switch(event->type())
0113     {
0114         case QEvent::KeyPress:
0115         case QEvent::KeyRelease:
0116         case QEvent::MouseButtonPress:
0117         case QEvent::MouseButtonRelease:
0118         case QEvent::FocusIn:
0119         case QEvent::FocusOut:
0120         case QEvent::Enter:
0121         case QEvent::Leave:
0122             hide();
0123         default: break;
0124     }
0125 
0126     return QFrame::eventFilter(object, event);
0127 }