1 | /* |
2 | This file is part of the KDE libraries |
3 | SPDX-FileCopyrightText: 2005 Olivier Goffart <ogoffart at kde.org> |
4 | |
5 | SPDX-License-Identifier: LGPL-2.0-only |
6 | */ |
7 | |
8 | #include "knotifyeventlist.h" |
9 | |
10 | #include <knotifyconfig_debug.h> |
11 | |
12 | #include <KConfig> |
13 | #include <KConfigGroup> |
14 | #include <KLocalizedString> |
15 | |
16 | #include <QHeaderView> |
17 | #include <QPainter> |
18 | #include <QRegularExpression> |
19 | #include <QStandardPaths> |
20 | #include <QStyledItemDelegate> |
21 | |
22 | // BEGIN KNotifyEventListDelegate |
23 | |
24 | class KNotifyEventList::KNotifyEventListDelegate : public QStyledItemDelegate |
25 | { |
26 | public: |
27 | explicit KNotifyEventListDelegate(QObject *parent = nullptr); |
28 | |
29 | void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override; |
30 | |
31 | private: |
32 | }; |
33 | |
34 | KNotifyEventList::KNotifyEventListDelegate::KNotifyEventListDelegate(QObject *parent) |
35 | : QStyledItemDelegate(parent) |
36 | { |
37 | } |
38 | |
39 | void KNotifyEventList::KNotifyEventListDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const |
40 | { |
41 | if (index.column() != 0) { |
42 | return QStyledItemDelegate::paint(painter, option, index); |
43 | } |
44 | |
45 | QVariant displayData = index.data(arole: Qt::UserRole); |
46 | QString prstring = displayData.toString(); |
47 | |
48 | QStyledItemDelegate::paint(painter, option, index); |
49 | |
50 | // qDebug() << prstring; |
51 | |
52 | QRect rect = option.rect; |
53 | |
54 | QStringList optionsList = prstring.split(sep: QLatin1Char('|')); |
55 | QList<QIcon> iconList; |
56 | iconList << (optionsList.contains(QStringLiteral("Sound" )) ? QIcon::fromTheme(QStringLiteral("media-playback-start" )) : QIcon()); |
57 | iconList << (optionsList.contains(QStringLiteral("Popup" )) ? QIcon::fromTheme(QStringLiteral("dialog-information" )) : QIcon()); |
58 | |
59 | int mc_x = 0; |
60 | |
61 | int iconWidth = option.decorationSize.width(); |
62 | int iconHeight = option.decorationSize.height(); |
63 | for (const QIcon &icon : std::as_const(t&: iconList)) { |
64 | icon.paint(painter, x: rect.left() + mc_x + 4, y: rect.top() + (rect.height() - iconHeight) / 2, w: iconWidth, h: iconHeight); |
65 | mc_x += iconWidth + 4; |
66 | } |
67 | } |
68 | |
69 | // END KNotifyEventListDelegate |
70 | |
71 | KNotifyEventList::KNotifyEventList(QWidget *parent) |
72 | : QTreeWidget(parent) |
73 | , config(nullptr) |
74 | { |
75 | QStringList ; |
76 | headerLabels << i18nc("State of the notified event" , "State" ) << i18nc("Title of the notified event" , "Title" ) |
77 | << i18nc("Description of the notified event" , "Description" ); |
78 | setHeaderLabels(headerLabels); |
79 | |
80 | setItemDelegate(new KNotifyEventListDelegate(this)); |
81 | setRootIsDecorated(false); |
82 | setAlternatingRowColors(true); |
83 | |
84 | // Extract icon size as the font height (as h=w on icons) |
85 | QStyleOptionViewItem iconOption; |
86 | iconOption.initFrom(w: this); |
87 | int iconWidth = iconOption.fontMetrics.height() - 2; // 1px margin top & bottom |
88 | setIconSize(QSize(iconWidth, iconWidth)); |
89 | |
90 | header()->setSectionResizeMode(logicalIndex: 0, mode: QHeaderView::Fixed); |
91 | header()->setSectionResizeMode(logicalIndex: 1, mode: QHeaderView::ResizeToContents); |
92 | |
93 | connect(sender: this, SIGNAL(currentItemChanged(QTreeWidgetItem *, QTreeWidgetItem *)), receiver: this, SLOT(slotSelectionChanged(QTreeWidgetItem *, QTreeWidgetItem *))); |
94 | } |
95 | |
96 | KNotifyEventList::~KNotifyEventList() |
97 | { |
98 | delete config; |
99 | } |
100 | |
101 | void KNotifyEventList::fill(const QString &appname, bool loadDefaults) |
102 | { |
103 | m_elements.clear(); |
104 | clear(); |
105 | delete config; |
106 | config = new KConfig(appname + QStringLiteral(".notifyrc" ), KConfig::NoGlobals); |
107 | config->addConfigSources( |
108 | sources: QStandardPaths::locateAll(type: QStandardPaths::GenericDataLocation, QStringLiteral("knotifications6/" ) + appname + QStringLiteral(".notifyrc" ))); |
109 | |
110 | QStringList conflist = config->groupList(); |
111 | QRegularExpression rx(QStringLiteral("^Event/([^/]*)$" )); |
112 | conflist = conflist.filter(re: rx); |
113 | |
114 | for (const QString &group : std::as_const(t&: conflist)) { |
115 | KConfigGroup cg(config, group); |
116 | QString id = rx.match(subject: group).captured(nth: 1); |
117 | QString name = cg.readEntry(key: "Name" ); |
118 | QString description = cg.readEntry(key: "Comment" ); |
119 | |
120 | if (loadDefaults) { |
121 | KConfigGroup g(config, QStringLiteral("Event/" ) + id); |
122 | const auto keyList = g.keyList(); |
123 | for (const QString &entry : keyList) { |
124 | g.revertToDefault(key: entry); |
125 | } |
126 | } |
127 | |
128 | m_elements << new KNotifyEventListItem(this, id, name, description, config); |
129 | } |
130 | |
131 | resizeColumnToContents(column: 2); |
132 | } |
133 | |
134 | void KNotifyEventList::save() |
135 | { |
136 | for (KNotifyEventListItem *it : std::as_const(t&: m_elements)) { |
137 | it->save(); |
138 | } |
139 | config->sync(); |
140 | } |
141 | |
142 | bool KNotifyEventList::disableAllSounds() |
143 | { |
144 | bool changed = false; |
145 | for (KNotifyEventListItem *it : std::as_const(t&: m_elements)) { |
146 | QStringList actions = it->configElement()->readEntry(QStringLiteral("Action" )).split(sep: QLatin1Char('|')); |
147 | if (actions.removeAll(QStringLiteral("Sound" ))) { |
148 | it->configElement()->writeEntry(QStringLiteral("Action" ), data: actions.join(sep: QLatin1Char('|'))); |
149 | changed = true; |
150 | } |
151 | } |
152 | return changed; |
153 | } |
154 | |
155 | void KNotifyEventList::slotSelectionChanged(QTreeWidgetItem *current, QTreeWidgetItem *previous) |
156 | { |
157 | Q_UNUSED(current); |
158 | |
159 | KNotifyEventListItem *it = dynamic_cast<KNotifyEventListItem *>(currentItem()); |
160 | if (it) { |
161 | Q_EMIT eventSelected(it->configElement()); |
162 | } else { |
163 | Q_EMIT eventSelected(nullptr); |
164 | } |
165 | |
166 | it = dynamic_cast<KNotifyEventListItem *>(previous); |
167 | if (it) { |
168 | it->update(); |
169 | } |
170 | } |
171 | |
172 | void KNotifyEventList::updateCurrentItem() |
173 | { |
174 | KNotifyEventListItem *it = dynamic_cast<KNotifyEventListItem *>(currentItem()); |
175 | if (it) { |
176 | it->update(); |
177 | } |
178 | } |
179 | |
180 | void KNotifyEventList::updateAllItems() |
181 | { |
182 | for (KNotifyEventListItem *it : std::as_const(t&: m_elements)) { |
183 | it->update(); |
184 | } |
185 | } |
186 | |
187 | void KNotifyEventList::selectEvent(const QString &eventId) |
188 | { |
189 | auto it = std::find_if(first: m_elements.constBegin(), last: m_elements.constEnd(), pred: [&eventId](KNotifyEventListItem *item) { |
190 | return item->configElement()->eventId() == eventId; |
191 | }); |
192 | |
193 | if (it != m_elements.constEnd()) { |
194 | setCurrentItem(*it); |
195 | } |
196 | } |
197 | |
198 | QSize KNotifyEventList::sizeHint() const |
199 | { |
200 | int fontSize = fontMetrics().height(); |
201 | return QSize(48 * fontSize, 12 * fontSize); |
202 | } |
203 | |
204 | KNotifyEventListItem::KNotifyEventListItem(QTreeWidget *parent, const QString &eventName, const QString &name, const QString &description, KConfig *config) |
205 | : QTreeWidgetItem(parent) |
206 | , m_config(eventName, config) |
207 | { |
208 | setText(column: 1, atext: name); |
209 | setToolTip(column: 1, atoolTip: description); |
210 | setText(column: 2, atext: description); |
211 | setToolTip(column: 2, atoolTip: description); |
212 | update(); |
213 | } |
214 | |
215 | KNotifyEventListItem::~KNotifyEventListItem() |
216 | { |
217 | } |
218 | |
219 | void KNotifyEventListItem::save() |
220 | { |
221 | m_config.save(); |
222 | } |
223 | |
224 | void KNotifyEventListItem::update() |
225 | { |
226 | setData(column: 0, role: Qt::UserRole, value: m_config.readEntry(QStringLiteral("Action" ))); |
227 | } |
228 | |
229 | #include "moc_knotifyeventlist.cpp" |
230 | |