File indexing completed on 2024-05-12 05:14:59
0001 /* 0002 * undo.cpp - undo/redo facility 0003 * Program: kalarm 0004 * SPDX-FileCopyrightText: 2005-2022 David Jarvie <djarvie@kde.org> 0005 * 0006 * SPDX-License-Identifier: GPL-2.0-or-later 0007 */ 0008 0009 #include "undo.h" 0010 0011 #include "functions.h" 0012 #include "resources/resources.h" 0013 #include "lib/messagebox.h" 0014 #include "kalarmcalendar/alarmtext.h" 0015 #include "kalarm_debug.h" 0016 0017 #include <KLocalizedString> 0018 0019 #include <QApplication> 0020 0021 static int maxCount = 12; 0022 0023 #ifdef DELETE 0024 #undef DELETE // conflicting Windows macro 0025 #endif 0026 0027 class UndoItem 0028 { 0029 public: 0030 enum Operation { ADD, EDIT, DELETE, REACTIVATE, DEACTIVATE, MULTI }; 0031 UndoItem(); // needed by QList 0032 virtual ~UndoItem(); 0033 virtual Operation operation() const = 0; 0034 virtual QString actionText() const { return !mName.isEmpty() ? mName : defaultActionText(); } 0035 virtual QString defaultActionText() const = 0; 0036 virtual QString description() const { return {}; } 0037 virtual QString eventID() const { return {}; } 0038 virtual QString oldEventID() const { return {}; } 0039 virtual QString newEventID() const { return {}; } 0040 virtual Resource resource() const { return {}; } 0041 int id() const { return mId; } 0042 Undo::Type type() const { return mType; } 0043 void setType(Undo::Type t) { mType = t; } 0044 CalEvent::Type calendar() const { return mCalendar; } 0045 virtual void setCalendar(CalEvent::Type s) { mCalendar = s; } 0046 virtual UndoItem* restore() = 0; 0047 virtual bool deleteID(const QString& /*id*/) { return false; } 0048 virtual void dumpDebug() const; 0049 0050 enum Error { ERR_NONE, ERR_PROG, ERR_NOT_FOUND, ERR_CREATE, ERR_TEMPLATE, ERR_ARCHIVED }; 0051 enum Warning { WARN_NONE, WARN_KORG_ADD, WARN_KORG_MODIFY, WARN_KORG_DELETE }; 0052 static int mLastId; 0053 static Error mRestoreError; // error code valid only if restore() returns 0 0054 static Warning mRestoreWarning; // warning code set by restore() 0055 static KAlarm::UpdateResult mRestoreWarningKorg; // KOrganizer error status set by restore() 0056 static int mRestoreWarningCount; // item count for mRestoreWarning (to allow i18n messages to work correctly) 0057 0058 protected: 0059 UndoItem(Undo::Type, const QString& name = QString()); 0060 static QString addDeleteActionText(CalEvent::Type, bool add); 0061 QString description(const KAEvent&) const; 0062 void replaceWith(UndoItem* item) { Undo::replace(this, item); } 0063 virtual void dumpDebugTitle(const char* typeName) const; 0064 0065 QString mName; // specified action name (overrides default) 0066 int mId {0}; // unique identifier (only for mType = UNDO, REDO) 0067 Undo::Type mType; // which list (if any) the object is in 0068 CalEvent::Type mCalendar; 0069 }; 0070 0071 class UndoMultiBase : public UndoItem 0072 { 0073 public: 0074 UndoMultiBase(Undo::Type t, const QString& name) 0075 : UndoItem(t, name), mUndos(new Undo::List) {} 0076 UndoMultiBase(Undo::Type t, Undo::List* undos, const QString& name) 0077 : UndoItem(t, name), mUndos(undos) {} 0078 UndoMultiBase(const UndoMultiBase&) = delete; 0079 UndoMultiBase& operator=(const UndoMultiBase&) = delete; 0080 ~UndoMultiBase() override { delete mUndos; } 0081 const Undo::List* undos() const { return mUndos; } 0082 protected: 0083 void dumpDebugTitle(const char* typeName) const override; 0084 0085 Undo::List* mUndos; // this list must always have >= 2 entries 0086 }; 0087 0088 template <class T> class UndoMulti : public UndoMultiBase 0089 { 0090 public: 0091 UndoMulti(Undo::Type, const Undo::EventList&, const QString& name); 0092 UndoMulti(Undo::Type t, Undo::List* undos, const QString& name) : UndoMultiBase(t, undos, name) {} 0093 Operation operation() const override { return MULTI; } 0094 UndoItem* restore() override; 0095 bool deleteID(const QString& id) override; 0096 virtual UndoItem* createRedo(Undo::List*) = 0; 0097 }; 0098 0099 class UndoAdd : public UndoItem 0100 { 0101 public: 0102 UndoAdd(Undo::Type, const Undo::Event&, const QString& name = QString()); 0103 UndoAdd(Undo::Type, const KAEvent&, const Resource&, const QString& name = QString()); 0104 UndoAdd(Undo::Type, const KAEvent&, const Resource&, const QString& name, CalEvent::Type); 0105 Operation operation() const override { return ADD; } 0106 QString defaultActionText() const override; 0107 QString description() const override { return mDescription; } 0108 Resource resource() const override { return mResource; } 0109 QString eventID() const override { return mEventId; } 0110 QString newEventID() const override { return mEventId; } 0111 UndoItem* restore() override { return doRestore(); } 0112 void dumpDebug() const override; 0113 protected: 0114 UndoItem* doRestore(bool setArchive = false); 0115 virtual UndoItem* createRedo(const KAEvent&, const Resource&); 0116 void dumpDebugTitle(const char* typeName) const override; 0117 private: 0118 Resource mResource; // resource containing the event 0119 QString mEventId; 0120 QString mDescription; 0121 }; 0122 0123 class UndoEdit : public UndoItem 0124 { 0125 public: 0126 UndoEdit(Undo::Type, const KAEvent& oldEvent, const QString& newEventID, 0127 const Resource&, const QStringList& dontShowErrors, const QString& description); 0128 UndoEdit(const UndoEdit&) = delete; 0129 UndoEdit& operator=(const UndoEdit&) = delete; 0130 ~UndoEdit() override; 0131 Operation operation() const override { return EDIT; } 0132 QString defaultActionText() const override; 0133 QString description() const override { return mDescription; } 0134 Resource resource() const override { return mResource; } 0135 QString eventID() const override { return mNewEventId; } 0136 QString oldEventID() const override { return mOldEvent->id(); } 0137 QString newEventID() const override { return mNewEventId; } 0138 UndoItem* restore() override; 0139 void dumpDebug() const override; 0140 protected: 0141 void dumpDebugTitle(const char* typeName) const override; 0142 private: 0143 Resource mResource; // resource containing the event 0144 KAEvent* mOldEvent; 0145 QString mNewEventId; 0146 QString mDescription; 0147 QStringList mDontShowErrors; 0148 }; 0149 0150 class UndoDelete : public UndoItem 0151 { 0152 public: 0153 UndoDelete(Undo::Type, const Undo::Event&, const QString& name = QString()); 0154 UndoDelete(Undo::Type, const KAEvent&, const Resource&, const QStringList& dontShowErrors, const QString& name = QString()); 0155 UndoDelete(const UndoDelete&) = delete; 0156 UndoDelete& operator=(const UndoDelete&) = delete; 0157 ~UndoDelete() override; 0158 Operation operation() const override { return DELETE; } 0159 QString defaultActionText() const override; 0160 QString description() const override { return UndoItem::description(*mEvent); } 0161 Resource resource() const override { return mResource; } 0162 QString eventID() const override { return mEvent->id(); } 0163 QString oldEventID() const override { return mEvent->id(); } 0164 UndoItem* restore() override; 0165 KAEvent* event() const { return mEvent; } 0166 void dumpDebug() const override; 0167 protected: 0168 virtual UndoItem* createRedo(const KAEvent&, const Resource&); 0169 void dumpDebugTitle(const char* typeName) const override; 0170 private: 0171 Resource mResource; // resource containing the event 0172 KAEvent* mEvent; 0173 QStringList mDontShowErrors; 0174 }; 0175 0176 class UndoReactivate : public UndoAdd 0177 { 0178 public: 0179 UndoReactivate(Undo::Type t, const Undo::Event& e, const QString& name = QString()) 0180 : UndoAdd(t, e.event, e.resource, name, CalEvent::ACTIVE) {} 0181 UndoReactivate(Undo::Type t, const KAEvent& e, const Resource& r, const QString& name = QString()) 0182 : UndoAdd(t, e, r, name, CalEvent::ACTIVE) {} 0183 Operation operation() const override { return REACTIVATE; } 0184 QString defaultActionText() const override; 0185 UndoItem* restore() override; 0186 void dumpDebug() const override; 0187 protected: 0188 UndoItem* createRedo(const KAEvent&, const Resource&) override; 0189 }; 0190 0191 class UndoDeactivate : public UndoDelete 0192 { 0193 public: 0194 UndoDeactivate(Undo::Type t, const KAEvent& e, const Resource& r, const QString& name = QString()) 0195 : UndoDelete(t, e, r, QStringList(), name) {} 0196 Operation operation() const override { return DEACTIVATE; } 0197 QString defaultActionText() const override; 0198 UndoItem* restore() override; 0199 void dumpDebug() const override; 0200 protected: 0201 UndoItem* createRedo(const KAEvent&, const Resource&) override; 0202 }; 0203 0204 class UndoAdds : public UndoMulti<UndoAdd> 0205 { 0206 public: 0207 UndoAdds(Undo::Type t, const Undo::EventList& events, const QString& name = QString()) 0208 : UndoMulti<UndoAdd>(t, events, name) {} // UNDO only 0209 UndoAdds(Undo::Type t, Undo::List* undos, const QString& name) 0210 : UndoMulti<UndoAdd>(t, undos, name) {} 0211 QString defaultActionText() const override; 0212 UndoItem* createRedo(Undo::List*) override; 0213 void dumpDebug() const override; 0214 }; 0215 0216 class UndoDeletes : public UndoMulti<UndoDelete> 0217 { 0218 public: 0219 UndoDeletes(Undo::Type t, const Undo::EventList& events, const QString& name = QString()) 0220 : UndoMulti<UndoDelete>(t, events, name) {} // UNDO only 0221 UndoDeletes(Undo::Type t, Undo::List* undos, const QString& name) 0222 : UndoMulti<UndoDelete>(t, undos, name) {} 0223 QString defaultActionText() const override; 0224 UndoItem* createRedo(Undo::List*) override; 0225 void dumpDebug() const override; 0226 }; 0227 0228 class UndoReactivates : public UndoMulti<UndoReactivate> 0229 { 0230 public: 0231 UndoReactivates(Undo::Type t, const Undo::EventList& events, const QString& name = QString()) 0232 : UndoMulti<UndoReactivate>(t, events, name) {} // UNDO only 0233 UndoReactivates(Undo::Type t, Undo::List* undos, const QString& name) 0234 : UndoMulti<UndoReactivate>(t, undos, name) {} 0235 QString defaultActionText() const override; 0236 UndoItem* createRedo(Undo::List*) override; 0237 void dumpDebug() const override; 0238 }; 0239 0240 Undo* Undo::mInstance = nullptr; 0241 Undo::List Undo::mUndoList; 0242 Undo::List Undo::mRedoList; 0243 0244 0245 /****************************************************************************** 0246 * Create the one and only instance of the Undo class. 0247 */ 0248 Undo* Undo::instance() 0249 { 0250 if (!mInstance) 0251 mInstance = new Undo(qApp); 0252 return mInstance; 0253 } 0254 0255 /****************************************************************************** 0256 * Clear the lists of undo and redo items. 0257 */ 0258 void Undo::clear() 0259 { 0260 if (!mUndoList.isEmpty() || !mRedoList.isEmpty()) 0261 { 0262 mInstance->blockSignals(true); 0263 while (!mUndoList.isEmpty()) 0264 delete mUndoList.first(); // N.B. 'delete' removes the object from the list 0265 while (!mRedoList.isEmpty()) 0266 delete mRedoList.first(); // N.B. 'delete' removes the object from the list 0267 mInstance->blockSignals(false); 0268 emitChanged(); 0269 } 0270 } 0271 0272 /****************************************************************************** 0273 * Create an undo item and add it to the list of undos. 0274 * N.B. The base class constructor adds the object to the undo list. 0275 */ 0276 void Undo::saveAdd(const KAEvent& event, const Resource& resource, const QString& name) 0277 { 0278 new UndoAdd(UNDO, event, resource, name); 0279 emitChanged(); 0280 } 0281 0282 void Undo::saveAdds(const Undo::EventList& events, const QString& name) 0283 { 0284 int count = events.count(); 0285 if (count == 1) 0286 saveAdd(events.first().event, events.first().resource, name); 0287 else if (count > 1) 0288 { 0289 new UndoAdds(UNDO, events, name); 0290 emitChanged(); 0291 } 0292 } 0293 0294 void Undo::saveEdit(const Undo::Event& oldEvent, const KAEvent& newEvent) 0295 { 0296 new UndoEdit(UNDO, oldEvent.event, newEvent.id(), oldEvent.resource, oldEvent.dontShowErrors, AlarmText::summary(newEvent)); 0297 removeRedos(oldEvent.event.id()); // remove any redos which are made invalid by this edit 0298 emitChanged(); 0299 } 0300 0301 void Undo::saveDelete(const Undo::Event& event, const QString& name) 0302 { 0303 new UndoDelete(UNDO, event.event, event.resource, event.dontShowErrors, name); 0304 removeRedos(event.event.id()); // remove any redos which are made invalid by this deletion 0305 emitChanged(); 0306 } 0307 0308 void Undo::saveDeletes(const Undo::EventList& events, const QString& name) 0309 { 0310 int count = events.count(); 0311 if (count == 1) 0312 saveDelete(events[0], name); 0313 else if (count > 1) 0314 { 0315 new UndoDeletes(UNDO, events, name); 0316 for (const Undo::Event& event : events) 0317 removeRedos(event.event.id()); // remove any redos which are made invalid by these deletions 0318 emitChanged(); 0319 } 0320 } 0321 0322 void Undo::saveReactivate(const KAEvent& event, const Resource& resource, const QString& name) 0323 { 0324 new UndoReactivate(UNDO, event, resource, name); 0325 emitChanged(); 0326 } 0327 0328 void Undo::saveReactivates(const EventList& events, const QString& name) 0329 { 0330 int count = events.count(); 0331 if (count == 1) 0332 saveReactivate(events[0].event, events[0].resource, name); 0333 else if (count > 1) 0334 { 0335 new UndoReactivates(UNDO, events, name); 0336 emitChanged(); 0337 } 0338 } 0339 0340 /****************************************************************************** 0341 * Remove any redos which are made invalid by a new undo. 0342 */ 0343 void Undo::removeRedos(const QString& eventID) 0344 { 0345 QString id = eventID; 0346 for (int i = 0; i < mRedoList.count(); ) 0347 { 0348 UndoItem* item = mRedoList[i]; 0349 if (item->operation() == UndoItem::MULTI) 0350 { 0351 if (item->deleteID(id)) 0352 { 0353 // The old multi-redo was replaced with a new single redo 0354 delete item; // N.B. 'delete' removes the object from the list 0355 } 0356 } 0357 else if (item->eventID() == id) 0358 { 0359 if (item->operation() == UndoItem::EDIT) 0360 id = item->oldEventID(); // continue looking for its post-edit ID 0361 delete item; // N.B. 'delete' removes the object from the list 0362 } 0363 else 0364 ++i; 0365 } 0366 } 0367 0368 /****************************************************************************** 0369 * Undo or redo a specified item. 0370 * Reply = true if success, or if the item no longer exists. 0371 */ 0372 bool Undo::undo(int i, Undo::Type type, QWidget* parent, const QString& action) 0373 { 0374 UndoItem::mRestoreError = UndoItem::ERR_NONE; 0375 UndoItem::mRestoreWarning = UndoItem::WARN_NONE; 0376 UndoItem::mRestoreWarningKorg = KAlarm::UPDATE_OK; 0377 UndoItem::mRestoreWarningCount = 0; 0378 List& list = (type == UNDO) ? mUndoList : mRedoList; 0379 if (i < list.count() && list[i]->type() == type) 0380 { 0381 list[i]->restore(); 0382 delete list[i]; // N.B. 'delete' removes the object from its list 0383 emitChanged(); 0384 } 0385 0386 QString err; 0387 switch (UndoItem::mRestoreError) 0388 { 0389 case UndoItem::ERR_NONE: 0390 { 0391 KAlarm::UpdateError errcode; 0392 switch (UndoItem::mRestoreWarning) 0393 { 0394 case UndoItem::WARN_KORG_ADD: errcode = KAlarm::ERR_ADD; break; 0395 case UndoItem::WARN_KORG_MODIFY: errcode = KAlarm::ERR_MODIFY; break; 0396 case UndoItem::WARN_KORG_DELETE: errcode = KAlarm::ERR_DELETE; break; 0397 case UndoItem::WARN_NONE: 0398 default: 0399 return true; 0400 } 0401 KAlarm::displayKOrgUpdateError(parent, errcode, UndoItem::mRestoreWarningKorg, UndoItem::mRestoreWarningCount); 0402 return true; 0403 } 0404 case UndoItem::ERR_NOT_FOUND: err = i18nc("@info", "Alarm not found"); break; 0405 case UndoItem::ERR_CREATE: err = i18nc("@info", "Error recreating alarm"); break; 0406 case UndoItem::ERR_TEMPLATE: err = i18nc("@info", "Error recreating alarm template"); break; 0407 case UndoItem::ERR_ARCHIVED: err = i18nc("@info", "Cannot reactivate archived alarm"); break; 0408 case UndoItem::ERR_PROG: err = i18nc("@info", "Program error"); break; 0409 default: err = i18nc("@info", "Unknown error"); break; 0410 } 0411 KAMessageBox::error(parent, i18nc("@info Undo-action: message", "%1: %2", action, err)); 0412 return false; 0413 } 0414 0415 /****************************************************************************** 0416 * Add an undo item to the start of one of the lists. 0417 */ 0418 void Undo::add(UndoItem* item, bool undo) 0419 { 0420 if (item) 0421 { 0422 // Limit the number of items stored 0423 const int undoCount = mUndoList.count(); 0424 const int redoCount = mRedoList.count(); 0425 if (undoCount + redoCount >= maxCount - 1) 0426 { 0427 if (undoCount) 0428 mUndoList.pop_back(); 0429 else 0430 mRedoList.pop_back(); 0431 } 0432 0433 // Append the new item 0434 List* const list = undo ? &mUndoList : &mRedoList; 0435 list->prepend(item); 0436 } 0437 } 0438 0439 /****************************************************************************** 0440 * Remove an undo item from one of the lists. 0441 */ 0442 void Undo::remove(UndoItem* item, bool undo) 0443 { 0444 List* const list = undo ? &mUndoList : &mRedoList; 0445 if (!list->isEmpty()) 0446 list->removeAt(list->indexOf(item)); 0447 } 0448 0449 /****************************************************************************** 0450 * Replace an undo item in one of the lists. 0451 */ 0452 void Undo::replace(UndoItem* old, UndoItem* New) 0453 { 0454 const Type type = old->type(); 0455 List* const list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : nullptr; 0456 if (!list) 0457 return; 0458 const int i = list->indexOf(old); 0459 if (i >= 0) 0460 { 0461 New->setType(type); // ensure the item points to the correct list 0462 (*list)[i] = New; 0463 old->setType(NONE); // mark the old item as no longer being in a list 0464 } 0465 } 0466 0467 /****************************************************************************** 0468 * Return the action description of the latest undo/redo item. 0469 */ 0470 QString Undo::actionText(Undo::Type type) 0471 { 0472 const List* const list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : nullptr; 0473 return (list && !list->isEmpty()) ? (*list)[0]->actionText() : QString(); 0474 } 0475 0476 /****************************************************************************** 0477 * Return the action description of the undo/redo item with the specified ID. 0478 */ 0479 QString Undo::actionText(Undo::Type type, int id) 0480 { 0481 const UndoItem* undo = getItem(id, type); 0482 return undo ? undo->actionText() : QString(); 0483 } 0484 0485 /****************************************************************************** 0486 * Return the alarm description of the undo/redo item with the specified ID. 0487 */ 0488 QString Undo::description(Undo::Type type, int id) 0489 { 0490 const UndoItem* undo = getItem(id, type); 0491 return undo ? undo->description() : QString(); 0492 } 0493 0494 /****************************************************************************** 0495 * Return the descriptions of all undo or redo items, in order latest first. 0496 * For alarms which have undergone more than one change, only the first one is 0497 * listed, to force dependent undos to be executed in their correct order. 0498 * If 'ids' is non-null, also returns a list of their corresponding IDs. 0499 */ 0500 QList<int> Undo::ids(Undo::Type type) 0501 { 0502 QList<int> ids; 0503 QStringList ignoreIDs; 0504 //int n=0; 0505 const List* const list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : nullptr; 0506 if (!list) 0507 return ids; 0508 for (const UndoItem* item : *list) 0509 { 0510 // Check whether this item should be ignored because it is a 0511 // dependent undo. If not, add this item's ID to the ignore list. 0512 bool omit = false; 0513 if (item->operation() == UndoItem::MULTI) 0514 { 0515 // If any item in a multi-undo is disqualified, omit the whole multi-undo 0516 QStringList newIDs; 0517 const Undo::List* undos = ((UndoMultiBase*)item)->undos(); 0518 for (const UndoItem* undo : *undos) 0519 { 0520 const QString evid = undo->eventID(); 0521 if (ignoreIDs.contains(evid)) 0522 omit = true; 0523 else if (omit) 0524 ignoreIDs.append(evid); 0525 else 0526 newIDs.append(evid); 0527 } 0528 if (omit) 0529 { 0530 for (const QString& newID : std::as_const(newIDs)) 0531 ignoreIDs.append(newID); 0532 } 0533 } 0534 else 0535 { 0536 omit = ignoreIDs.contains(item->eventID()); 0537 if (!omit) 0538 ignoreIDs.append(item->eventID()); 0539 if (item->operation() == UndoItem::EDIT) 0540 ignoreIDs.append(item->oldEventID()); // continue looking for its post-edit ID 0541 } 0542 if (!omit) 0543 ids.append(item->id()); 0544 //else qCDebug(KALARM_LOG)<<"Undo::ids(): omit"<<item->actionText()<<":"<<item->description(); 0545 } 0546 //qCDebug(KALARM_LOG)<<"Undo::ids():"<<n<<" ->"<<ids.count(); 0547 return ids; 0548 } 0549 0550 /****************************************************************************** 0551 * Emit the appropriate 'changed' signal. 0552 */ 0553 void Undo::emitChanged() 0554 { 0555 if (mInstance) 0556 mInstance->emitChanged(actionText(UNDO), actionText(REDO)); 0557 } 0558 0559 /****************************************************************************** 0560 * Return the item with the specified ID. 0561 */ 0562 UndoItem* Undo::getItem(int id, Undo::Type type) 0563 { 0564 List* const list = (type == UNDO) ? &mUndoList : (type == REDO) ? &mRedoList : nullptr; 0565 if (list) 0566 { 0567 for (int i = 0, end = list->count(); i < end; ++i) 0568 { 0569 UndoItem* item = (*list)[i]; 0570 if (item->id() == id) 0571 return item; 0572 } 0573 } 0574 return nullptr; 0575 } 0576 0577 /****************************************************************************** 0578 * Find an item with the specified ID. 0579 */ 0580 int Undo::findItem(int id, Undo::Type type) 0581 { 0582 const List& list = (type == UNDO) ? mUndoList : mRedoList; 0583 int i = 0; 0584 for (int end = list.count(); i < end; ++i) 0585 { 0586 if (list[i]->id() == id) 0587 break; 0588 } 0589 return i; 0590 } 0591 0592 /****************************************************************************** 0593 * Dump the last 'count' undos or redos to debug, starting with the most recent. 0594 */ 0595 void Undo::dumpDebug(Undo::Type type, int count) 0596 { 0597 #ifndef KDE_NO_DEBUG_OUTPUT 0598 const List& list = (type == UNDO) ? mUndoList : mRedoList; 0599 if (count > list.count()) 0600 count = list.count(); 0601 qCDebug(KALARM_LOG) << "Undo::dumpDebug():" << count; 0602 for (int i = 0; i < count; ++i) 0603 list[i]->dumpDebug(); 0604 #endif 0605 } 0606 0607 /*============================================================================= 0608 = Class: UndoItem 0609 = A single undo action. 0610 =============================================================================*/ 0611 int UndoItem::mLastId = 0; 0612 UndoItem::Error UndoItem::mRestoreError; 0613 UndoItem::Warning UndoItem::mRestoreWarning; 0614 KAlarm::UpdateResult UndoItem::mRestoreWarningKorg; 0615 int UndoItem::mRestoreWarningCount; 0616 0617 /****************************************************************************** 0618 * Constructor. 0619 * Optionally appends the undo to the list of undos. 0620 */ 0621 UndoItem::UndoItem(Undo::Type type, const QString& name) 0622 : mName(name) 0623 , mType(type) 0624 , mCalendar(CalEvent::EMPTY) 0625 { 0626 if (type != Undo::NONE) 0627 { 0628 mId = ++mLastId; 0629 if (mId < 0) 0630 mId = mLastId = 1; // wrap round if we reach a negative number 0631 Undo::add(this, (mType == Undo::UNDO)); 0632 } 0633 } 0634 0635 /****************************************************************************** 0636 * Destructor. 0637 * Removes the undo from the list (if it's in the list). 0638 */ 0639 UndoItem::~UndoItem() 0640 { 0641 if (mType != Undo::NONE) 0642 Undo::remove(this, (mType == Undo::UNDO)); 0643 } 0644 0645 /****************************************************************************** 0646 * Return the description of an event. 0647 */ 0648 QString UndoItem::description(const KAEvent& event) const 0649 { 0650 return (mCalendar == CalEvent::TEMPLATE) ? event.name() : AlarmText::summary(event); 0651 } 0652 0653 /****************************************************************************** 0654 * Return the action description of an add or delete Undo/Redo item for displaying. 0655 */ 0656 QString UndoItem::addDeleteActionText(CalEvent::Type calendar, bool add) 0657 { 0658 switch (calendar) 0659 { 0660 case CalEvent::ACTIVE: 0661 if (add) 0662 return i18nc("@info Action to create a new alarm", "New alarm"); 0663 else 0664 return i18nc("@info Action to delete an alarm", "Delete alarm"); 0665 case CalEvent::TEMPLATE: 0666 if (add) 0667 return i18nc("@info Action to create a new alarm template", "New template"); 0668 else 0669 return i18nc("@info Action to delete an alarm template", "Delete template"); 0670 case CalEvent::ARCHIVED: 0671 return i18nc("@info", "Delete archived alarm"); 0672 default: 0673 break; 0674 } 0675 return {}; 0676 } 0677 0678 /****************************************************************************** 0679 * Dump the instance's contents to debug. 0680 */ 0681 void UndoItem::dumpDebug() const 0682 { 0683 #ifndef KDE_NO_DEBUG_OUTPUT 0684 dumpDebugTitle("UndoItem"); 0685 #endif 0686 } 0687 void UndoItem::dumpDebugTitle(const char* typeName) const 0688 { 0689 #ifndef KDE_NO_DEBUG_OUTPUT 0690 qCDebug(KALARM_LOG) << typeName << "begin:"; 0691 qCDebug(KALARM_LOG) << "-- mName: " << mName; 0692 qCDebug(KALARM_LOG) << "-- mId: " << mId; 0693 qCDebug(KALARM_LOG) << "-- mType: " << (mType == Undo::UNDO ? "Undo" : mType == Undo::REDO ? "Redo" : "None"); 0694 qCDebug(KALARM_LOG) << "-- mCalendar: " << mCalendar; 0695 #endif 0696 } 0697 0698 /*============================================================================= 0699 = Class: UndoMultiBase 0700 = Undo item for multiple alarms. 0701 =============================================================================*/ 0702 0703 /****************************************************************************** 0704 * Dump the instance's contents to debug. 0705 */ 0706 void UndoMultiBase::dumpDebugTitle(const char* typeName) const 0707 { 0708 #ifndef KDE_NO_DEBUG_OUTPUT 0709 UndoItem::dumpDebugTitle(typeName); 0710 qCDebug(KALARM_LOG) << "-- mUndos count:" << mUndos->count(); 0711 #endif 0712 } 0713 0714 /*============================================================================= 0715 = Class: UndoMulti 0716 = Undo item for multiple alarms. 0717 =============================================================================*/ 0718 0719 template <class T> 0720 UndoMulti<T>::UndoMulti(Undo::Type type, const Undo::EventList& events, const QString& name) 0721 : UndoMultiBase(type, name) // UNDO only 0722 { 0723 for (const Undo::Event& event : events) 0724 mUndos->append(new T(Undo::NONE, event)); 0725 } 0726 0727 /****************************************************************************** 0728 * Undo the item, i.e. restore multiple alarms which were deleted (or delete 0729 * alarms which were restored). 0730 * Create a redo item to delete (or restore) the alarms again. 0731 * Reply = redo item. 0732 */ 0733 template <class T> 0734 UndoItem* UndoMulti<T>::restore() 0735 { 0736 auto newUndos = new Undo::List; 0737 for (int i = 0, end = mUndos->count(); i < end; ++i) 0738 { 0739 UndoItem* undo = (*mUndos)[i]->restore(); 0740 if (undo) 0741 newUndos->append(undo); 0742 } 0743 if (newUndos->isEmpty()) 0744 { 0745 delete newUndos; 0746 return nullptr; 0747 } 0748 0749 // Create a redo item to delete the alarm again 0750 return createRedo(newUndos); 0751 } 0752 0753 /****************************************************************************** 0754 * If one of the multiple items has the specified ID, delete it. 0755 * If an item is deleted and there is only one item left, the UndoMulti 0756 * instance is removed from its list and replaced by the remaining UndoItem instead. 0757 * Reply = true if this instance was replaced. The caller must delete it. 0758 * = false otherwise. 0759 */ 0760 template <class T> 0761 bool UndoMulti<T>::deleteID(const QString& id) 0762 { 0763 for (int i = 0, end = mUndos->count(); i < end; ++i) 0764 { 0765 UndoItem* item = (*mUndos)[i]; 0766 if (item->eventID() == id) 0767 { 0768 // Found a matching entry - remove it 0769 mUndos->removeAt(i); 0770 if (mUndos->count() == 1) 0771 { 0772 // There is only one entry left after removal. 0773 // Replace 'this' multi instance with the remaining single entry. 0774 replaceWith(item); 0775 return true; 0776 } 0777 else 0778 { 0779 delete item; 0780 return false; 0781 } 0782 } 0783 } 0784 return false; 0785 } 0786 0787 0788 /*============================================================================= 0789 = Class: UndoAdd 0790 = Undo item for alarm creation. 0791 =============================================================================*/ 0792 0793 UndoAdd::UndoAdd(Undo::Type type, const Undo::Event& undo, const QString& name) 0794 : UndoItem(type, name) 0795 , mResource(undo.resource) 0796 , mEventId(undo.event.id()) 0797 { 0798 setCalendar(undo.event.category()); 0799 mDescription = UndoItem::description(undo.event); // calendar must be set before calling this 0800 } 0801 0802 UndoAdd::UndoAdd(Undo::Type type, const KAEvent& event, const Resource& resource, const QString& name) 0803 : UndoItem(type, name) 0804 , mResource(resource) 0805 , mEventId(event.id()) 0806 { 0807 setCalendar(event.category()); 0808 mDescription = UndoItem::description(event); // calendar must be set before calling this 0809 } 0810 0811 UndoAdd::UndoAdd(Undo::Type type, const KAEvent& event, const Resource& resource, const QString& name, CalEvent::Type cal) 0812 : UndoItem(type, name) 0813 , mResource(resource) 0814 , mEventId(CalEvent::uid(event.id(), cal)) // convert if old-style event ID 0815 { 0816 setCalendar(cal); 0817 mDescription = UndoItem::description(event); // calendar must be set before calling this 0818 } 0819 0820 /****************************************************************************** 0821 * Undo the item, i.e. delete the alarm which was added. 0822 * Create a redo item to add the alarm back again. 0823 * Reply = redo item. 0824 */ 0825 UndoItem* UndoAdd::doRestore(bool setArchive) 0826 { 0827 // Retrieve the current state of the alarm 0828 qCDebug(KALARM_LOG) << "UndoAdd::doRestore:" << mEventId; 0829 KAEvent event = mResource.event(mEventId); 0830 if (!event.isValid()) 0831 { 0832 // Alarm is no longer in calendar, or its type is now disabled 0833 mRestoreError = ERR_NOT_FOUND; 0834 return nullptr; 0835 } 0836 0837 // Create a redo item to recreate the alarm. 0838 // Do it now, since 'event' gets modified by KAlarm::deleteEvent() 0839 UndoItem* undo = createRedo(event, mResource); 0840 0841 switch (calendar()) 0842 { 0843 case CalEvent::ACTIVE: 0844 { 0845 if (setArchive) 0846 event.setArchive(); 0847 // Archive it if it has already triggered 0848 KAlarm::UpdateResult status = KAlarm::deleteEvent(event, mResource, true); 0849 switch (status.status) 0850 { 0851 case KAlarm::UPDATE_ERROR: 0852 case KAlarm::UPDATE_FAILED: 0853 case KAlarm::SAVE_FAILED: 0854 mRestoreError = ERR_CREATE; 0855 break; 0856 case KAlarm::UPDATE_KORG_FUNCERR: 0857 case KAlarm::UPDATE_KORG_ERRINIT: 0858 case KAlarm::UPDATE_KORG_ERRSTART: 0859 case KAlarm::UPDATE_KORG_ERR: 0860 mRestoreWarning = WARN_KORG_DELETE; 0861 ++mRestoreWarningCount; 0862 if (status.status > mRestoreWarningKorg.status) 0863 mRestoreWarningKorg = status; 0864 break; 0865 default: 0866 break; 0867 } 0868 break; 0869 } 0870 case CalEvent::TEMPLATE: 0871 if (KAlarm::deleteTemplate(event) != KAlarm::UPDATE_OK) 0872 mRestoreError = ERR_TEMPLATE; 0873 break; 0874 case CalEvent::ARCHIVED: // redoing the deletion of an archived alarm 0875 { 0876 Resource resource; 0877 KAlarm::deleteEvent(event, resource); 0878 break; 0879 } 0880 default: 0881 delete undo; 0882 mRestoreError = ERR_PROG; 0883 return nullptr; 0884 } 0885 return undo; 0886 } 0887 0888 /****************************************************************************** 0889 * Create a redo item to add the alarm back again. 0890 */ 0891 UndoItem* UndoAdd::createRedo(const KAEvent& event, const Resource& resource) 0892 { 0893 const Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE; 0894 return new UndoDelete(t, event, resource, QStringList(), mName); 0895 } 0896 0897 /****************************************************************************** 0898 * Return the action description of the Undo item for displaying. 0899 */ 0900 QString UndoAdd::defaultActionText() const 0901 { 0902 return addDeleteActionText(calendar(), (type() == Undo::UNDO)); 0903 } 0904 0905 /****************************************************************************** 0906 * Dump the instance's contents to debug. 0907 */ 0908 void UndoAdd::dumpDebug() const 0909 { 0910 #ifndef KDE_NO_DEBUG_OUTPUT 0911 dumpDebugTitle("UndoAdd"); 0912 #endif 0913 } 0914 void UndoAdd::dumpDebugTitle(const char* typeName) const 0915 { 0916 #ifndef KDE_NO_DEBUG_OUTPUT 0917 UndoItem::dumpDebugTitle(typeName); 0918 qCDebug(KALARM_LOG) << "-- mResource: " << mResource.id(); 0919 qCDebug(KALARM_LOG) << "-- mEventId: " << mEventId; 0920 qCDebug(KALARM_LOG) << "-- mDescript: " << mDescription; 0921 #endif 0922 } 0923 0924 0925 /*============================================================================= 0926 = Class: UndoAdds 0927 = Undo item for multiple alarm creation. 0928 =============================================================================*/ 0929 0930 /****************************************************************************** 0931 * Create a redo item to add the alarms again. 0932 */ 0933 UndoItem* UndoAdds::createRedo(Undo::List* undos) 0934 { 0935 const Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE; 0936 return new UndoAdds(t, undos, mName); 0937 } 0938 0939 /****************************************************************************** 0940 * Return the action description of the Undo item for displaying. 0941 */ 0942 QString UndoAdds::defaultActionText() const 0943 { 0944 return i18nc("@info", "Create multiple alarms"); 0945 } 0946 0947 /****************************************************************************** 0948 * Dump the instance's contents to debug. 0949 */ 0950 void UndoAdds::dumpDebug() const 0951 { 0952 #ifndef KDE_NO_DEBUG_OUTPUT 0953 dumpDebugTitle("UndoAdds"); 0954 #endif 0955 } 0956 0957 0958 /*============================================================================= 0959 = Class: UndoEdit 0960 = Undo item for alarm edit. 0961 =============================================================================*/ 0962 0963 UndoEdit::UndoEdit(Undo::Type type, const KAEvent& oldEvent, const QString& newEventID, 0964 const Resource& resource, const QStringList& dontShowErrors, const QString& description) 0965 : UndoItem(type) 0966 , mResource(resource) 0967 , mOldEvent(new KAEvent(oldEvent)) 0968 , mNewEventId(newEventID) 0969 , mDescription(description) 0970 , mDontShowErrors(dontShowErrors) 0971 { 0972 setCalendar(oldEvent.category()); 0973 } 0974 0975 UndoEdit::~UndoEdit() 0976 { 0977 delete mOldEvent; 0978 } 0979 0980 /****************************************************************************** 0981 * Undo the item, i.e. undo an edit to a previously existing alarm. 0982 * Create a redo item to reapply the edit. 0983 * Reply = redo item. 0984 */ 0985 UndoItem* UndoEdit::restore() 0986 { 0987 qCDebug(KALARM_LOG) << "UndoEdit::restore:" << mNewEventId; 0988 // Retrieve the current state of the alarm 0989 KAEvent newEvent = mResource.event(mNewEventId); 0990 if (!newEvent.isValid()) 0991 { 0992 mRestoreError = ERR_NOT_FOUND; // alarm is no longer in calendar 0993 return nullptr; 0994 } 0995 0996 // Create a redo item to restore the edit 0997 const Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE; 0998 UndoItem* undo = new UndoEdit(t, newEvent, mOldEvent->id(), mResource, KAlarm::dontShowErrors(EventId(newEvent)), mDescription); 0999 1000 switch (calendar()) 1001 { 1002 case CalEvent::ACTIVE: 1003 { 1004 KAlarm::UpdateResult status = KAlarm::modifyEvent(newEvent, *mOldEvent); 1005 switch (status.status) 1006 { 1007 case KAlarm::UPDATE_ERROR: 1008 case KAlarm::UPDATE_FAILED: 1009 case KAlarm::SAVE_FAILED: 1010 mRestoreError = ERR_CREATE; 1011 break; 1012 case KAlarm::UPDATE_KORG_FUNCERR: 1013 case KAlarm::UPDATE_KORG_ERRINIT: 1014 case KAlarm::UPDATE_KORG_ERRSTART: 1015 case KAlarm::UPDATE_KORG_ERR: 1016 mRestoreWarning = WARN_KORG_MODIFY; 1017 ++mRestoreWarningCount; 1018 if (status.status > mRestoreWarningKorg.status) 1019 mRestoreWarningKorg = status; 1020 // fall through to default 1021 [[fallthrough]]; 1022 default: 1023 KAlarm::setDontShowErrors(EventId(*mOldEvent), mDontShowErrors); 1024 break; 1025 } 1026 break; 1027 } 1028 case CalEvent::TEMPLATE: 1029 if (KAlarm::updateTemplate(*mOldEvent) != KAlarm::UPDATE_OK) 1030 mRestoreError = ERR_TEMPLATE; 1031 break; 1032 case CalEvent::ARCHIVED: // editing of archived events is not allowed 1033 default: 1034 delete undo; 1035 mRestoreError = ERR_PROG; 1036 return nullptr; 1037 } 1038 return undo; 1039 } 1040 1041 /****************************************************************************** 1042 * Return the action description of the Undo item for displaying. 1043 */ 1044 QString UndoEdit::defaultActionText() const 1045 { 1046 switch (calendar()) 1047 { 1048 case CalEvent::ACTIVE: 1049 return i18nc("@info Action to edit an alarm", "Edit alarm"); 1050 case CalEvent::TEMPLATE: 1051 return i18nc("@info Action to edit an alarm template", "Edit template"); 1052 default: 1053 break; 1054 } 1055 return {}; 1056 } 1057 1058 /****************************************************************************** 1059 * Dump the instance's contents to debug. 1060 */ 1061 void UndoEdit::dumpDebug() const 1062 { 1063 #ifndef KDE_NO_DEBUG_OUTPUT 1064 dumpDebugTitle("UndoEdit"); 1065 #endif 1066 } 1067 void UndoEdit::dumpDebugTitle(const char* typeName) const 1068 { 1069 #ifndef KDE_NO_DEBUG_OUTPUT 1070 UndoItem::dumpDebugTitle(typeName); 1071 qCDebug(KALARM_LOG) << "-- mResource: " << mResource.id(); 1072 qCDebug(KALARM_LOG) << "-- mOldEvent: " << mOldEvent->id(); 1073 qCDebug(KALARM_LOG) << "-- mNewEventId: " << mNewEventId; 1074 qCDebug(KALARM_LOG) << "-- mDescription:" << mDescription; 1075 qCDebug(KALARM_LOG) << "-- mDontShowErr:" << mDontShowErrors; 1076 #endif 1077 } 1078 1079 1080 /*============================================================================= 1081 = Class: UndoDelete 1082 = Undo item for alarm deletion. 1083 =============================================================================*/ 1084 1085 UndoDelete::UndoDelete(Undo::Type type, const Undo::Event& undo, const QString& name) 1086 : UndoItem(type, name) 1087 , mResource(undo.resource) 1088 , mEvent(new KAEvent(undo.event)) 1089 , mDontShowErrors(undo.dontShowErrors) 1090 { 1091 setCalendar(mEvent->category()); 1092 } 1093 1094 UndoDelete::UndoDelete(Undo::Type type, const KAEvent& event, const Resource& resource, const QStringList& dontShowErrors, const QString& name) 1095 : UndoItem(type, name) 1096 , mResource(resource) 1097 , mEvent(new KAEvent(event)) 1098 , mDontShowErrors(dontShowErrors) 1099 { 1100 setCalendar(mEvent->category()); 1101 } 1102 1103 UndoDelete::~UndoDelete() 1104 { 1105 delete mEvent; 1106 } 1107 1108 /****************************************************************************** 1109 * Undo the item, i.e. restore an alarm which was deleted. 1110 * Create a redo item to delete the alarm again. 1111 * Reply = redo item. 1112 */ 1113 UndoItem* UndoDelete::restore() 1114 { 1115 qCDebug(KALARM_LOG) << "UndoDelete::restore:" << mEvent->id(); 1116 // Restore the original event 1117 CalEvent::Type saveType = calendar(); 1118 switch (calendar()) 1119 { 1120 case CalEvent::ACTIVE: 1121 if (mEvent->toBeArchived()) 1122 { 1123 // It was archived when it was deleted 1124 mEvent->setCategory(CalEvent::ARCHIVED); 1125 mEvent->setResourceId(Resources::resourceForEvent(mEvent->id()).id()); 1126 const KAlarm::UpdateResult status = KAlarm::reactivateEvent(*mEvent, mResource); 1127 switch (status.status) 1128 { 1129 case KAlarm::UPDATE_KORG_FUNCERR: 1130 case KAlarm::UPDATE_KORG_ERRINIT: 1131 case KAlarm::UPDATE_KORG_ERRSTART: 1132 case KAlarm::UPDATE_KORG_ERR: 1133 mRestoreWarning = WARN_KORG_ADD; 1134 ++mRestoreWarningCount; 1135 if (status.status > mRestoreWarningKorg.status) 1136 mRestoreWarningKorg = status; 1137 break; 1138 case KAlarm::UPDATE_ERROR: 1139 case KAlarm::UPDATE_FAILED: 1140 case KAlarm::SAVE_FAILED: 1141 mRestoreError = ERR_ARCHIVED; 1142 return nullptr; 1143 case KAlarm::UPDATE_OK: 1144 break; 1145 } 1146 } 1147 else 1148 { 1149 const KAlarm::UpdateResult status = KAlarm::addEvent(*mEvent, mResource, nullptr, true); 1150 switch (status.status) 1151 { 1152 case KAlarm::UPDATE_KORG_FUNCERR: 1153 case KAlarm::UPDATE_KORG_ERRINIT: 1154 case KAlarm::UPDATE_KORG_ERRSTART: 1155 case KAlarm::UPDATE_KORG_ERR: 1156 mRestoreWarning = WARN_KORG_ADD; 1157 ++mRestoreWarningCount; 1158 if (status.status > mRestoreWarningKorg.status) 1159 mRestoreWarningKorg = status; 1160 break; 1161 case KAlarm::UPDATE_ERROR: 1162 case KAlarm::UPDATE_FAILED: 1163 case KAlarm::SAVE_FAILED: 1164 mRestoreError = ERR_CREATE; 1165 return nullptr; 1166 case KAlarm::UPDATE_OK: 1167 break; 1168 } 1169 } 1170 KAlarm::setDontShowErrors(EventId(*mEvent), mDontShowErrors); 1171 break; 1172 case CalEvent::TEMPLATE: 1173 if (KAlarm::addTemplate(*mEvent, mResource) != KAlarm::UPDATE_OK) 1174 { 1175 mRestoreError = ERR_CREATE; 1176 return nullptr; 1177 } 1178 break; 1179 case CalEvent::ARCHIVED: 1180 if (!KAlarm::addArchivedEvent(*mEvent, mResource)) 1181 { 1182 mRestoreError = ERR_CREATE; 1183 return nullptr; 1184 } 1185 break; 1186 default: 1187 mRestoreError = ERR_PROG; 1188 return nullptr; 1189 } 1190 1191 // Create a redo item to delete the alarm again 1192 mEvent->setCategory(saveType); 1193 return createRedo(*mEvent, mResource); 1194 } 1195 1196 /****************************************************************************** 1197 * Create a redo item to archive the alarm again. 1198 */ 1199 UndoItem* UndoDelete::createRedo(const KAEvent& event, const Resource& resource) 1200 { 1201 const Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE; 1202 return new UndoAdd(t, event, resource, mName); 1203 } 1204 1205 /****************************************************************************** 1206 * Return the action description of the Undo item for displaying. 1207 */ 1208 QString UndoDelete::defaultActionText() const 1209 { 1210 return addDeleteActionText(calendar(), (type() == Undo::REDO)); 1211 } 1212 1213 /****************************************************************************** 1214 * Dump the instance's contents to debug. 1215 */ 1216 void UndoDelete::dumpDebug() const 1217 { 1218 #ifndef KDE_NO_DEBUG_OUTPUT 1219 dumpDebugTitle("UndoDelete"); 1220 #endif 1221 } 1222 void UndoDelete::dumpDebugTitle(const char* typeName) const 1223 { 1224 #ifndef KDE_NO_DEBUG_OUTPUT 1225 UndoItem::dumpDebugTitle(typeName); 1226 qCDebug(KALARM_LOG) << "-- mResource: " << mResource.id(); 1227 qCDebug(KALARM_LOG) << "-- mEvent: " << mEvent->id(); 1228 qCDebug(KALARM_LOG) << "-- mDontShowErr:" << mDontShowErrors; 1229 #endif 1230 } 1231 1232 1233 /*============================================================================= 1234 = Class: UndoDeletes 1235 = Undo item for multiple alarm deletion. 1236 =============================================================================*/ 1237 1238 /****************************************************************************** 1239 * Create a redo item to delete the alarms again. 1240 */ 1241 UndoItem* UndoDeletes::createRedo(Undo::List* undos) 1242 { 1243 const Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE; 1244 return new UndoDeletes(t, undos, mName); 1245 } 1246 1247 /****************************************************************************** 1248 * Return the action description of the Undo item for displaying. 1249 */ 1250 QString UndoDeletes::defaultActionText() const 1251 { 1252 if (mUndos->isEmpty()) 1253 return {}; 1254 for (const UndoItem* item : std::as_const(*mUndos)) 1255 { 1256 switch (item->calendar()) 1257 { 1258 case CalEvent::ACTIVE: 1259 return i18nc("@info", "Delete multiple alarms"); 1260 case CalEvent::TEMPLATE: 1261 return i18nc("@info", "Delete multiple templates"); 1262 case CalEvent::ARCHIVED: 1263 break; // check if they are ALL archived 1264 default: 1265 return {}; 1266 } 1267 } 1268 return i18nc("@info", "Delete multiple archived alarms"); 1269 } 1270 1271 /****************************************************************************** 1272 * Dump the instance's contents to debug. 1273 */ 1274 void UndoDeletes::dumpDebug() const 1275 { 1276 #ifndef KDE_NO_DEBUG_OUTPUT 1277 dumpDebugTitle("UndoDeletes"); 1278 #endif 1279 } 1280 1281 1282 /*============================================================================= 1283 = Class: UndoReactivate 1284 = Undo item for alarm reactivation. 1285 =============================================================================*/ 1286 1287 /****************************************************************************** 1288 * Undo the item, i.e. re-archive the alarm which was reactivated. 1289 * Create a redo item to reactivate the alarm back again. 1290 * Reply = redo item. 1291 */ 1292 UndoItem* UndoReactivate::restore() 1293 { 1294 qCDebug(KALARM_LOG) << "UndoReactivate::restore"; 1295 // Validate the alarm's calendar 1296 switch (calendar()) 1297 { 1298 case CalEvent::ACTIVE: 1299 break; 1300 default: 1301 mRestoreError = ERR_PROG; 1302 return nullptr; 1303 } 1304 return UndoAdd::doRestore(true); // restore alarm, ensuring that it is re-archived 1305 } 1306 1307 /****************************************************************************** 1308 * Create a redo item to add the alarm back again. 1309 */ 1310 UndoItem* UndoReactivate::createRedo(const KAEvent& event, const Resource& resource) 1311 { 1312 const Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE; 1313 return new UndoDeactivate(t, event, resource, mName); 1314 } 1315 1316 /****************************************************************************** 1317 * Return the action description of the Undo item for displaying. 1318 */ 1319 QString UndoReactivate::defaultActionText() const 1320 { 1321 return i18nc("@info", "Reactivate alarm"); 1322 } 1323 1324 /****************************************************************************** 1325 * Dump the instance's contents to debug. 1326 */ 1327 void UndoReactivate::dumpDebug() const 1328 { 1329 #ifndef KDE_NO_DEBUG_OUTPUT 1330 dumpDebugTitle("UndoReactivate"); 1331 #endif 1332 } 1333 1334 1335 /*============================================================================= 1336 = Class: UndoDeactivate 1337 = Redo item for alarm reactivation. 1338 =============================================================================*/ 1339 1340 /****************************************************************************** 1341 * Undo the item, i.e. reactivate an alarm which was archived. 1342 * Create a redo item to archive the alarm again. 1343 * Reply = redo item. 1344 */ 1345 UndoItem* UndoDeactivate::restore() 1346 { 1347 qCDebug(KALARM_LOG) << "UndoDeactivate::restore"; 1348 // Validate the alarm's calendar 1349 switch (calendar()) 1350 { 1351 case CalEvent::ACTIVE: 1352 break; 1353 default: 1354 mRestoreError = ERR_PROG; 1355 return nullptr; 1356 } 1357 1358 return UndoDelete::restore(); 1359 } 1360 1361 /****************************************************************************** 1362 * Create a redo item to archive the alarm again. 1363 */ 1364 UndoItem* UndoDeactivate::createRedo(const KAEvent& event, const Resource& resource) 1365 { 1366 const Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE; 1367 return new UndoReactivate(t, event, resource, mName); 1368 } 1369 1370 /****************************************************************************** 1371 * Return the action description of the Undo item for displaying. 1372 */ 1373 QString UndoDeactivate::defaultActionText() const 1374 { 1375 return i18nc("@info", "Reactivate alarm"); 1376 } 1377 1378 /****************************************************************************** 1379 * Dump the instance's contents to debug. 1380 */ 1381 void UndoDeactivate::dumpDebug() const 1382 { 1383 #ifndef KDE_NO_DEBUG_OUTPUT 1384 dumpDebugTitle("UndoDeactivate"); 1385 #endif 1386 } 1387 1388 1389 /*============================================================================= 1390 = Class: UndoReactivates 1391 = Undo item for multiple alarm reactivation. 1392 =============================================================================*/ 1393 1394 /****************************************************************************** 1395 * Create a redo item to reactivate the alarms again. 1396 */ 1397 UndoItem* UndoReactivates::createRedo(Undo::List* undos) 1398 { 1399 const Undo::Type t = (type() == Undo::UNDO) ? Undo::REDO : (type() == Undo::REDO) ? Undo::UNDO : Undo::NONE; 1400 return new UndoReactivates(t, undos, mName); 1401 } 1402 1403 /****************************************************************************** 1404 * Return the action description of the Undo item for displaying. 1405 */ 1406 QString UndoReactivates::defaultActionText() const 1407 { 1408 return i18nc("@info", "Reactivate multiple alarms"); 1409 } 1410 1411 /****************************************************************************** 1412 * Dump the instance's contents to debug. 1413 */ 1414 void UndoReactivates::dumpDebug() const 1415 { 1416 #ifndef KDE_NO_DEBUG_OUTPUT 1417 dumpDebugTitle("UndoReactivates"); 1418 #endif 1419 } 1420 1421 1422 /*============================================================================= 1423 = Class: Event 1424 = Event details for external calls. 1425 =============================================================================*/ 1426 Undo::Event::Event(const KAEvent& e, const Resource& r) 1427 : event(e) 1428 , resource(r) 1429 { 1430 if (e.category() == CalEvent::ACTIVE) 1431 dontShowErrors = KAlarm::dontShowErrors(EventId(e)); 1432 } 1433 1434 #include "moc_undo.cpp" 1435 1436 // vim: et sw=4: