From: Manuel Nickschas Date: Sat, 14 Feb 2009 21:38:32 +0000 (+0100) Subject: Introduce SystemTray class to handle the systray icon sanely X-Git-Tag: 0.4.0~49 X-Git-Url: https://git.quassel-irc.org/?p=quassel.git;a=commitdiff_plain;h=5a470c1acab34c95d957bf81dce7e7cd330a2c58;hp=03015d11b4b8f66f2c55797a82000d45149c355a Introduce SystemTray class to handle the systray icon sanely This provides a sane API to set the state of the icon without having to bother with icon files (this is all handled internally now). State progressions are now animated thanks to Nuno's animation phases, and we have a nice glow effect on highlight too! --- diff --git a/src/qtui/CMakeLists.txt b/src/qtui/CMakeLists.txt index 492c50ad..de9db43d 100644 --- a/src/qtui/CMakeLists.txt +++ b/src/qtui/CMakeLists.txt @@ -43,6 +43,7 @@ set(SOURCES sessionsettings.cpp settingsdlg.cpp settingspagedlg.cpp + systemtray.cpp systraynotificationbackend.cpp taskbarnotificationbackend.cpp titlesetter.cpp @@ -83,6 +84,7 @@ set(MOC_HDRS qtuimessageprocessor.h settingsdlg.h settingspagedlg.h + systemtray.h systraynotificationbackend.h taskbarnotificationbackend.h titlesetter.h diff --git a/src/qtui/systemtray.cpp b/src/qtui/systemtray.cpp new file mode 100644 index 00000000..acb68b19 --- /dev/null +++ b/src/qtui/systemtray.cpp @@ -0,0 +1,155 @@ +/*************************************************************************** +* Copyright (C) 2005-09 by the Quassel Project * +* devel@quassel-irc.org * +* * +* This program 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 2 of the License, or * +* (at your option) version 3. * +* * +* This program 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 this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ + +#include + +#include "systemtray.h" + +#include "actioncollection.h" +#include "iconloader.h" +#include "qtui.h" +#include "qtuisettings.h" + +SystemTray::SystemTray(QObject *parent) +: QObject(parent), + _state(Inactive), + _alert(false), + _currentIdx(0) +{ + loadAnimations(); + _currentIdx = _idxOffEnd; + _trayIcon = new QSystemTrayIcon(_phases.at(_currentIdx), this); + + _animationTimer.setInterval(150); + _animationTimer.setSingleShot(false); + connect(&_animationTimer, SIGNAL(timeout()), SLOT(nextPhase())); + + ActionCollection *coll = QtUi::actionCollection("General"); + _trayMenu = new QMenu(); + _trayMenu->addAction(coll->action("ConnectCore")); + _trayMenu->addAction(coll->action("DisconnectCore")); + _trayMenu->addAction(coll->action("CoreInfo")); + _trayMenu->addSeparator(); + _trayMenu->addAction(coll->action("Quit")); + + _trayIcon->setContextMenu(_trayMenu); + + QtUiSettings s; + if(s.value("UseSystemTrayIcon", QVariant(true)).toBool()) { + _trayIcon->show(); + } + + connect(_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), SIGNAL(activated(QSystemTrayIcon::ActivationReason))); + connect(_trayIcon, SIGNAL(messageClicked()), SIGNAL(messageClicked())); +} + +SystemTray::~SystemTray() { + _trayMenu->deleteLater(); +} + +void SystemTray::loadAnimations() { +// system tray icon size +#ifdef Q_WS_WIN + const int size = 16; +#elif defined Q_WS_MAC + const int size = 128; +#else + const int size = 22; +#endif + + _phases.clear(); + +#ifdef HAVE_KDE + KIconLoader *loader = KIconLoader::global(); +#else + IconLoader *loader = IconLoader::global(); +#endif + + _idxOffStart = 0; + QString fadeOffName("quassel_tray-fade-off-%1"); + for(int i = 2; i <= 10; i++) + _phases.append(loader->loadIcon(fadeOffName.arg(i), IconLoader::Panel, size)); + _idxOffEnd = _idxOnStart = _phases.count() - 1; + + QString fadeOnName("quassel_tray-fade-on-%1"); + for(int i = 2; i <= 15; i++) + _phases.append(loader->loadIcon(fadeOnName.arg(i), IconLoader::Panel, size)); + _idxOnEnd = _idxAlertStart = _phases.count() - 1; + + QString alertName("quassel_tray-alert-%1"); + for(int i = 1; i <= 10; i++) + _phases.append(loader->loadIcon(alertName.arg(i), IconLoader::Panel, size)); +} + +void SystemTray::nextPhase() { + if(_currentIdx == _idxOnEnd && !_alert && _state == Inactive) + _currentIdx = _idxOffStart; // skip alert phases + + else if(++_currentIdx >= _phases.count()) { + if(_alert) + _currentIdx = _idxAlertStart; + else + if(_state == Active) + _currentIdx = _idxOnEnd; + else + _currentIdx = _idxOffStart; + } + + _trayIcon->setIcon(_phases.at(_currentIdx)); + + if(_alert) + return; + + if((_state == Active && _currentIdx == _idxOnEnd) || (_state == Inactive && _currentIdx == _idxOffEnd)) + _animationTimer.stop(); +} + +void SystemTray::setState(State state) { + if(_state != state) { + _state = state; + if(state == Inactive && _alert) + _alert = false; + if(!_animationTimer.isActive()) + _animationTimer.start(); + } +} + +void SystemTray::setAlert(bool alert) { + if(_alert != alert) { + _alert = alert; + if(!_animationTimer.isActive()) + _animationTimer.start(); + } +} + +void SystemTray::setIconVisible(bool visible) { + if(visible) + _trayIcon->show(); + else + _trayIcon->hide(); +} + +void SystemTray::setToolTip(const QString &tip) { + _trayIcon->setToolTip(tip); +} + +void SystemTray::showMessage(const QString &title, const QString &message, QSystemTrayIcon::MessageIcon icon, int millisecondsTimeoutHint) { + _trayIcon->showMessage(title, message, icon, millisecondsTimeoutHint); +} diff --git a/src/qtui/systemtray.h b/src/qtui/systemtray.h new file mode 100644 index 00000000..1e811cd8 --- /dev/null +++ b/src/qtui/systemtray.h @@ -0,0 +1,81 @@ +/*************************************************************************** +* Copyright (C) 2005-09 by the Quassel Project * +* devel@quassel-irc.org * +* * +* This program 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 2 of the License, or * +* (at your option) version 3. * +* * +* This program 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 this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ + +#ifndef SYSTEMTRAY_H_ +#define SYSTEMTRAY_H_ + +#include +#include + +#include "icon.h" + +class SystemTray : public QObject { + Q_OBJECT + +public: + enum State { + Inactive, + Active + }; + + SystemTray(QObject *parent = 0); + ~SystemTray(); + + inline bool isSystemTrayAvailable() const; + Icon icon() const; + QString toolTip() const; + +public slots: + void setState(State); + void setAlert(bool alert = true); + void setIconVisible(bool visible = true); + void setToolTip(const QString &tip); + void showMessage(const QString &title, const QString &message, + QSystemTrayIcon::MessageIcon icon = QSystemTrayIcon::Information, int millisecondsTimeoutHint = 10000); + + +signals: + void activated(QSystemTrayIcon::ActivationReason); + void iconChanged(const Icon &); + void messageClicked(); + +private slots: + void nextPhase(); + +private: + void loadAnimations(); + + QSystemTrayIcon *_trayIcon; + QMenu *_trayMenu; + State _state; + bool _alert; + + int _idxOffStart, _idxOffEnd, _idxOnStart, _idxOnEnd, _idxAlertStart; + int _currentIdx; + QTimer _animationTimer; + + QList _phases; +}; + +// inlines + +bool SystemTray::isSystemTrayAvailable() const { return QSystemTrayIcon::isSystemTrayAvailable(); } + +#endif