File indexing completed on 2024-04-28 05:11:29

0001 /*
0002   SPDX-FileCopyrightText: 2010 Bertjan Broeksema <broeksema@kde.org>
0003   SPDX-FileCopyrightText: 2010 Klarälvdalens Datakonsult AB, a KDAB Group company <info@kdab.com>
0004 
0005   SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "alarmpresets.h"
0009 
0010 #include <CalendarSupport/KCalPrefs>
0011 
0012 #include <KLocalizedString>
0013 
0014 #include "incidenceeditor_debug.h"
0015 
0016 using namespace CalendarSupport;
0017 using namespace KCalendarCore;
0018 
0019 namespace IncidenceEditorNG
0020 {
0021 namespace AlarmPresets
0022 {
0023 // Don't use a map, because order matters
0024 Q_GLOBAL_STATIC(QStringList, sBeforeStartPresetNames)
0025 Q_GLOBAL_STATIC(QStringList, sBeforeEndPresetNames)
0026 Q_GLOBAL_STATIC(QList<KCalendarCore::Alarm::Ptr>, sBeforeStartPresets)
0027 Q_GLOBAL_STATIC(QList<KCalendarCore::Alarm::Ptr>, sBeforeEndPresets)
0028 
0029 static int sDefaultPresetIndex = 0;
0030 static int sDefaultAlarmOffset = 0; // We must save it, so we can detect that config changed.
0031 
0032 int configuredReminderTimeInMinutes()
0033 {
0034     QList<int> units;
0035     units << 1 << 60 << (24 * 60);
0036 
0037     const int configuredUnits = KCalPrefs::instance()->reminderTimeUnits();
0038     const int unitsToUse = configuredUnits >= 0 && configuredUnits <= 2 ? configuredUnits : 0;
0039 
0040     const int configuredReminderTime = KCalPrefs::instance()->reminderTime();
0041     const int reminderTimeToUse = configuredReminderTime >= 0 ? configuredReminderTime : DEFAULT_REMINDER_OFFSET;
0042 
0043     return reminderTimeToUse * units[unitsToUse];
0044 }
0045 
0046 void initPresets(AlarmPresets::When when)
0047 {
0048     QList<int> hardcodedPresets;
0049     hardcodedPresets << 0 // at start/due
0050                      << 5 // 5 minutes
0051                      << 10 << 15 << 30 << 45 << 60 // 1 hour
0052                      << 2 * 60 // 2 hours
0053                      << 24 * 60 // 1 day
0054                      << 2 * 24 * 60 // 2 days
0055                      << 5 * 24 * 60; // 5 days
0056 
0057     sDefaultAlarmOffset = configuredReminderTimeInMinutes();
0058 
0059     if (!hardcodedPresets.contains(sDefaultAlarmOffset)) {
0060         // Lets insert the user's favorite preset (and keep the list sorted):
0061         int index;
0062         for (index = 0; index < hardcodedPresets.count(); ++index) {
0063             if (hardcodedPresets[index] > sDefaultAlarmOffset) {
0064                 break;
0065             }
0066         }
0067         hardcodedPresets.insert(index, sDefaultAlarmOffset);
0068         sDefaultPresetIndex = index;
0069     } else {
0070         sDefaultPresetIndex = hardcodedPresets.indexOf(sDefaultAlarmOffset);
0071     }
0072 
0073     switch (when) {
0074     case AlarmPresets::BeforeStart:
0075 
0076         for (int i = 0; i < hardcodedPresets.count(); ++i) {
0077             KCalendarCore::Alarm::Ptr alarm(new KCalendarCore::Alarm(nullptr));
0078             alarm->setType(KCalendarCore::Alarm::Display);
0079             const int minutes = hardcodedPresets[i];
0080             alarm->setStartOffset(-minutes * 60);
0081             alarm->setEnabled(true);
0082             if (minutes == 0) {
0083                 sBeforeStartPresetNames->append(i18nc("@item:inlistbox", "At start"));
0084             } else if (minutes < 60) {
0085                 sBeforeStartPresetNames->append(i18ncp("@item:inlistbox", "%1 minute before start", "%1 minutes before start", minutes));
0086             } else if (minutes < 24 * 60) {
0087                 sBeforeStartPresetNames->append(i18ncp("@item:inlistbox", "%1 hour before start", "%1 hours before start", minutes / 60));
0088             } else {
0089                 sBeforeStartPresetNames->append(i18ncp("@item:inlistbox", "%1 day before start", "%1 days before start", minutes / (24 * 60)));
0090             }
0091             sBeforeStartPresets->append(alarm);
0092         }
0093         break;
0094 
0095     case AlarmPresets::BeforeEnd:
0096         for (int i = 0; i < hardcodedPresets.count(); ++i) {
0097             KCalendarCore::Alarm::Ptr alarm(new KCalendarCore::Alarm(nullptr));
0098             alarm->setType(KCalendarCore::Alarm::Display);
0099             const int minutes = hardcodedPresets[i];
0100             alarm->setEndOffset(-minutes * 60);
0101             alarm->setEnabled(true);
0102             if (minutes == 0) {
0103                 sBeforeEndPresetNames->append(i18nc("@item:inlistbox", "When due"));
0104             } else if (minutes < 60) {
0105                 sBeforeEndPresetNames->append(i18ncp("@item:inlistbox", "%1 minute before due", "%1 minutes before due", minutes));
0106             } else if (minutes < 24 * 60) {
0107                 sBeforeEndPresetNames->append(i18ncp("@item:inlistbox", "%1 hour before due", "%1 hours before due", minutes / 60));
0108             } else {
0109                 sBeforeEndPresetNames->append(i18ncp("@item:inlistbox", "%1 day before due", "%1 days before due", minutes / (24 * 60)));
0110             }
0111             sBeforeEndPresets->append(alarm);
0112         }
0113         break;
0114     }
0115 }
0116 
0117 void checkInitNeeded(When when)
0118 {
0119     const int currentAlarmOffset = configuredReminderTimeInMinutes();
0120     const bool configChanged = currentAlarmOffset != sDefaultAlarmOffset;
0121 
0122     switch (when) {
0123     case AlarmPresets::BeforeStart:
0124         if (sBeforeStartPresetNames->isEmpty() || configChanged) {
0125             sBeforeStartPresetNames->clear();
0126             sBeforeStartPresets->clear();
0127             initPresets(when);
0128         }
0129         break;
0130     case AlarmPresets::BeforeEnd:
0131         if (sBeforeEndPresetNames->isEmpty() || configChanged) {
0132             sBeforeEndPresetNames->clear();
0133             sBeforeEndPresets->clear();
0134             initPresets(when);
0135         }
0136         break;
0137     default:
0138         Q_ASSERT_X(false, "checkInitNeeded", "Unknown preset type");
0139     }
0140 }
0141 
0142 QStringList availablePresets(AlarmPresets::When when)
0143 {
0144     checkInitNeeded(when);
0145 
0146     switch (when) {
0147     case AlarmPresets::BeforeStart:
0148         return *sBeforeStartPresetNames;
0149     case AlarmPresets::BeforeEnd:
0150         return *sBeforeEndPresetNames;
0151     }
0152     return {};
0153 }
0154 
0155 KCalendarCore::Alarm::Ptr preset(When when, const QString &name)
0156 {
0157     checkInitNeeded(when);
0158 
0159     switch (when) {
0160     case AlarmPresets::BeforeStart:
0161         // The name should exists and only once
0162         if (sBeforeStartPresetNames->count(name) != 1) {
0163             // print some debug info before crashing
0164             qCDebug(INCIDENCEEDITOR_LOG) << " name = " << name << "; when = " << when << "; count for name = " << sBeforeStartPresetNames->count(name)
0165                                          << "; global count = " << sBeforeStartPresetNames->count();
0166             Q_ASSERT_X(false, "preset", "Number of presets should be one");
0167         }
0168 
0169         return KCalendarCore::Alarm::Ptr(new KCalendarCore::Alarm(*sBeforeStartPresets->at(sBeforeStartPresetNames->indexOf(name))));
0170     case AlarmPresets::BeforeEnd:
0171         Q_ASSERT(sBeforeEndPresetNames->count(name) == 1); // The name should exists and only once
0172 
0173         return KCalendarCore::Alarm::Ptr(new KCalendarCore::Alarm(*sBeforeEndPresets->at(sBeforeEndPresetNames->indexOf(name))));
0174     }
0175     return {};
0176 }
0177 
0178 KCalendarCore::Alarm::Ptr defaultAlarm(When when)
0179 {
0180     checkInitNeeded(when);
0181 
0182     switch (when) {
0183     case AlarmPresets::BeforeStart:
0184         return Alarm::Ptr(new Alarm(*sBeforeStartPresets->at(sDefaultPresetIndex)));
0185     case AlarmPresets::BeforeEnd:
0186         return Alarm::Ptr(new Alarm(*sBeforeEndPresets->at(sDefaultPresetIndex)));
0187     }
0188     return {};
0189 }
0190 
0191 int presetIndex(When when, const KCalendarCore::Alarm::Ptr &alarm)
0192 {
0193     checkInitNeeded(when);
0194     const QStringList presets = availablePresets(when);
0195 
0196     for (int i = 0; i < presets.size(); ++i) {
0197         KCalendarCore::Alarm::Ptr presetAlarm(preset(when, presets.at(i)));
0198         if (presetAlarm == alarm) {
0199             return i;
0200         }
0201     }
0202 
0203     return -1;
0204 }
0205 
0206 int defaultPresetIndex()
0207 {
0208     // BeforeEnd would do too, index is the same.
0209     checkInitNeeded(AlarmPresets::BeforeStart);
0210     return sDefaultPresetIndex;
0211 }
0212 } // AlarmPresets
0213 } // IncidenceEditorNG