Commit 45d7e997 authored by David Jarvie's avatar David Jarvie
Browse files

Archive repeat-at-login alarms if previously triggered, when deleted

parent 483591a7
KAlarm Change Log
=== Version 2.12.7 (KDE Applications 19.08.2) --- 7 October 2019 ===
=== Version 2.12.7 (KDE Applications 19.08.2) --- 9 October 2019 ===
+ Show correct read-only status of an alarm in its context menu.
+ Fix errors deleting and reactivating alarms (regression introduced in 2.12.5).
+ Fix error on undo of an active alarm deletion.
+ Don't trigger repeat-at-login alarms when they are edited or imported.
+ Archive repeat-at-login alarms if previously triggered, when they are deleted.
=== Version 2.12.6 (KDE Applications 19.08.1) --- 26 August 2019 ===
+ Fix crash sometimes when a resource is enabled [KDE Bug 410596]
......
......@@ -138,6 +138,7 @@ AkonadiModel::AkonadiModel(ChangeRecorder* monitor, QObject* parent)
connect(this, &AkonadiModel::rowsInserted, this, &AkonadiModel::slotRowsInserted);
connect(this, &AkonadiModel::rowsAboutToBeRemoved, this, &AkonadiModel::slotRowsAboutToBeRemoved);
connect(this, &Akonadi::EntityTreeModel::collectionPopulated, this, &AkonadiModel::slotCollectionPopulated);
connect(monitor, &Monitor::itemChanged, this, &AkonadiModel::slotMonitoredItemChanged);
connect(ServerManager::self(), &ServerManager::stateChanged, this, &AkonadiModel::checkResources);
......@@ -1802,6 +1803,20 @@ void AkonadiModel::slotCollectionBeingCreated(const QString& path, Akonadi::Coll
mCollectionsBeingCreated << path;
}
/******************************************************************************
* Called when a collection has been populated.
*/
void AkonadiModel::slotCollectionPopulated(Akonadi::Collection::Id)
{
if (isFullyPopulated())
{
// All collections have now been populated.
Q_EMIT collectionsPopulated();
// Prevent the signal being emitted more than once.
disconnect(this, &Akonadi::EntityTreeModel::collectionPopulated, this, &AkonadiModel::slotCollectionPopulated);
}
}
/******************************************************************************
* Called when calendar migration has completed.
*/
......
......@@ -246,6 +246,9 @@ class AkonadiModel : public Akonadi::EntityTreeModel
*/
void itemDone(Akonadi::Item::Id id, bool status = true);
/** Signal emitted when all collections have been populated. */
void collectionsPopulated();
/** Signal emitted when calendar migration/creation has completed. */
void migrationCompleted();
......@@ -262,6 +265,7 @@ class AkonadiModel : public Akonadi::EntityTreeModel
void slotCollectionChanged(const Akonadi::Collection& c, const QSet<QByteArray>& attrNames);
void slotCollectionRemoved(const Akonadi::Collection&);
void slotCollectionBeingCreated(const QString& path, Akonadi::Collection::Id, bool finished);
void slotCollectionPopulated(Akonadi::Collection::Id);
void slotUpdateTimeTo();
void slotUpdateArchivedColour(const QColor&);
void slotUpdateDisabledColour(const QColor&);
......
......@@ -133,6 +133,7 @@ AlarmCalendar::AlarmCalendar()
connect(model, &AkonadiModel::eventsToBeRemoved, this, &AlarmCalendar::slotEventsToBeRemoved);
connect(model, &AkonadiModel::eventChanged, this, &AlarmCalendar::slotEventChanged);
connect(model, &AkonadiModel::collectionStatusChanged, this, &AlarmCalendar::slotCollectionStatusChanged);
connect(model, &AkonadiModel::collectionsPopulated, this, &AlarmCalendar::slotCollectionsPopulated);
Preferences::connect(SIGNAL(askResourceChanged(bool)), this, SLOT(setAskResource(bool)));
}
......@@ -523,6 +524,17 @@ void AlarmCalendar::slotCollectionStatusChanged(const Collection& collection, Ak
}
}
/******************************************************************************
* Called when all collections have been populated for the first time.
*/
void AlarmCalendar::slotCollectionsPopulated()
{
// Now that all calendars have been processed, all repeat-at-login alarms
// will have been triggered. Prevent any new or updated repeat-at-login
// alarms (e.g. when they are edited by the user) triggering from now on.
mIgnoreAtLogin = true;
}
/******************************************************************************
* Called when events have been added to AkonadiModel.
* Add corresponding KAEvent instances to those held by AlarmCalendar.
......@@ -570,11 +582,8 @@ void AlarmCalendar::slotEventChanged(const AkonadiModel::Event& event)
{
bool enabled = event.event.enabled();
checkForDisabledAlarms(!enabled, enabled);
if (added && enabled && event.event.repeatAtLogin())
{
if (!mIgnoreAtLogin.remove(event.event.id())) // don't trigger events added by user
Q_EMIT atLoginEventAdded(event.event);
}
if (!mIgnoreAtLogin && added && enabled && event.event.repeatAtLogin())
Q_EMIT atLoginEventAdded(event.event);
}
}
......@@ -717,8 +726,6 @@ bool AlarmCalendar::importAlarms(QWidget* parent, Collection* collection)
// Give the event a new ID and add it to the calendars
newev->setUid(CalEvent::uid(CalFormat::createUniqueId(), type));
KAEvent* newEvent = new KAEvent(newev);
if (newEvent->repeatAtLogin())
mIgnoreAtLogin += newEvent->id(); // don't trigger the alarm now
if (!AkonadiModel::instance()->addEvent(*newEvent, *coll))
success = false;
}
......@@ -965,9 +972,6 @@ bool AlarmCalendar::addEvent(KAEvent& evnt, QWidget* promptParent, bool useEvent
}
if (col.isValid())
{
if (event->repeatAtLogin())
mIgnoreAtLogin += event->id(); // don't trigger the alarm now
// Don't add event to mEventMap yet - its Akonadi item id is not yet known.
// It will be added once it is inserted into AkonadiModel.
ok = AkonadiModel::instance()->addEvent(*event, col);
......@@ -1082,8 +1086,6 @@ bool AlarmCalendar::modifyEvent(const EventId& oldEventId, KAEvent& newEvent)
Collection c = AkonadiModel::instance()->collectionById(oldEventId.collectionId());
if (!c.isValid())
return false;
if (newEvent.repeatAtLogin())
mIgnoreAtLogin += newEvent.id(); // don't trigger the alarm now
// Don't add new event to mEventMap yet - its Akonadi item id is not yet known
if (!AkonadiModel::instance()->addEvent(newEvent, c))
return false;
......
......@@ -100,6 +100,7 @@ class AlarmCalendar : public QObject
void setAskResource(bool ask);
void slotCollectionStatusChanged(const Akonadi::Collection&, AkonadiModel::Change,
const QVariant& value, bool inserted);
void slotCollectionsPopulated();
void slotEventsAdded(const AkonadiModel::EventList&);
void slotEventsToBeRemoved(const AkonadiModel::EventList&);
void slotEventChanged(const AkonadiModel::Event&);
......@@ -135,13 +136,13 @@ class AlarmCalendar : public QObject
KAEventMap mEventMap; // lookup of all events by UID
EarliestMap mEarliestAlarm; // alarm with earliest trigger time, by resource
QSet<QString> mPendingAlarms; // IDs of alarms which are currently being processed after triggering
QSet<QString> mIgnoreAtLogin; // IDs of repeat-at-login alarms added by user
QUrl mUrl; // URL of current calendar file
QUrl mICalUrl; // URL of iCalendar file
QString mLocalFile; // calendar file, or local copy if it's a remote file
CalType mCalType; // what type of calendar mCalendar is (resources/ical/vcal)
CalEvent::Type mEventType; // what type of events the calendar file is for
bool mOpen; // true if the calendar file is open
bool mIgnoreAtLogin{false}; // ignore new/updated repeat-at-login alarms
int mUpdateCount; // nesting level of group of calendar update calls
bool mUpdateSave; // save() was called while mUpdateCount > 0
bool mHaveDisabledAlarms; // there is at least one individually disabled alarm
......
......@@ -1680,8 +1680,10 @@ int KAlarmApp::rescheduleAlarm(KAEvent& event, const KAAlarm& alarm, bool update
// Executing an at-login alarm: first schedule the reminder
// which occurs AFTER the main alarm.
event.activateReminderAfter(KADateTime::currentUtcDateTime());
update = true;
}
// Repeat-at-login alarms are usually unchanged after triggering.
// Ensure that the archive flag (which was set in execAlarm()) is saved.
update = true;
}
else if (alarm.isReminder() || alarm.deferred())
{
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment