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 }