};
NotificationSettings();
-
+
+ inline void setValue(const QString &key, const QVariant &data) { setLocalValue(key, data); }
+ inline QVariant value(const QString &key, const QVariant &def = QVariant()) { return localValue(key, def); }
+ inline void remove(const QString &key) { removeLocalKey(key); }
+
void setHighlightList(const QVariantList &highlightList);
QVariantList highlightList();
sessionsettings.cpp
settingsdlg.cpp
settingspagedlg.cpp
+ systraynotificationbackend.cpp
titlesetter.cpp
topiclabel.cpp
topicwidget.cpp
qtuimessageprocessor.h
settingsdlg.h
settingspagedlg.h
+ systraynotificationbackend.h
titlesetter.h
topiclabel.h
topicwidget.h
msgProcessorStatusWidget(new MsgProcessorStatusWidget()),
_titleSetter(this),
- systray(new QSystemTrayIcon(this)),
+ _trayIcon(new QSystemTrayIcon(this)),
activeTrayIcon(DesktopIcon("quassel_newmessage", IconLoader::SizeEnormous)),
onlineTrayIcon(DesktopIcon("quassel", IconLoader::SizeEnormous)),
setWindowTitle("Quassel IRC");
setWindowIcon(offlineTrayIcon);
qApp->setWindowIcon(offlineTrayIcon);
- systray->setIcon(offlineTrayIcon);
+ systemTrayIcon()->setIcon(offlineTrayIcon);
setWindowIconText("Quassel IRC");
QtUi::actionCollection()->addAssociatedWidget(this);
systrayMenu->addSeparator();
systrayMenu->addAction(ui.actionQuit);
- systray->setContextMenu(systrayMenu);
+ systemTrayIcon()->setContextMenu(systrayMenu);
UiSettings s;
if(s.value("UseSystemTrayIcon", QVariant(true)).toBool()) {
- systray->show();
+ systemTrayIcon()->show();
}
#ifndef Q_WS_MAC
- connect(systray, SIGNAL(activated( QSystemTrayIcon::ActivationReason )),
+ connect(systemTrayIcon(), SIGNAL(activated( QSystemTrayIcon::ActivationReason )),
this, SLOT(systrayActivated( QSystemTrayIcon::ActivationReason )));
#endif
statusBar()->showMessage(tr("Connected to core."));
setWindowIcon(onlineTrayIcon);
qApp->setWindowIcon(onlineTrayIcon);
- systray->setIcon(onlineTrayIcon);
+ systemTrayIcon()->setIcon(onlineTrayIcon);
if(sslLabel->width() == 0)
sslLabel->setPixmap(SmallIcon("security-low"));
}
statusBar()->showMessage(tr("Not connected to core."));
setWindowIcon(offlineTrayIcon);
qApp->setWindowIcon(offlineTrayIcon);
- systray->setIcon(offlineTrayIcon);
+ systemTrayIcon()->setIcon(offlineTrayIcon);
sslLabel->setPixmap(QPixmap());
}
// setFocus(); //Qt::ActiveWindowFocusReason
} else {
- if(systray->isSystemTrayAvailable ()) {
+ if(systemTrayIcon()->isSystemTrayAvailable ()) {
clearFocus();
hide();
- if(!systray->isVisible()) {
- systray->show();
+ if(!systemTrayIcon()->isVisible()) {
+ systemTrayIcon()->show();
}
} else {
lower();
#endif /* HAVE_DBUS */
void MainWin::displayTrayIconMessage(const QString &title, const QString &message) {
- systray->showMessage(title, message);
+ systemTrayIcon()->showMessage(title, message);
}
void MainWin::setTrayIconActivity(bool active) {
timer->start(500);
} else {
timer->stop();
- systray->setIcon(onlineTrayIcon);
+ systemTrayIcon()->setIcon(onlineTrayIcon);
}
}
void MainWin::makeTrayIconBlink() {
if(trayIconActive) {
- systray->setIcon(onlineTrayIcon);
+ systemTrayIcon()->setIcon(onlineTrayIcon);
trayIconActive = false;
} else {
- systray->setIcon(activeTrayIcon);
+ systemTrayIcon()->setIcon(activeTrayIcon);
trayIconActive = true;
}
}
class MsgProcessorStatusWidget;
class Message;
class NickListWidget;
+class SystemTrayIcon;
#ifdef HAVE_DBUS
# include "desktopnotifications.h"
void addBufferView(BufferViewConfig *config = 0);
void displayTrayIconMessage(const QString &title, const QString &message);
+ inline QSystemTrayIcon *systemTrayIcon() const;
#ifdef HAVE_DBUS
void sendDesktopNotification(const QString &title, const QString &message);
void securedConnection();
void disconnectedFromCore();
void setDisconnectedState();
- void systrayActivated( QSystemTrayIcon::ActivationReason );
+ void systrayActivated(QSystemTrayIcon::ActivationReason);
private slots:
void addBufferView(int bufferViewConfigId);
void toggleVisibility();
void enableMenus();
- QSystemTrayIcon *systray;
+ QSystemTrayIcon *_trayIcon;
QPixmap activeTrayIcon;
QPixmap onlineTrayIcon;
QPixmap offlineTrayIcon;
friend class QtUi;
};
+QSystemTrayIcon *MainWin::systemTrayIcon() const {
+ return _trayIcon;
+}
+
#endif
#include "util.h"
ActionCollection *QtUi::_actionCollection = 0;
+MainWin *QtUi::_mainWin = 0;
QSet<AbstractNotificationBackend *> QtUi::_notificationBackends;
+QList<AbstractNotificationBackend::Notification> QtUi::_notifications;
QtUiStyle *QtUi::_style = 0;
QtUi::QtUi() : AbstractUi() {
UiSettings uiSettings;
loadTranslation(uiSettings.value("Locale", QLocale::system()).value<QLocale>());
- mainWin = new MainWin();
+ _mainWin = new MainWin();
_style = new QtUiStyle;
- connect(mainWin, SIGNAL(connectToCore(const QVariantMap &)), this, SIGNAL(connectToCore(const QVariantMap &)));
- connect(mainWin, SIGNAL(disconnectFromCore()), this, SIGNAL(disconnectFromCore()));
+ connect(_mainWin, SIGNAL(connectToCore(const QVariantMap &)), this, SIGNAL(connectToCore(const QVariantMap &)));
+ connect(_mainWin, SIGNAL(disconnectFromCore()), this, SIGNAL(disconnectFromCore()));
}
QtUi::~QtUi() {
unregisterAllNotificationBackends();
delete _style;
- delete mainWin;
+ delete _mainWin;
}
void QtUi::init() {
- mainWin->init();
+ _mainWin->init();
}
MessageModel *QtUi::createMessageModel(QObject *parent) {
}
void QtUi::connectedToCore() {
- mainWin->connectedToCore();
+ _mainWin->connectedToCore();
}
void QtUi::disconnectedFromCore() {
- mainWin->disconnectedFromCore();
+ _mainWin->disconnectedFromCore();
}
void QtUi::registerNotificationBackend(AbstractNotificationBackend *backend) {
_notificationBackends.clear();
}
-void QtUi::notify(BufferId id, const QString &sender, const QString &text) {
+const QSet<AbstractNotificationBackend *> &QtUi::notificationBackends() {
+ return _notificationBackends;
+}
+
+uint QtUi::invokeNotification(BufferId bufId, const QString &sender, const QString &text) {
+ static int notificationId = 0;
+ //notificationId++;
+ AbstractNotificationBackend::Notification notification(++notificationId, bufId, sender, text);
+ _notifications.append(notification);
foreach(AbstractNotificationBackend *backend, _notificationBackends)
- backend->notify(id, sender, text);
+ backend->notify(notification);
+ return notificationId;
+}
+
+void QtUi::closeNotification(uint notificationId) {
+ QList<AbstractNotificationBackend::Notification>::iterator i = _notifications.begin();
+ while(i != _notifications.end()) {
+ if((*i).notificationId == notificationId) {
+ foreach(AbstractNotificationBackend *backend, _notificationBackends)
+ backend->close(notificationId);
+ _notifications.erase(i);
+ break;
+ }
+ ++i;
+ }
}
+
+void QtUi::closeNotifications(BufferId bufferId) {
+ QList<AbstractNotificationBackend::Notification>::iterator i = _notifications.begin();
+ while(i != _notifications.end()) {
+ if((*i).bufferId == bufferId) {
+ foreach(AbstractNotificationBackend *backend, _notificationBackends)
+ backend->close((*i).notificationId);
+ _notifications.erase(i);
+ }
+ ++i;
+ }
+}
+
+const QList<AbstractNotificationBackend::Notification> &QtUi::activeNotifications() {
+ return _notifications;
+}
+
#include "quasselui.h"
-class AbstractNotificationBackend;
+#include "abstractnotificationbackend.h"
+
class ActionCollection;
class MainWin;
class MessageModel;
AbstractMessageProcessor *createMessageProcessor(QObject *parent);
inline static QtUiStyle *style();
+ inline static MainWin *mainWindow();
//! Access the global ActionCollection.
/** This ActionCollection is associated with the main window, i.e. it contains global
*/
inline static ActionCollection *actionCollection();
+ /* Notifications */
+
static void registerNotificationBackend(AbstractNotificationBackend *);
static void unregisterNotificationBackend(AbstractNotificationBackend *);
static void unregisterAllNotificationBackends();
- static void notify(BufferId bufId, const QString &sender, const QString &text);
+ static const QSet<AbstractNotificationBackend *> ¬ificationBackends();
+ static uint invokeNotification(BufferId bufId, const QString &sender, const QString &text);
+ static void closeNotification(uint notificationId);
+ static void closeNotifications(BufferId bufferId);
+ static const QList<AbstractNotificationBackend::Notification> &activeNotifications();
public slots:
void init();
void disconnectedFromCore();
private:
- MainWin *mainWin;
+ static MainWin *_mainWin;
static ActionCollection *_actionCollection;
static QtUiStyle *_style;
static QSet<AbstractNotificationBackend *> _notificationBackends;
+ static QList<AbstractNotificationBackend::Notification> _notifications;
};
ActionCollection *QtUi::actionCollection() { return _actionCollection; }
QtUiStyle *QtUi::style() { return _style; }
+MainWin *QtUi::mainWindow() { return _mainWin; }
#endif
--- /dev/null
+/***************************************************************************
+* Copyright (C) 2005-08 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 "systraynotificationbackend.h"
+
+#include <QtGui>
+
+#include "client.h"
+#include "clientsettings.h"
+#include "icon.h"
+#include "mainwin.h"
+#include "networkmodel.h"
+#include "qtui.h"
+
+SystrayNotificationBackend::SystrayNotificationBackend(QObject *parent) : AbstractNotificationBackend(parent) {
+ NotificationSettings notificationSettings;
+ _showBubble = notificationSettings.value("Systray/ShowBubble", true).toBool();
+ _animate = notificationSettings.value("Systray/Animate", true).toBool();
+
+ notificationSettings.notify("Systray/ShowBubble", this, SLOT(showBubbleChanged(const QVariant &)));
+ notificationSettings.notify("Systray/Animate", this, SLOT(animateChanged(const QVariant &)));
+
+ _configWidget = new ConfigWidget();
+ _iconActive = false;
+ connect(&_animationTimer, SIGNAL(timeout()), SLOT(blink()));
+}
+
+SystrayNotificationBackend::~SystrayNotificationBackend() {
+ delete _configWidget;
+}
+
+void SystrayNotificationBackend::notify(const Notification ¬ification) {
+ /* fancy stuff to be implemented later: show notifications in order
+ _notifications.append(notification);
+ if(_showBubble && _notifications.count() == 1) {
+ showBubble();
+ }
+ */
+ _notifications.clear();
+ _notifications.append(notification);
+ if(_showBubble) {
+ showBubble();
+ }
+ if(_animate && _notifications.count() == 1) {
+ startAnimation();
+ }
+}
+
+void SystrayNotificationBackend::close(uint notificationId) {
+ Q_UNUSED(notificationId);
+ /* fancy stuff to be implemented later
+ int idx = _notifications.indexOf(notificationId);
+
+ if(_notifications.isEmpty()) {
+ */
+ _notifications.clear();
+ closeBubble();
+ stopAnimation();
+}
+
+void SystrayNotificationBackend::showBubble() {
+ // fancy stuff later: show messages in order
+ // for now, we just show the last message
+ if(_notifications.isEmpty()) return;
+ Notification n = _notifications.takeLast();
+ QString title = Client::networkModel()->networkName(n.bufferId) + " - " + Client::networkModel()->bufferName(n.bufferId);
+ QString message = QString("<%1> %2").arg(n.sender, n.message);
+ QtUi::mainWindow()->systemTrayIcon()->showMessage(title, message);
+}
+
+void SystrayNotificationBackend::closeBubble() {
+ // there really seems to be no decent way to close the bubble...
+ QtUi::mainWindow()->systemTrayIcon()->showMessage("", "", QSystemTrayIcon::NoIcon, 1);
+}
+
+void SystrayNotificationBackend::showBubbleChanged(const QVariant &v) {
+ _showBubble = v.toBool();
+}
+
+void SystrayNotificationBackend::startAnimation() {
+ if(!_animationTimer.isActive())
+ _animationTimer.start(500);
+}
+
+void SystrayNotificationBackend::stopAnimation() {
+ _animationTimer.stop();
+ QtUi::mainWindow()->systemTrayIcon()->setIcon(Icon("quassel"));
+ _iconActive = false;
+}
+
+void SystrayNotificationBackend::blink() {
+ QtUi::mainWindow()->systemTrayIcon()->setIcon(_iconActive ? Icon("quassel") : Icon("quassel_newmessage"));
+ _iconActive = !_iconActive;
+}
+
+void SystrayNotificationBackend::animateChanged(const QVariant &v) {
+ _animate = v.toBool();
+}
+
+SettingsPage *SystrayNotificationBackend::configWidget() const {
+ return _configWidget;
+}
+
+/***************************************************************************/
+
+SystrayNotificationBackend::ConfigWidget::ConfigWidget(QWidget *parent) : SettingsPage("Internal", "SystrayNotification", parent) {
+ QGroupBox *groupBox = new QGroupBox(tr("System Tray Icon"), this);
+ _animateBox = new QCheckBox(tr("Animate"));
+ connect(_animateBox, SIGNAL(toggled(bool)), this, SLOT(widgetChanged()));
+ _showBubbleBox = new QCheckBox(tr("Show bubble"));
+ connect(_showBubbleBox, SIGNAL(toggled(bool)), this, SLOT(widgetChanged()));
+ QVBoxLayout *layout = new QVBoxLayout(groupBox);
+ layout->addWidget(_animateBox);
+ layout->addWidget(_showBubbleBox);
+ layout->addStretch(1);
+ QVBoxLayout *globalLayout = new QVBoxLayout(this);
+ globalLayout->addWidget(groupBox);
+
+}
+
+void SystrayNotificationBackend::ConfigWidget::widgetChanged() {
+ bool changed = (_showBubble != _showBubbleBox->isChecked() || _animate != _animateBox->isChecked());
+ if(changed != hasChanged()) setChangedState(changed);
+}
+
+bool SystrayNotificationBackend::ConfigWidget::hasDefaults() const {
+ return true;
+}
+
+void SystrayNotificationBackend::ConfigWidget::defaults() {
+ _animateBox->setChecked(true);
+ _showBubbleBox->setChecked(false);
+ widgetChanged();
+}
+
+void SystrayNotificationBackend::ConfigWidget::load() {
+ NotificationSettings s;
+ _animate = s.value("Systray/Animate", true).toBool();
+ _showBubble = s.value("Systray/ShowBubble", false).toBool();
+ _animateBox->setChecked(_animate);
+ _showBubbleBox->setChecked(_showBubble);
+ setChangedState(false);
+}
+
+void SystrayNotificationBackend::ConfigWidget::save() {
+ NotificationSettings s;
+ s.setValue("Systray/Animate", _animateBox->isChecked());
+ s.setValue("Systray/ShowBubble", _showBubbleBox->isChecked());
+ load();
+}
--- /dev/null
+/***************************************************************************
+* Copyright (C) 2005-08 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 SYSTRAYNOTIFICATIONBACKEND_H_
+#define SYSTRAYNOTIFICATIONBACKEND_H_
+
+#include "abstractnotificationbackend.h"
+
+#include "settingspage.h"
+
+class QCheckBox;
+
+class SystrayNotificationBackend : public AbstractNotificationBackend {
+ Q_OBJECT
+
+public:
+ SystrayNotificationBackend(QObject *parent = 0);
+ ~SystrayNotificationBackend();
+
+ void notify(const Notification &);
+ void close(uint notificationId);
+ SettingsPage *configWidget() const;
+
+private slots:
+ void showBubble();
+ void closeBubble();
+ void startAnimation();
+ void stopAnimation();
+ void blink();
+
+ void animateChanged(const QVariant &);
+ void showBubbleChanged(const QVariant &);
+
+private:
+ class ConfigWidget;
+
+ SettingsPage *_configWidget;
+ bool _showBubble;
+ bool _animate;
+ bool _iconActive;
+ QTimer _animationTimer;
+ QList<Notification> _notifications;
+};
+
+class SystrayNotificationBackend::ConfigWidget : public SettingsPage {
+ Q_OBJECT
+
+public:
+ ConfigWidget(QWidget *parent = 0);
+ void save();
+ void load();
+ bool hasDefaults() const;
+ void defaults();
+
+private slots:
+ void widgetChanged();
+
+private:
+ QCheckBox *_showBubbleBox, *_animateBox;
+ bool _showBubble, _animate;
+};
+
+#endif
Q_OBJECT
public:
- //AbstractNotificationBackend(QObject *parent);
- //virtual ~AbstractNotificationBackend();
+ struct Notification {
+ uint notificationId;
+ BufferId bufferId;
+ QString sender;
+ QString message;
- virtual void notify(BufferId bufId, const QString &sender, const QString &text) = 0;
+ Notification(uint id_, BufferId buf_, const QString &sender_, const QString &msg_)
+ : notificationId(id_), bufferId(buf_), sender(sender_), message(msg_) {};
+ };
+
+ inline AbstractNotificationBackend(QObject *parent) : QObject(parent) {};
+ virtual ~AbstractNotificationBackend() {};
+
+ virtual void notify(const Notification &) = 0;
+ virtual void close(uint notificationId) { Q_UNUSED(notificationId); }
virtual SettingsPage *configWidget() const = 0;
};