undo_model.cpp 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. /* undo_model.cpp - undo/redo action list model
  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 <QIcon>
  18. #include <core/action_stack.h>
  19. #include <util/strings.h>
  20. #include "undo_model.h"
  21. namespace rainynite::studio {
  22. UndoModel::UndoModel(shared_ptr<core::ActionStack> action_stack_, QObject* parent) :
  23. QAbstractItemModel(parent),
  24. action_stack(action_stack_)
  25. {
  26. auto update = [this]() {
  27. beginResetModel();
  28. endResetModel();
  29. };
  30. connect_boost(action_stack->undone_or_redone, update);
  31. connect_boost(action_stack->action_closed, update);
  32. }
  33. UndoModel::~UndoModel() {
  34. }
  35. QVariant UndoModel::data(QModelIndex const& index, int role) const {
  36. if (!index.isValid() || index.column() != 0 || index.parent().isValid())
  37. return {};
  38. switch (role) {
  39. case Qt::DisplayRole:
  40. return util::str(get_action(index)->doc_string());
  41. case Qt::DecorationRole:
  42. if (index.row() < (ptrdiff_t)action_stack->get_undo_stack().size())
  43. return QIcon::fromTheme("emblem-ok-symbolic");
  44. return QIcon::fromTheme("clock");
  45. default:
  46. return {};
  47. }
  48. }
  49. Qt::ItemFlags UndoModel::flags(QModelIndex const& /*index*/) const {
  50. return Qt::ItemIsEnabled;
  51. }
  52. QVariant UndoModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const {
  53. return {};
  54. }
  55. QModelIndex UndoModel::index(int row, int column, QModelIndex const& parent) const {
  56. if (parent.isValid())
  57. return {};
  58. return createIndex(row, column);
  59. }
  60. QModelIndex UndoModel::parent(QModelIndex const& /*index*/) const {
  61. return {};
  62. }
  63. int UndoModel::rowCount(QModelIndex const& parent) const {
  64. if (parent.isValid())
  65. return 0;
  66. return
  67. action_stack->get_undo_stack().size() +
  68. action_stack->get_redo_stack().size();
  69. }
  70. int UndoModel::columnCount(QModelIndex const& /*parent*/) const {
  71. return 1;
  72. }
  73. unique_ptr<core::AbstractAction> const& UndoModel::get_action(QModelIndex const& index) const {
  74. static unique_ptr<core::AbstractAction> static_null = nullptr;
  75. if (index.parent().isValid())
  76. return static_null;
  77. auto const& undo_stack = action_stack->get_undo_stack();
  78. auto undo_index = index.row();
  79. ptrdiff_t redo_index = undo_index - undo_stack.size();
  80. if (redo_index >= 0) {
  81. auto const& redo_stack = action_stack->get_redo_stack();
  82. if (redo_index >= (ptrdiff_t)redo_stack.size())
  83. return static_null;
  84. return redo_stack.rbegin()[redo_index];
  85. }
  86. return undo_stack[undo_index];
  87. }
  88. void UndoModel::reset() {
  89. beginResetModel();
  90. endResetModel();
  91. }
  92. } // namespace rainynite::studio