Events.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /*
  2. This file is part of QTau
  3. Copyright (C) 2013-2018 Tobias "Tomoko" Platen <tplaten@posteo.de>
  4. Copyright (C) 2013 digited <https://github.com/digited>
  5. Copyright (C) 2010-2013 HAL@ShurabaP <https://github.com/haruneko>
  6. QTau is free software: you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation, either version 3 of the License, or
  9. (at your option) any later version.
  10. This program is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. GNU General Public License for more details.
  14. You should have received a copy of the GNU General Public License
  15. along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. SPDX-License-Identifier: GPL-3.0+
  17. */
  18. #ifndef EVENTS_H
  19. #define EVENTS_H
  20. #include <QObject>
  21. #include <QStack>
  22. class qtauEvent
  23. {
  24. friend class qtauEventManager;
  25. public:
  26. typedef enum { // linking is sorta shortcut because I don't feel like making composite events
  27. single = 0, // separate event
  28. linkedToNext, // requires applying next after this one
  29. linkedToPrev, // should be applied right after previous one
  30. linkedToBoth // is in the middle of chain of events
  31. } EEventLink;
  32. qtauEvent(int type = 0, bool forward = true, EEventLink link = single) :
  33. _type(type), _forward(forward), _linkType(link), _isSavePoint(false) {}
  34. virtual ~qtauEvent() {}
  35. int type() const { return _type; }
  36. bool isForward() const { return _forward; } // is event used to apply or to revert its changeset
  37. EEventLink isLinked() const { return _linkType; } // should event be applied with other(s)
  38. bool isSavePoint() { return _isSavePoint; }
  39. void setSavePoint(bool isSP = true) { _isSavePoint = isSP; }
  40. protected:
  41. int _type;
  42. bool _forward;
  43. EEventLink _linkType;
  44. bool _isSavePoint;
  45. virtual qtauEvent *allocCopy() const = 0; // should create exact copy of event object on heap
  46. };
  47. /// logic for any class that wants to use events
  48. class qtauEventManager : public QObject
  49. {
  50. Q_OBJECT
  51. public:
  52. explicit qtauEventManager(QObject *parent = 0) : QObject(parent) {}
  53. virtual ~qtauEventManager() { clearHistory(); }
  54. virtual void storeEvent(const qtauEvent *e)
  55. {
  56. clearFuture();
  57. events.push(e->allocCopy());
  58. stackChanged();
  59. }
  60. virtual void undo()
  61. {
  62. if (canUndo())
  63. {
  64. futureEvents.push(events.pop());
  65. futureEvents.top()->_forward = false;
  66. processEvent(futureEvents.top());
  67. stackChanged();
  68. emit onEvent(futureEvents.top());
  69. }
  70. }
  71. virtual void redo()
  72. {
  73. if (canRedo())
  74. {
  75. events.push(futureEvents.pop());
  76. events.top()->_forward = true;
  77. processEvent(events.top());
  78. stackChanged();
  79. emit onEvent(events.top());
  80. }
  81. }
  82. virtual void clearHistory() { clearPast(); clearFuture(); stackChanged(); }
  83. virtual int historyDepth() { return events.size(); }
  84. virtual bool isHistoryEmpty() { return events.isEmpty(); }
  85. virtual bool canUndo() { return !events.isEmpty(); }
  86. virtual bool canRedo() { return !futureEvents.isEmpty(); }
  87. signals:
  88. void onEvent(qtauEvent*);
  89. protected:
  90. QStack<qtauEvent*> events;
  91. QStack<qtauEvent*> futureEvents; // what was undo'ed
  92. // making those functions purely virtual crashes app at calling stackChange from clearHistory on destruction
  93. virtual bool processEvent(qtauEvent*) { return false; } // on undo/redo
  94. virtual void stackChanged() {} // on store (add) and clear (remove all)
  95. void clearPast()
  96. {
  97. while (!events.isEmpty())
  98. delete events.pop();
  99. }
  100. void clearFuture()
  101. {
  102. while (!futureEvents.isEmpty())
  103. delete futureEvents.pop();
  104. }
  105. };
  106. #endif // EVENTS_H