File indexing completed on 2024-05-12 05:14:46

0001 /*
0002  *  functions.h  -  miscellaneous functions
0003  *  Program:  kalarm
0004  *  SPDX-FileCopyrightText: 2007-2022 David Jarvie <djarvie@kde.org>
0005  *
0006  *  SPDX-License-Identifier: GPL-2.0-or-later
0007  */
0008 
0009 #pragma once
0010 
0011 /**  @file functions.h - miscellaneous functions */
0012 
0013 #include "config-kalarm.h"
0014 #include "editdlg.h"
0015 #include "eventid.h"
0016 #include "kalarmcalendar/kaevent.h"
0017 
0018 #include <QList>
0019 #include <QString>
0020 
0021 using namespace KAlarmCal;
0022 
0023 namespace KCal { class Event; }
0024 namespace KAlarmCal { class AlarmText; }
0025 class QWidget;
0026 class QAction;
0027 class QMimeData;
0028 class KToggleAction;
0029 class Resource;
0030 class MainWindow;
0031 class AlarmListModel;
0032 
0033 namespace KAlarm
0034 {
0035 
0036 /** Return codes from calendar update functions.
0037  *  The codes are ordered by severity, so...
0038  *  DO NOT CHANGE THE ORDER OF THESE VALUES!
0039  */
0040 enum UpdateStatus {
0041     UPDATE_OK,            // update succeeded
0042     UPDATE_KORG_FUNCERR,  // update succeeded, but KOrganizer reported an error updating
0043     UPDATE_KORG_ERRSTART, // update succeeded, but KOrganizer update failed (KOrganizer not fully started)
0044     UPDATE_KORG_ERRINIT,  // update succeeded, but KOrganizer update failed (KOrganizer not started)
0045     UPDATE_KORG_ERR,      // update succeeded, but KOrganizer update failed
0046     UPDATE_ERROR,         // update failed partially
0047     UPDATE_FAILED,        // update failed completely
0048     SAVE_FAILED           // calendar was updated in memory, but save failed
0049 };
0050 /** Error codes supplied as parameter to displayUpdateError() */
0051 enum UpdateError { ERR_ADD, ERR_MODIFY, ERR_DELETE, ERR_REACTIVATE, ERR_TEMPLATE };
0052 
0053 /** Result of calendar update. */
0054 struct UpdateResult
0055 {
0056     UpdateStatus  status;   // status code
0057     QString       message;  // error message if any
0058     QList<int>    failed;   // indexes to events whose update failed
0059 
0060     UpdateResult() : status(UPDATE_OK) {}
0061     explicit UpdateResult(UpdateStatus s, const QString& m = QString()) : status(s), message(m) {}
0062     UpdateResult& operator=(UpdateStatus s)  { status = s; message.clear(); return *this; }
0063     bool operator==(UpdateStatus s) const  { return status == s; }
0064     bool operator!=(UpdateStatus s) const  { return status != s; }
0065     bool operator>(UpdateStatus s) const   { return status > s; }
0066     bool operator>=(UpdateStatus s) const  { return status >= s; }
0067     bool operator<=(UpdateStatus s) const  { return status <= s; }
0068     bool operator<(UpdateStatus s) const   { return status < s; }
0069     void set(UpdateStatus s) { operator=(s); }
0070     void set(UpdateStatus s, const QString& m) { status = s; message = m; }
0071 };
0072 
0073 QString i18n_act_StopPlay();      // text of Stop Play action
0074 
0075 /** Display a main window with the specified event selected */
0076 MainWindow*    displayMainWindowSelected(const QString& eventId);
0077 
0078 bool           editNewAlarm(const QString& templateName, QWidget* parent = nullptr);
0079 void           editNewAlarm(EditAlarmDlg::Type, QWidget* parent = nullptr);
0080 void           editNewAlarm(EditAlarmDlg::Type, const QDate& startDate, QWidget* parent = nullptr);
0081 void           editNewAlarm(KAEvent::SubAction, QWidget* parent = nullptr, const AlarmText* = nullptr);
0082 void           editNewAlarm(const KAEvent& preset, QWidget* parent = nullptr);
0083 void           editNewAlarm(const KAEvent& preset, const QDate& startDate, QWidget* parent = nullptr);
0084 void           editAlarm(KAEvent&, QWidget* parent = nullptr);
0085 bool           editAlarmById(const EventId& eventID, QWidget* parent = nullptr);
0086 void           updateEditedAlarm(EditAlarmDlg*, KAEvent&, Resource&);
0087 void           viewAlarm(const KAEvent&, QWidget* parent = nullptr);
0088 void           editNewTemplate(EditAlarmDlg::Type, QWidget* parent = nullptr);
0089 void           editNewTemplate(const KAEvent& preset, QWidget* parent = nullptr);
0090 void           editTemplate(const KAEvent&, QWidget* parent = nullptr);
0091 void           execNewAlarmDlg(EditAlarmDlg*, const QDate& startDate = QDate());
0092 /** Create a "New From Template" QAction */
0093 KToggleAction* createAlarmEnableAction(QObject* parent);
0094 QAction*       createStopPlayAction(QObject* parent);
0095 KToggleAction* createSpreadWindowsAction(QObject* parent);
0096 /** Returns a list of all alarm templates.
0097  *  If shell commands are disabled, command alarm templates are omitted.
0098  */
0099 QList<KAEvent> templateList();
0100 void           outputAlarmWarnings(QWidget* parent, const KAEvent* = nullptr);
0101 void           refreshAlarms();
0102 void           refreshAlarmsIfQueued();    // must only be called from KAlarmApp::processQueue()
0103 
0104 QStringList    dontShowErrors(const EventId&);
0105 bool           dontShowErrors(const EventId&, const QString& tag);
0106 void           setDontShowErrors(const EventId&, const QStringList& tags = QStringList());
0107 void           setDontShowErrors(const EventId&, const QString& tag);
0108 void           setDontShowErrors(const QString& eventId, const QString& tag);
0109 
0110 enum         // 'options' parameter values for addEvent(). May be OR'ed together.
0111 {
0112     USE_EVENT_ID       = 0x01,   // use event ID if it's provided
0113     NO_RESOURCE_PROMPT = 0x02,   // don't prompt for resource
0114     ALLOW_KORG_UPDATE  = 0x04    // allow change to be sent to KOrganizer
0115 };
0116 
0117 /** Add a new active (non-archived) alarm to a resource.
0118  *  @param event      Updated with the actual event ID.
0119  *  @param resource   Resource to add event to. If invalid, the default resource
0120  *                    is used or the user is prompted, depending on policy, and
0121  *                    'resource' is updated with the actual resource used.
0122  *  @param msgParent  Parent widget for any calendar selection prompt or error
0123  *                    message.
0124  *  @return  Success status; if >= UPDATE_FAILED, the new alarm has been discarded.
0125  */
0126 UpdateResult addEvent(KAEvent& event, Resource& resource, QWidget* msgParent = nullptr, int options = ALLOW_KORG_UPDATE, bool showKOrgErr = true);
0127 
0128 /** Add new active (non-archived) alarms to a resource.
0129  *  @param events     Updated with the actual event IDs.
0130  *  @param resource   Resource to add event to. If invalid, the default resource
0131  *                    is used or the user is prompted, depending on policy, and
0132  *                    'resource' is updated with the actual resource used.
0133  *  @param msgParent  Parent widget for any calendar selection prompt or error
0134  *                    message.
0135  *  @return  Success status; if >= UPDATE_FAILED, all new alarms have been discarded.
0136  */
0137 UpdateResult addEvents(QList<KAEvent>& events, Resource& resource, QWidget* msgParent = nullptr,
0138                        bool allowKOrgUpdate = true, bool showKOrgErr = true);
0139 
0140 /** Save the event in the archived calendar.
0141  *  The event's ID is changed to an archived ID if necessary.
0142  *  @param event      Updated with the archived event ID.
0143  *  @param resource   Resource to add event to. If invalid, the default resource
0144  *                    is used or the user is prompted, depending on policy, and
0145  *                    'resource' is updated with the actual resource used.
0146  */
0147 bool addArchivedEvent(KAEvent& event, Resource& resource);
0148 
0149 /** Add a new template to a resource.
0150  *  @param event      Updated with the actual event ID.
0151  *  @param resource   Resource to add event to. If invalid, the default resource
0152  *                    is used or the user is prompted, depending on policy, and
0153  *                    'resource' is updated with the actual resource used.
0154  *  @param msgParent  Parent widget for any calendar selection prompt or error
0155  *                    message.
0156  *  @return  Success status; if >= UPDATE_FAILED, the new template has been discarded.
0157  */
0158 UpdateResult addTemplate(KAEvent& event, Resource& resource, QWidget* msgParent = nullptr);
0159 
0160 /** Modify an active (non-archived) alarm in a resource.
0161  *  The new event must have a different event ID from the old one.
0162  *  @param oldEvent   Event to be replaced. Its resourceId() must give the ID of
0163  *                    the resource which contains it.
0164  *  @param newEvent   Modified version of the event. Updated with its new ID if
0165  *                    it was not supplied with one.
0166  *  @param msgParent  Parent widget for any calendar selection prompt or error
0167  *                    message.
0168  *  @return  Success status; if >= UPDATE_FAILED, the modification has been discarded.
0169  */
0170 UpdateResult modifyEvent(KAEvent& oldEvent, KAEvent& newEvent, QWidget* msgParent = nullptr, bool showKOrgErr = true);
0171 
0172 /** Update an active (non-archived) alarm.
0173  *  The new event will have the same event ID as the old one.
0174  *  The event is not updated in KOrganizer, since this function is called when an
0175  *  existing alarm is rescheduled (due to recurrence or deferral).
0176  *  @param event           Event to be replaced. Its resourceId() must give the
0177  *                         ID of the resource which contains it.
0178  *  @param msgParent       Parent widget for any calendar selection prompt or
0179  *                         error message.
0180  *  @param saveIfReadOnly  If the resource is read-only, whether to try to save
0181  *                         the resource after updating the event. (Writable
0182  *                         resources will always be saved.)
0183  *  @return  Success status; if >= UPDATE_FAILED, the update has been discarded.
0184  */
0185 UpdateResult updateEvent(KAEvent& event, QWidget* msgParent = nullptr, bool archiveOnDelete = true,
0186                          bool saveIfReadOnly = true);
0187 
0188 /** Update an alarm template.
0189  *  The new event will have the same event ID as the old one.
0190  *  @param event      Event to be replaced. Its resourceId() must give the ID of
0191  *                    the resource which contains it.
0192  *  @param msgParent  Parent widget for any calendar selection prompt or error
0193  *                    message.
0194  *  @return  Success status; if >= UPDATE_FAILED, the update has been discarded.
0195  */
0196 UpdateResult updateTemplate(KAEvent& event, QWidget* msgParent = nullptr);
0197 
0198 /** Delete an alarm from a resource.
0199  *  If the event is archived, the event's ID is changed to an archived ID if necessary.
0200  *  @param event      Event to delete.
0201  *  @param resource   Resource to delete event from. If invalid, this is
0202  *                    updated to the resource which contained the event.
0203  *  @param msgParent  Parent widget for any calendar selection prompt or error
0204  *                    message.
0205  *  @return  Success status; if >= UPDATE_FAILED, the deletion has been discarded.
0206  */
0207 UpdateResult deleteEvent(KAEvent& event, Resource& resource, bool archive = true, QWidget* msgParent = nullptr, bool showKOrgErr = true);
0208 
0209 /** Delete alarms from the resources.
0210  *  If the events are archived, the events' IDs are changed to archived IDs if necessary.
0211  *  @param events     Events to delete.
0212  *  @param resource   Resource to delete event from. If invalid, and all events
0213  *                    are found in the same resource, this is updated to the
0214  *                    resource which contained the events.
0215  *  @param msgParent  Parent widget for any calendar selection prompt or error
0216  *                    message.
0217  *  @return  Success status; if >= UPDATE_FAILED, all deletions have been discarded.
0218  */
0219 UpdateResult deleteEvents(QList<KAEvent>& events, Resource& resource, bool archive = true,
0220                           QWidget* msgParent = nullptr, bool showKOrgErr = true);
0221 
0222 /** Delete templates from the resources.
0223  *  @param event      Event to delete.
0224  *  @param msgParent  Parent widget for any calendar selection prompt or error
0225  *                    message.
0226  *  @return  Success status; if >= UPDATE_FAILED, all deletions have been discarded.
0227  */
0228 UpdateResult deleteTemplates(const KAEvent::List& events, QWidget* msgParent = nullptr);
0229 
0230 inline UpdateResult deleteTemplate(KAEvent& event, QWidget* msgParent = nullptr)
0231                         { KAEvent::List e;  e += &event;  return deleteTemplates(e, msgParent); }
0232 void                deleteDisplayEvent(const QString& eventID);
0233 
0234 /** Undelete an archived alarm.
0235  *  The archive bit is set to ensure that it gets re-archived if deleted again.
0236  *  @param event      Updated with the restored event.
0237  *  @param resource   Active alarms resource to restore the event to. If
0238  *                    invalid, the default resource is used or the user is
0239  *                    prompted, depending on policy, and 'resource' is updated
0240  *                    with the actual resource used.
0241  *  @param msgParent  Parent widget for any calendar selection prompt or error
0242  *                    message.
0243  *  @return  Success status; if >= UPDATE_FAILED, the reactivated event has been discarded.
0244  */
0245 UpdateResult reactivateEvent(KAEvent& event, Resource& resource, QWidget* msgParent = nullptr, bool showKOrgErr = true);
0246 
0247 /** Undelete archived alarms.
0248  *  The archive bit is set to ensure that they get re-archived if deleted again.
0249  *  @param events     Updated to contain the restored events.
0250  *  @param ineligibleIndexes  Receives the indexes to any ineligible events.
0251  *  @param resource   Active alarms resource to restore the events to. If
0252  *                    invalid, the default resource is used or the user is
0253  *                    prompted, depending on policy, and 'resource' is updated
0254  *                    with the actual resource used.
0255  *  @param msgParent  Parent widget for any calendar selection prompt or error
0256  *                    message.
0257  *  @return  Success status; if >= UPDATE_FAILED, all reactivated events have been discarded.
0258  */
0259 UpdateResult reactivateEvents(QList<KAEvent>& events, QList<int>& ineligibleIndexes,
0260                               Resource& resource, QWidget* msgParent = nullptr, bool showKOrgErr = true);
0261 
0262 /** Enable or disable alarms.
0263  *  The new events will have the same event IDs as the old ones.
0264  *  @param events     Events to be enabled. Each one's resourceId() must give
0265  *                    the ID of the resource which contains it.
0266  *  @param enable     Whether to enable or disable the events.
0267  *  @param msgParent  Parent widget for any calendar selection prompt or error
0268  *                    message.
0269  *  @return  Success status; if == UPDATE_FAILED, the enabled status of all
0270  *           events is unchanged; if == SAVE_FAILED, the enabled status of at
0271  *           least one event has been successfully changed, but will be lost
0272  *           when its resource is reloaded.
0273  */
0274 UpdateResult enableEvents(QList<KAEvent>& events, bool enable, QWidget* msgParent = nullptr);
0275 
0276 /** Return whether an event is read-only.
0277  *  This depends on whether the event or its resource is read-only.
0278  */
0279 bool eventReadOnly(const QString& eventId);
0280 
0281 QList<KAEvent> getSortedActiveEvents(QObject* parent, AlarmListModel** model = nullptr);
0282 void           purgeArchive(int purgeDays);    // must only be called from KAlarmApp::processQueue()
0283 
0284 /** Prompt the user for an external calendar file to import alarms from,
0285  *  and merge them into a resource. If the resource is invalid, the events
0286  *  will be merged into the default resource for each alarm type (obtained
0287  *  by calling destination(type)).
0288  *  The alarms are given new unique event IDs.
0289  *  @param parent    Parent widget for error message boxes
0290  *  @param resource  Resource to import into
0291  *  @return  true if all alarms in the calendar were successfully imported;
0292  *           false if any alarms failed to be imported.
0293  */
0294 bool importAlarms(Resource& resource, QWidget* parent);
0295 
0296 /** Prompt the user for an external calendar file, and export a list of
0297  *  alarms to it. If an existing file is chosen, the user has the choice
0298  *  whether to append or overwrite.
0299  *  The alarms are given new unique event IDs.
0300  *  @param events  Events to export
0301  *  @param parent  Parent widget for error message boxes
0302  *  @return  true if all alarms in the calendar were successfully exported;
0303  *           false if any alarms failed to be exported.
0304  */
0305 bool exportAlarms(const QList<KAEvent>& events, QWidget* parent);
0306 
0307 void        displayKOrgUpdateError(QWidget* parent, UpdateError, const UpdateResult& korgError, int nAlarms = 0);
0308 #if ENABLE_RTC_WAKE_FROM_SUSPEND
0309 QStringList checkRtcWakeConfig(bool checkEventExists = false);
0310 void        deleteRtcWakeConfig();
0311 void        cancelRtcWake(QWidget* msgParent, const QString& eventId = QString());
0312 bool        setRtcWakeTime(unsigned triggerTime, QWidget* parent);
0313 #endif
0314 
0315 /** Extract dragged and dropped Akonadi RFC822 message data.
0316  *  If the data does not contain an Akonadi email URL, or if the KAlarm Akonadi
0317  *  plugin is not available, this function simply returns the dropped URL.
0318  *  @param data       Dropped data.
0319  *  @param url        Receives the first URL in the data, or empty if data does
0320  *                    not provide URLs.
0321  *  @param alarmText  Receives the extracted Akonadi email data.
0322  *  @return  true if @p data contained Akonadi RFC822 message data, false if not.
0323  */
0324 bool dropAkonadiEmail(const QMimeData* data, QUrl& url, AlarmText& alarmText);
0325 
0326 bool        convertTimeString(const QByteArray& timeString, KADateTime& dateTime,
0327                               const KADateTime& defaultDt = KADateTime(), bool allowTZ = true);
0328 KADateTime  applyTimeZone(const QString& tzstring, const QDate& date, const QTime& time,
0329                           bool haveTime, const KADateTime& defaultDt = KADateTime());
0330 
0331 #ifndef NDEBUG
0332 void        setTestModeConditions();
0333 void        setSimulatedSystemTime(const KADateTime&);
0334 #endif
0335 
0336 } // namespace KAlarm
0337 
0338 bool caseInsensitiveLessThan(const QString& s1, const QString& s2);
0339 
0340 // vim: et sw=4: