!XT (BREAK-16) (Sandbox) Remove double-newlines at the end of files.
[CRYENGINE.git] / Code / Sandbox / EditorQt / Undo / CommandHistory.cpp
blob9abe2b3ddade2cb9aed6def8a123b8b61bd537ed
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
5 #include "CommandHistory.h"
6 #include "RecursionLoopGuard.h"
7 #include "IUndoManager.h"
8 #include <QMouseEvent>
9 #include <QLayout>
10 #include <QAdvancedTreeView.h>
11 #include <EditorStyleHelper.h>
12 #include "IEditorClassFactory.h"
14 REGISTER_HIDDEN_VIEWPANE_FACTORY(CHistoryPanel, "Undo History", "Tools", true)
16 namespace Private_CommandHistory
18 class QHistoryModel : public QAbstractTableModel
20 public:
21 QHistoryModel(QWidget* parent, IUndoManager* pCommandManager);
22 ~QHistoryModel();
23 int rowCount(const QModelIndex& parent = QModelIndex()) const;
24 int columnCount(const QModelIndex& parent = QModelIndex()) const;
25 QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
26 QVariant headerData(int section, Qt::Orientation orientation, int role) const;
27 void OnCommandBufferChange(CUndoStep* pCommand, IUndoManager::ECommandChangeType change, int index);
28 void FillHistoryFromCommandBuffer();
30 CCrySignal<void(CUndoStep*, IUndoManager::ECommandChangeType, int)> signalBufferChanged;
32 private:
33 IUndoManager* m_pCommandManager;
34 std::vector<CUndoStep*> m_commands;
35 QFont m_font;
36 QFont m_disabledFont;
38 int getCurrentIndex() const
40 if (m_pCommandManager)
41 return m_pCommandManager->GetUndoStackLen();
42 return 0;
46 QHistoryModel::QHistoryModel(QWidget* parent, IUndoManager* pCommandManager)
47 : QAbstractTableModel(parent)
48 , m_pCommandManager(pCommandManager)
50 FillHistoryFromCommandBuffer();
51 if (m_pCommandManager)
52 m_pCommandManager->signalBufferChanged.Connect(this, &QHistoryModel::OnCommandBufferChange);
54 m_font = QFont(parent->font());
58 QHistoryModel::~QHistoryModel()
60 if (m_pCommandManager)
61 m_pCommandManager->signalBufferChanged.DisconnectObject(this);
64 void QHistoryModel::FillHistoryFromCommandBuffer()
66 m_commands.clear();
68 if (m_pCommandManager)
70 for (CUndoStep* pCommand : m_pCommandManager->GetUndoStack())
71 m_commands.push_back(pCommand);
72 for (CUndoStep* pCommand : m_pCommandManager->GetRedoStack())
73 m_commands.push_back(pCommand);
76 dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
79 void QHistoryModel::OnCommandBufferChange(CUndoStep* pCommand, IUndoManager::ECommandChangeType changeType, int changedIndex)
81 if (!m_pCommandManager)
82 return;
84 if (IUndoManager::eCommandChangeType_Move & changeType)
86 dataChanged(index(0, 0), index(rowCount() - 1, columnCount() - 1));
89 if (IUndoManager::eCommandChangeType_Insert & changeType)
91 beginInsertRows(QModelIndex(), changedIndex + 1, changedIndex + 1);
92 m_commands.insert(m_commands.begin() + changedIndex, pCommand);
93 endInsertRows();
96 if (IUndoManager::eCommandChangeType_Remove & changeType)
98 if (-1 != changedIndex && 0 != m_commands.size())
100 if (pCommand)
102 beginRemoveRows(QModelIndex(), changedIndex + 1, changedIndex + 1);
103 m_commands.erase(m_commands.begin() + changedIndex);
104 endRemoveRows();
106 else if (IUndoManager::eCommandChangeType_Undo & changeType)
108 beginRemoveRows(QModelIndex(), 1, changedIndex);
109 m_commands.erase(m_commands.begin(), m_commands.begin() + changedIndex);
110 endRemoveRows();
112 else if (IUndoManager::eCommandChangeType_Redo & changeType)
114 beginRemoveRows(QModelIndex(), rowCount() - (changedIndex + 1), rowCount() - 1);
115 m_commands.erase(m_commands.end() - changedIndex, m_commands.end());
116 endRemoveRows();
121 signalBufferChanged(pCommand, changeType, changedIndex);
124 int QHistoryModel::rowCount(const QModelIndex& parent) const
126 if (!parent.isValid() && m_pCommandManager)
127 return 1 + m_commands.size();
128 return 1;
131 int QHistoryModel::columnCount(const QModelIndex& parent) const
133 if (!parent.isValid())
134 return 1;
135 return 0;
138 QVariant QHistoryModel::data(const QModelIndex& index, int role) const
140 int row = index.row();
141 int col = index.column();
143 switch (role)
145 case Qt::DisplayRole:
146 if (0 == row)
148 return QString("Starting Point");
150 else if (m_commands.size() >= row && m_pCommandManager)
152 string name;
153 m_pCommandManager->GetCommandName(m_commands[row - 1], name);
154 return QString(name.GetBuffer());
156 break;
158 case Qt::FontRole:
159 if (row > getCurrentIndex())
161 QFont font;
162 font.setItalic(true);
163 return font;
165 break;
167 case Qt::TextColorRole:
168 if (row > getCurrentIndex())
170 QColor color = GetStyleHelper()->disabledWindowTextColor();
171 return color;
173 break;
175 return QVariant();
178 QVariant QHistoryModel::headerData(int section, Qt::Orientation orientation, int role) const
180 if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
182 switch (section)
184 case 0:
185 return QString("Commands");
189 return QVariant();
192 class QHistoryView : public QAdvancedTreeView
194 public:
195 QHistoryView(IUndoManager* pCommandManager, QHistoryModel* pModel)
196 : m_pCommandManager(pCommandManager)
197 , m_validating(false)
198 , m_pModel(pModel)
200 setSelectionMode(QAbstractItemView::SingleSelection);
202 if (m_pCommandManager && pModel)
204 pModel->signalBufferChanged.Connect(this, &QHistoryView::OnCommandBufferChange);
208 ~QHistoryView()
212 protected:
213 void selectRow(int row)
215 if (selectionModel() && model())
216 selectionModel()->select(model()->index(row, 0), QItemSelectionModel::ClearAndSelect);
219 void QHistoryView::OnCommandBufferChange(CUndoStep* pCommand, IUndoManager::ECommandChangeType changeType, int index)
221 RECURSION_GUARD(m_validating);
223 if (IUndoManager::eCommandChangeType_Move & changeType)
225 selectRow(index + 1);
228 if (IUndoManager::eCommandChangeType_Insert & changeType)
230 selectRow(index + 1);
233 if (IUndoManager::eCommandChangeType_Remove & changeType)
235 if (-1 != index)
237 if (m_pCommandManager)
239 selectRow(index);
241 else if (IUndoManager::eCommandChangeType_Undo & changeType)
243 selectRow(model()->rowCount() - 1);
245 else if (IUndoManager::eCommandChangeType_Redo & changeType)
247 selectRow(model()->rowCount() - 1);
253 virtual void selectionChanged(const QItemSelection& selected, const QItemSelection& deselected) override
255 RECURSION_GUARD(m_validating);
257 if (0 != selected.size() && m_pCommandManager)
259 int row = selected.front().top();
260 int count = m_pCommandManager->GetRedoStackLen() + m_pCommandManager->GetUndoStackLen() + 1;
262 if (0 <= row && count > row)
264 int undoCount = m_pCommandManager->GetUndoStackLen();
265 int commandIndex = row - undoCount;
267 if (commandIndex > 0)
268 m_pCommandManager->Redo(commandIndex);
269 else if (commandIndex < 0)
270 m_pCommandManager->Undo(abs(commandIndex));
274 __super::selectionChanged(selected, deselected);
277 private:
278 bool m_validating;
279 IUndoManager* m_pCommandManager;
280 QHistoryModel* m_pModel;
284 CHistoryPanel::CHistoryPanel()
285 : CDockableWidget()
287 QVBoxLayout* layout = new QVBoxLayout();
288 layout->setContentsMargins(1, 1, 1, 1);
289 setLayout(layout);
291 IUndoManager* pCommandManager = GetIEditorImpl()->GetIUndoManager();
292 if (pCommandManager)
294 Private_CommandHistory::QHistoryModel* pHistoryModel = new Private_CommandHistory::QHistoryModel(this, pCommandManager);
295 Private_CommandHistory::QHistoryView* pHistoryList = new Private_CommandHistory::QHistoryView(pCommandManager, pHistoryModel);
296 pHistoryList->setModel(pHistoryModel);
297 layout->addWidget(pHistoryList);
301 CHistoryPanel::~CHistoryPanel()