File indexing completed on 2024-04-21 07:43:29

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 
0059     int mc_x = 0;
0060 
0061     int iconWidth = option.decorationSize.width();
0062     int iconHeight = option.decorationSize.height();
0063     for (const QIcon &icon : std::as_const(iconList)) {
0064         icon.paint(painter, rect.left() + mc_x + 4, rect.top() + (rect.height() - iconHeight) / 2, iconWidth, iconHeight);
0065         mc_x += iconWidth + 4;
0066     }
0067 }
0068 
0069 // END KNotifyEventListDelegate
0070 
0071 KNotifyEventList::KNotifyEventList(QWidget *parent)
0072     : QTreeWidget(parent)
0073     , config(nullptr)
0074 {
0075     QStringList headerLabels;
0076     headerLabels << i18nc("State of the notified event", "State") << i18nc("Title of the notified event", "Title")
0077                  << i18nc("Description of the notified event", "Description");
0078     setHeaderLabels(headerLabels);
0079 
0080     setItemDelegate(new KNotifyEventListDelegate(this));
0081     setRootIsDecorated(false);
0082     setAlternatingRowColors(true);
0083 
0084     // Extract icon size as the font height (as h=w on icons)
0085     QStyleOptionViewItem iconOption;
0086     iconOption.initFrom(this);
0087     int iconWidth = iconOption.fontMetrics.height() - 2; // 1px margin top & bottom
0088     setIconSize(QSize(iconWidth, iconWidth));
0089 
0090     header()->setSectionResizeMode(0, QHeaderView::Fixed);
0091     header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
0092 
0093     connect(this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), this, SLOT(slotSelectionChanged(QTreeWidgetItem *, QTreeWidgetItem *)));
0094 }
0095 
0096 KNotifyEventList::~KNotifyEventList()
0097 {
0098     delete config;
0099 }
0100 
0101 void KNotifyEventList::fill(const QString &appname, bool loadDefaults)
0102 {
0103     m_elements.clear();
0104     clear();
0105     delete config;
0106     config = new KConfig(appname + QStringLiteral(".notifyrc"), KConfig::NoGlobals);
0107     config->addConfigSources(
0108         QStandardPaths::locateAll(QStandardPaths::GenericDataLocation, QStringLiteral("knotifications6/") + appname + QStringLiteral(".notifyrc")));
0109 
0110     QStringList conflist = config->groupList();
0111     QRegularExpression rx(QStringLiteral("^Event/([^/]*)$"));
0112     conflist = conflist.filter(rx);
0113 
0114     for (const QString &group : std::as_const(conflist)) {
0115         KConfigGroup cg(config, group);
0116         QString id = rx.match(group).captured(1);
0117         QString name = cg.readEntry("Name");
0118         QString description = cg.readEntry("Comment");
0119 
0120         if (loadDefaults) {
0121             KConfigGroup g(config, QStringLiteral("Event/") + id);
0122             const auto keyList = g.keyList();
0123             for (const QString &entry : keyList) {
0124                 g.revertToDefault(entry);
0125             }
0126         }
0127 
0128         m_elements << new KNotifyEventListItem(this, id, name, description, config);
0129     }
0130 
0131     resizeColumnToContents(2);
0132 }
0133 
0134 void KNotifyEventList::save()
0135 {
0136     for (KNotifyEventListItem *it : std::as_const(m_elements)) {
0137         it->save();
0138     }
0139     config->sync();
0140 }
0141 
0142 bool KNotifyEventList::disableAllSounds()
0143 {
0144     bool changed = false;
0145     for (KNotifyEventListItem *it : std::as_const(m_elements)) {
0146         QStringList actions = it->configElement()->readEntry(QStringLiteral("Action")).split(QLatin1Char('|'));
0147         if (actions.removeAll(QStringLiteral("Sound"))) {
0148             it->configElement()->writeEntry(QStringLiteral("Action"), actions.join(QLatin1Char('|')));
0149             changed = true;
0150         }
0151     }
0152     return changed;
0153 }
0154 
0155 void KNotifyEventList::slotSelectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous)
0156 {
0157     Q_UNUSED(current);
0158 
0159     KNotifyEventListItem *it = dynamic_cast<KNotifyEventListItem *>(currentItem());
0160     if (it) {
0161         Q_EMIT eventSelected(it->configElement());
0162     } else {
0163         Q_EMIT eventSelected(nullptr);
0164     }
0165 
0166     it = dynamic_cast<KNotifyEventListItem *>(previous);
0167     if (it) {
0168         it->update();
0169     }
0170 }
0171 
0172 void KNotifyEventList::updateCurrentItem()
0173 {
0174     KNotifyEventListItem *it = dynamic_cast<KNotifyEventListItem *>(currentItem());
0175     if (it) {
0176         it->update();
0177     }
0178 }
0179 
0180 void KNotifyEventList::updateAllItems()
0181 {
0182     for (KNotifyEventListItem *it : std::as_const(m_elements)) {
0183         it->update();
0184     }
0185 }
0186 
0187 void KNotifyEventList::selectEvent(const QString &eventId)
0188 {
0189     auto it = std::find_if(m_elements.constBegin(), m_elements.constEnd(), [&eventId](KNotifyEventListItem *item) {
0190         return item->configElement()->eventId() == eventId;
0191     });
0192 
0193     if (it != m_elements.constEnd()) {
0194         setCurrentItem(*it);
0195     }
0196 }
0197 
0198 QSize KNotifyEventList::sizeHint() const
0199 {
0200     int fontSize = fontMetrics().height();
0201     return QSize(48 * fontSize, 12 * fontSize);
0202 }
0203 
0204 KNotifyEventListItem::KNotifyEventListItem(QTreeWidget *parent, const QString &eventName, const QString &name, const QString &description, KConfig *config)
0205     : QTreeWidgetItem(parent)
0206     , m_config(eventName, config)
0207 {
0208     setText(1, name);
0209     setToolTip(1, description);
0210     setText(2, description);
0211     setToolTip(2, description);
0212     update();
0213 }
0214 
0215 KNotifyEventListItem::~KNotifyEventListItem()
0216 {
0217 }
0218 
0219 void KNotifyEventListItem::save()
0220 {
0221     m_config.save();
0222 }
0223 
0224 void KNotifyEventListItem::update()
0225 {
0226     setData(0, Qt::UserRole, m_config.readEntry(QStringLiteral("Action")));
0227 }
0228 
0229 #include "moc_knotifyeventlist.cpp"