00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <qapplication.h>
00025 #include <qdesktopwidget.h>
00026 #include <qevent.h>
00027 #include <qhash.h>
00028 #include <qlabel.h>
00029 #include <qpointer.h>
00030 #include <qstyle.h>
00031 #include <qstyleoption.h>
00032 #include <qstylepainter.h>
00033 #include <qtimer.h>
00034 #include <qtooltip.h>
00035 #include <private/qeffects_p.h>
00036 #include <qtextdocument.h>
00037
00038 #ifndef QT_NO_TOOLTIP
00039
00080 class QTipLabel : public QLabel
00081 {
00082 Q_OBJECT
00083 public:
00084 QTipLabel(const QString& text, QWidget* parent);
00085 ~QTipLabel();
00086 static QTipLabel *instance;
00087
00088 bool eventFilter(QObject *, QEvent *);
00089
00090 QBasicTimer hideTimer, deleteTimer;
00091
00092 void hideTip();
00093 void setTipRect(QWidget *w, const QRect &r);
00094 protected:
00095 void enterEvent(QEvent*){hideTip();}
00096 void timerEvent(QTimerEvent *e);
00097 void paintEvent(QPaintEvent *e);
00098
00099 private:
00100 QWidget *widget;
00101 QRect rect;
00102 };
00103
00104 QTipLabel *QTipLabel::instance = 0;
00105
00106 QTipLabel::QTipLabel(const QString& text, QWidget* parent)
00107 : QLabel(parent, Qt::ToolTip), widget(0)
00108 {
00109 delete instance;
00110 instance = this;
00111 ensurePolished();
00112 setMargin(1 + style()->pixelMetric(QStyle::PM_ToolTipLabelFrameWidth, 0, this));
00113 setFrameStyle(QFrame::NoFrame);
00114 setAlignment(Qt::AlignLeft);
00115 setIndent(1);
00116 setWordWrap(Qt::mightBeRichText(text));
00117 setText(text);
00118
00119 QFontMetrics fm(font());
00120 QSize extra(1, 0);
00121
00122 if (fm.descent() == 2 && fm.ascent() >= 11)
00123 ++extra.rheight();
00124
00125 resize(sizeHint() + extra);
00126 qApp->installEventFilter(this);
00127
00128 int time = 10000 + 40 * qMax(0, text.length()-100);
00129 hideTimer.start(time, this);
00130 setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / 255.0);
00131 setPalette(QToolTip::palette());
00132 }
00133
00134 void QTipLabel::paintEvent(QPaintEvent *ev)
00135 {
00136 QStylePainter p(this);
00137 QStyleOptionFrame opt;
00138 opt.init(this);
00139 p.drawPrimitive(QStyle::PE_PanelTipLabel, opt);
00140 p.end();
00141
00142 QLabel::paintEvent(ev);
00143 }
00144
00145 QTipLabel::~QTipLabel()
00146 {
00147 instance = 0;
00148 }
00149
00150 void QTipLabel::hideTip()
00151 {
00152 hide();
00153
00154 deleteTimer.start(250, this);
00155 }
00156
00157 void QTipLabel::setTipRect(QWidget *w, const QRect &r)
00158 {
00159 if (w) {
00160 widget = w;
00161 rect = r;
00162 }
00163 }
00164
00165 void QTipLabel::timerEvent(QTimerEvent *e)
00166 {
00167 if (e->timerId() == hideTimer.timerId())
00168 hideTip();
00169 else if (e->timerId() == deleteTimer.timerId())
00170 delete this;
00171 }
00172
00173 bool QTipLabel::eventFilter(QObject *o, QEvent *e)
00174 {
00175 switch (e->type()) {
00176 case QEvent::KeyPress:
00177 case QEvent::KeyRelease: {
00178 int key = static_cast<QKeyEvent *>(e)->key();
00179 Qt::KeyboardModifiers mody = static_cast<QKeyEvent *>(e)->modifiers();
00180
00181 if ((mody & Qt::KeyboardModifierMask)
00182 || (key == Qt::Key_Shift || key == Qt::Key_Control
00183 || key == Qt::Key_Alt || key == Qt::Key_Meta))
00184 break;
00185 }
00186 case QEvent::Leave:
00187 case QEvent::WindowActivate:
00188 case QEvent::WindowDeactivate:
00189 case QEvent::MouseButtonPress:
00190 case QEvent::MouseButtonRelease:
00191 case QEvent::MouseButtonDblClick:
00192 case QEvent::FocusIn:
00193 case QEvent::FocusOut:
00194 case QEvent::Wheel:
00195 hideTip();
00196 break;
00197
00198 case QEvent::MouseMove:
00199 if (o == widget && !rect.isNull() && !rect.contains(static_cast<QMouseEvent*>(e)->pos()))
00200 hideTip();
00201 default:
00202 break;
00203 }
00204 return false;
00205 }
00206
00223 void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect)
00224 {
00225 if (QTipLabel::instance && QTipLabel::instance->text() == text)
00226 return;
00227
00228
00229
00230
00231
00232
00233 if (text.isEmpty()) {
00234 if (QTipLabel::instance)
00235 QTipLabel::instance->hideTip();
00236 return;
00237 }
00238
00239 #ifndef QT_NO_EFFECTS
00240 bool preventAnimation = (QTipLabel::instance != 0);
00241 #endif
00242 int scr;
00243 if (QApplication::desktop()->isVirtualDesktop())
00244 scr = QApplication::desktop()->screenNumber(pos);
00245 else
00246 scr = QApplication::desktop()->screenNumber(w);
00247
00248 #ifdef Q_WS_MAC
00249 QRect screen = QApplication::desktop()->availableGeometry(scr);
00250 #else
00251 QRect screen = QApplication::desktop()->screenGeometry(scr);
00252 #endif
00253
00254 QTipLabel *label = new QTipLabel(text, QApplication::desktop()->screen(scr));
00255 if (!rect.isNull() && !w) {
00256 qWarning("QToolTip::showText: Cannot pass null widget if rect is set");
00257 } else {
00258 label->setTipRect(w, rect);
00259 }
00260
00261 label->setObjectName(QLatin1String("qtooltip_label"));
00262
00263 QPoint p = pos;
00264 p += QPoint(2,
00265 #ifdef Q_WS_WIN
00266 24
00267 #else
00268 16
00269 #endif
00270 );
00271 if (p.x() + label->width() > screen.x() + screen.width())
00272 p.rx() -= 4 + label->width();
00273 if (p.y() + label->height() > screen.y() + screen.height())
00274 p.ry() -= 24 + label->height();
00275 if (p.y() < screen.y())
00276 p.setY(screen.y());
00277 if (p.x() + label->width() > screen.x() + screen.width())
00278 p.setX(screen.x() + screen.width() - label->width());
00279 if (p.x() < screen.x())
00280 p.setX(screen.x());
00281 if (p.y() + label->height() > screen.y() + screen.height())
00282 p.setY(screen.y() + screen.height() - label->height());
00283 label->move(p);
00284
00285 #ifndef QT_NO_EFFECTS
00286 if ( QApplication::isEffectEnabled(Qt::UI_AnimateTooltip) == false || preventAnimation)
00287 label->show();
00288 else if (QApplication::isEffectEnabled(Qt::UI_FadeTooltip)) {
00289 qFadeEffect(label);
00290 }
00291 else
00292 qScrollEffect(label);
00293 #else
00294 label->show();
00295 #endif
00296
00297 }
00298
00305 void QToolTip::showText(const QPoint &pos, const QString &text, QWidget *w)
00306 {
00307 QToolTip::showText(pos, text, w, QRect());
00308 }
00309
00310
00322 Q_GLOBAL_STATIC_WITH_ARGS(QPalette, tooltip_palette, (Qt::black, QColor(255,255,220),
00323 QColor(96,96,96), Qt::black, Qt::black,
00324 Qt::black, QColor(255,255,220)))
00325
00326
00329 QPalette QToolTip::palette()
00330 {
00331 return *tooltip_palette();
00332 }
00333
00339 QFont QToolTip::font()
00340 {
00341 return QApplication::font("QTipLabel");
00342 }
00343
00349 void QToolTip::setPalette(const QPalette &palette)
00350 {
00351 *tooltip_palette() = palette;
00352 }
00353
00359 void QToolTip::setFont(const QFont &font)
00360 {
00361 QApplication::setFont(font, "QTipLabel");
00362 }
00363
00364
00398 #include "qtooltip.moc"
00399 #endif // QT_NO_TOOLTIP