Commit 0d64852b authored by David Jarvie's avatar David Jarvie
Browse files

Fix infinite loop when evaluating next alarm to schedule

Ensure that all KAEvent instances returned by resources contain the
correct resource ID.

Revise ResourcesCalendar to not keep its own separate copies of
KAEvent instances, but to use those held in resources instead.
parent 644f966c
Pipeline #27825 passed with stage
in 10 minutes and 29 seconds
KAlarm Change Log
=== Version 2.90.0 (KDE Applications 20.08 rc) --- 20 July 2020 ===
+ Fix infinite loop when evaluating next alarm to schedule.
=== Version 2.80.0 (KDE Applications 20.08 beta) --- 30 June 2020 ===
+ Default to using file system resources instead of Akonadi resources.
+ Enable selection of multiple calendar files in Import Alarms dialogue.
......
......@@ -97,14 +97,13 @@ void BirthdaySortModel::setPrefixSuffix(const QString& prefix, const QString& su
mPrefix = prefix;
mSuffix = suffix;
KAEvent event;
const KAEvent::List events = ResourcesCalendar::instance()->events(CalEvent::ACTIVE);
for (KAEvent* event : events)
const QVector<KAEvent> events = ResourcesCalendar::instance()->events(CalEvent::ACTIVE);
for (const KAEvent& event : events)
{
if (event->actionSubType() == KAEvent::MESSAGE
&& event->recurType() == KARecurrence::ANNUAL_DATE
&& (prefix.isEmpty() || event->message().startsWith(prefix)))
mContactsWithAlarm.append(event->message());
if (event.actionSubType() == KAEvent::MESSAGE
&& event.recurType() == KARecurrence::ANNUAL_DATE
&& (prefix.isEmpty() || event.message().startsWith(prefix)))
mContactsWithAlarm.append(event.message());
}
invalidateFilter();
......
......@@ -991,7 +991,7 @@ bool EditAlarmDlg::validate()
errmsg = i18nc("@info", "You must enter a name for the alarm template");
else if (name != mSavedTemplateName)
{
if (ResourcesCalendar::instance()->templateEvent(name))
if (ResourcesCalendar::instance()->templateEvent(name).isValid())
errmsg = i18nc("@info", "Template name is already in use");
}
if (!errmsg.isEmpty())
......
......@@ -679,7 +679,7 @@ UpdateResult reactivateEvents(QVector<KAEvent>& events, QVector<int>& ineligible
status.korgUpdate(st);
}
if (cal->event(EventId(*event))) // no error if event doesn't exist in archived resource
if (cal->event(EventId(*event)).isValid()) // no error if event doesn't exist in archived resource
eventsToDelete.append(*event);
events[i] = newevent;
}
......@@ -738,8 +738,8 @@ UpdateResult enableEvents(QVector<KAEvent>& events, bool enable, QWidget* msgPar
deleteWakeFromSuspendAlarm = true;
// Update the event in the calendar file
const KAEvent* newev = cal->updateEvent(*event);
if (!newev)
const KAEvent newev = cal->updateEvent(*event);
if (!newev.isValid())
{
qCCritical(KALARM_LOG) << "KAlarm::enableEvents: Error updating event in calendar:" << event->id();
status.appendFailed(i);
......@@ -803,10 +803,10 @@ void purgeArchive(int purgeDays)
const Resource resource = Resources::getStandard(CalEvent::ARCHIVED);
if (!resource.isValid())
return;
KAEvent::List events = ResourcesCalendar::instance()->events(resource);
QVector<KAEvent> events = ResourcesCalendar::instance()->events(resource);
for (int i = 0; i < events.count(); )
{
if (purgeDays && events.at(i)->createdDateTime().date() >= cutoff)
if (purgeDays && events.at(i).createdDateTime().date() >= cutoff)
events.remove(i);
else
++i;
......@@ -915,7 +915,7 @@ bool importAlarms(Resource& resource, QWidget* parent)
* Reply = true if all alarms in the calendar were successfully exported
* = false if any alarms failed to be exported.
*/
bool exportAlarms(const KAEvent::List& events, QWidget* parent)
bool exportAlarms(const QVector<KAEvent>& events, QWidget* parent)
{
bool append;
QString file = FileDialog::getSaveFileName(lastExportUrl,
......@@ -954,14 +954,13 @@ bool exportAlarms(const KAEvent::List& events, QWidget* parent)
// Add the alarms to the calendar
bool success = true;
bool exported = false;
for (int i = 0, end = events.count(); i < end; ++i)
for (const KAEvent& event : events)
{
const KAEvent* event = events[i];
Event::Ptr kcalEvent(new Event);
const CalEvent::Type type = event->category();
const CalEvent::Type type = event.category();
const QString id = CalEvent::uid(kcalEvent->uid(), type);
kcalEvent->setUid(id);
event->updateKCalEvent(kcalEvent, KAEvent::UID_IGNORE);
event.updateKCalEvent(kcalEvent, KAEvent::UID_IGNORE);
if (calendar->addEvent(kcalEvent))
exported = true;
else
......@@ -1186,10 +1185,10 @@ bool editNewAlarm(const QString& templateName, QWidget* parent)
{
if (!templateName.isEmpty())
{
KAEvent* templateEvent = ResourcesCalendar::instance()->templateEvent(templateName);
if (templateEvent->isValid())
KAEvent templateEvent = ResourcesCalendar::instance()->templateEvent(templateName);
if (templateEvent.isValid())
{
editNewAlarm(templateEvent, parent);
editNewAlarm(&templateEvent, parent);
return true;
}
qCWarning(KALARM_LOG) << "KAlarm::editNewAlarm:" << templateName << ": template not found";
......@@ -1332,8 +1331,8 @@ KAlarm::UpdateResult updateEvent(KAEvent& event, KAlarm::UpdateError err, QWidge
{
UpdateStatusData status;
ResourcesCalendar* cal = ResourcesCalendar::instance();
const KAEvent* newEvent = cal->updateEvent(event);
if (!newEvent)
const KAEvent newEvent = cal->updateEvent(event);
if (!newEvent.isValid())
status.status = KAlarm::UPDATE_FAILED;
else
{
......@@ -1406,7 +1405,7 @@ void editAlarm(KAEvent* event, QWidget* parent)
AutoQPointer<EditAlarmDlg> editDlg = EditAlarmDlg::create(false, event, false, parent, EditAlarmDlg::RES_USE_EVENT_ID);
if (editDlg && editDlg->exec() == QDialog::Accepted)
{
if (!ResourcesCalendar::instance()->event(id))
if (!ResourcesCalendar::instance()->event(id).isValid())
{
// Event has been deleted while the user was editing the alarm,
// so treat it as a new alarm.
......@@ -1445,8 +1444,8 @@ void editAlarm(KAEvent* event, QWidget* parent)
bool editAlarmById(const EventId& id, QWidget* parent)
{
const QString eventID(id.eventId());
KAEvent* event = ResourcesCalendar::instance()->event(id, true);
if (!event)
KAEvent event = ResourcesCalendar::instance()->event(id, true);
if (!event.isValid())
{
if (id.resourceId() != -1)
qCWarning(KALARM_LOG) << "KAlarm::editAlarmById: Event ID not found, or duplicated:" << eventID;
......@@ -1454,12 +1453,12 @@ bool editAlarmById(const EventId& id, QWidget* parent)
qCWarning(KALARM_LOG) << "KAlarm::editAlarmById: Event ID not found:" << eventID;
return false;
}
if (ResourcesCalendar::instance()->eventReadOnly(event->id()))
if (ResourcesCalendar::instance()->eventReadOnly(event.id()))
{
qCCritical(KALARM_LOG) << "KAlarm::editAlarmById:" << eventID << ": read-only";
return false;
}
switch (event->category())
switch (event.category())
{
case CalEvent::ACTIVE:
case CalEvent::TEMPLATE:
......@@ -1468,7 +1467,7 @@ bool editAlarmById(const EventId& id, QWidget* parent)
qCCritical(KALARM_LOG) << "KAlarm::editAlarmById:" << eventID << ": event not active or template";
return false;
}
editAlarm(event, parent);
editAlarm(&event, parent);
return true;
}
......@@ -1536,7 +1535,7 @@ void updateEditedAlarm(EditAlarmDlg* editDlg, KAEvent& event, Resource& resource
// Update the displayed lists and the calendar file
UpdateResult status;
if (ResourcesCalendar::instance()->event(EventId(event)))
if (ResourcesCalendar::instance()->event(EventId(event)).isValid())
{
// The old alarm hasn't expired yet, so replace it
const Undo::Event undo(event, resource);
......@@ -1561,14 +1560,14 @@ void updateEditedAlarm(EditAlarmDlg* editDlg, KAEvent& event, Resource& resource
* Returns a list of all alarm templates.
* If shell commands are disabled, command alarm templates are omitted.
*/
KAEvent::List templateList()
QVector<KAEvent> templateList()
{
KAEvent::List templates;
QVector<KAEvent> templates;
const bool includeCmdAlarms = ShellProcess::authorised();
const KAEvent::List events = ResourcesCalendar::instance()->events(CalEvent::TEMPLATE);
for (KAEvent* event : events)
const QVector<KAEvent> events = ResourcesCalendar::instance()->events(CalEvent::TEMPLATE);
for (const KAEvent& event : events)
{
if (includeCmdAlarms || !(event->actionTypes() & KAEvent::ACT_COMMAND))
if (includeCmdAlarms || !(event.actionTypes() & KAEvent::ACT_COMMAND))
templates.append(event);
}
return templates;
......@@ -1625,12 +1624,12 @@ void refreshAlarmsIfQueued()
resource.reload();
// Close any message windows for alarms which are now disabled
const KAEvent::List events = ResourcesCalendar::instance()->events(CalEvent::ACTIVE);
for (KAEvent* event : events)
const QVector<KAEvent> events = ResourcesCalendar::instance()->events(CalEvent::ACTIVE);
for (const KAEvent& event : events)
{
if (!event->enabled() && (event->actionTypes() & KAEvent::ACT_DISPLAY))
if (!event.enabled() && (event.actionTypes() & KAEvent::ACT_DISPLAY))
{
MessageWin* win = MessageWin::findEvent(EventId(*event));
MessageWin* win = MessageWin::findEvent(EventId(event));
delete win;
}
}
......
......@@ -99,7 +99,7 @@ KToggleAction* createSpreadWindowsAction(QObject* parent);
/** Returns a list of all alarm templates.
* If shell commands are disabled, command alarm templates are omitted.
*/
KAEvent::List templateList();
QVector<KAEvent> templateList();
void outputAlarmWarnings(QWidget* parent, const KAEvent* = nullptr);
void refreshAlarms();
void refreshAlarmsIfQueued(); // must only be called from KAlarmApp::processQueue()
......@@ -295,7 +295,7 @@ bool importAlarms(Resource& resource, QWidget* parent);
* @return true if all alarms in the calendar were successfully exported;
* false if any alarms failed to be exported.
*/
bool exportAlarms(const KAEvent::List& events, QWidget* parent);
bool exportAlarms(const QVector<KAEvent>& events, QWidget* parent);
void displayKOrgUpdateError(QWidget* parent, UpdateError, const UpdateResult& korgError, int nAlarms = 0);
QStringList checkRtcWakeConfig(bool checkEventExists = false);
......
......@@ -847,18 +847,18 @@ void KAlarmApp::checkNextDueAlarm()
if (!mAlarmsEnabled)
return;
// Find the first alarm due
const KAEvent* nextEvent = ResourcesCalendar::instance()->earliestAlarm();
if (!nextEvent)
const KAEvent nextEvent = ResourcesCalendar::instance()->earliestAlarm();
if (!nextEvent.isValid())
return; // there are no alarms pending
const KADateTime nextDt = nextEvent->nextTrigger(KAEvent::ALL_TRIGGER).effectiveKDateTime();
const KADateTime nextDt = nextEvent.nextTrigger(KAEvent::ALL_TRIGGER).effectiveKDateTime();
const KADateTime now = KADateTime::currentDateTime(Preferences::timeSpec());
qint64 interval = now.msecsTo(nextDt);
qCDebug(KALARM_LOG) << "KAlarmApp::checkNextDueAlarm: now:" << qPrintable(now.toString(QStringLiteral("%Y-%m-%d %H:%M %:Z"))) << ", next:" << qPrintable(nextDt.toString(QStringLiteral("%Y-%m-%d %H:%M %:Z"))) << ", due:" << interval;
if (interval <= 0)
{
// Queue the alarm
queueAlarmId(*nextEvent);
qCDebug(KALARM_LOG) << "KAlarmApp::checkNextDueAlarm:" << nextEvent->id() << ": due now";
queueAlarmId(nextEvent);
qCDebug(KALARM_LOG) << "KAlarmApp::checkNextDueAlarm:" << nextEvent.id() << ": due now";
QTimer::singleShot(0, this, &KAlarmApp::processQueue);
}
else
......@@ -885,7 +885,7 @@ void KAlarmApp::checkNextDueAlarm()
++interval; // ensure we don't trigger just before the minute boundary
if (interval > INT_MAX)
interval = INT_MAX;
qCDebug(KALARM_LOG) << "KAlarmApp::checkNextDueAlarm:" << nextEvent->id() << "wait" << interval/1000 << "seconds";
qCDebug(KALARM_LOG) << "KAlarmApp::checkNextDueAlarm:" << nextEvent.id() << "wait" << interval/1000 << "seconds";
mAlarmTimer->start(static_cast<int>(interval));
}
}
......@@ -1221,7 +1221,7 @@ void KAlarmApp::changeStartOfDay()
{
DateTime::setStartOfDay(Preferences::startOfDay());
KAEvent::setStartOfDay(Preferences::startOfDay());
ResourcesCalendar::instance()->adjustStartOfDay();
Resources::adjustStartOfDay();
DisplayCalendar::instance()->adjustStartOfDay();
}
......@@ -1694,13 +1694,15 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
KAlarm::checkRtcWakeConfig();
const QString eventID(id.eventId());
KAEvent* event = ResourcesCalendar::instance()->event(id, findUniqueId);
if (!event)
KAEvent event = ResourcesCalendar::instance()->event(id, findUniqueId);
if (!event.isValid())
{
if (id.resourceId() != -1)
qCWarning(KALARM_LOG) << "KAlarmApp::handleEvent: Event ID not found:" << eventID;
else if (findUniqueId)
qCWarning(KALARM_LOG) << "KAlarmApp::handleEvent: Event ID not found, or duplicated:" << eventID;
else
qCWarning(KALARM_LOG) << "KAlarmApp::handleEvent: Event ID not found:" << eventID;
qCCritical(KALARM_LOG) << "KAlarmApp::handleEvent: No resource ID specified for event:" << eventID;
return false;
}
switch (action)
......@@ -1708,8 +1710,8 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
case QueuedAction::Cancel:
{
qCDebug(KALARM_LOG) << "KAlarmApp::handleEvent:" << eventID << ", CANCEL";
Resource resource = Resources::resource(event->resourceId());
KAlarm::deleteEvent(*event, resource, true);
Resource resource = Resources::resource(event.resourceId());
KAlarm::deleteEvent(event, resource, true);
break;
}
case QueuedAction::Trigger: // handle it if it's due, else execute it regardless
......@@ -1723,9 +1725,9 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
bool restart = false;
// Check all the alarms in turn.
// Note that the main alarm is fetched before any other alarms.
for (KAAlarm alarm = event->firstAlarm();
for (KAAlarm alarm = event.firstAlarm();
alarm.isValid();
alarm = (restart ? event->firstAlarm() : event->nextAlarm(alarm)), restart = false)
alarm = (restart ? event.firstAlarm() : event.nextAlarm(alarm)), restart = false)
{
// Check if the alarm is due yet.
const KADateTime nextDT = alarm.dateTime(true).effectiveKDateTime();
......@@ -1745,7 +1747,7 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
}
bool reschedule = false;
bool rescheduleWork = false;
if ((event->workTimeOnly() || event->holidaysExcluded()) && !alarm.deferred())
if ((event.workTimeOnly() || event.holidaysExcluded()) && !alarm.deferred())
{
// The alarm is restricted to working hours and/or non-holidays
// (apart from deferrals). This needs to be re-evaluated every
......@@ -1754,10 +1756,10 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
{
KADateTime dt(nextDT);
dt.setDateOnly(true);
reschedule = !event->isWorkingTime(dt);
reschedule = !event.isWorkingTime(dt);
}
else
reschedule = !event->isWorkingTime(nextDT);
reschedule = !event.isWorkingTime(nextDT);
rescheduleWork = reschedule;
if (reschedule)
qCDebug(KALARM_LOG) << "KAlarmApp::handleEvent: Alarm" << alarm.type() << "at" << nextDT.qDateTime() << ": not during working hours";
......@@ -1774,7 +1776,7 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
// Set the time to display if it's a display alarm
alarm.setTime(now);
}
if (!reschedule && event->lateCancel())
if (!reschedule && event.lateCancel())
{
// Alarm is due, and it is to be cancelled if too late.
qCDebug(KALARM_LOG) << "KAlarmApp::handleEvent: LATE_CANCEL";
......@@ -1782,14 +1784,14 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
if (alarm.dateTime().isDateOnly())
{
// The alarm has no time, so cancel it if its date is too far past
const int maxlate = event->lateCancel() / 1440; // maximum lateness in days
const int maxlate = event.lateCancel() / 1440; // maximum lateness in days
KADateTime limit(DateTime(nextDT.addDays(maxlate + 1)).effectiveKDateTime());
if (now >= limit)
{
// It's too late to display the scheduled occurrence.
// Find the last previous occurrence of the alarm.
DateTime next;
const KAEvent::OccurType type = event->previousOccurrence(now, next, true);
const KAEvent::OccurType type = event.previousOccurrence(now, next, true);
switch (type & ~KAEvent::OCCURRENCE_REPEAT)
{
case KAEvent::FIRST_OR_ONLY_OCCURRENCE:
......@@ -1800,7 +1802,7 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
if (now >= limit)
{
if (type == KAEvent::LAST_RECURRENCE
|| (type == KAEvent::FIRST_OR_ONLY_OCCURRENCE && !event->recurs()))
|| (type == KAEvent::FIRST_OR_ONLY_OCCURRENCE && !event.recurs()))
cancel = true; // last occurrence (and there are no repetitions)
else
reschedule = true;
......@@ -1816,13 +1818,13 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
else
{
// The alarm is timed. Allow it to be the permitted amount late before cancelling it.
const int maxlate = maxLateness(event->lateCancel());
const int maxlate = maxLateness(event.lateCancel());
if (secs > maxlate)
{
// It's over the maximum interval late.
// Find the most recent occurrence of the alarm.
DateTime next;
const KAEvent::OccurType type = event->previousOccurrence(now, next, true);
const KAEvent::OccurType type = event.previousOccurrence(now, next, true);
switch (type & ~KAEvent::OCCURRENCE_REPEAT)
{
case KAEvent::FIRST_OR_ONLY_OCCURRENCE:
......@@ -1832,7 +1834,7 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
if (next.effectiveKDateTime().secsTo(now) > maxlate)
{
if (type == KAEvent::LAST_RECURRENCE
|| (type == KAEvent::FIRST_OR_ONLY_OCCURRENCE && !event->recurs()))
|| (type == KAEvent::FIRST_OR_ONLY_OCCURRENCE && !event.recurs()))
cancel = true; // last occurrence (and there are no repetitions)
else
reschedule = true;
......@@ -1849,8 +1851,8 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
if (cancel)
{
// All recurrences are finished, so cancel the event
event->setArchive();
if (cancelAlarm(*event, alarm.type(), false))
event.setArchive();
if (cancelAlarm(event, alarm.type(), false))
return true; // event has been deleted
updateCalAndDisplay = true;
continue;
......@@ -1859,7 +1861,7 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
if (reschedule)
{
// The latest repetition was too long ago, so schedule the next one
switch (rescheduleAlarm(*event, alarm, false, (rescheduleWork ? nextDT : KADateTime())))
switch (rescheduleAlarm(event, alarm, false, (rescheduleWork ? nextDT : KADateTime())))
{
case 1:
// A working-time-only alarm has been rescheduled and the
......@@ -1889,7 +1891,7 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
// If there is an alarm to execute, do this last after rescheduling/cancelling
// any others. This ensures that the updated event is only saved once to the calendar.
if (alarmToExecute.isValid())
execAlarm(*event, alarmToExecute, true, !alarmToExecute.repeatAtLogin());
execAlarm(event, alarmToExecute, true, !alarmToExecute.repeatAtLogin());
else
{
if (action == QueuedAction::Trigger)
......@@ -1897,12 +1899,12 @@ bool KAlarmApp::handleEvent(const EventId& id, QueuedAction action, bool findUni
// The alarm is to be executed regardless of whether it's due.
// Only trigger one alarm from the event - we don't want multiple
// identical messages, for example.
const KAAlarm alarm = event->firstAlarm();
const KAAlarm alarm = event.firstAlarm();
if (alarm.isValid())
execAlarm(*event, alarm, false);
execAlarm(event, alarm, false);
}
if (updateCalAndDisplay)
KAlarm::updateEvent(*event); // update the window lists and calendar file
KAlarm::updateEvent(event); // update the window lists and calendar file
else if (action != QueuedAction::Trigger) { qCDebug(KALARM_LOG) << "KAlarmApp::handleEvent: No action"; }
}
break;
......@@ -2168,7 +2170,7 @@ void* KAlarmApp::execAlarm(KAEvent& event, const KAAlarm& alarm, bool reschedule
const int flags = (reschedule ? ProcData::RESCHEDULE : 0) | (allowDefer ? ProcData::ALLOW_DEFER : 0);
if (doShellCommand(command, event, &alarm, (flags | ProcData::PRE_ACTION)))
{
ResourcesCalendar::instance()->setAlarmPending(&event);
ResourcesCalendar::instance()->setAlarmPending(event);
return result; // display the message after the command completes
}
// Error executing command
......@@ -2544,7 +2546,7 @@ void KAlarmApp::slotCommandExited(ShellProcess* proc)
}
}
if (pd->preAction())
ResourcesCalendar::instance()->setAlarmPending(pd->event, false);
ResourcesCalendar::instance()->setAlarmPending(*pd->event, false);
if (executeAlarm)
execAlarm(*pd->event, *pd->alarm, pd->reschedule(), pd->allowDefer(), true);
mCommandProcesses.removeAt(i);
......@@ -2681,9 +2683,12 @@ void KAlarmApp::setEventCommandError(const KAEvent& event, KAEvent::CmdErrType e
if (err == KAEvent::CMD_ERROR_POST && event.commandError() == KAEvent::CMD_ERROR_PRE)
err = KAEvent::CMD_ERROR_PRE_POST;
event.setCommandError(err);
KAEvent* ev = ResourcesCalendar::instance()->event(EventId(event));
if (ev && ev->commandError() != err)
ev->setCommandError(err);
KAEvent ev = ResourcesCalendar::instance()->event(EventId(event));
if (ev.isValid() && ev.commandError() != err)
{
ev.setCommandError(err);
ResourcesCalendar::instance()->updateEvent(ev);
}
Resource resource = Resources::resourceForEvent(event.id());
resource.handleCommandErrorChange(event);
}
......@@ -2699,11 +2704,12 @@ void KAlarmApp::clearEventCommandError(const KAEvent& event, KAEvent::CmdErrType
KAEvent::CmdErrType newerr = static_cast<KAEvent::CmdErrType>(event.commandError() & ~err);
event.setCommandError(newerr);
KAEvent* ev = ResourcesCalendar::instance()->event(EventId(event));
if (ev)
KAEvent ev = ResourcesCalendar::instance()->event(EventId(event));
if (ev.isValid())
{
newerr = static_cast<KAEvent::CmdErrType>(ev->commandError() & ~err);
ev->setCommandError(newerr);
newerr = static_cast<KAEvent::CmdErrType>(ev.commandError() & ~err);
ev.setCommandError(newerr);
ResourcesCalendar::instance()->updateEvent(ev);
}
Resource resource = Resources::resourceForEvent(event.id());
resource.handleCommandErrorChange(event);
......
......@@ -862,12 +862,9 @@ void MainWindow::slotImportAlarms()
*/
void MainWindow::slotExportAlarms()
{
QVector<KAEvent> events = mListView->selectedEvents();
const QVector<KAEvent> events = mListView->selectedEvents();
if (!events.isEmpty())
{
const KAEvent::List evts = KAEvent::ptrList(events);
KAlarm::exportAlarms(evts, this);
}
KAlarm::exportAlarms(events, this);
}
/******************************************************************************
......@@ -1224,7 +1221,7 @@ void MainWindow::executeDropEvent(MainWindow* win, QDropEvent* e)
QList<QUrl> urls;
MemoryCalendar::Ptr calendar(new MemoryCalendar(Preferences::timeSpecAsZone()));
#ifndef NDEBUG
QString fmts = data->formats().join(QLatin1String(", "));
const QString fmts = data->formats().join(QLatin1String(", "));
qCDebug(KALARM_LOG) << "MainWindow::executeDropEvent:" << fmts;
#endif
......@@ -1419,15 +1416,15 @@ void MainWindow::slotSelection()
const KADateTime now = KADateTime::currentUtcDateTime();
for (int i = 0; i < count; ++i)
{
KAEvent* ev = resources->event(EventId(events.at(i))); // get up-to-date status
KAEvent* event = ev ? ev : &events[i];
bool expired = event->expired();
const KAEvent ev = resources->event(EventId(events.at(i))); // get up-to-date status
const KAEvent& event = ev.isValid() ? ev : events[i];
bool expired = event.expired();
if (!expired)
allArchived = false;
if (resources->eventReadOnly(event->id()))
if (resources->eventReadOnly(event.id()))
readOnly = true;
if (enableReactivate
&& (!expired || !event->occursAfter(now, true)))
&& (!expired || !event.occursAfter(now, true)))
enableReactivate = false;
if (enableEnableDisable)
{
......@@ -1435,9 +1432,9 @@ void MainWindow::slotSelection()
enableEnableDisable = enableEnable = enableDisable = false;
else
{
if (!enableEnable && !event->enabled())
if (!enableEnable && !event.enabled())
enableEnable = true;
if (!enableDisable && event->enabled())
if (!enableDisable && event.enabled())
enableDisable = true;
}
}
......
......@@ -1073,10 +1073,10 @@ void MessageWin::redisplayAlarm()
qCDebug(KALARM_LOG) << "MessageWin::redisplayAlarm: Deleting duplicate window:" << mEventId;
delete duplicate;
KAEvent* event = ResourcesCalendar::instance()->event(mEventId);
if (event)
const KAEvent event = ResourcesCalendar::instance()->event(mEventId);
if (event.isValid())
{
mEvent = *event;
mEvent = event;
mShowEdit = true;
}
else
......@@ -1149,13 +1149,13 @@ bool MessageWin::retrieveEvent(KAEvent& event, Resource& resource, bool& showEdi
{
// The event isn't in the displaying calendar.
// Try to retrieve it from the archive calendar.
KAEvent* ev = nullptr;
KAEvent ev;
Resource archiveRes = Resources::getStandard(CalEvent::ARCHIVED);
if (archiveRes.isValid())
ev = ResourcesCalendar::instance()->event(EventId(archiveRes.id(), CalEvent::uid(mEventId.eventId(), CalEvent::ARCHIVED)));
if (!ev)
if (!ev.isValid())
return false;
event = *ev;
event = ev;
event.setArchive(); // ensure that it gets re-archived if it's saved
event.setCategory(CalEvent::ACTIVE);
if (mEventId.eventId() != event.id())
......@@ -1191,14 +1191,14 @@ bool MessageWin::reinstateFromDisplaying(const Event::Ptr& kcalEvent, KAEvent& e
* alarm in the displaying calendar, and to reschedule it for its next repetition.
* If no repetitions remain, cancel it.
*/
void MessageWin::alarmShowing(KAEvent& event)
bool MessageWin::alarmShowing(KAEvent& event)
{
qCDebug(KALARM_LOG) << "MessageWin::alarmShowing:" << event.id() << "," << KAAlarm::debugType(mAlarmType);
const KAAlarm alarm = event.alarm(mAlarmType);
if (!alarm.isValid())
{
qCCritical(KALARM_LOG) << "MessageWin::alarmShowing: Alarm type not found:" << event.id() << ":" << mAlarmType;
return;
return false;
}
if (!mAlwaysHide)
{
......@@ -1216,6 +1216,7 @@ void MessageWin::alarmShowing(KAEvent& event)
}
}
theApp()->rescheduleAlarm(event, alarm);
return true;
}
/******************************************************************************
......@@ -1655,8 +1656,10 @@ void MessageWin::repeat(const KAAlarm& alarm)