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 "qsystemtrayicon.h"
00025 #include "qsystemtrayicon_p.h"
00026
00027 #ifndef QT_NO_SYSTEMTRAYICON
00028
00029 #include "qmenu.h"
00030 #include "qevent.h"
00031 #include "qpoint.h"
00032 #include "qlabel.h"
00033 #include "qpushbutton.h"
00034 #include "qpainterpath.h"
00035 #include "qpainter.h"
00036 #include "qstyle.h"
00037 #include "qgridlayout.h"
00038 #include "qapplication.h"
00039 #include "qdesktopwidget.h"
00040 #include "qbitmap.h"
00041
00104 QSystemTrayIcon::QSystemTrayIcon(QObject *parent)
00105 : QObject(*new QSystemTrayIconPrivate(), parent)
00106 {
00107 }
00108
00116 QSystemTrayIcon::QSystemTrayIcon(const QIcon &icon, QObject *parent)
00117 : QObject(*new QSystemTrayIconPrivate(), parent)
00118 {
00119 setIcon(icon);
00120 }
00121
00125 QSystemTrayIcon::~QSystemTrayIcon()
00126 {
00127 Q_D(QSystemTrayIcon);
00128 d->remove_sys();
00129 }
00130
00131 #ifndef QT_NO_MENU
00132
00142 void QSystemTrayIcon::setContextMenu(QMenu *menu)
00143 {
00144 Q_D(QSystemTrayIcon);
00145 d->menu = menu;
00146 d->updateMenu_sys();
00147 }
00148
00152 QMenu* QSystemTrayIcon::contextMenu() const
00153 {
00154 Q_D(const QSystemTrayIcon);
00155 return d->menu;
00156 }
00157
00158 #endif // QT_NO_MENU
00159
00171 void QSystemTrayIcon::setIcon(const QIcon &icon)
00172 {
00173 Q_D(QSystemTrayIcon);
00174 d->icon = icon;
00175 d->updateIcon_sys();
00176 }
00177
00178 QIcon QSystemTrayIcon::icon() const
00179 {
00180 Q_D(const QSystemTrayIcon);
00181 return d->icon;
00182 }
00183
00191 void QSystemTrayIcon::setToolTip(const QString &tooltip)
00192 {
00193 Q_D(QSystemTrayIcon);
00194 d->toolTip = tooltip;
00195 d->updateToolTip_sys();
00196 }
00197
00198 QString QSystemTrayIcon::toolTip() const
00199 {
00200 Q_D(const QSystemTrayIcon);
00201 return d->toolTip;
00202 }
00203
00220 #if 0
00221
00226 QPoint QSystemTrayIcon::pos() const
00227 {
00228 Q_D(const QSystemTrayIcon);
00229 if (!d->visible)
00230 return QPoint();
00231 return d->globalPos_sys();
00232 }
00233 #endif
00234
00242 void QSystemTrayIcon::setVisible(bool visible)
00243 {
00244 Q_D(QSystemTrayIcon);
00245 if (visible == d->visible)
00246 return;
00247 if (d->icon.isNull() && visible)
00248 qWarning("QSystemTrayIcon::setVisible: No Icon set");
00249 d->visible = visible;
00250 if (d->visible)
00251 d->install_sys();
00252 else
00253 d->remove_sys();
00254 }
00255
00256 bool QSystemTrayIcon::isVisible() const
00257 {
00258 Q_D(const QSystemTrayIcon);
00259 return d->visible;
00260 }
00261
00265 bool QSystemTrayIcon::event(QEvent *e)
00266 {
00267 #if defined(Q_WS_X11)
00268 if (e->type() == QEvent::ToolTip) {
00269 Q_D(QSystemTrayIcon);
00270 return d->sys->deliverToolTipEvent(e);
00271 }
00272 #endif
00273 return QObject::event(e);
00274 }
00275
00318 bool QSystemTrayIcon::isSystemTrayAvailable()
00319 {
00320 return QSystemTrayIconPrivate::isSystemTrayAvailable_sys();
00321 }
00322
00330 bool QSystemTrayIcon::supportsMessages()
00331 {
00332 #if defined(Q_WS_MAC) || defined(Q_WS_QWS)
00333 return false;
00334 #endif
00335 return true;
00336 }
00337
00353 void QSystemTrayIcon::showMessage(const QString& title, const QString& msg,
00354 QSystemTrayIcon::MessageIcon icon, int msecs)
00355 {
00356 Q_D(QSystemTrayIcon);
00357 if (d->visible)
00358 d->showMessage_sys(title, msg, icon, msecs);
00359 }
00360
00362 static QBalloonTip *theSolitaryBalloonTip = 0;
00363
00364 void QBalloonTip::showBalloon(QSystemTrayIcon::MessageIcon icon, const QString& title,
00365 const QString& message, QSystemTrayIcon *trayIcon,
00366 const QPoint& pos, int timeout, bool showArrow)
00367 {
00368 hideBalloon();
00369 theSolitaryBalloonTip = new QBalloonTip(icon, title, message, trayIcon);
00370 if (timeout < 0)
00371 timeout = 10000;
00372 theSolitaryBalloonTip->balloon(pos, timeout, showArrow);
00373 }
00374
00375 void QBalloonTip::hideBalloon()
00376 {
00377 if (!theSolitaryBalloonTip)
00378 return;
00379 theSolitaryBalloonTip->hide();
00380 delete theSolitaryBalloonTip;
00381 theSolitaryBalloonTip = 0;
00382 }
00383
00384 QBalloonTip::QBalloonTip(QSystemTrayIcon::MessageIcon icon, const QString& title,
00385 const QString& message, QSystemTrayIcon *ti)
00386 : QWidget(0, Qt::ToolTip), trayIcon(ti), timerId(-1)
00387 {
00388 setAttribute(Qt::WA_DeleteOnClose);
00389 QObject::connect(ti, SIGNAL(destroyed()), this, SLOT(close()));
00390
00391 QLabel *titleLabel = new QLabel;
00392 titleLabel->installEventFilter(this);
00393 titleLabel->setText(title);
00394 QFont f = titleLabel->font();
00395 f.setBold(true);
00396 titleLabel->setFont(f);
00397 titleLabel->setTextFormat(Qt::PlainText);
00398
00399 QPushButton *closeButton = new QPushButton;
00400 closeButton->setIcon(style()->standardIcon(QStyle::SP_DockWidgetCloseButton));
00401 closeButton->setIconSize(QSize(18, 18));
00402 closeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00403 closeButton->setFixedSize(18, 18);
00404 QObject::connect(closeButton, SIGNAL(clicked()), this, SLOT(close()));
00405
00406 QLabel *msgLabel = new QLabel;
00407 msgLabel->installEventFilter(this);
00408 msgLabel->setText(message);
00409 msgLabel->setTextFormat(Qt::PlainText);
00410 msgLabel->setAlignment(Qt::AlignTop | Qt::AlignLeft);
00411
00412 QIcon si;
00413 switch (icon) {
00414 case QSystemTrayIcon::Warning:
00415 si = style()->standardIcon(QStyle::SP_MessageBoxWarning);
00416 break;
00417 case QSystemTrayIcon::Critical:
00418 si = style()->standardIcon(QStyle::SP_MessageBoxCritical);
00419 break;
00420 case QSystemTrayIcon::Information:
00421 si = style()->standardIcon(QStyle::SP_MessageBoxInformation);
00422 break;
00423 case QSystemTrayIcon::NoIcon:
00424 default:
00425 break;
00426 }
00427
00428 QGridLayout *layout = new QGridLayout;
00429 if (!si.isNull()) {
00430 QLabel *iconLabel = new QLabel;
00431 iconLabel->setPixmap(si.pixmap(15, 15));
00432 iconLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
00433 iconLabel->setMargin(2);
00434 layout->addWidget(iconLabel, 0, 0);
00435 layout->addWidget(titleLabel, 0, 1);
00436 } else {
00437 layout->addWidget(titleLabel, 0, 0, 1, 2);
00438 }
00439
00440 layout->addWidget(closeButton, 0, 2);
00441 layout->addWidget(msgLabel, 1, 0, 1, 3);
00442 layout->setSizeConstraint(QLayout::SetFixedSize);
00443 layout->setMargin(3);
00444 layout->setSpacing(1);
00445 setLayout(layout);
00446
00447 QPalette pal = palette();
00448 pal.setColor(QPalette::Window, QColor(0xff, 0xff, 0xe1));
00449 setPalette(pal);
00450 }
00451
00452 QBalloonTip::~QBalloonTip()
00453 {
00454 theSolitaryBalloonTip = 0;
00455 }
00456
00457 void QBalloonTip::paintEvent(QPaintEvent *)
00458 {
00459 QPainter painter(this);
00460 painter.drawPixmap(rect(), pixmap);
00461 }
00462
00463 void QBalloonTip::resizeEvent(QResizeEvent *ev)
00464 {
00465 QWidget::resizeEvent(ev);
00466 }
00467
00468 void QBalloonTip::balloon(const QPoint& pos, int msecs, bool showArrow)
00469 {
00470 QRect scr = QApplication::desktop()->screenGeometry(pos);
00471 QSize sh = sizeHint();
00472 const int border = 1;
00473 const int ah = 18, ao = 18, aw = 18, rc = 7;
00474 bool arrowAtTop = (pos.y() + sh.height() + ah < scr.height());
00475 bool arrowAtLeft = (pos.x() + sh.width() - ao < scr.width());
00476 setContentsMargins(border + 3, border + (arrowAtTop ? ah : 0) + 2, border + 3, border + (arrowAtTop ? 0 : ah) + 2);
00477 updateGeometry();
00478 sh = sizeHint();
00479
00480 int ml, mr, mt, mb;
00481 QSize sz = sizeHint();
00482 if (!arrowAtTop) {
00483 ml = mt = 0;
00484 mr = sz.width() - 1;
00485 mb = sz.height() - ah - 1;
00486 } else {
00487 ml = 0;
00488 mt = ah;
00489 mr = sz.width() - 1;
00490 mb = sz.height() - 1;
00491 }
00492
00493 QPainterPath path;
00494 path.moveTo(ml + rc, mt);
00495 if (arrowAtTop && arrowAtLeft) {
00496 if (showArrow) {
00497 path.lineTo(ml + ao, mt);
00498 path.lineTo(ml + ao, mt - ah);
00499 path.lineTo(ml + ao + aw, mt);
00500 }
00501 move(qMax(pos.x() - ao, scr.left() + 2), pos.y());
00502 } else if (arrowAtTop && !arrowAtLeft) {
00503 if (showArrow) {
00504 path.lineTo(mr - ao - aw, mt);
00505 path.lineTo(mr - ao, mt - ah);
00506 path.lineTo(mr - ao, mt);
00507 }
00508 move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2), pos.y());
00509 }
00510 path.lineTo(mr - rc, mt);
00511 path.arcTo(QRect(mr - rc*2, mt, rc*2, rc*2), 90, -90);
00512 path.lineTo(mr, mb - rc);
00513 path.arcTo(QRect(mr - rc*2, mb - rc*2, rc*2, rc*2), 0, -90);
00514 if (!arrowAtTop && !arrowAtLeft) {
00515 if (showArrow) {
00516 path.lineTo(mr - ao, mb);
00517 path.lineTo(mr - ao, mb + ah);
00518 path.lineTo(mr - ao - aw, mb);
00519 }
00520 move(qMin(pos.x() - sh.width() + ao, scr.right() - sh.width() - 2),
00521 pos.y() - sh.height());
00522 } else if (!arrowAtTop && arrowAtLeft) {
00523 if (showArrow) {
00524 path.lineTo(ao + aw, mb);
00525 path.lineTo(ao, mb + ah);
00526 path.lineTo(ao, mb);
00527 }
00528 move(qMax(pos.x() - ao, scr.x() + 2), pos.y() - sh.height());
00529 }
00530 path.lineTo(ml + rc, mb);
00531 path.arcTo(QRect(ml, mb - rc*2, rc*2, rc*2), -90, -90);
00532 path.lineTo(ml, mt + rc);
00533 path.arcTo(QRect(ml, mt, rc*2, rc*2), 180, -90);
00534
00535
00536 QBitmap bitmap = QBitmap(sizeHint());
00537 bitmap.fill(Qt::color0);
00538 QPainter painter1(&bitmap);
00539 painter1.setPen(QPen(Qt::color1, border));
00540 painter1.setBrush(QBrush(Qt::color1));
00541 painter1.drawPath(path);
00542 setMask(bitmap);
00543
00544
00545 pixmap = QPixmap(sz);
00546 QPainter painter2(&pixmap);
00547 painter2.setPen(QPen(Qt::black, border));
00548 painter2.setBrush(palette().color(QPalette::Window));
00549 painter2.drawPath(path);
00550
00551 if (msecs > 0)
00552 timerId = startTimer(msecs);
00553 show();
00554 }
00555
00556 void QBalloonTip::mousePressEvent(QMouseEvent *e)
00557 {
00558 close();
00559 if(e->button() == Qt::LeftButton)
00560 emit trayIcon->messageClicked();
00561 }
00562
00563 void QBalloonTip::timerEvent(QTimerEvent *e)
00564 {
00565 if (e->timerId() == timerId) {
00566 killTimer(timerId);
00567 if (!underMouse())
00568 close();
00569 return;
00570 }
00571 QWidget::timerEvent(e);
00572 }
00573
00574 void qtsystray_sendActivated(QSystemTrayIcon *i, int r)
00575 {
00576 emit i->activated((QSystemTrayIcon::ActivationReason)r);
00577 }
00578
00579 #endif // QT_NO_SYSTEMTRAYICON