Events.h 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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. friend class qtauEventManager;
  24. public:
  25. typedef enum { // linking is sorta shortcut because I don't feel like making
  26. // 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 {
  36. return _type;
  37. }
  38. bool isForward() const {
  39. return _forward;
  40. } // is event used to apply or to revert its changeset
  41. EEventLink isLinked() const {
  42. return _linkType;
  43. } // should event be applied with other(s)
  44. bool isSavePoint() {
  45. return _isSavePoint;
  46. }
  47. void setSavePoint(bool isSP = true) {
  48. _isSavePoint = isSP;
  49. }
  50. protected:
  51. int _type;
  52. bool _forward;
  53. EEventLink _linkType;
  54. bool _isSavePoint;
  55. virtual qtauEvent *allocCopy()
  56. const = 0; // should create exact copy of event object on heap
  57. };
  58. /// logic for any class that wants to use events
  59. class qtauEventManager : public QObject {
  60. Q_OBJECT
  61. public:
  62. explicit qtauEventManager(QObject *parent = 0) : QObject(parent) {}
  63. virtual ~qtauEventManager() {
  64. clearHistory();
  65. }
  66. virtual void storeEvent(const qtauEvent *e) {
  67. clearFuture();
  68. events.push(e->allocCopy());
  69. stackChanged();
  70. }
  71. virtual void undo() {
  72. if (canUndo()) {
  73. futureEvents.push(events.pop());
  74. futureEvents.top()->_forward = false;
  75. processEvent(futureEvents.top());
  76. stackChanged();
  77. emit onEvent(futureEvents.top());
  78. }
  79. }
  80. virtual void redo() {
  81. if (canRedo()) {
  82. events.push(futureEvents.pop());
  83. events.top()->_forward = true;
  84. processEvent(events.top());
  85. stackChanged();
  86. emit onEvent(events.top());
  87. }
  88. }
  89. virtual void clearHistory() {
  90. clearPast();
  91. clearFuture();
  92. stackChanged();
  93. }
  94. virtual int historyDepth() {
  95. return events.size();
  96. }
  97. virtual bool isHistoryEmpty() {
  98. return events.isEmpty();
  99. }
  100. virtual bool canUndo() {
  101. return !events.isEmpty();
  102. }
  103. virtual bool canRedo() {
  104. return !futureEvents.isEmpty();
  105. }
  106. signals:
  107. void onEvent(qtauEvent *);
  108. protected:
  109. QStack<qtauEvent *> events;
  110. QStack<qtauEvent *> futureEvents; // what was undo'ed
  111. // making those functions purely virtual crashes app at calling stackChange
  112. // from clearHistory on destruction
  113. virtual bool processEvent(qtauEvent *) {
  114. return false; // on undo/redo
  115. }
  116. virtual void stackChanged() {} // on store (add) and clear (remove all)
  117. void clearPast() {
  118. while (!events.isEmpty()) delete events.pop();
  119. }
  120. void clearFuture() {
  121. while (!futureEvents.isEmpty()) delete futureEvents.pop();
  122. }
  123. };
  124. #endif // EVENTS_H