24 #include <tqstringlist.h>
26 #include <tdeapplication.h>
27 #include <tdelocale.h>
28 #include <tdemessagebox.h>
31 #include "alarmcalendar.h"
33 #include "alarmtext.h"
37 static int maxCount = 12;
43 enum Operation { ADD, EDIT, DELETE, REACTIVATE, DEACTIVATE, MULTI };
46 virtual Operation operation()
const = 0;
47 virtual TQString actionText()
const = 0;
48 virtual TQString description()
const {
return TQString(); }
49 virtual TQString eventID()
const {
return TQString(); }
50 virtual TQString oldEventID()
const {
return TQString(); }
51 virtual TQString newEventID()
const {
return TQString(); }
52 int id()
const {
return mId; }
53 Undo::Type type()
const {
return mType; }
54 void setType(Undo::Type t) { mType = t; }
57 virtual UndoItem* restore() = 0;
58 virtual bool deleteID(
const TQString& ) {
return false; }
60 enum Error { ERR_NONE, ERR_PROG, ERR_NOT_FOUND, ERR_CREATE, ERR_TEMPLATE, ERR_EXPIRED };
61 enum Warning { WARN_NONE, WARN_KORG_ADD, WARN_KORG_MODIFY, WARN_KORG_DELETE };
63 static Error mRestoreError;
64 static Warning mRestoreWarning;
65 static int mRestoreWarningCount;
70 TQString description(
const KAEvent&)
const;
71 void replaceWith(UndoItem* item) { Undo::replace(
this, item); }
78 class UndoMultiBase :
public UndoItem
81 UndoMultiBase(Undo::Type t) : UndoItem(t) { }
82 UndoMultiBase(Undo::Type t, Undo::List& undos) : UndoItem(t), mUndos(undos) { }
84 const Undo::List& undos()
const {
return mUndos; }
89 template <
class T>
class UndoMulti :
public UndoMultiBase
92 UndoMulti(Undo::Type,
const TQValueList<KAEvent>&);
93 UndoMulti(Undo::Type t, Undo::List& undos) : UndoMultiBase(t, undos) { }
94 virtual Operation operation()
const {
return MULTI; }
95 virtual UndoItem* restore();
96 virtual bool deleteID(
const TQString&
id);
97 virtual UndoItem* createRedo(Undo::List&) = 0;
100 class UndoAdd :
public UndoItem
103 UndoAdd(Undo::Type,
const KAEvent&);
105 virtual Operation operation()
const {
return ADD; }
106 virtual TQString actionText()
const;
107 virtual TQString description()
const {
return mDescription; }
108 virtual TQString eventID()
const {
return mEventID; }
109 virtual TQString newEventID()
const {
return mEventID; }
110 virtual UndoItem* restore() {
return doRestore(); }
112 UndoItem* doRestore(
bool setArchive =
false);
113 virtual UndoItem* createRedo(
const KAEvent&);
116 TQString mDescription;
119 class UndoEdit :
public UndoItem
122 UndoEdit(Undo::Type,
const KAEvent& oldEvent,
const TQString& newEventID,
const TQString& description);
124 virtual Operation operation()
const {
return EDIT; }
125 virtual TQString actionText()
const;
126 virtual TQString description()
const {
return mDescription; }
127 virtual TQString eventID()
const {
return mNewEventID; }
128 virtual TQString oldEventID()
const {
return mOldEvent->id(); }
129 virtual TQString newEventID()
const {
return mNewEventID; }
130 virtual UndoItem* restore();
133 TQString mNewEventID;
134 TQString mDescription;
137 class UndoDelete :
public UndoItem
140 UndoDelete(Undo::Type,
const KAEvent&);
142 virtual Operation operation()
const {
return DELETE; }
143 virtual TQString actionText()
const;
144 virtual TQString description()
const {
return UndoItem::description(*mEvent); }
145 virtual TQString eventID()
const {
return mEvent->id(); }
146 virtual TQString oldEventID()
const {
return mEvent->id(); }
147 virtual UndoItem* restore();
148 KAEvent* event()
const {
return mEvent; }
150 virtual UndoItem* createRedo(
const KAEvent&);
155 class UndoReactivate :
public UndoAdd
158 UndoReactivate(Undo::Type t,
const KAEvent& e) : UndoAdd(t, e,
KAEvent::ACTIVE) { }
159 virtual Operation operation()
const {
return REACTIVATE; }
160 virtual TQString actionText()
const;
161 virtual UndoItem* restore();
163 virtual UndoItem* createRedo(
const KAEvent&);
166 class UndoDeactivate :
public UndoDelete
169 UndoDeactivate(Undo::Type t,
const KAEvent& e) : UndoDelete(t, e) { }
170 virtual Operation operation()
const {
return DEACTIVATE; }
171 virtual TQString actionText()
const;
172 virtual UndoItem* restore();
174 virtual UndoItem* createRedo(
const KAEvent&);
177 class UndoDeletes :
public UndoMulti<UndoDelete>
180 UndoDeletes(Undo::Type t,
const TQValueList<KAEvent>& events)
181 : UndoMulti<UndoDelete>(t, events) { }
182 UndoDeletes(Undo::Type t, Undo::List& undos)
183 : UndoMulti<UndoDelete>(t, undos) { }
184 virtual TQString actionText()
const;
185 virtual UndoItem* createRedo(Undo::List&);
188 class UndoReactivates :
public UndoMulti<UndoReactivate>
191 UndoReactivates(Undo::Type t,
const TQValueList<KAEvent>& events)
192 : UndoMulti<UndoReactivate>(t, events) { }
193 UndoReactivates(Undo::Type t, Undo::List& undos)
194 : UndoMulti<UndoReactivate>(t, undos) { }
195 virtual TQString actionText()
const;
196 virtual UndoItem* createRedo(Undo::List&);
199 Undo* Undo::mInstance = 0;
200 Undo::List Undo::mUndoList;
201 Undo::List Undo::mRedoList;
207 Undo* Undo::instance()
210 mInstance =
new Undo(kapp);
219 if (!mUndoList.isEmpty() || !mRedoList.isEmpty())
221 mInstance->blockSignals(
true);
222 while (mUndoList.count())
223 delete mUndoList.first();
224 while (mRedoList.count())
225 delete mRedoList.first();
226 mInstance->blockSignals(
false);
235 void Undo::saveAdd(
const KAEvent& event)
237 new UndoAdd(UNDO, event);
241 void Undo::saveEdit(
const KAEvent& oldEvent,
const KAEvent& newEvent)
243 new UndoEdit(UNDO, oldEvent, newEvent.id(), AlarmText::summary(newEvent));
244 removeRedos(oldEvent.id());
248 void Undo::saveDelete(
const KAEvent& event)
250 new UndoDelete(UNDO, event);
251 removeRedos(event.id());
255 void Undo::saveDeletes(
const TQValueList<KAEvent>& events)
257 int count = events.count();
259 saveDelete(events.first());
262 new UndoDeletes(UNDO, events);
263 for (TQValueList<KAEvent>::ConstIterator it = events.begin(); it != events.end(); ++it)
264 removeRedos((*it).id());
269 void Undo::saveReactivate(
const KAEvent& event)
271 new UndoReactivate(UNDO, event);
275 void Undo::saveReactivates(
const TQValueList<KAEvent>& events)
277 int count = events.count();
279 saveReactivate(events.first());
282 new UndoReactivates(UNDO, events);
290 void Undo::removeRedos(
const TQString& eventID)
292 TQString
id = eventID;
293 for (Iterator it = mRedoList.begin(); it != mRedoList.end(); )
295 UndoItem* item = *it;
297 if (item->operation() == UndoItem::MULTI)
299 if (item->deleteID(
id))
306 else if (item->eventID() ==
id)
308 if (item->operation() == UndoItem::EDIT)
309 id = item->oldEventID();
312 it = mRedoList.remove(it);
323 bool Undo::undo(Undo::Iterator it, Undo::Type type, TQWidget* parent,
const TQString& action)
325 UndoItem::mRestoreError = UndoItem::ERR_NONE;
326 UndoItem::mRestoreWarning = UndoItem::WARN_NONE;
327 UndoItem::mRestoreWarningCount = 0;
328 if (it != mUndoList.end() && it != mRedoList.end() && (*it)->type() == type)
336 switch (UndoItem::mRestoreError)
338 case UndoItem::ERR_NONE:
341 switch (UndoItem::mRestoreWarning)
343 case UndoItem::WARN_KORG_ADD: errcode = KAlarm::KORG_ERR_ADD;
break;
344 case UndoItem::WARN_KORG_MODIFY: errcode = KAlarm::KORG_ERR_MODIFY;
break;
345 case UndoItem::WARN_KORG_DELETE: errcode = KAlarm::KORG_ERR_DELETE;
break;
346 case UndoItem::WARN_NONE:
350 KAlarm::displayKOrgUpdateError(parent, errcode, UndoItem::mRestoreWarningCount);
353 case UndoItem::ERR_NOT_FOUND: err = i18n(
"Alarm not found");
break;
354 case UndoItem::ERR_CREATE: err = i18n(
"Error recreating alarm");
break;
355 case UndoItem::ERR_TEMPLATE: err = i18n(
"Error recreating alarm template");
break;
356 case UndoItem::ERR_EXPIRED: err = i18n(
"Cannot reactivate expired alarm");
break;
357 case UndoItem::ERR_PROG: err = i18n(
"Program error");
break;
358 default: err = i18n(
"Unknown error");
break;
360 KMessageBox::sorry(parent, i18n(
"Undo-action: message",
"%1: %2").arg(action).arg(err));
367 void Undo::add(UndoItem* item,
bool undo)
372 int undoCount = mUndoList.count();
373 int redoCount = mRedoList.count();
374 if (undoCount + redoCount >= maxCount - 1)
377 mUndoList.pop_back();
379 mRedoList.pop_back();
383 List* list = undo ? &mUndoList : &mRedoList;
391 void Undo::remove(UndoItem* item,
bool undo)
393 List* list = undo ? &mUndoList : &mRedoList;
394 if (!list->isEmpty())
401 void Undo::replace(UndoItem* old, UndoItem* New)
403 Type type = old->type();
404 List* list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : 0;
407 Iterator it = list->find(old);
408 if (it != list->end())
419 TQString Undo::actionText(Undo::Type type)
421 List* list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : 0;
422 return (list && !list->isEmpty()) ? list->first()->actionText() : TQString();
428 TQString Undo::actionText(Undo::Type type,
int id)
430 UndoItem* undo = getItem(
id, type);
431 return undo ? undo->actionText() : TQString();
437 TQString Undo::description(Undo::Type type,
int id)
439 UndoItem* undo = getItem(
id, type);
440 return undo ? undo->description() : TQString();
449 TQValueList<int> Undo::ids(Undo::Type type)
451 TQValueList<int> ids;
452 TQStringList ignoreIDs;
454 List* list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : 0;
457 for (Iterator it = list->begin(); it != list->end(); ++it)
461 UndoItem* item = *it;
463 if (item->operation() == UndoItem::MULTI)
467 const Undo::List& undos = ((UndoMultiBase*)item)->undos();
468 for (Undo::List::ConstIterator u = undos.begin(); u != undos.end(); ++u)
470 TQString evid = (*u)->eventID();
471 if (ignoreIDs.find(evid) != ignoreIDs.end())
474 ignoreIDs.append(evid);
480 for (TQStringList::ConstIterator i = newIDs.begin(); i != newIDs.end(); ++i)
481 ignoreIDs.append(*i);
486 omit = (ignoreIDs.find(item->eventID()) != ignoreIDs.end());
488 ignoreIDs.append(item->eventID());
489 if (item->operation() == UndoItem::EDIT)
490 ignoreIDs.append(item->oldEventID());
493 ids.append(item->id());
503 void Undo::emitChanged()
506 mInstance->emitChanged(actionText(UNDO), actionText(REDO));
512 UndoItem* Undo::getItem(
int id, Undo::Type type)
514 List* list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : 0;
517 for (Iterator it = list->begin(); it != list->end(); ++it)
519 if ((*it)->id() == id)
529 Undo::Iterator Undo::findItem(
int id, Undo::Type type)
531 List* list = (type == UNDO) ? &mUndoList : &mRedoList;
533 for (it = list->begin(); it != list->end(); ++it)
535 if ((*it)->id() == id)
546 int UndoItem::mLastId = 0;
547 UndoItem::Error UndoItem::mRestoreError;
548 UndoItem::Warning UndoItem::mRestoreWarning;
549 int UndoItem::mRestoreWarningCount;
555 UndoItem::UndoItem(Undo::Type type)
559 if (type != Undo::NONE)
564 Undo::add(
this, (mType == Undo::UNDO));
572 UndoItem::~UndoItem()
574 if (mType != Undo::NONE)
575 Undo::remove(
this, (mType == Undo::UNDO));
581 TQString UndoItem::description(
const KAEvent& event)
const
583 return (mCalendar == KAEvent::TEMPLATE) ?
event.templateName() : AlarmText::summary(event);
589 TQString UndoItem::addDeleteActionText(
KAEvent::Status calendar,
bool add)
593 case KAEvent::ACTIVE:
595 return i18n(
"Action to create a new alarm",
"New alarm");
597 return i18n(
"Action to delete an alarm",
"Delete alarm");
598 case KAEvent::TEMPLATE:
600 return i18n(
"Action to create a new alarm template",
"New template");
602 return i18n(
"Action to delete an alarm template",
"Delete template");
603 case KAEvent::EXPIRED:
604 return i18n(
"Delete expired alarm");
618 UndoMulti<T>::UndoMulti(Undo::Type type,
const TQValueList<KAEvent>& events)
619 : UndoMultiBase(type)
621 for (TQValueList<KAEvent>::ConstIterator it = events.begin(); it != events.end(); ++it)
622 mUndos.append(
new T(Undo::NONE, *it));
625 UndoMultiBase::~UndoMultiBase()
627 for (Undo::List::Iterator it = mUndos.begin(); it != mUndos.end(); ++it)
638 UndoItem* UndoMulti<T>::restore()
641 for (Undo::List::Iterator it = mUndos.begin(); it != mUndos.end(); ++it)
643 UndoItem* undo = (*it)->restore();
645 newUndos.append(undo);
647 if (newUndos.isEmpty())
651 return createRedo(newUndos);
662 bool UndoMulti<T>::deleteID(
const TQString&
id)
664 for (Undo::List::Iterator it = mUndos.begin(); it != mUndos.end(); ++it)
666 UndoItem* item = *it;
667 if (item->eventID() ==
id)
671 if (mUndos.count() == 1)
694 UndoAdd::UndoAdd(Undo::Type type,
const KAEvent& event)
698 setCalendar(KAEvent::uidStatus(mEventID));
699 mDescription = UndoItem::description(event);
704 mEventID(
KAEvent::uid(event.id(), cal))
707 mDescription = UndoItem::description(event);
715 UndoItem* UndoAdd::doRestore(
bool setArchive)
718 kdDebug(5950) <<
"UndoAdd::doRestore(" << mEventID <<
")\n";
719 const KCal::Event* kcalEvent = AlarmCalendar::getEvent(mEventID);
722 mRestoreError = ERR_NOT_FOUND;
729 UndoItem* undo = createRedo(event);
733 case KAEvent::ACTIVE:
737 switch (KAlarm::deleteEvent(event,
true))
739 case KAlarm::UPDATE_ERROR:
740 case KAlarm::UPDATE_FAILED:
741 case KAlarm::SAVE_FAILED:
742 mRestoreError = ERR_CREATE;
744 case KAlarm::UPDATE_KORG_ERR:
745 mRestoreWarning = WARN_KORG_DELETE;
746 ++mRestoreWarningCount;
752 case KAEvent::TEMPLATE:
753 if (KAlarm::deleteTemplate(event) != KAlarm::UPDATE_OK)
754 mRestoreError = ERR_TEMPLATE;
756 case KAEvent::EXPIRED:
757 KAlarm::deleteEvent(event);
761 mRestoreError = ERR_PROG;
770 UndoItem* UndoAdd::createRedo(
const KAEvent& event)
772 Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE;
773 return new UndoDelete(t, event);
779 TQString UndoAdd::actionText()
const
781 return addDeleteActionText(calendar(), (type() == Undo::UNDO));
790 UndoEdit::UndoEdit(Undo::Type type,
const KAEvent& oldEvent,
const TQString& newEventID,
const TQString& description)
792 mOldEvent(new
KAEvent(oldEvent)),
793 mNewEventID(newEventID),
794 mDescription(description)
796 setCalendar(KAEvent::uidStatus(mNewEventID));
799 UndoEdit::~UndoEdit()
809 UndoItem* UndoEdit::restore()
811 kdDebug(5950) <<
"UndoEdit::restore(" << mNewEventID <<
")\n";
813 const KCal::Event* kcalEvent = AlarmCalendar::getEvent(mNewEventID);
816 mRestoreError = ERR_NOT_FOUND;
822 Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE;
823 UndoItem* undo =
new UndoEdit(t, newEvent, mOldEvent->id(), mDescription);
827 case KAEvent::ACTIVE:
828 switch (KAlarm::modifyEvent(newEvent, *mOldEvent, 0))
830 case KAlarm::UPDATE_ERROR:
831 case KAlarm::UPDATE_FAILED:
832 case KAlarm::SAVE_FAILED:
833 mRestoreError = ERR_CREATE;
835 case KAlarm::UPDATE_KORG_ERR:
836 mRestoreWarning = WARN_KORG_MODIFY;
837 ++mRestoreWarningCount;
843 case KAEvent::TEMPLATE:
844 if (KAlarm::updateTemplate(*mOldEvent, 0) != KAlarm::UPDATE_OK)
845 mRestoreError = ERR_TEMPLATE;
847 case KAEvent::EXPIRED:
850 mRestoreError = ERR_PROG;
859 TQString UndoEdit::actionText()
const
863 case KAEvent::ACTIVE:
864 return i18n(
"Action to edit an alarm",
"Edit alarm");
865 case KAEvent::TEMPLATE:
866 return i18n(
"Action to edit an alarm template",
"Edit template");
879 UndoDelete::UndoDelete(Undo::Type type,
const KAEvent& event)
883 setCalendar(KAEvent::uidStatus(mEvent->id()));
886 UndoDelete::~UndoDelete()
896 UndoItem* UndoDelete::restore()
898 kdDebug(5950) <<
"UndoDelete::restore(" << mEvent->id() <<
")\n";
902 case KAEvent::ACTIVE:
903 if (mEvent->toBeArchived())
906 mEvent->setUid(KAEvent::EXPIRED);
907 switch (KAlarm::reactivateEvent(*mEvent, 0,
true))
909 case KAlarm::UPDATE_KORG_ERR:
910 mRestoreWarning = WARN_KORG_ADD;
911 ++mRestoreWarningCount;
913 case KAlarm::UPDATE_ERROR:
914 case KAlarm::UPDATE_FAILED:
915 case KAlarm::SAVE_FAILED:
916 mRestoreError = ERR_EXPIRED;
918 case KAlarm::UPDATE_OK:
924 switch (KAlarm::addEvent(*mEvent, 0, 0,
true))
926 case KAlarm::UPDATE_KORG_ERR:
927 mRestoreWarning = WARN_KORG_ADD;
928 ++mRestoreWarningCount;
930 case KAlarm::UPDATE_ERROR:
931 case KAlarm::UPDATE_FAILED:
932 case KAlarm::SAVE_FAILED:
933 mRestoreError = ERR_CREATE;
935 case KAlarm::UPDATE_OK:
940 case KAEvent::TEMPLATE:
941 if (KAlarm::addTemplate(*mEvent, 0) != KAlarm::UPDATE_OK)
943 mRestoreError = ERR_CREATE;
947 case KAEvent::EXPIRED:
948 if (!KAlarm::addExpiredEvent(*mEvent))
950 mRestoreError = ERR_CREATE;
955 mRestoreError = ERR_PROG;
960 return createRedo(*mEvent);
966 UndoItem* UndoDelete::createRedo(
const KAEvent& event)
968 Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE;
969 return new UndoAdd(t, event);
975 TQString UndoDelete::actionText()
const
977 return addDeleteActionText(calendar(), (type() == Undo::REDO));
989 UndoItem* UndoDeletes::createRedo(Undo::List& undos)
991 Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE;
992 return new UndoDeletes(t, undos);
998 TQString UndoDeletes::actionText()
const
1000 if (mUndos.isEmpty())
1002 for (Undo::List::ConstIterator it = mUndos.begin(); it != mUndos.end(); ++it)
1004 switch ((*it)->calendar())
1006 case KAEvent::ACTIVE:
1007 return i18n(
"Delete multiple alarms");
1008 case KAEvent::TEMPLATE:
1009 return i18n(
"Delete multiple templates");
1010 case KAEvent::EXPIRED:
1016 return i18n(
"Delete multiple expired alarms");
1030 UndoItem* UndoReactivate::restore()
1032 kdDebug(5950) <<
"UndoReactivate::restore()\n";
1036 case KAEvent::ACTIVE:
1039 mRestoreError = ERR_PROG;
1042 return UndoAdd::doRestore(
true);
1048 UndoItem* UndoReactivate::createRedo(
const KAEvent& event)
1050 Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE;
1051 return new UndoDeactivate(t, event);
1057 TQString UndoReactivate::actionText()
const
1059 return i18n(
"Reactivate alarm");
1073 UndoItem* UndoDeactivate::restore()
1075 kdDebug(5950) <<
"UndoDeactivate::restore()\n";
1079 case KAEvent::ACTIVE:
1082 mRestoreError = ERR_PROG;
1086 return UndoDelete::restore();
1092 UndoItem* UndoDeactivate::createRedo(
const KAEvent& event)
1094 Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE;
1095 return new UndoReactivate(t, event);
1101 TQString UndoDeactivate::actionText()
const
1103 return i18n(
"Reactivate alarm");
1115 UndoItem* UndoReactivates::createRedo(Undo::List& undos)
1117 Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE;
1118 return new UndoReactivates(t, undos);
1124 TQString UndoReactivates::actionText()
const
1126 return i18n(
"Reactivate multiple alarms");
represents calendar alarms and events
KAEvent corresponds to a KCal::Event instance.
Status
The category of an event, indicated by the middle part of its UID.
KOrgUpdateError
Error codes supplied as parameter to displayKOrgUpdateError()