1 /*
2 This file is part of KOrganizer.
3
4 SPDX-FileCopyrightText: 2000, 2001, 2002, 2003 Cornelius Schumacher <schumacher@kde.org>
5 SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6
7 SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
8 */
9
10 #include "koprefsdialogplugins.h"
11 #include "kocore.h"
12 #include "koprefs.h"
13 #include <CalendarSupport/KCalPrefs>
14 #include <KGuiItem>
15 #include <KLocalizedString>
16 #include <KMessageBox>
17 #include <KPluginFactory>
18 #include <KService>
19 #include <QAction>
20 #include <QGroupBox>
21 #include <QHeaderView>
22 #include <QLabel>
23 #include <QRadioButton>
24 #include <QToolButton>
25 #include <QTreeWidget>
26 #include <QVBoxLayout>
27
28 class PluginItem : public QTreeWidgetItem
29 {
30 public:
PluginItem(QTreeWidget * parent,const KService::Ptr & service)31 PluginItem(QTreeWidget *parent, const KService::Ptr &service)
32 : QTreeWidgetItem(parent, {service->name()})
33 , mService(service)
34 {
35 }
36
PluginItem(QTreeWidgetItem * parent,const KService::Ptr & service)37 PluginItem(QTreeWidgetItem *parent, const KService::Ptr &service)
38 : QTreeWidgetItem(parent, {service->name()})
39 , mService(service)
40 {
41 }
42
service()43 KService::Ptr service()
44 {
45 return mService;
46 }
47
48 private:
49 const KService::Ptr mService;
50 };
51
52 Q_DECLARE_METATYPE(PluginItem *)
53
54 K_PLUGIN_CLASS_WITH_JSON(KOPrefsDialogPlugins, "korganizer_configplugins.json")
55
56 /**
57 Dialog for selecting and configuring KOrganizer plugins
58 */
KOPrefsDialogPlugins(QWidget * parent,const QVariantList & args)59 KOPrefsDialogPlugins::KOPrefsDialogPlugins(QWidget *parent, const QVariantList &args)
60 : KPrefsModule(KOPrefs::instance(), parent, args)
61 {
62 auto topTopLayout = new QVBoxLayout(this);
63 mTreeWidget = new QTreeWidget(this);
64 mTreeWidget->setColumnCount(2);
65 mTreeWidget->setHeaderHidden(true);
66 mTreeWidget->setSelectionMode(QAbstractItemView::SingleSelection);
67 mTreeWidget->header()->setSectionResizeMode(0, QHeaderView::ResizeToContents);
68 mTreeWidget->header()->setSectionResizeMode(1, QHeaderView::ResizeToContents);
69 mTreeWidget->header()->setStretchLastSection(false);
70 topTopLayout->addWidget(mTreeWidget);
71
72 mDescription = new QLabel(this);
73 mDescription->setAlignment(Qt::AlignVCenter);
74 mDescription->setWordWrap(true);
75 mDescription->setFrameShape(QLabel::Panel);
76 mDescription->setFrameShadow(QLabel::Sunken);
77 mDescription->setMinimumSize(QSize(0, 55));
78 QSizePolicy policy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
79 policy.setHorizontalStretch(0);
80 policy.setVerticalStretch(0);
81 policy.setHeightForWidth(mDescription->sizePolicy().hasHeightForWidth());
82 mDescription->setSizePolicy(policy);
83 topTopLayout->addWidget(mDescription);
84
85 mPositioningGroupBox = new QGroupBox(i18nc("@title:group", "Position"), this);
86 // mPositionMonthTop = new QCheckBox(
87 // i18nc( "@option:check", "Show in the month view" ), mPositioningGroupBox );
88 mPositionAgendaTop = new QRadioButton(i18nc("@option:check", "Show at the top of the agenda views"), mPositioningGroupBox);
89 mPositionAgendaBottom = new QRadioButton(i18nc("@option:check", "Show at the bottom of the agenda views"), mPositioningGroupBox);
90 auto positioningLayout = new QVBoxLayout(mPositioningGroupBox);
91 // positioningLayout->addWidget( mPositionMonthTop );
92 positioningLayout->addWidget(mPositionAgendaTop);
93 positioningLayout->addWidget(mPositionAgendaBottom);
94 positioningLayout->addStretch(1);
95 topTopLayout->addWidget(mPositioningGroupBox);
96
97 connect(mPositionAgendaTop, &QRadioButton::clicked, this, &KOPrefsDialogPlugins::positioningChanged);
98 connect(mPositionAgendaBottom, &QRadioButton::clicked, this, &KOPrefsDialogPlugins::positioningChanged);
99
100 connect(mTreeWidget, &QTreeWidget::itemSelectionChanged, this, &KOPrefsDialogPlugins::selectionChanged);
101 connect(mTreeWidget, &QTreeWidget::itemChanged, this, &KOPrefsDialogPlugins::selectionChanged);
102 connect(mTreeWidget, &QTreeWidget::itemClicked, this, &KOPrefsDialogPlugins::slotWidChanged);
103
104 load();
105
106 selectionChanged();
107 }
108
~KOPrefsDialogPlugins()109 KOPrefsDialogPlugins::~KOPrefsDialogPlugins()
110 {
111 delete mDecorations;
112 }
113
usrReadConfig()114 void KOPrefsDialogPlugins::usrReadConfig()
115 {
116 mTreeWidget->clear();
117 KService::List plugins = KOCore::self()->availableCalendarDecorations();
118
119 EventViews::PrefsPtr viewPrefs = KOPrefs::instance()->eventViewsPreferences();
120
121 QStringList selectedPlugins = viewPrefs->selectedPlugins();
122
123 mDecorations = new QTreeWidgetItem(mTreeWidget, QStringList(i18nc("@title:group", "Calendar Decorations")));
124
125 KService::List::ConstIterator it;
126 KService::List::ConstIterator end(plugins.constEnd());
127
128 for (it = plugins.constBegin(); it != end; ++it) {
129 PluginItem *item = nullptr;
130 if ((*it)->hasServiceType(EventViews::CalendarDecoration::Decoration::serviceType())) {
131 item = new PluginItem(mDecorations, *it);
132 } else {
133 continue;
134 }
135 if (selectedPlugins.contains((*it)->desktopEntryName())) {
136 item->setCheckState(0, Qt::Checked);
137 } else {
138 item->setCheckState(0, Qt::Unchecked);
139 }
140 const QVariant variant = (*it)->property(QStringLiteral("X-KDE-KOrganizer-HasSettings"));
141 const bool hasSettings = (variant.isValid() && variant.toBool());
142 if (hasSettings) {
143 auto but = new QToolButton(mTreeWidget);
144 auto act = new QAction(but);
145 const QString decoration = (*it)->desktopEntryName();
146 act->setData(QVariant::fromValue<PluginItem *>(item));
147 but->setDefaultAction(act);
148 but->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
149 but->setFixedWidth(28);
150 but->setToolTip(i18nc("@action", "Configure"));
151 but->setAutoFillBackground(true);
152 but->setEnabled(true);
153 mTreeWidget->setItemWidget(item, 1, but);
154 connect(but, &QToolButton::triggered, this, &KOPrefsDialogPlugins::configureClicked);
155 }
156 }
157
158 mDecorations->setExpanded(true);
159
160 const auto monthViewTop = KOPrefs::instance()->decorationsAtMonthViewTop();
161 mDecorationsAtMonthViewTop = QSet<QString>(monthViewTop.begin(), monthViewTop.end());
162 const auto agendaViewTop = viewPrefs->decorationsAtAgendaViewTop();
163 mDecorationsAtAgendaViewTop = QSet<QString>(agendaViewTop.begin(), agendaViewTop.end());
164 const auto agendaViewBottom = viewPrefs->decorationsAtAgendaViewBottom();
165 mDecorationsAtAgendaViewBottom = QSet<QString>(agendaViewBottom.begin(), agendaViewBottom.end());
166 }
167
usrWriteConfig()168 void KOPrefsDialogPlugins::usrWriteConfig()
169 {
170 QStringList selectedPlugins;
171
172 for (int i = 0; i < mTreeWidget->topLevelItemCount(); ++i) {
173 QTreeWidgetItem *serviceTypeGroup = mTreeWidget->topLevelItem(i);
174 for (int j = 0; j < serviceTypeGroup->childCount(); ++j) {
175 auto item = static_cast<PluginItem *>(serviceTypeGroup->child(j));
176 if (item->checkState(0) == Qt::Checked) {
177 selectedPlugins.append(item->service()->desktopEntryName());
178 }
179 }
180 }
181 EventViews::PrefsPtr viewPrefs = KOPrefs::instance()->eventViewsPreferences();
182 viewPrefs->setSelectedPlugins(selectedPlugins);
183
184 KOPrefs::instance()->setDecorationsAtMonthViewTop(mDecorationsAtMonthViewTop.values());
185 viewPrefs->setDecorationsAtAgendaViewTop(mDecorationsAtAgendaViewTop.values());
186 viewPrefs->setDecorationsAtAgendaViewBottom(mDecorationsAtAgendaViewBottom.values());
187 }
188
configureClicked(QAction * action)189 void KOPrefsDialogPlugins::configureClicked(QAction *action)
190 {
191 if (!action) {
192 return;
193 }
194
195 auto item = action->data().value<PluginItem *>();
196
197 if (!item) {
198 return;
199 }
200
201 EventViews::CalendarDecoration::Decoration *plugin = KOCore::self()->loadCalendarDecoration(item->service());
202
203 if (plugin) {
204 plugin->configure(this);
205 delete plugin;
206
207 slotWidChanged();
208 } else {
209 KMessageBox::sorry(this, i18nc("@info", "Unable to configure this plugin"), QStringLiteral("PluginConfigUnable"));
210 }
211 }
212
positioningChanged()213 void KOPrefsDialogPlugins::positioningChanged()
214 {
215 if (mTreeWidget->selectedItems().count() != 1) {
216 return;
217 }
218
219 PluginItem *item = dynamic_cast<PluginItem *>(mTreeWidget->selectedItems().last());
220 if (!item) {
221 return;
222 }
223
224 QString decoration = item->service()->desktopEntryName();
225
226 /*if ( mPositionMonthTop->checkState() == Qt::Checked ) {
227 if ( !mDecorationsAtMonthViewTop.contains( decoration ) ) {
228 mDecorationsAtMonthViewTop.insert( decoration );
229 }
230 } else {
231 mDecorationsAtMonthViewTop.remove( decoration );
232 }*/
233
234 if (mPositionAgendaTop->isChecked()) {
235 if (!mDecorationsAtAgendaViewTop.contains(decoration)) {
236 mDecorationsAtAgendaViewTop.insert(decoration);
237 }
238 } else {
239 mDecorationsAtAgendaViewTop.remove(decoration);
240 }
241
242 if (mPositionAgendaBottom->isChecked()) {
243 if (!mDecorationsAtAgendaViewBottom.contains(decoration)) {
244 mDecorationsAtAgendaViewBottom.insert(decoration);
245 }
246 } else {
247 mDecorationsAtAgendaViewBottom.remove(decoration);
248 }
249
250 slotWidChanged();
251 }
252
selectionChanged()253 void KOPrefsDialogPlugins::selectionChanged()
254 {
255 mPositioningGroupBox->hide();
256 // mPositionMonthTop->setChecked( false );
257 mPositionAgendaTop->setChecked(false);
258 mPositionAgendaBottom->setChecked(false);
259
260 if (mTreeWidget->selectedItems().count() != 1) {
261 mDescription->setText(QString());
262 return;
263 }
264
265 PluginItem *item = dynamic_cast<PluginItem *>(mTreeWidget->selectedItems().last());
266 if (!item) {
267 mDescription->setText(QString());
268 return;
269 }
270
271 mDescription->setText(item->service()->comment());
272
273 if (item->service()->hasServiceType(EventViews::CalendarDecoration::Decoration::serviceType())) {
274 bool hasPosition = false;
275 QString decoration = item->service()->desktopEntryName();
276 /*if ( mDecorationsAtMonthViewTop.contains( decoration ) ) {
277 mPositionMonthTop->setChecked( true );
278 hasPosition = true;
279 }*/
280 if (mDecorationsAtAgendaViewTop.contains(decoration)) {
281 mPositionAgendaTop->setChecked(true);
282 hasPosition = true;
283 }
284 if (mDecorationsAtAgendaViewBottom.contains(decoration)) {
285 mPositionAgendaBottom->setChecked(true);
286 hasPosition = true;
287 }
288
289 if (!hasPosition) {
290 // no position has been selected, so default to Agenda Top
291 mDecorationsAtAgendaViewTop << decoration;
292 mPositionAgendaTop->setChecked(true);
293 }
294
295 mPositioningGroupBox->setEnabled(item->checkState(0) == Qt::Checked);
296 mPositioningGroupBox->show();
297 }
298
299 slotWidChanged();
300 }
301
302 #include "koprefsdialogplugins.moc"
303