1 /*
2   SPDX-FileCopyrightText: 2001, 2003 Cornelius Schumacher <schumacher@kde.org>
3   SPDX-FileCopyrightText: 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
4   SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.net>
5   SPDX-FileContributor: Kevin Krammer <krake@kdab.com>
6 
7   SPDX-License-Identifier: GPL-2.0-or-later WITH Qt-Commercial-exception-1.0
8 */
9 #include "prefs.h"
10 #include "prefs_base.h"
11 
12 #include "calendarview_debug.h"
13 
14 #include <Akonadi/AttributeFactory>
15 #include <Akonadi/CollectionColorAttribute>
16 
17 #include <QFontDatabase>
18 #include <QRandomGenerator>
19 using namespace EventViews;
20 
iconArrayToSet(const QByteArray & array)21 QSet<EventViews::EventView::ItemIcon> iconArrayToSet(const QByteArray &array)
22 {
23     QSet<EventViews::EventView::ItemIcon> set;
24     for (int i = 0; i < array.count(); ++i) {
25         if (i >= EventViews::EventView::IconCount) {
26             qCWarning(CALENDARVIEW_LOG) << "Icon array is too big: " << array.count();
27             return set;
28         }
29         if (array[i] != 0) {
30             set.insert(static_cast<EventViews::EventView::ItemIcon>(i));
31         }
32     }
33     return set;
34 }
35 
iconSetToArray(const QSet<EventViews::EventView::ItemIcon> & set)36 QByteArray iconSetToArray(const QSet<EventViews::EventView::ItemIcon> &set)
37 {
38     QByteArray array;
39     for (int i = 0; i < EventViews::EventView::IconCount; ++i) {
40         const bool contains = set.contains(static_cast<EventViews::EventView::ItemIcon>(i));
41         array.append(contains ? 1 : 0);
42     }
43 
44     return array;
45 }
46 
agendaViewIconDefaults()47 QByteArray agendaViewIconDefaults()
48 {
49     QByteArray iconDefaults;
50     iconDefaults.resize(7);
51 
52     iconDefaults[EventViews::EventView::CalendarCustomIcon] = 1;
53     iconDefaults[EventViews::EventView::TaskIcon] = 1;
54     iconDefaults[EventViews::EventView::JournalIcon] = 1;
55     iconDefaults[EventViews::EventView::RecurringIcon] = 1;
56     iconDefaults[EventViews::EventView::ReminderIcon] = 1;
57     iconDefaults[EventViews::EventView::ReadOnlyIcon] = 1;
58     iconDefaults[EventViews::EventView::ReplyIcon] = 0;
59 
60     return iconDefaults;
61 }
62 
monthViewIconDefaults()63 QByteArray monthViewIconDefaults()
64 {
65     QByteArray iconDefaults;
66     iconDefaults.resize(7);
67 
68     iconDefaults[EventViews::EventView::CalendarCustomIcon] = 1;
69     iconDefaults[EventViews::EventView::TaskIcon] = 1;
70     iconDefaults[EventViews::EventView::JournalIcon] = 1;
71     iconDefaults[EventViews::EventView::RecurringIcon] = 0;
72     iconDefaults[EventViews::EventView::ReminderIcon] = 0;
73     iconDefaults[EventViews::EventView::ReadOnlyIcon] = 1;
74     iconDefaults[EventViews::EventView::ReplyIcon] = 0;
75 
76     return iconDefaults;
77 }
78 
79 class BaseConfig : public PrefsBase
80 {
81 public:
82     BaseConfig();
83 
84     void setResourceColor(const QString &resource, const QColor &color);
85 
86     void setTimeScaleTimezones(const QStringList &timeZones);
87     QStringList timeScaleTimezones() const;
88 
89 public:
90     QHash<QString, QColor> mResourceColors;
91     QColor mDefaultResourceColor;
92 
93     QFont mDefaultMonthViewFont;
94     QFont mDefaultAgendaTimeLabelsFont;
95 
96     QStringList mTimeScaleTimeZones;
97 
98     QSet<EventViews::EventView::ItemIcon> mAgendaViewIcons;
99     QSet<EventViews::EventView::ItemIcon> mMonthViewIcons;
100 
101 protected:
102     void usrSetDefaults() override;
103     void usrRead() override;
104     bool usrSave() override;
105 };
106 
BaseConfig()107 BaseConfig::BaseConfig()
108     : PrefsBase()
109 {
110     mDefaultResourceColor = QColor(); // Default is a color invalid
111 
112     mDefaultAgendaTimeLabelsFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
113     // make a large default time bar font, at least 16 points.
114     mDefaultAgendaTimeLabelsFont.setPointSize(qMax(mDefaultAgendaTimeLabelsFont.pointSize() + 4, 16));
115 
116     mDefaultMonthViewFont = QFontDatabase::systemFont(QFontDatabase::GeneralFont);
117     // make it a bit smaller
118     mDefaultMonthViewFont.setPointSize(qMax(mDefaultMonthViewFont.pointSize() - 2, 6));
119 
120     agendaTimeLabelsFontItem()->setDefaultValue(mDefaultAgendaTimeLabelsFont);
121     agendaTimeLabelsFontItem()->setDefault();
122     monthViewFontItem()->setDefaultValue(mDefaultMonthViewFont);
123     monthViewFontItem()->setDefault();
124 }
125 
setResourceColor(const QString & resource,const QColor & color)126 void BaseConfig::setResourceColor(const QString &resource, const QColor &color)
127 {
128     mResourceColors.insert(resource, color);
129 }
130 
setTimeScaleTimezones(const QStringList & list)131 void BaseConfig::setTimeScaleTimezones(const QStringList &list)
132 {
133     mTimeScaleTimeZones = list;
134 }
135 
timeScaleTimezones() const136 QStringList BaseConfig::timeScaleTimezones() const
137 {
138     return mTimeScaleTimeZones;
139 }
140 
usrSetDefaults()141 void BaseConfig::usrSetDefaults()
142 {
143     setAgendaTimeLabelsFont(mDefaultAgendaTimeLabelsFont);
144     setMonthViewFont(mDefaultMonthViewFont);
145 
146     PrefsBase::usrSetDefaults();
147 }
148 
usrRead()149 void BaseConfig::usrRead()
150 {
151     KConfigGroup rColorsConfig(config(), "Resources Colors");
152     const QStringList colorKeyList = rColorsConfig.keyList();
153 
154     for (const QString &key : colorKeyList) {
155         QColor color = rColorsConfig.readEntry(key, mDefaultResourceColor);
156         // qCDebug(CALENDARVIEW_LOG) << "key:" << key << "value:" << color;
157         setResourceColor(key, color);
158     }
159 
160 #if 0
161     config()->setGroup("FreeBusy");
162     if (mRememberRetrievePw) {
163         mRetrievePassword
164             = KStringHandler::obscure(config()->readEntry("Retrieve Server Password"));
165     }
166 #endif
167 
168     KConfigGroup timeScaleConfig(config(), "Timescale");
169     setTimeScaleTimezones(timeScaleConfig.readEntry("Timescale Timezones", QStringList()));
170 
171     KConfigGroup monthViewConfig(config(), "Month View");
172     KConfigGroup agendaViewConfig(config(), "Agenda View");
173     const auto agendaIconArray = agendaViewConfig.readEntry<QByteArray>("agendaViewItemIcons", agendaViewIconDefaults());
174     const auto monthIconArray = monthViewConfig.readEntry<QByteArray>("monthViewItemIcons", monthViewIconDefaults());
175 
176     mAgendaViewIcons = iconArrayToSet(agendaIconArray);
177     mMonthViewIcons = iconArrayToSet(monthIconArray);
178 
179     KConfigSkeleton::usrRead();
180 }
181 
usrSave()182 bool BaseConfig::usrSave()
183 {
184     KConfigGroup rColorsConfig(config(), "Resources Colors");
185     for (auto it = mResourceColors.constBegin(); it != mResourceColors.constEnd(); ++it) {
186         rColorsConfig.writeEntry(it.key(), it.value());
187     }
188 
189 #if 0
190     if (mRememberRetrievePw) {
191         config()->writeEntry("Retrieve Server Password",
192                              KStringHandler::obscure(mRetrievePassword));
193     } else {
194         config()->deleteEntry("Retrieve Server Password");
195     }
196 #endif
197 
198     KConfigGroup timeScaleConfig(config(), "Timescale");
199     timeScaleConfig.writeEntry("Timescale Timezones", timeScaleTimezones());
200 
201     KConfigGroup monthViewConfig(config(), "Month View");
202     KConfigGroup agendaViewConfig(config(), "Agenda View");
203 
204     const QByteArray agendaIconArray = iconSetToArray(mAgendaViewIcons);
205     const QByteArray monthIconArray = iconSetToArray(mMonthViewIcons);
206 
207     agendaViewConfig.writeEntry<QByteArray>("agendaViewItemIcons", agendaIconArray);
208     monthViewConfig.writeEntry<QByteArray>("monthViewItemIcons", monthIconArray);
209 
210     return KConfigSkeleton::usrSave();
211 }
212 
213 class EventViews::PrefsPrivate
214 {
215 public:
PrefsPrivate(Prefs * parent)216     explicit PrefsPrivate(Prefs *parent)
217         : mAppConfig(nullptr)
218         , q(parent)
219     {
220     }
221 
PrefsPrivate(Prefs * parent,KCoreConfigSkeleton * appConfig)222     PrefsPrivate(Prefs *parent, KCoreConfigSkeleton *appConfig)
223         : mAppConfig(appConfig)
224         , q(parent)
225     {
226     }
227 
228     KConfigSkeletonItem *appConfigItem(const KConfigSkeletonItem *baseConfigItem) const;
229 
230     void setBool(KCoreConfigSkeleton::ItemBool *baseConfigItem, bool value);
231     bool getBool(const KCoreConfigSkeleton::ItemBool *baseConfigItem) const;
232 
233     void setInt(KCoreConfigSkeleton::ItemInt *baseConfigItem, int value);
234     int getInt(const KCoreConfigSkeleton::ItemInt *baseConfigItem) const;
235 
236     void setString(KCoreConfigSkeleton::ItemString *baseConfigItem, const QString &value);
237     QString getString(const KCoreConfigSkeleton::ItemString *baseConfigItem) const;
238 
239     void setDateTime(KCoreConfigSkeleton::ItemDateTime *baseConfigItem, const QDateTime &value);
240     QDateTime getDateTime(const KCoreConfigSkeleton::ItemDateTime *baseConfigItem) const;
241 
242     void setStringList(KCoreConfigSkeleton::ItemStringList *baseConfigItem, const QStringList &value);
243     QStringList getStringList(const KCoreConfigSkeleton::ItemStringList *baseConfigItem) const;
244 
245     void setColor(KConfigSkeleton::ItemColor *baseConfigItem, const QColor &value);
246     QColor getColor(const KConfigSkeleton::ItemColor *baseConfigItem) const;
247 
248     void setFont(KConfigSkeleton::ItemFont *baseConfigItem, const QFont &value);
249     QFont getFont(const KConfigSkeleton::ItemFont *baseConfigItem) const;
250 
251 public:
252     BaseConfig mBaseConfig;
253     KCoreConfigSkeleton *mAppConfig = nullptr;
254 
255 private:
256     Prefs *q;
257 };
258 
appConfigItem(const KConfigSkeletonItem * baseConfigItem) const259 KConfigSkeletonItem *PrefsPrivate::appConfigItem(const KConfigSkeletonItem *baseConfigItem) const
260 {
261     Q_ASSERT(baseConfigItem);
262 
263     if (mAppConfig) {
264         return mAppConfig->findItem(baseConfigItem->name());
265     }
266 
267     return nullptr;
268 }
269 
setBool(KCoreConfigSkeleton::ItemBool * baseConfigItem,bool value)270 void PrefsPrivate::setBool(KCoreConfigSkeleton::ItemBool *baseConfigItem, bool value)
271 {
272     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
273     if (appItem) {
274         auto item = dynamic_cast<KCoreConfigSkeleton::ItemBool *>(appItem);
275         if (item) {
276             item->setValue(value);
277         } else {
278             qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Bool";
279         }
280     } else {
281         baseConfigItem->setValue(value);
282     }
283 }
284 
getBool(const KCoreConfigSkeleton::ItemBool * baseConfigItem) const285 bool PrefsPrivate::getBool(const KCoreConfigSkeleton::ItemBool *baseConfigItem) const
286 {
287     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
288     if (appItem) {
289         auto item = dynamic_cast<KCoreConfigSkeleton::ItemBool *>(appItem);
290         if (item) {
291             return item->value();
292         }
293         qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Bool";
294     }
295     return baseConfigItem->value();
296 }
297 
setInt(KCoreConfigSkeleton::ItemInt * baseConfigItem,int value)298 void PrefsPrivate::setInt(KCoreConfigSkeleton::ItemInt *baseConfigItem, int value)
299 {
300     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
301     if (appItem) {
302         auto item = dynamic_cast<KCoreConfigSkeleton::ItemInt *>(appItem);
303         if (item) {
304             item->setValue(value);
305         } else {
306             qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Int";
307         }
308     } else {
309         baseConfigItem->setValue(value);
310     }
311 }
312 
getInt(const KCoreConfigSkeleton::ItemInt * baseConfigItem) const313 int PrefsPrivate::getInt(const KCoreConfigSkeleton::ItemInt *baseConfigItem) const
314 {
315     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
316     if (appItem) {
317         auto item = dynamic_cast<KCoreConfigSkeleton::ItemInt *>(appItem);
318         if (item) {
319             return item->value();
320         }
321         qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Int";
322     }
323     return baseConfigItem->value();
324 }
325 
setString(KCoreConfigSkeleton::ItemString * baseConfigItem,const QString & value)326 void PrefsPrivate::setString(KCoreConfigSkeleton::ItemString *baseConfigItem, const QString &value)
327 {
328     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
329     if (appItem) {
330         auto item = dynamic_cast<KCoreConfigSkeleton::ItemString *>(appItem);
331 
332         if (item) {
333             item->setValue(value);
334         } else {
335             qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type String";
336         }
337     } else {
338         baseConfigItem->setValue(value);
339     }
340 }
341 
getString(const KCoreConfigSkeleton::ItemString * baseConfigItem) const342 QString PrefsPrivate::getString(const KCoreConfigSkeleton::ItemString *baseConfigItem) const
343 {
344     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
345     if (appItem) {
346         auto item = dynamic_cast<KCoreConfigSkeleton::ItemString *>(appItem);
347 
348         if (item) {
349             return item->value();
350         }
351         qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type String";
352     }
353     return baseConfigItem->value();
354 }
355 
setDateTime(KCoreConfigSkeleton::ItemDateTime * baseConfigItem,const QDateTime & value)356 void PrefsPrivate::setDateTime(KCoreConfigSkeleton::ItemDateTime *baseConfigItem, const QDateTime &value)
357 {
358     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
359     if (appItem) {
360         auto item = dynamic_cast<KCoreConfigSkeleton::ItemDateTime *>(appItem);
361 
362         if (item) {
363             item->setValue(value);
364         } else {
365             qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type DateTime";
366         }
367     } else {
368         baseConfigItem->setValue(value);
369     }
370 }
371 
getDateTime(const KCoreConfigSkeleton::ItemDateTime * baseConfigItem) const372 QDateTime PrefsPrivate::getDateTime(const KCoreConfigSkeleton::ItemDateTime *baseConfigItem) const
373 {
374     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
375     if (appItem) {
376         auto item = dynamic_cast<KCoreConfigSkeleton::ItemDateTime *>(appItem);
377 
378         if (item) {
379             return item->value();
380         }
381         qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type DateTime";
382     }
383     return baseConfigItem->value();
384 }
385 
setStringList(KCoreConfigSkeleton::ItemStringList * baseConfigItem,const QStringList & value)386 void PrefsPrivate::setStringList(KCoreConfigSkeleton::ItemStringList *baseConfigItem, const QStringList &value)
387 {
388     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
389     if (appItem) {
390         auto item = dynamic_cast<KCoreConfigSkeleton::ItemStringList *>(appItem);
391 
392         if (item) {
393             item->setValue(value);
394         } else {
395             qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type StringList";
396         }
397     } else {
398         baseConfigItem->setValue(value);
399     }
400 }
401 
getStringList(const KCoreConfigSkeleton::ItemStringList * baseConfigItem) const402 QStringList PrefsPrivate::getStringList(const KCoreConfigSkeleton::ItemStringList *baseConfigItem) const
403 {
404     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
405     if (appItem) {
406         auto item = dynamic_cast<KCoreConfigSkeleton::ItemStringList *>(appItem);
407 
408         if (item) {
409             return item->value();
410         }
411         qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type StringList";
412     }
413     return baseConfigItem->value();
414 }
415 
setColor(KConfigSkeleton::ItemColor * baseConfigItem,const QColor & value)416 void PrefsPrivate::setColor(KConfigSkeleton::ItemColor *baseConfigItem, const QColor &value)
417 {
418     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
419     if (appItem) {
420         auto item = dynamic_cast<KConfigSkeleton::ItemColor *>(appItem);
421         if (item) {
422             item->setValue(value);
423         } else {
424             qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Color";
425         }
426     } else {
427         baseConfigItem->setValue(value);
428     }
429 }
430 
getColor(const KConfigSkeleton::ItemColor * baseConfigItem) const431 QColor PrefsPrivate::getColor(const KConfigSkeleton::ItemColor *baseConfigItem) const
432 {
433     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
434     if (appItem) {
435         auto item = dynamic_cast<KConfigSkeleton::ItemColor *>(appItem);
436         if (item) {
437             return item->value();
438         }
439         qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Color";
440     }
441     return baseConfigItem->value();
442 }
443 
setFont(KConfigSkeleton::ItemFont * baseConfigItem,const QFont & value)444 void PrefsPrivate::setFont(KConfigSkeleton::ItemFont *baseConfigItem, const QFont &value)
445 {
446     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
447     if (appItem) {
448         auto item = dynamic_cast<KConfigSkeleton::ItemFont *>(appItem);
449         if (item) {
450             item->setValue(value);
451         } else {
452             qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Font";
453         }
454     } else {
455         baseConfigItem->setValue(value);
456     }
457 }
458 
getFont(const KConfigSkeleton::ItemFont * baseConfigItem) const459 QFont PrefsPrivate::getFont(const KConfigSkeleton::ItemFont *baseConfigItem) const
460 {
461     KConfigSkeletonItem *appItem = appConfigItem(baseConfigItem);
462     if (appItem) {
463         auto item = dynamic_cast<KConfigSkeleton::ItemFont *>(appItem);
464         if (item) {
465             return item->value();
466         }
467         qCCritical(CALENDARVIEW_LOG) << "Application config item" << appItem->name() << "is not of type Font";
468     }
469     return baseConfigItem->value();
470 }
471 
Prefs()472 Prefs::Prefs()
473     : d(new PrefsPrivate(this))
474 {
475     // necessary to use CollectionColorAttribute in the EventViews::resourceColor and EventViews::setResourceColor
476     Akonadi::AttributeFactory::registerAttribute<Akonadi::CollectionColorAttribute>();
477 }
478 
Prefs(KCoreConfigSkeleton * appConfig)479 Prefs::Prefs(KCoreConfigSkeleton *appConfig)
480     : d(new PrefsPrivate(this, appConfig))
481 {
482     // necessary to use CollectionColorAttribute in the EventViews::resourceColor and EventViews::setResourceColor
483     Akonadi::AttributeFactory::registerAttribute<Akonadi::CollectionColorAttribute>();
484 }
485 
486 Prefs::~Prefs() = default;
487 
readConfig()488 void Prefs::readConfig()
489 {
490     d->mBaseConfig.load();
491     if (d->mAppConfig) {
492         d->mAppConfig->load();
493     }
494 }
495 
writeConfig()496 void Prefs::writeConfig()
497 {
498     d->mBaseConfig.save();
499     if (d->mAppConfig) {
500         d->mAppConfig->save();
501     }
502 }
503 
setUseSystemColor(bool useSystemColor)504 void Prefs::setUseSystemColor(bool useSystemColor)
505 {
506     d->setBool(d->mBaseConfig.useSystemColorItem(), useSystemColor);
507 }
508 
useSystemColor() const509 bool Prefs::useSystemColor() const
510 {
511     return d->getBool(d->mBaseConfig.useSystemColorItem());
512 }
513 
setMarcusBainsShowSeconds(bool showSeconds)514 void Prefs::setMarcusBainsShowSeconds(bool showSeconds)
515 {
516     d->setBool(d->mBaseConfig.marcusBainsShowSecondsItem(), showSeconds);
517 }
518 
marcusBainsShowSeconds() const519 bool Prefs::marcusBainsShowSeconds() const
520 {
521     return d->getBool(d->mBaseConfig.marcusBainsShowSecondsItem());
522 }
523 
setAgendaMarcusBainsLineLineColor(const QColor & color)524 void Prefs::setAgendaMarcusBainsLineLineColor(const QColor &color)
525 {
526     d->setColor(d->mBaseConfig.agendaMarcusBainsLineLineColorItem(), color);
527 }
528 
agendaMarcusBainsLineLineColor() const529 QColor Prefs::agendaMarcusBainsLineLineColor() const
530 {
531     return d->getColor(d->mBaseConfig.agendaMarcusBainsLineLineColorItem());
532 }
533 
setMarcusBainsEnabled(bool enabled)534 void Prefs::setMarcusBainsEnabled(bool enabled)
535 {
536     d->setBool(d->mBaseConfig.marcusBainsEnabledItem(), enabled);
537 }
538 
marcusBainsEnabled() const539 bool Prefs::marcusBainsEnabled() const
540 {
541     return d->getBool(d->mBaseConfig.marcusBainsEnabledItem());
542 }
543 
setAgendaMarcusBainsLineFont(const QFont & font)544 void Prefs::setAgendaMarcusBainsLineFont(const QFont &font)
545 {
546     d->setFont(d->mBaseConfig.agendaMarcusBainsLineFontItem(), font);
547 }
548 
agendaMarcusBainsLineFont() const549 QFont Prefs::agendaMarcusBainsLineFont() const
550 {
551     return d->getFont(d->mBaseConfig.agendaMarcusBainsLineFontItem());
552 }
553 
setHourSize(int size)554 void Prefs::setHourSize(int size)
555 {
556     d->setInt(d->mBaseConfig.hourSizeItem(), size);
557 }
558 
hourSize() const559 int Prefs::hourSize() const
560 {
561     return d->getInt(d->mBaseConfig.hourSizeItem());
562 }
563 
setDayBegins(const QDateTime & dateTime)564 void Prefs::setDayBegins(const QDateTime &dateTime)
565 {
566     d->setDateTime(d->mBaseConfig.dayBeginsItem(), dateTime);
567 }
568 
dayBegins() const569 QDateTime Prefs::dayBegins() const
570 {
571     return d->getDateTime(d->mBaseConfig.dayBeginsItem());
572 }
573 
setFirstDayOfWeek(const int day)574 void Prefs::setFirstDayOfWeek(const int day)
575 {
576     d->setInt(d->mBaseConfig.weekStartDayItem(), day - 1);
577 }
578 
firstDayOfWeek() const579 int Prefs::firstDayOfWeek() const
580 {
581     return d->getInt(d->mBaseConfig.weekStartDayItem()) + 1;
582 }
583 
setWorkingHoursStart(const QDateTime & dateTime)584 void Prefs::setWorkingHoursStart(const QDateTime &dateTime)
585 {
586     d->setDateTime(d->mBaseConfig.workingHoursStartItem(), dateTime);
587 }
588 
workingHoursStart() const589 QDateTime Prefs::workingHoursStart() const
590 {
591     return d->getDateTime(d->mBaseConfig.workingHoursStartItem());
592 }
593 
setWorkingHoursEnd(const QDateTime & dateTime)594 void Prefs::setWorkingHoursEnd(const QDateTime &dateTime)
595 {
596     d->setDateTime(d->mBaseConfig.workingHoursEndItem(), dateTime);
597 }
598 
workingHoursEnd() const599 QDateTime Prefs::workingHoursEnd() const
600 {
601     return d->getDateTime(d->mBaseConfig.workingHoursEndItem());
602 }
603 
setSelectionStartsEditor(bool startEditor)604 void Prefs::setSelectionStartsEditor(bool startEditor)
605 {
606     d->setBool(d->mBaseConfig.selectionStartsEditorItem(), startEditor);
607 }
608 
selectionStartsEditor() const609 bool Prefs::selectionStartsEditor() const
610 {
611     return d->getBool(d->mBaseConfig.selectionStartsEditorItem());
612 }
613 
setAgendaGridWorkHoursBackgroundColor(const QColor & color)614 void Prefs::setAgendaGridWorkHoursBackgroundColor(const QColor &color)
615 {
616     d->setColor(d->mBaseConfig.agendaGridWorkHoursBackgroundColorItem(), color);
617 }
618 
agendaGridWorkHoursBackgroundColor() const619 QColor Prefs::agendaGridWorkHoursBackgroundColor() const
620 {
621     return d->getColor(d->mBaseConfig.agendaGridWorkHoursBackgroundColorItem());
622 }
623 
setAgendaGridHighlightColor(const QColor & color)624 void Prefs::setAgendaGridHighlightColor(const QColor &color)
625 {
626     d->setColor(d->mBaseConfig.agendaGridHighlightColorItem(), color);
627 }
628 
agendaGridHighlightColor() const629 QColor Prefs::agendaGridHighlightColor() const
630 {
631     return d->getColor(d->mBaseConfig.agendaGridHighlightColorItem());
632 }
633 
setAgendaGridBackgroundColor(const QColor & color)634 void Prefs::setAgendaGridBackgroundColor(const QColor &color)
635 {
636     d->setColor(d->mBaseConfig.agendaGridBackgroundColorItem(), color);
637 }
638 
agendaGridBackgroundColor() const639 QColor Prefs::agendaGridBackgroundColor() const
640 {
641     return d->getColor(d->mBaseConfig.agendaGridBackgroundColorItem());
642 }
643 
setEnableAgendaItemIcons(bool enable)644 void Prefs::setEnableAgendaItemIcons(bool enable)
645 {
646     d->setBool(d->mBaseConfig.enableAgendaItemIconsItem(), enable);
647 }
648 
enableAgendaItemIcons() const649 bool Prefs::enableAgendaItemIcons() const
650 {
651     return d->getBool(d->mBaseConfig.enableAgendaItemIconsItem());
652 }
653 
setTodosUseCategoryColors(bool useColors)654 void Prefs::setTodosUseCategoryColors(bool useColors)
655 {
656     d->setBool(d->mBaseConfig.todosUseCategoryColorsItem(), useColors);
657 }
658 
todosUseCategoryColors() const659 bool Prefs::todosUseCategoryColors() const
660 {
661     return d->getBool(d->mBaseConfig.todosUseCategoryColorsItem());
662 }
663 
setAgendaHolidaysBackgroundColor(const QColor & color) const664 void Prefs::setAgendaHolidaysBackgroundColor(const QColor &color) const
665 {
666     d->setColor(d->mBaseConfig.agendaHolidaysBackgroundColorItem(), color);
667 }
668 
agendaHolidaysBackgroundColor() const669 QColor Prefs::agendaHolidaysBackgroundColor() const
670 {
671     return d->getColor(d->mBaseConfig.agendaHolidaysBackgroundColorItem());
672 }
673 
setAgendaViewColors(int colors)674 void Prefs::setAgendaViewColors(int colors)
675 {
676     d->setInt(d->mBaseConfig.agendaViewColorsItem(), colors);
677 }
678 
agendaViewColors() const679 int Prefs::agendaViewColors() const
680 {
681     return d->getInt(d->mBaseConfig.agendaViewColorsItem());
682 }
683 
setAgendaViewFont(const QFont & font)684 void Prefs::setAgendaViewFont(const QFont &font)
685 {
686     d->setFont(d->mBaseConfig.agendaViewFontItem(), font);
687 }
688 
agendaViewFont() const689 QFont Prefs::agendaViewFont() const
690 {
691     return d->getFont(d->mBaseConfig.agendaViewFontItem());
692 }
693 
setMonthViewFont(const QFont & font)694 void Prefs::setMonthViewFont(const QFont &font)
695 {
696     d->setFont(d->mBaseConfig.monthViewFontItem(), font);
697 }
698 
monthViewFont() const699 QFont Prefs::monthViewFont() const
700 {
701     return d->getFont(d->mBaseConfig.monthViewFontItem());
702 }
703 
monthGridBackgroundColor() const704 QColor Prefs::monthGridBackgroundColor() const
705 {
706     return d->getColor(d->mBaseConfig.monthGridBackgroundColorItem());
707 }
708 
setMonthGridBackgroundColor(const QColor & color)709 void Prefs::setMonthGridBackgroundColor(const QColor &color)
710 {
711     d->setColor(d->mBaseConfig.monthGridBackgroundColorItem(), color);
712 }
713 
monthGridWorkHoursBackgroundColor() const714 QColor Prefs::monthGridWorkHoursBackgroundColor() const
715 {
716     return d->getColor(d->mBaseConfig.monthGridWorkHoursBackgroundColorItem());
717 }
718 
monthGridWorkHoursBackgroundColor(const QColor & color)719 void Prefs::monthGridWorkHoursBackgroundColor(const QColor &color)
720 {
721     d->setColor(d->mBaseConfig.monthGridWorkHoursBackgroundColorItem(), color);
722 }
723 
monthViewColors() const724 int Prefs::monthViewColors() const
725 {
726     return d->getInt(d->mBaseConfig.monthViewColorsItem());
727 }
728 
setMonthViewColors(int colors) const729 void Prefs::setMonthViewColors(int colors) const
730 {
731     d->setInt(d->mBaseConfig.monthViewColorsItem(), colors);
732 }
733 
setEnableMonthItemIcons(bool enable)734 void Prefs::setEnableMonthItemIcons(bool enable)
735 {
736     d->setBool(d->mBaseConfig.enableMonthItemIconsItem(), enable);
737 }
738 
enableMonthItemIcons() const739 bool Prefs::enableMonthItemIcons() const
740 {
741     return d->getBool(d->mBaseConfig.enableMonthItemIconsItem());
742 }
743 
showTimeInMonthView() const744 bool Prefs::showTimeInMonthView() const
745 {
746     return d->getBool(d->mBaseConfig.showTimeInMonthViewItem());
747 }
748 
setShowTimeInMonthView(bool show)749 void Prefs::setShowTimeInMonthView(bool show)
750 {
751     d->setBool(d->mBaseConfig.showTimeInMonthViewItem(), show);
752 }
753 
showTodosMonthView() const754 bool Prefs::showTodosMonthView() const
755 {
756     return d->getBool(d->mBaseConfig.showTodosMonthViewItem());
757 }
758 
setShowTodosMonthView(bool enable)759 void Prefs::setShowTodosMonthView(bool enable)
760 {
761     d->setBool(d->mBaseConfig.showTodosMonthViewItem(), enable);
762 }
763 
showJournalsMonthView() const764 bool Prefs::showJournalsMonthView() const
765 {
766     return d->getBool(d->mBaseConfig.showJournalsMonthViewItem());
767 }
768 
setShowJournalsMonthView(bool enable)769 void Prefs::setShowJournalsMonthView(bool enable)
770 {
771     d->setBool(d->mBaseConfig.showJournalsMonthViewItem(), enable);
772 }
773 
fullViewMonth() const774 bool Prefs::fullViewMonth() const
775 {
776     return d->getBool(d->mBaseConfig.fullViewMonthItem());
777 }
778 
setFullViewMonth(bool fullView)779 void Prefs::setFullViewMonth(bool fullView)
780 {
781     d->setBool(d->mBaseConfig.fullViewMonthItem(), fullView);
782 }
783 
sortCompletedTodosSeparately() const784 bool Prefs::sortCompletedTodosSeparately() const
785 {
786     return d->getBool(d->mBaseConfig.sortCompletedTodosSeparatelyItem());
787 }
788 
setSortCompletedTodosSeparately(bool enable)789 void Prefs::setSortCompletedTodosSeparately(bool enable)
790 {
791     d->setBool(d->mBaseConfig.sortCompletedTodosSeparatelyItem(), enable);
792 }
793 
setEnableToolTips(bool enable)794 void Prefs::setEnableToolTips(bool enable)
795 {
796     d->setBool(d->mBaseConfig.enableToolTipsItem(), enable);
797 }
798 
enableToolTips() const799 bool Prefs::enableToolTips() const
800 {
801     return d->getBool(d->mBaseConfig.enableToolTipsItem());
802 }
803 
setShowTodosAgendaView(bool show)804 void Prefs::setShowTodosAgendaView(bool show)
805 {
806     d->setBool(d->mBaseConfig.showTodosAgendaViewItem(), show);
807 }
808 
showTodosAgendaView() const809 bool Prefs::showTodosAgendaView() const
810 {
811     return d->getBool(d->mBaseConfig.showTodosAgendaViewItem());
812 }
813 
setAgendaTimeLabelsFont(const QFont & font)814 void Prefs::setAgendaTimeLabelsFont(const QFont &font)
815 {
816     d->setFont(d->mBaseConfig.agendaTimeLabelsFontItem(), font);
817 }
818 
agendaTimeLabelsFont() const819 QFont Prefs::agendaTimeLabelsFont() const
820 {
821     return d->getFont(d->mBaseConfig.agendaTimeLabelsFontItem());
822 }
823 
timeZone() const824 QTimeZone Prefs::timeZone() const
825 {
826     return QTimeZone::systemTimeZone();
827 }
828 
colorAgendaBusyDays() const829 bool Prefs::colorAgendaBusyDays() const
830 {
831     return d->getBool(d->mBaseConfig.colorBusyDaysEnabledItem());
832 }
833 
colorMonthBusyDays() const834 bool Prefs::colorMonthBusyDays() const
835 {
836     return d->getBool(d->mBaseConfig.colorMonthBusyDaysEnabledItem());
837 }
838 
viewBgBusyColor() const839 QColor Prefs::viewBgBusyColor() const
840 {
841     return d->getColor(d->mBaseConfig.viewBgBusyColorItem());
842 }
843 
setViewBgBusyColor(const QColor & color)844 void Prefs::setViewBgBusyColor(const QColor &color)
845 {
846     d->mBaseConfig.mViewBgBusyColor = color;
847 }
848 
holidayColor() const849 QColor Prefs::holidayColor() const
850 {
851     return d->getColor(d->mBaseConfig.holidayColorItem());
852 }
853 
setHolidayColor(const QColor & color)854 void Prefs::setHolidayColor(const QColor &color)
855 {
856     d->mBaseConfig.mHolidayColor = color;
857 }
858 
agendaViewBackgroundColor() const859 QColor Prefs::agendaViewBackgroundColor() const
860 {
861     return d->getColor(d->mBaseConfig.agendaBgColorItem());
862 }
863 
setAgendaViewBackgroundColor(const QColor & color)864 void Prefs::setAgendaViewBackgroundColor(const QColor &color)
865 {
866     d->mBaseConfig.mAgendaBgColor = color;
867 }
868 
workingHoursColor() const869 QColor Prefs::workingHoursColor() const
870 {
871     return d->getColor(d->mBaseConfig.workingHoursColorItem());
872 }
873 
setWorkingHoursColor(const QColor & color)874 void Prefs::setWorkingHoursColor(const QColor &color)
875 {
876     d->mBaseConfig.mWorkingHoursColor = color;
877 }
878 
todoDueTodayColor() const879 QColor Prefs::todoDueTodayColor() const
880 {
881     return d->getColor(d->mBaseConfig.todoDueTodayColorItem());
882 }
883 
setTodoDueTodayColor(const QColor & color)884 void Prefs::setTodoDueTodayColor(const QColor &color)
885 {
886     d->mBaseConfig.mTodoDueTodayColor = color;
887 }
888 
todoOverdueColor() const889 QColor Prefs::todoOverdueColor() const
890 {
891     return d->getColor(d->mBaseConfig.todoOverdueColorItem());
892 }
893 
setTodoOverdueColor(const QColor & color)894 void Prefs::setTodoOverdueColor(const QColor &color)
895 {
896     d->mBaseConfig.mTodoOverdueColor = color;
897 }
898 
setColorAgendaBusyDays(bool enable)899 void Prefs::setColorAgendaBusyDays(bool enable)
900 {
901     d->mBaseConfig.mColorBusyDaysEnabled = enable;
902 }
903 
setColorMonthBusyDays(bool enable)904 void Prefs::setColorMonthBusyDays(bool enable)
905 {
906     d->mBaseConfig.mColorMonthBusyDaysEnabled = enable;
907 }
908 
setResourceColor(const QString & cal,const QColor & color)909 void Prefs::setResourceColor(const QString &cal, const QColor &color)
910 {
911     d->mBaseConfig.setResourceColor(cal, color);
912 }
913 
resourceColorKnown(const QString & cal) const914 QColor Prefs::resourceColorKnown(const QString &cal) const
915 {
916     QColor color;
917     if (!cal.isEmpty()) {
918         color = d->mBaseConfig.mResourceColors.value(cal);
919     }
920     return color;
921 }
922 
resourceColor(const QString & cal)923 QColor Prefs::resourceColor(const QString &cal)
924 {
925     if (cal.isEmpty()) {
926         return d->mBaseConfig.mDefaultResourceColor;
927     }
928 
929     QColor color = resourceColorKnown(cal);
930 
931     // assign default color if enabled
932     if (!color.isValid() && d->getBool(d->mBaseConfig.assignDefaultResourceColorsItem())) {
933         color.setRgb(0x37, 0x7A, 0xBC); // blueish
934         const int seed = d->getInt(d->mBaseConfig.defaultResourceColorSeedItem());
935         const QStringList colors = d->getStringList(d->mBaseConfig.defaultResourceColorsItem());
936         if (seed > 0 && seed - 1 < colors.size()) {
937             color.setNamedColor(colors[seed - 1]);
938         } else {
939             color.setRgb(QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256), QRandomGenerator::global()->bounded(256));
940         }
941         d->setInt(d->mBaseConfig.defaultResourceColorSeedItem(), (seed + 1));
942         d->mBaseConfig.setResourceColor(cal, color);
943     }
944     if (color.isValid()) {
945         return color;
946     } else {
947         return d->mBaseConfig.mDefaultResourceColor;
948     }
949 }
950 
timeScaleTimezones() const951 QStringList Prefs::timeScaleTimezones() const
952 {
953     return d->mBaseConfig.timeScaleTimezones();
954 }
955 
setTimeScaleTimezones(const QStringList & list)956 void Prefs::setTimeScaleTimezones(const QStringList &list)
957 {
958     d->mBaseConfig.setTimeScaleTimezones(list);
959 }
960 
fontItem(const QString & name) const961 KConfigSkeleton::ItemFont *Prefs::fontItem(const QString &name) const
962 {
963     KConfigSkeletonItem *item = d->mAppConfig ? d->mAppConfig->findItem(name) : nullptr;
964 
965     if (!item) {
966         item = d->mBaseConfig.findItem(name);
967     }
968 
969     return dynamic_cast<KConfigSkeleton::ItemFont *>(item);
970 }
971 
selectedPlugins() const972 QStringList Prefs::selectedPlugins() const
973 {
974     return d->mBaseConfig.mSelectedPlugins;
975 }
976 
decorationsAtAgendaViewTop() const977 QStringList Prefs::decorationsAtAgendaViewTop() const
978 {
979     return d->mBaseConfig.decorationsAtAgendaViewTop();
980 }
981 
decorationsAtAgendaViewBottom() const982 QStringList Prefs::decorationsAtAgendaViewBottom() const
983 {
984     return d->mBaseConfig.decorationsAtAgendaViewBottom();
985 }
986 
setSelectedPlugins(const QStringList & plugins)987 void Prefs::setSelectedPlugins(const QStringList &plugins)
988 {
989     d->mBaseConfig.setSelectedPlugins(plugins);
990 }
991 
setDecorationsAtAgendaViewTop(const QStringList & decorations)992 void Prefs::setDecorationsAtAgendaViewTop(const QStringList &decorations)
993 {
994     d->mBaseConfig.setDecorationsAtAgendaViewTop(decorations);
995 }
996 
setDecorationsAtAgendaViewBottom(const QStringList & decorations)997 void Prefs::setDecorationsAtAgendaViewBottom(const QStringList &decorations)
998 {
999     d->mBaseConfig.setDecorationsAtAgendaViewBottom(decorations);
1000 }
1001 
agendaViewIcons() const1002 QSet<EventViews::EventView::ItemIcon> Prefs::agendaViewIcons() const
1003 {
1004     return d->mBaseConfig.mAgendaViewIcons;
1005 }
1006 
setAgendaViewIcons(const QSet<EventViews::EventView::ItemIcon> & icons)1007 void Prefs::setAgendaViewIcons(const QSet<EventViews::EventView::ItemIcon> &icons)
1008 {
1009     d->mBaseConfig.mAgendaViewIcons = icons;
1010 }
1011 
monthViewIcons() const1012 QSet<EventViews::EventView::ItemIcon> Prefs::monthViewIcons() const
1013 {
1014     return d->mBaseConfig.mMonthViewIcons;
1015 }
1016 
setMonthViewIcons(const QSet<EventViews::EventView::ItemIcon> & icons)1017 void Prefs::setMonthViewIcons(const QSet<EventViews::EventView::ItemIcon> &icons)
1018 {
1019     d->mBaseConfig.mMonthViewIcons = icons;
1020 }
1021 
setFlatListTodo(bool enable)1022 void Prefs::setFlatListTodo(bool enable)
1023 {
1024     d->mBaseConfig.mFlatListTodo = enable;
1025 }
1026 
flatListTodo() const1027 bool Prefs::flatListTodo() const
1028 {
1029     return d->mBaseConfig.mFlatListTodo;
1030 }
1031 
setFullViewTodo(bool enable)1032 void Prefs::setFullViewTodo(bool enable)
1033 {
1034     d->mBaseConfig.mFullViewTodo = enable;
1035 }
1036 
fullViewTodo() const1037 bool Prefs::fullViewTodo() const
1038 {
1039     return d->mBaseConfig.mFullViewTodo;
1040 }
1041 
enableTodoQuickSearch() const1042 bool Prefs::enableTodoQuickSearch() const
1043 {
1044     return d->mBaseConfig.mEnableTodoQuickSearch;
1045 }
1046 
setEnableTodoQuickSearch(bool enable)1047 void Prefs::setEnableTodoQuickSearch(bool enable)
1048 {
1049     d->mBaseConfig.mEnableTodoQuickSearch = enable;
1050 }
1051 
enableQuickTodo() const1052 bool Prefs::enableQuickTodo() const
1053 {
1054     return d->mBaseConfig.mEnableQuickTodo;
1055 }
1056 
setEnableQuickTodo(bool enable)1057 void Prefs::setEnableQuickTodo(bool enable)
1058 {
1059     d->mBaseConfig.mEnableQuickTodo = enable;
1060 }
1061 
highlightTodos() const1062 bool Prefs::highlightTodos() const
1063 {
1064     return d->mBaseConfig.mHighlightTodos;
1065 }
1066 
setHighlightTodos(bool highlight)1067 void Prefs::setHighlightTodos(bool highlight)
1068 {
1069     d->mBaseConfig.mHighlightTodos = highlight;
1070 }
1071 
config() const1072 KConfig *Prefs::config() const
1073 {
1074     return d->mAppConfig ? d->mAppConfig->config() : d->mBaseConfig.config();
1075 }
1076