File indexing completed on 2024-04-14 05:39:36

0001 // SPDX-License-Identifier: GPL-3.0-or-later
0002 /*
0003   Copyright 2017 - 2023 Martin Koller, kollix@aon.at
0004 
0005   This file is part of liquidshell.
0006 
0007   liquidshell is free software: you can redistribute it and/or modify
0008   it under the terms of the GNU General Public License as published by
0009   the Free Software Foundation, either version 3 of the License, or
0010   (at your option) any later version.
0011 
0012   liquidshell is distributed in the hope that it will be useful,
0013   but WITHOUT ANY WARRANTY; without even the implied warranty of
0014   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
0015   GNU General Public License for more details.
0016 
0017   You should have received a copy of the GNU General Public License
0018   along with liquidshell.  If not, see <http://www.gnu.org/licenses/>.
0019 */
0020 
0021 #include <NotificationServer.hxx>
0022 #include <NotificationList.hxx>
0023 
0024 #include <notificationsadaptor.h>
0025 
0026 #include <QIcon>
0027 #include <QDBusConnection>
0028 #include <QDebug>
0029 
0030 #include <KLocalizedString>
0031 #include <KService>
0032 #include <KIconLoader>
0033 
0034 //--------------------------------------------------------------------------------
0035 
0036 NotificationServer::NotificationServer(QWidget *parent)
0037   : SysTrayItem(parent, "preferences-desktop-notification")
0038 {
0039   new NotificationsAdaptor(this);
0040 
0041   QDBusConnection dbus = QDBusConnection::sessionBus();
0042   if ( dbus.registerService("org.freedesktop.Notifications") )
0043   {
0044     if ( !dbus.registerObject("/org/freedesktop/Notifications", this) )
0045       dbus.unregisterService("org.freedesktop.Notifications");
0046   }
0047   notificationList = new NotificationList(this);
0048   connect(notificationList, &NotificationList::listNowEmpty, this, &NotificationServer::hide);
0049 
0050   connect(notificationList, &NotificationList::itemsCountChanged,
0051           [this]()
0052           {
0053             show();
0054             setToolTip(makeToolTip());
0055           }
0056          );
0057 
0058   hide();
0059 
0060   setAvoidPopup(getAvoidPopup());  // adjust icon for current state
0061 
0062   connect(KIconLoader::global(), &KIconLoader::iconLoaderSettingsChanged, this,
0063           [this]() { setAvoidPopup(getAvoidPopup()); });
0064 }
0065 
0066 //--------------------------------------------------------------------------------
0067 
0068 QString NotificationServer::makeToolTip() const
0069 {
0070   QString tip = "<html>";
0071   tip += i18np("%1 notification", "%1 notifications", notificationList->itemCount());
0072 
0073   if ( notificationList->itemCount() < 4 )
0074   {
0075     for (const NotifyItem *item : notificationList->getItems())
0076     {
0077       tip += "<hr>";
0078       tip += item->timeLabel->text() + " ";
0079       QString title = (item->appName == item->summary) ? item->appName : (item->appName + ": " + item->summary);
0080       tip += "<b>" + title + "</b>";
0081       tip += "<br>" + item->body;
0082     }
0083   }
0084 
0085   tip += "</html>";
0086   return tip;
0087 }
0088 
0089 //--------------------------------------------------------------------------------
0090 
0091 QStringList NotificationServer::GetCapabilities()
0092 {
0093   return QStringList()
0094            << "body"
0095            << "body-hyperlinks"
0096            << "body-images"
0097            << "body-markup"
0098            << "icon-static"
0099            << "persistence"
0100            << "actions"
0101            ;
0102 }
0103 
0104 //--------------------------------------------------------------------------------
0105 
0106 void NotificationServer::CloseNotification(uint id)
0107 {
0108   //qDebug() << "CloseNotification" << id;
0109   notificationList->closeItem(id);
0110   emit NotificationClosed(id, CloseReason::Closed);
0111 }
0112 
0113 //--------------------------------------------------------------------------------
0114 
0115 QString NotificationServer::GetServerInformation(QString &vendor, QString &version, QString &spec_version)
0116 {
0117   vendor = "KDE";
0118   version = "1.0";
0119   spec_version = "1.2";
0120   return "liquidshell";
0121 }
0122 
0123 //--------------------------------------------------------------------------------
0124 
0125 uint NotificationServer::Notify(const QString &app_name, uint replaces_id, const QString &app_icon,
0126                                 const QString &summary, const QString &theBody, const QStringList &actions,
0127                                 const QVariantMap &hints, int timeout)
0128 {
0129   //qDebug() << "app" << app_name << "summary" << summary << "body" << theBody << "timeout" << timeout
0130            //<< "replaceId" << replaces_id << "hints" << hints << "actions" << actions;
0131 
0132   uint newId;
0133 
0134   if ( replaces_id != 0 )
0135     notificationList->closeItem(newId = replaces_id);  // reuse id
0136   else
0137     newId = notifyId++;
0138 
0139   QString body(theBody);
0140   body.replace("\n", "<br>");
0141 
0142   QIcon icon;
0143   if ( !app_icon.isEmpty() )
0144     icon = QIcon::fromTheme(app_icon);
0145   else if ( hints.contains("image-path") )
0146     icon = QIcon(hints["image-path"].toString());
0147 
0148   QString appName = app_name;
0149   if ( appName.isEmpty() && hints.contains("desktop-entry") )
0150   {
0151     KService::Ptr service = KService::serviceByDesktopName(hints["desktop-entry"].toString().toLower());
0152     if ( service )
0153       appName = service->name();
0154   }
0155 
0156   notificationList->addItem(newId, appName, summary, body, icon, actions, hints, timeout);
0157 
0158   return newId;
0159 }
0160 
0161 //--------------------------------------------------------------------------------
0162 
0163 QWidget *NotificationServer::getDetailsList()
0164 {
0165   return notificationList;
0166 }
0167 
0168 //--------------------------------------------------------------------------------
0169 
0170 void NotificationServer::setAvoidPopup(bool avoid)
0171 {
0172   notificationList->setAvoidPopup(avoid);
0173 
0174   if ( avoid )
0175     setPixmap(QIcon::fromTheme(iconName).pixmap(size(), QIcon::Disabled));
0176   else
0177     setPixmap(QIcon::fromTheme(iconName).pixmap(size()));
0178 }
0179 
0180 //--------------------------------------------------------------------------------
0181 
0182 bool NotificationServer::getAvoidPopup() const
0183 {
0184   return notificationList->getAvoidPopup();
0185 }
0186 
0187 //--------------------------------------------------------------------------------