28 #include <kalarmcal/alarmtext.h>
29 #include <kalarmcal/kaevent.h>
31 #include <kapplication.h>
38 #undef DELETE // conflicting Windows macro
43 #define RESOURCE_PARAM_TYPE const Collection&
44 #define EVENT_RESOURCE collection
46 #define RESOURCE_PARAM_TYPE AlarmResource*
47 #define EVENT_RESOURCE resource
51 using namespace Akonadi;
57 enum Operation { ADD, EDIT, DELETE, REACTIVATE, DEACTIVATE, MULTI };
60 virtual Operation operation()
const = 0;
61 virtual QString actionText()
const {
return !mName.
isEmpty() ? mName : defaultActionText(); }
62 virtual QString defaultActionText()
const = 0;
68 virtual Collection collection()
const {
return Collection(); }
70 virtual AlarmResource* resource()
const {
return 0; }
72 int id()
const {
return mId; }
75 CalEvent::Type calendar()
const {
return mCalendar; }
76 virtual void setCalendar(CalEvent::Type s) { mCalendar = s; }
77 virtual UndoItem* restore() = 0;
78 virtual bool deleteID(
const QString& ) {
return false; }
80 enum Error { ERR_NONE, ERR_PROG, ERR_NOT_FOUND, ERR_CREATE, ERR_TEMPLATE, ERR_ARCHIVED };
81 enum Warning { WARN_NONE, WARN_KORG_ADD, WARN_KORG_MODIFY, WARN_KORG_DELETE };
83 static Error mRestoreError;
84 static Warning mRestoreWarning;
86 static int mRestoreWarningCount;
90 static QString addDeleteActionText(CalEvent::Type,
bool add);
91 QString description(
const KAEvent&)
const;
92 void replaceWith(UndoItem* item) {
Undo::replace(
this, item); }
97 CalEvent::Type mCalendar;
100 class UndoMultiBase :
public UndoItem
104 : UndoItem(t, name), mUndos(new
Undo::List) { }
106 : UndoItem(t, name), mUndos(undos) { }
107 ~UndoMultiBase() {
delete mUndos; }
108 const Undo::List* undos()
const {
return mUndos; }
113 template <
class T>
class UndoMulti :
public UndoMultiBase
118 virtual Operation operation()
const {
return MULTI; }
119 virtual UndoItem* restore();
120 virtual bool deleteID(
const QString&
id);
121 virtual UndoItem* createRedo(
Undo::List*) = 0;
124 class UndoAdd :
public UndoItem
130 virtual Operation operation()
const {
return ADD; }
131 virtual QString defaultActionText()
const;
132 virtual QString description()
const {
return mDescription; }
134 virtual Collection collection()
const {
return mResource; }
136 virtual AlarmResource* resource()
const {
return mResource; }
138 virtual QString eventID()
const {
return mEventId; }
139 virtual QString newEventID()
const {
return mEventId; }
140 virtual UndoItem* restore() {
return doRestore(); }
142 UndoItem* doRestore(
bool setArchive =
false);
146 Collection mResource;
148 AlarmResource* mResource;
154 class UndoEdit :
public UndoItem
160 virtual Operation operation()
const {
return EDIT; }
161 virtual QString defaultActionText()
const;
162 virtual QString description()
const {
return mDescription; }
164 virtual Collection collection()
const {
return mResource; }
166 virtual AlarmResource* resource()
const {
return mResource; }
168 virtual QString eventID()
const {
return mNewEventId; }
169 virtual QString oldEventID()
const {
return mOldEvent->id(); }
170 virtual QString newEventID()
const {
return mNewEventId; }
171 virtual UndoItem* restore();
174 Collection mResource;
176 AlarmResource* mResource;
184 class UndoDelete :
public UndoItem
190 virtual Operation operation()
const {
return DELETE; }
191 virtual QString defaultActionText()
const;
192 virtual QString description()
const {
return UndoItem::description(*mEvent); }
194 virtual Collection collection()
const {
return mResource; }
196 virtual AlarmResource* resource()
const {
return mResource; }
198 virtual QString eventID()
const {
return mEvent->id(); }
199 virtual QString oldEventID()
const {
return mEvent->id(); }
200 virtual UndoItem* restore();
201 KAEvent* event()
const {
return mEvent; }
206 Collection mResource;
208 AlarmResource* mResource;
214 class UndoReactivate :
public UndoAdd
218 : UndoAdd(t, e.event, e.
EVENT_RESOURCE, name, CalEvent::ACTIVE) { }
220 : UndoAdd(t, e, r, name, CalEvent::ACTIVE) { }
221 virtual Operation operation()
const {
return REACTIVATE; }
222 virtual QString defaultActionText()
const;
223 virtual UndoItem* restore();
228 class UndoDeactivate :
public UndoDelete
233 virtual Operation operation()
const {
return DEACTIVATE; }
234 virtual QString defaultActionText()
const;
235 virtual UndoItem* restore();
240 class UndoAdds :
public UndoMulti<UndoAdd>
244 : UndoMulti<UndoAdd>(t, events, name) { }
246 : UndoMulti<UndoAdd>(t, undos, name) { }
247 virtual QString defaultActionText()
const;
251 class UndoDeletes :
public UndoMulti<UndoDelete>
255 : UndoMulti<UndoDelete>(t, events, name) { }
257 : UndoMulti<UndoDelete>(t, undos, name) { }
258 virtual QString defaultActionText()
const;
262 class UndoReactivates :
public UndoMulti<UndoReactivate>
266 : UndoMulti<UndoReactivate>(t, events, name) { }
268 : UndoMulti<UndoReactivate>(t, undos, name) { }
269 virtual QString defaultActionText()
const;
273 Undo* Undo::mInstance = 0;
284 mInstance =
new Undo(kapp);
293 if (!mUndoList.isEmpty() || !mRedoList.isEmpty())
295 mInstance->blockSignals(
true);
296 while (!mUndoList.isEmpty())
297 delete mUndoList.first();
298 while (!mRedoList.isEmpty())
299 delete mRedoList.first();
300 mInstance->blockSignals(
false);
311 new UndoAdd(UNDO, event, resource, name);
317 int count = events.
count();
319 saveAdd(events.
first().event, events.
first().EVENT_RESOURCE, name);
322 new UndoAdds(UNDO, events, name);
329 new UndoEdit(UNDO, oldEvent.
event, newEvent.id(), oldEvent.EVENT_RESOURCE, oldEvent.
dontShowErrors, AlarmText::summary(newEvent));
330 removeRedos(oldEvent.
event.id());
337 removeRedos(event.
event.id());
343 int count = events.
count();
345 saveDelete(events[0], name);
348 new UndoDeletes(UNDO, events, name);
349 for (
int i = 0, end = events.
count(); i < end; ++i)
350 removeRedos(events[i].event.id());
357 new UndoReactivate(UNDO, event, resource, name);
363 int count = events.
count();
368 new UndoReactivates(UNDO, events, name);
376 void Undo::removeRedos(
const QString& eventID)
379 for (
int i = 0; i < mRedoList.count(); )
381 UndoItem* item = mRedoList[i];
383 if (item->operation() == UndoItem::MULTI)
385 if (item->deleteID(
id))
391 else if (item->eventID() == id)
393 if (item->operation() == UndoItem::EDIT)
394 id = item->oldEventID();
408 UndoItem::mRestoreError = UndoItem::ERR_NONE;
409 UndoItem::mRestoreWarning = UndoItem::WARN_NONE;
410 UndoItem::mRestoreWarningKorg = KAlarm::UPDATE_OK;
411 UndoItem::mRestoreWarningCount = 0;
412 List& list = (type == UNDO) ? mUndoList : mRedoList;
413 if (i < list.count() && list[i]->type() == type)
421 switch (UndoItem::mRestoreError)
423 case UndoItem::ERR_NONE:
425 KAlarm::UpdateError errcode;
426 switch (UndoItem::mRestoreWarning)
428 case UndoItem::WARN_KORG_ADD: errcode = KAlarm::ERR_ADD;
break;
429 case UndoItem::WARN_KORG_MODIFY: errcode = KAlarm::ERR_MODIFY;
break;
430 case UndoItem::WARN_KORG_DELETE: errcode = KAlarm::ERR_DELETE;
break;
431 case UndoItem::WARN_NONE:
435 KAlarm::displayKOrgUpdateError(parent, errcode, UndoItem::mRestoreWarningKorg, UndoItem::mRestoreWarningCount);
438 case UndoItem::ERR_NOT_FOUND: err = i18nc(
"@info/plain",
"Alarm not found");
break;
439 case UndoItem::ERR_CREATE: err = i18nc(
"@info/plain",
"Error recreating alarm");
break;
440 case UndoItem::ERR_TEMPLATE: err = i18nc(
"@info/plain",
"Error recreating alarm template");
break;
441 case UndoItem::ERR_ARCHIVED: err = i18nc(
"@info/plain",
"Cannot reactivate archived alarm");
break;
442 case UndoItem::ERR_PROG: err = i18nc(
"@info/plain",
"Program error");
break;
443 default: err = i18nc(
"@info/plain",
"Unknown error");
break;
457 int undoCount = mUndoList.count();
458 int redoCount = mRedoList.count();
459 if (undoCount + redoCount >=
maxCount - 1)
462 mUndoList.pop_back();
464 mRedoList.pop_back();
468 List* list = undo ? &mUndoList : &mRedoList;
478 List* list = undo ? &mUndoList : &mRedoList;
488 Type type = old->type();
489 List* list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : 0;
506 List* list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : 0;
507 return (list && !list->
isEmpty()) ? (*list)[0]->actionText() :
QString();
515 UndoItem* undo = getItem(
id, type);
516 return undo ? undo->actionText() :
QString();
524 UndoItem* undo = getItem(
id, type);
525 return undo ? undo->description() :
QString();
539 List* list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : 0;
542 for (
int i = 0, end = list->
count(); i < end; ++i)
546 UndoItem* item = (*list)[i];
548 if (item->operation() == UndoItem::MULTI)
552 const Undo::List* undos = ((UndoMultiBase*)item)->undos();
553 for (
int u = 0, uend = undos->
count(); u < uend; ++u)
555 QString evid = (*undos)[u]->eventID();
565 for (
int i = 0, iend = newIDs.
count(); i < iend; ++i)
566 ignoreIDs.
append(newIDs[i]);
571 omit = ignoreIDs.
contains(item->eventID());
573 ignoreIDs.
append(item->eventID());
574 if (item->operation() == UndoItem::EDIT)
575 ignoreIDs.
append(item->oldEventID());
591 mInstance->emitChanged(actionText(UNDO), actionText(REDO));
597 UndoItem* Undo::getItem(
int id,
Undo::Type type)
599 List* list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : 0;
602 for (
int i = 0, end = list->count(); i < end; ++i)
604 if ((*list)[i]->id() == id)
616 List& list = (type == UNDO) ? mUndoList : mRedoList;
618 for (
int end = list.count(); i < end; ++i)
620 if (list[i]->
id() == id)
631 int UndoItem::mLastId = 0;
632 UndoItem::Error UndoItem::mRestoreError;
633 UndoItem::Warning UndoItem::mRestoreWarning;
635 int UndoItem::mRestoreWarningCount;
645 mCalendar(CalEvent::EMPTY)
660 UndoItem::~UndoItem()
669 QString UndoItem::description(
const KAEvent& event)
const
671 return (mCalendar == CalEvent::TEMPLATE) ?
event.templateName() : AlarmText::summary(event);
677 QString UndoItem::addDeleteActionText(CalEvent::Type calendar,
bool add)
681 case CalEvent::ACTIVE:
683 return i18nc(
"@info/plain Action to create a new alarm",
"New alarm");
685 return i18nc(
"@info/plain Action to delete an alarm",
"Delete alarm");
686 case CalEvent::TEMPLATE:
688 return i18nc(
"@info/plain Action to create a new alarm template",
"New template");
690 return i18nc(
"@info/plain Action to delete an alarm template",
"Delete template");
691 case CalEvent::ARCHIVED:
692 return i18nc(
"@info/plain",
"Delete archived alarm");
707 : UndoMultiBase(type, name)
709 for (
int i = 0, end = events.
count(); i < end; ++i)
720 UndoItem* UndoMulti<T>::restore()
723 for (
int i = 0, end = mUndos->count(); i < end; ++i)
725 UndoItem* undo = (*mUndos)[i]->restore();
736 return createRedo(newUndos);
747 bool UndoMulti<T>::deleteID(
const QString&
id)
749 for (
int i = 0, end = mUndos->count(); i < end; ++i)
751 UndoItem* item = (*mUndos)[i];
752 if (item->eventID() == id)
756 if (mUndos->count() == 1)
780 : UndoItem(type, name),
782 mEventId(undo.event.id())
784 setCalendar(undo.
event.category());
785 mDescription = UndoItem::description(undo.
event);
789 : UndoItem(type, name),
793 setCalendar(event.category());
794 mDescription = UndoItem::description(event);
798 : UndoItem(type, name),
800 mEventId(CalEvent::uid(event.id(), cal))
803 mDescription = UndoItem::description(event);
811 UndoItem* UndoAdd::doRestore(
bool setArchive)
814 kDebug() << mEventId;
822 mRestoreError = ERR_NOT_FOUND;
829 UndoItem* undo = createRedo(event, mResource);
833 case CalEvent::ACTIVE:
841 case KAlarm::UPDATE_ERROR:
842 case KAlarm::UPDATE_FAILED:
843 case KAlarm::SAVE_FAILED:
844 mRestoreError = ERR_CREATE;
846 case KAlarm::UPDATE_KORG_FUNCERR:
847 case KAlarm::UPDATE_KORG_ERRINIT:
848 case KAlarm::UPDATE_KORG_ERRSTART:
849 case KAlarm::UPDATE_KORG_ERR:
850 mRestoreWarning = WARN_KORG_DELETE;
851 ++mRestoreWarningCount;
852 if (status.
status > mRestoreWarningKorg.status)
853 mRestoreWarningKorg = status;
860 case CalEvent::TEMPLATE:
862 if (KAlarm::deleteTemplate(event) != KAlarm::UPDATE_OK)
864 if (KAlarm::deleteTemplate(event.id()) != KAlarm::UPDATE_OK)
866 mRestoreError = ERR_TEMPLATE;
868 case CalEvent::ARCHIVED:
869 KAlarm::deleteEvent(event);
873 mRestoreError = ERR_PROG;
885 return new UndoDelete(t, event, resource,
QStringList(), mName);
891 QString UndoAdd::defaultActionText()
const
893 return addDeleteActionText(calendar(), (type() ==
Undo::UNDO));
905 UndoItem* UndoAdds::createRedo(
Undo::List* undos)
908 return new UndoAdds(t, undos, mName);
914 QString UndoAdds::defaultActionText()
const
916 return i18nc(
"@info/plain",
"Create multiple alarms");
925 UndoEdit::UndoEdit(
Undo::Type type,
const KAEvent& oldEvent,
const QString& newEventID,
929 mOldEvent(new KAEvent(oldEvent)),
930 mNewEventId(newEventID),
931 mDescription(description),
932 mDontShowErrors(dontShowErrors)
934 setCalendar(oldEvent.category());
937 UndoEdit::~UndoEdit()
947 UndoItem* UndoEdit::restore()
949 kDebug() << mNewEventId;
958 mRestoreError = ERR_NOT_FOUND;
961 KAEvent newEvent(*event);
966 UndoItem* undo =
new UndoEdit(t, newEvent, mOldEvent->id(), mResource, KAlarm::dontShowErrors(
EventId(newEvent)), mDescription);
968 UndoItem* undo =
new UndoEdit(t, newEvent, mOldEvent->id(), mResource, KAlarm::dontShowErrors(mNewEventId), mDescription);
973 case CalEvent::ACTIVE:
978 case KAlarm::UPDATE_ERROR:
979 case KAlarm::UPDATE_FAILED:
980 case KAlarm::SAVE_FAILED:
981 mRestoreError = ERR_CREATE;
983 case KAlarm::UPDATE_KORG_FUNCERR:
984 case KAlarm::UPDATE_KORG_ERRINIT:
985 case KAlarm::UPDATE_KORG_ERRSTART:
986 case KAlarm::UPDATE_KORG_ERR:
987 mRestoreWarning = WARN_KORG_MODIFY;
988 ++mRestoreWarningCount;
989 if (status.
status > mRestoreWarningKorg.status)
990 mRestoreWarningKorg = status;
994 KAlarm::setDontShowErrors(
EventId(*mOldEvent), mDontShowErrors);
996 KAlarm::setDontShowErrors(mOldEvent->id(), mDontShowErrors);
1002 case CalEvent::TEMPLATE:
1003 if (KAlarm::updateTemplate(*mOldEvent) != KAlarm::UPDATE_OK)
1004 mRestoreError = ERR_TEMPLATE;
1006 case CalEvent::ARCHIVED:
1009 mRestoreError = ERR_PROG;
1018 QString UndoEdit::defaultActionText()
const
1022 case CalEvent::ACTIVE:
1023 return i18nc(
"@info/plain Action to edit an alarm",
"Edit alarm");
1024 case CalEvent::TEMPLATE:
1025 return i18nc(
"@info/plain Action to edit an alarm template",
"Edit template");
1039 : UndoItem(type, name),
1041 mEvent(new KAEvent(undo.event)),
1042 mDontShowErrors(undo.dontShowErrors)
1044 setCalendar(mEvent->category());
1048 : UndoItem(type, name),
1049 mResource(resource),
1050 mEvent(new KAEvent(event)),
1051 mDontShowErrors(dontShowErrors)
1053 setCalendar(mEvent->category());
1056 UndoDelete::~UndoDelete()
1066 UndoItem* UndoDelete::restore()
1068 kDebug() << mEvent->id();
1072 case CalEvent::ACTIVE:
1073 if (mEvent->toBeArchived())
1076 mEvent->setCategory(CalEvent::ARCHIVED);
1084 case KAlarm::UPDATE_KORG_FUNCERR:
1085 case KAlarm::UPDATE_KORG_ERRINIT:
1086 case KAlarm::UPDATE_KORG_ERRSTART:
1087 case KAlarm::UPDATE_KORG_ERR:
1088 mRestoreWarning = WARN_KORG_ADD;
1089 ++mRestoreWarningCount;
1090 if (status.
status > mRestoreWarningKorg.status)
1091 mRestoreWarningKorg = status;
1093 case KAlarm::UPDATE_ERROR:
1094 case KAlarm::UPDATE_FAILED:
1095 case KAlarm::SAVE_FAILED:
1096 mRestoreError = ERR_ARCHIVED;
1098 case KAlarm::UPDATE_OK:
1111 case KAlarm::UPDATE_KORG_FUNCERR:
1112 case KAlarm::UPDATE_KORG_ERRINIT:
1113 case KAlarm::UPDATE_KORG_ERRSTART:
1114 case KAlarm::UPDATE_KORG_ERR:
1115 mRestoreWarning = WARN_KORG_ADD;
1116 ++mRestoreWarningCount;
1117 if (status.
status > mRestoreWarningKorg.status)
1118 mRestoreWarningKorg = status;
1120 case KAlarm::UPDATE_ERROR:
1121 case KAlarm::UPDATE_FAILED:
1122 case KAlarm::SAVE_FAILED:
1123 mRestoreError = ERR_CREATE;
1125 case KAlarm::UPDATE_OK:
1130 KAlarm::setDontShowErrors(
EventId(*mEvent), mDontShowErrors);
1132 KAlarm::setDontShowErrors(mEvent->id(), mDontShowErrors);
1135 case CalEvent::TEMPLATE:
1137 if (KAlarm::addTemplate(*mEvent, &mResource) != KAlarm::UPDATE_OK)
1139 if (KAlarm::addTemplate(*mEvent, mResource) != KAlarm::UPDATE_OK)
1142 mRestoreError = ERR_CREATE;
1146 case CalEvent::ARCHIVED:
1148 if (!KAlarm::addArchivedEvent(*mEvent, &mResource))
1150 if (!KAlarm::addArchivedEvent(*mEvent, mResource))
1153 mRestoreError = ERR_CREATE;
1158 mRestoreError = ERR_PROG;
1163 return createRedo(*mEvent, mResource);
1172 return new UndoAdd(t, event, resource, mName);
1178 QString UndoDelete::defaultActionText()
const
1180 return addDeleteActionText(calendar(), (type() ==
Undo::REDO));
1192 UndoItem* UndoDeletes::createRedo(
Undo::List* undos)
1195 return new UndoDeletes(t, undos, mName);
1201 QString UndoDeletes::defaultActionText()
const
1203 if (mUndos->isEmpty())
1205 for (
int i = 0, end = mUndos->count(); i < end; ++i)
1207 switch ((*mUndos)[i]->calendar())
1209 case CalEvent::ACTIVE:
1210 return i18nc(
"@info/plain",
"Delete multiple alarms");
1211 case CalEvent::TEMPLATE:
1212 return i18nc(
"@info/plain",
"Delete multiple templates");
1213 case CalEvent::ARCHIVED:
1219 return i18nc(
"@info/plain",
"Delete multiple archived alarms");
1233 UndoItem* UndoReactivate::restore()
1239 case CalEvent::ACTIVE:
1242 mRestoreError = ERR_PROG;
1245 return UndoAdd::doRestore(
true);
1254 return new UndoDeactivate(t, event, resource, mName);
1260 QString UndoReactivate::defaultActionText()
const
1262 return i18nc(
"@info/plain",
"Reactivate alarm");
1276 UndoItem* UndoDeactivate::restore()
1282 case CalEvent::ACTIVE:
1285 mRestoreError = ERR_PROG;
1289 return UndoDelete::restore();
1298 return new UndoReactivate(t, event, resource, mName);
1304 QString UndoDeactivate::defaultActionText()
const
1306 return i18nc(
"@info/plain",
"Reactivate alarm");
1318 UndoItem* UndoReactivates::createRedo(
Undo::List* undos)
1321 return new UndoReactivates(t, undos, mName);
1327 QString UndoReactivates::defaultActionText()
const
1329 return i18nc(
"@info/plain",
"Reactivate multiple alarms");
1341 if (e.category() == CalEvent::ACTIVE)
1343 dontShowErrors = KAlarm::dontShowErrors(
EventId(e));
1345 dontShowErrors = KAlarm::dontShowErrors(e.id());
static void emitChanged()
QStringList dontShowErrors
Result of calendar update.
bool contains(const QString &str, Qt::CaseSensitivity cs) const
static QString description(Type, int id)
static void saveEdit(const Event &oldEvent, const KAEvent &newEvent)
static void saveDeletes(const EventList &, const QString &name=QString())
int indexOf(const T &value, int from) const
static KAEvent * getEvent(const QString &uniqueId)
static void saveAdds(const EventList &, const QString &name=QString())
int count(const T &value) const
void append(const T &value)
static QList< int > ids(Type)
#define RESOURCE_PARAM_TYPE
static void saveReactivate(const KAEvent &, AlarmResource *, const QString &name=QString())
static bool undo(QWidget *parent, const QString &action)
static void remove(UndoItem *, bool undo)
static void saveAdd(const KAEvent &, AlarmResource *, const QString &name=QString())
Unique event identifier for Akonadi.
static void saveReactivates(const EventList &, const QString &name=QString())
static void replace(UndoItem *old, UndoItem *New)
static void saveDelete(const Event &, const QString &name=QString())
static void sorry(QWidget *parent, const QString &text, const QString &caption=QString(), Options options=Options(Notify|WindowModal))
static void add(UndoItem *, bool undo)
static QString actionText(Type)
void prepend(const T &value)
AutoDeleteList< UndoItem > List