156 lines
2.7 KiB
C++
156 lines
2.7 KiB
C++
#include <ntxundostack.h>
|
|
|
|
namespace ntx
|
|
{
|
|
|
|
NtxUndoStack::NtxUndoStack()
|
|
: m_index(0)
|
|
, m_cleanIndex(0)
|
|
, m_undoLimit(0)
|
|
{
|
|
}
|
|
|
|
void NtxUndoStack::push(NtxCommandUPtr command)
|
|
{
|
|
if (!command)
|
|
return;
|
|
|
|
if (!command->canExecute())
|
|
return;
|
|
|
|
if (!command->execute())
|
|
return;
|
|
|
|
if (m_index < static_cast<int>(m_commands.size()))
|
|
{
|
|
m_commands.erase(m_commands.begin() + m_index, m_commands.end());
|
|
}
|
|
|
|
m_commands.push_back(std::move(command));
|
|
m_index++;
|
|
|
|
if (m_cleanIndex > m_index)
|
|
m_cleanIndex = -1;
|
|
|
|
checkUndoLimit();
|
|
}
|
|
|
|
bool NtxUndoStack::canUndo() const
|
|
{
|
|
return m_index > 0;
|
|
}
|
|
|
|
bool NtxUndoStack::canRedo() const
|
|
{
|
|
return m_index < static_cast<int>(m_commands.size());
|
|
}
|
|
|
|
void NtxUndoStack::undo()
|
|
{
|
|
if (!canUndo())
|
|
return;
|
|
|
|
m_index--;
|
|
|
|
if (m_commands[m_index]->canUndo())
|
|
{
|
|
m_commands[m_index]->undo();
|
|
}
|
|
}
|
|
|
|
void NtxUndoStack::redo()
|
|
{
|
|
if (!canRedo())
|
|
return;
|
|
|
|
if (m_commands[m_index]->canExecute())
|
|
{
|
|
m_commands[m_index]->execute();
|
|
}
|
|
|
|
m_index++;
|
|
}
|
|
|
|
int NtxUndoStack::index() const
|
|
{
|
|
return m_index;
|
|
}
|
|
|
|
int NtxUndoStack::count() const
|
|
{
|
|
return static_cast<int>(m_commands.size());
|
|
}
|
|
|
|
NtxString NtxUndoStack::undoText() const
|
|
{
|
|
if (!canUndo())
|
|
return NtxString();
|
|
|
|
return m_commands[m_index - 1]->getDescription();
|
|
}
|
|
|
|
NtxString NtxUndoStack::redoText() const
|
|
{
|
|
if (!canRedo())
|
|
return NtxString();
|
|
|
|
return m_commands[m_index]->getDescription();
|
|
}
|
|
|
|
void NtxUndoStack::clear()
|
|
{
|
|
m_commands.clear();
|
|
m_index = 0;
|
|
m_cleanIndex = 0;
|
|
}
|
|
|
|
void NtxUndoStack::setClean()
|
|
{
|
|
m_cleanIndex = m_index;
|
|
}
|
|
|
|
bool NtxUndoStack::isClean() const
|
|
{
|
|
return m_cleanIndex == m_index;
|
|
}
|
|
|
|
void NtxUndoStack::setUndoLimit(int limit)
|
|
{
|
|
m_undoLimit = limit;
|
|
checkUndoLimit();
|
|
}
|
|
|
|
int NtxUndoStack::undoLimit() const
|
|
{
|
|
return m_undoLimit;
|
|
}
|
|
|
|
const NtxICommand* NtxUndoStack::command(int index) const
|
|
{
|
|
if (index < 0 || index >= static_cast<int>(m_commands.size()))
|
|
return nullptr;
|
|
|
|
return m_commands[index].get();
|
|
}
|
|
|
|
void NtxUndoStack::checkUndoLimit()
|
|
{
|
|
if (m_undoLimit <= 0)
|
|
return;
|
|
|
|
int deleteCount = m_index - m_undoLimit;
|
|
if (deleteCount <= 0)
|
|
return;
|
|
|
|
m_commands.erase(m_commands.begin(), m_commands.begin() + deleteCount);
|
|
m_index -= deleteCount;
|
|
|
|
if (m_cleanIndex != -1)
|
|
{
|
|
m_cleanIndex -= deleteCount;
|
|
if (m_cleanIndex < 0)
|
|
m_cleanIndex = -1;
|
|
}
|
|
}
|
|
|
|
} // namespace ntx
|