File indexing completed on 2024-05-19 09:42:19
0001 /*************************************************************************** 0002 * Copyright © 2009 Harald Sitter <apachelogger@ubuntu.com> * 0003 * Copyright © 2009 Jonathan Thomas <echidnaman@kubuntu.org> * 0004 * * 0005 * This program is free software; you can redistribute it and/or * 0006 * modify it under the terms of the GNU General Public License as * 0007 * published by the Free Software Foundation; either version 2 of * 0008 * the License or (at your option) version 3 or any later version * 0009 * accepted by the membership of KDE e.V. (or its successor approved * 0010 * by the membership of KDE e.V.), which shall act as a proxy * 0011 * defined in Section 14 of version 3 of the license. * 0012 * * 0013 * This program is distributed in the hope that it will be useful, * 0014 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0016 * GNU General Public License for more details. * 0017 * * 0018 * You should have received a copy of the GNU General Public License * 0019 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0020 ***************************************************************************/ 0021 0022 #include "event.h" 0023 0024 #include <QIcon> 0025 #include <QMenu> 0026 #include <QStringBuilder> 0027 0028 #include <KActionCollection> 0029 #include <KConfig> 0030 #include <KConfigGroup> 0031 #include <KNotification> 0032 #include <KStatusNotifierItem> 0033 0034 Event::Event(QObject* parent, const QString &name) 0035 : QObject(parent) 0036 , m_name(name) 0037 , m_hidden(false) 0038 , m_active(false) 0039 , m_notifierItem(0) 0040 { 0041 m_hiddenCfgString = QString("hide" % m_name % "Notifier"); 0042 m_hidden = readHiddenConfig(); 0043 readNotifyConfig(); 0044 } 0045 0046 Event::~Event() 0047 { 0048 } 0049 0050 bool Event::readHiddenConfig() 0051 { 0052 KConfig cfg("notificationhelper"); 0053 KConfigGroup notifyGroup(&cfg, "Event"); 0054 return notifyGroup.readEntry(m_hiddenCfgString, false); 0055 } 0056 0057 void Event::writeHiddenConfig(bool value) 0058 { 0059 KConfig cfg("notificationhelper"); 0060 KConfigGroup notifyGroup(&cfg, "Event"); 0061 notifyGroup.writeEntry(m_hiddenCfgString, value); 0062 notifyGroup.config()->sync(); 0063 } 0064 0065 void Event::readNotifyConfig() 0066 { 0067 KConfig cfg("notificationhelper"); 0068 KConfigGroup notifyTypeGroup(&cfg, "NotificationType"); 0069 QString notifyType = notifyTypeGroup.readEntry("NotifyType", "Combo"); 0070 0071 if (notifyType == "Combo") { 0072 m_useKNotify = true; 0073 m_useTrayIcon = true; 0074 } else if (notifyType == "TrayOnly") { 0075 m_useKNotify = false; 0076 m_useTrayIcon = true; 0077 } else { // KNotifyOnly 0078 m_useKNotify = true; 0079 m_useTrayIcon = false; 0080 } 0081 } 0082 0083 bool Event::isHidden() const 0084 { 0085 return m_hidden; 0086 } 0087 0088 void Event::show(const QString &icon, const QString &text, const QStringList &actions) 0089 { 0090 if (m_active || m_hidden) { 0091 return; 0092 } 0093 0094 // Only manually compose a notification if notifications are enabled AND 0095 // we don't have a tray icon, otherwise the tray icon will issue the notification. 0096 if (m_useKNotify && !m_useTrayIcon) { 0097 KNotification::NotificationFlag flag; 0098 0099 if (!m_useTrayIcon) { 0100 // Tray icon not in use, so be persistent 0101 flag = KNotification::Persistent; 0102 } 0103 0104 m_active = true; 0105 KNotification *notify = new KNotification(m_name, 0, flag); 0106 notify->setComponentName("notificationhelper"); 0107 notify->setPixmap(QIcon::fromTheme(icon).pixmap(NOTIFICATION_ICON_SIZE)); 0108 notify->setText(text); 0109 0110 // Tray icon not in use to handle actions 0111 notify->setActions(actions); 0112 connect(notify, SIGNAL(action1Activated()), this, SLOT(run())); 0113 connect(notify, SIGNAL(action2Activated()), this, SLOT(ignore())); 0114 connect(notify, SIGNAL(action3Activated()), this, SLOT(hide())); 0115 connect(notify, SIGNAL(closed()), this, SLOT(notifyClosed())); 0116 0117 notify->sendEvent(); 0118 } 0119 0120 if (m_useTrayIcon && !m_notifierItem) { // Only create item when there is none. 0121 m_notifierItem = new KStatusNotifierItem(this); 0122 m_notifierItem->setIconByName(icon); 0123 m_notifierItem->setToolTipIconByName(icon); 0124 m_notifierItem->setToolTipTitle(i18n("System Notification Helper")); 0125 m_notifierItem->setToolTipSubTitle(text); 0126 m_notifierItem->setStatus(KStatusNotifierItem::Active); 0127 m_notifierItem->setCategory(KStatusNotifierItem::SystemServices); 0128 m_notifierItem->setStandardActionsEnabled(false); 0129 0130 QMenu *contextMenu = new QMenu(0); 0131 // FIXME: addtitle does a whole pile of madness, I am not sure that should 0132 // be reused *at all* as the lack of frameworks continuity will 0133 // make for shitty UX 0134 // contextMenu->addTitle(QIcon::fromTheme("applications-system"), i18n("System Notification Helper")); 0135 0136 QAction *runAction = contextMenu->addAction(actions.at(0)); 0137 // FIXME: DBusmenu doesn't support pixmap icons yet. Change function to take QIcon::fromTheme 0138 runAction->setIcon(QIcon::fromTheme(icon)); 0139 connect(runAction, SIGNAL(triggered()), this, SLOT(run())); 0140 contextMenu->addAction(runAction); 0141 0142 QAction *ignoreForeverAction = contextMenu->addAction(actions.at(2)); 0143 connect(ignoreForeverAction, SIGNAL(triggered()), this, SLOT(hide())); 0144 contextMenu->addAction(ignoreForeverAction); 0145 0146 contextMenu->addSeparator(); 0147 0148 QAction *hideAction = contextMenu->addAction(i18n("Hide")); 0149 hideAction->setIcon(QIcon::fromTheme("application-exit")); 0150 connect(hideAction, SIGNAL(triggered()), this, SLOT(ignore())); 0151 contextMenu->addAction(hideAction); 0152 0153 m_notifierItem->setContextMenu(contextMenu); 0154 m_notifierItem->setAssociatedWidget(NULL); 0155 0156 connect(m_notifierItem, SIGNAL(activateRequested(bool, const QPoint &)), this, SLOT(run())); 0157 } 0158 0159 // Ask the KSNI to show a notification whenver show() is called. 0160 if (m_useTrayIcon && m_notifierItem) { 0161 m_notifierItem->showMessage(i18nc("notification title", "System Notification Helper"), 0162 text, icon); 0163 } 0164 } 0165 0166 void Event::run() 0167 { 0168 delete m_notifierItem; 0169 m_notifierItem = 0; 0170 notifyClosed(); 0171 } 0172 0173 void Event::ignore() 0174 { 0175 m_notifierItem->deleteLater(); 0176 m_notifierItem = 0; 0177 notifyClosed(); 0178 } 0179 0180 void Event::hide() 0181 { 0182 notifyClosed(); 0183 writeHiddenConfig(true); 0184 m_hidden = true; 0185 } 0186 0187 void Event::notifyClosed() 0188 { 0189 m_active = false; 0190 } 0191 0192 void Event::reloadConfig() 0193 { 0194 m_hidden = readHiddenConfig(); 0195 }