File indexing completed on 2022-11-23 10:36:00

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2005 Olivier Goffart <ogoffart at kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 
0008 #include "knotifyeventlist.h"
0009 
0010 #include <knotifyconfig_debug.h>
0011 
0012 #include <KConfig>
0013 #include <KConfigGroup>
0014 #include <KLocalizedString>
0015 
0016 #include <QHeaderView>
0017 #include <QPainter>
0018 #include <QRegularExpression>
0019 #include <QStandardPaths>
0020 #include <QStyledItemDelegate>
0021 
0022 // BEGIN KNotifyEventListDelegate
0023 
0024 class KNotifyEventList::KNotifyEventListDelegate : public QStyledItemDelegate
0025 {
0026 public:
0027     explicit KNotifyEventListDelegate(QObject *parent = nullptr);
0028 
0029     void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
0030 
0031 private:
0032 };
0033 
0034 KNotifyEventList::KNotifyEventListDelegate::KNotifyEventListDelegate(QObject *parent)
0035     : QStyledItemDelegate(parent)
0036 {
0037 }
0038 
0039 void KNotifyEventList::KNotifyEventListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
0040 {
0041     if (index.column() != 0) {
0042         return QStyledItemDelegate::paint(painter, option, index);
0043     }
0044 
0045     QVariant displayData = index.data(Qt::UserRole);
0046     QString prstring = displayData.toString();
0047 
0048     QStyledItemDelegate::paint(painter, option, index);
0049 
0050     //  qDebug() << prstring;
0051 
0052     QRect rect = option.rect;
0053 
0054     QStringList optionsList = prstring.split(QLatin1Char('|'));
0055     QList<QIcon> iconList;
0056     iconList << (optionsList.contains(QStringLiteral("Sound")) ? QIcon::fromTheme(QStringLiteral("media-playback-start")) : QIcon());
0057     iconList << (optionsList.contains(QStringLiteral("Popup")) ? QIcon::fromTheme(QStringLiteral("dialog-information")) : QIcon());
0058     iconList << (optionsList.contains(QStringLiteral("Logfile")) ? QIcon::fromTheme(QStringLiteral("text-x-generic")) : QIcon());
0059     iconList << (optionsList.contains(QStringLiteral("Taskbar")) ? QIcon::fromTheme(QStringLiteral("services")) : QIcon());
0060     iconList << (optionsList.contains(QStringLiteral("Execute")) ? QIcon::fromTheme(QStringLiteral("system-run")) : QIcon());
0061     if (KNotifyConfigElement::have_tts()) {
0062         iconList << (optionsList.contains(QStringLiteral("TTS")) ? QIcon::fromTheme(QStringLiteral("text-speak")) : QIcon());
0063     }
0064 
0065     int mc_x = 0;
0066 
0067     int iconWidth = option.decorationSize.width();
0068     int iconHeight = option.decorationSize.height();
0069     for (const QIcon &icon : std::as_const(iconList)) {
0070         icon.paint(painter, rect.left() + mc_x + 4, rect.top() + (rect.height() - iconHeight) / 2, iconWidth, iconHeight);
0071         mc_x += iconWidth + 4;
0072     }
0073 }
0074 
0075 // END KNotifyEventListDelegate
0076 
0077 KNotifyEventList::KNotifyEventList(QWidget *parent)
0078     : QTreeWidget(parent)
0079     , config(nullptr)
0080 {
0081     QStringList headerLabels;
0082     headerLabels << i18nc("State of the notified event", "State") << i18nc("Title of the notified event", "Title")
0083                  << i18nc("Description of the notified event", "Description");
0084     setHeaderLabels(headerLabels);
0085 
0086     setItemDelegate(new KNotifyEventListDelegate(this));
0087     setRootIsDecorated(false);
0088     setAlternatingRowColors(true);
0089 
0090     // Extract icon size as the font height (as h=w on icons)
0091     QStyleOptionViewItem iconOption;
0092     iconOption.initFrom(this);
0093     int iconWidth = iconOption.fontMetrics.height() - 2; // 1px margin top & bottom
0094     setIconSize(QSize(iconWidth, iconWidth));
0095 
0096     header()->setSectionResizeMode(0, QHeaderView::Fixed);
0097     header()->resizeSection(0, KNotifyConfigElement::have_tts() ? (iconWidth + 4) * 6 : (iconWidth + 4) * 5);
0098     header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
0099 
0100     connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(slotSelectionChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
0101 }
0102 
0103 KNotifyEventList::~KNotifyEventList()
0104 {
0105     delete config;
0106 }
0107 
0108 void KNotifyEventList::fill(const QString &appname, const QString &context_name, const QString &context_value, bool loadDefaults)
0109 {
0110     m_elements.clear();
0111     clear();
0112     delete config;
0113     config = new KConfig(appname + QStringLiteral(".notifyrc"), KConfig::NoGlobals);
0114     config->addConfigSources(
0115         QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("knotifications5/") + appname + QStringLiteral(".notifyrc")));
0116 
0117     QStringList conflist = config->groupList();
0118     QRegularExpression rx(QStringLiteral("^Event/([^/]*)$"));
0119     conflist = conflist.filter(rx);
0120 
0121     for (const QString &group : std::as_const(conflist)) {
0122         KConfigGroup cg(config, group);
0123         QString id = rx.match(group).captured(1);
0124 
0125         if (!context_name.isEmpty()) {
0126             QStringList contexts = cg.readEntry("Contexts", QStringList());
0127             if (!contexts.contains(context_name)) {
0128                 continue;
0129             }
0130 
0131             id = id + QLatin1Char('/') + context_name + QLatin1Char('/') + context_value;
0132         }
0133         QString name = cg.readEntry("Name");
0134         QString description = cg.readEntry("Comment");
0135 
0136         if (loadDefaults) {
0137             KConfigGroup g(config, QStringLiteral("Event/") + id);
0138             const auto keyList = g.keyList();
0139             for (const QString &entry : keyList) {
0140                 g.revertToDefault(entry);
0141             }
0142         }
0143 
0144         m_elements << new KNotifyEventListItem(this, id, name, description, config);
0145     }
0146 
0147     resizeColumnToContents(2);
0148 }
0149 
0150 void KNotifyEventList::save()
0151 {
0152     for (KNotifyEventListItem *it : std::as_const(m_elements)) {
0153         it->save();
0154     }
0155     config->sync();
0156 }
0157 
0158 bool KNotifyEventList::disableAllSounds()
0159 {
0160     bool changed = false;
0161     for (KNotifyEventListItem *it : std::as_const(m_elements)) {
0162         QStringList actions = it->configElement()->readEntry(QStringLiteral("Action")).split(QLatin1Char('|'));
0163         if (actions.removeAll(QStringLiteral("Sound"))) {
0164             it->configElement()->writeEntry(QStringLiteral("Action"), actions.join(QLatin1Char('|')));
0165             changed = true;
0166         }
0167     }
0168     return changed;
0169 }
0170 
0171 void KNotifyEventList::slotSelectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
0172 {
0173     Q_UNUSED(current);
0174 
0175     KNotifyEventListItem *it = dynamic_cast<KNotifyEventListItem *>(currentItem());
0176     if (it) {
0177         Q_EMIT eventSelected(it->configElement());
0178     } else {
0179         Q_EMIT eventSelected(nullptr);
0180     }
0181 
0182     it = dynamic_cast<KNotifyEventListItem *>(previous);
0183     if (it) {
0184         it->update();
0185     }
0186 }
0187 
0188 void KNotifyEventList::updateCurrentItem()
0189 {
0190     KNotifyEventListItem *it = dynamic_cast<KNotifyEventListItem *>(currentItem());
0191     if (it) {
0192         it->update();
0193     }
0194 }
0195 
0196 void KNotifyEventList::updateAllItems()
0197 {
0198     for (KNotifyEventListItem *it : std::as_const(m_elements)) {
0199         it->update();
0200     }
0201 }
0202 
0203 void KNotifyEventList::selectEvent(const QString &eventId)
0204 {
0205     auto it = std::find_if(m_elements.constBegin(), m_elements.constEnd(), [&eventId](KNotifyEventListItem *item) {
0206         return item->configElement()->eventId() == eventId;
0207     });
0208 
0209     if (it != m_elements.constEnd()) {
0210         setCurrentItem(*it);
0211     }
0212 }
0213 
0214 QSize KNotifyEventList::sizeHint() const
0215 {
0216     int fontSize = fontMetrics().height();
0217     return QSize(48 * fontSize, 12 * fontSize);
0218 }
0219 
0220 KNotifyEventListItem::KNotifyEventListItem(QTreeWidget *parent, const QString &eventName, const QString &name, const QString &description, KConfig *config)
0221     : QTreeWidgetItem(parent)
0222     , m_config(eventName, config)
0223 {
0224     setText(1, name);
0225     setToolTip(1, description);
0226     setText(2, description);
0227     setToolTip(2, description);
0228     update();
0229 }
0230 
0231 KNotifyEventListItem::~KNotifyEventListItem()
0232 {
0233 }
0234 
0235 void KNotifyEventListItem::save()
0236 {
0237     m_config.save();
0238 }
0239 
0240 void KNotifyEventListItem::update()
0241 {
0242     setData(0, Qt::UserRole, m_config.readEntry(QStringLiteral("Action")));
0243 }