action_stack.cpp 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. /* action_stack.cpp - Action undo/redo stack
  2. * Copyright (C) 2017 caryoscelus
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation, either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  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. */
  17. #include <core/action_stack.h>
  18. namespace rainynite::core {
  19. bool ActionStack::append(AbstractAction const& action) {
  20. if (undo_stack.empty())
  21. return false;
  22. return undo_stack.back()->append(action);
  23. }
  24. void ActionStack::push(unique_ptr<AbstractAction> action) {
  25. try {
  26. action->redo();
  27. } catch (...) {
  28. // TODO: report exception
  29. return;
  30. }
  31. redo_stack.clear();
  32. if (!append(*action)) {
  33. close();
  34. bool should_close = !action->appendable();
  35. undo_stack.emplace_back(std::move(action));
  36. if (should_close)
  37. close();
  38. }
  39. }
  40. bool ActionStack::undo() {
  41. return undo_redo(undo_stack, redo_stack, UndoRedo::Undo);
  42. }
  43. bool ActionStack::redo() {
  44. return undo_redo(redo_stack, undo_stack, UndoRedo::Redo);
  45. }
  46. bool ActionStack::undo_redo(Stack& from, Stack& to, UndoRedo op) {
  47. if (from.size() == 0)
  48. return false;
  49. auto action = std::move(from.back());
  50. from.pop_back();
  51. action->undo_redo(op);
  52. to.push_back(std::move(action));
  53. undone_or_redone();
  54. return true;
  55. }
  56. void ActionStack::close() {
  57. if (!undo_stack.empty()) {
  58. if (undo_stack.back()->close())
  59. action_closed();
  60. }
  61. }
  62. void ActionStack::clear() {
  63. undo_stack.clear();
  64. redo_stack.clear();
  65. }
  66. } // namespace rainynite::core