161 lines
3.6 KiB
C++
161 lines
3.6 KiB
C++
#include "ntxnodecommands.h"
|
|
|
|
namespace ntx
|
|
{
|
|
|
|
// =========================================================================
|
|
// NtxInsertNodeCmd
|
|
// =========================================================================
|
|
|
|
NtxInsertNodeCmd::NtxInsertNodeCmd(NtxNodePtr parent, NtxNodePtr node, size_t index)
|
|
: m_parent(std::move(parent))
|
|
, m_node(std::move(node))
|
|
, m_index(index)
|
|
{
|
|
setDescription("Insert node");
|
|
}
|
|
|
|
bool NtxInsertNodeCmd::execute()
|
|
{
|
|
if (!canExecute())
|
|
return false;
|
|
|
|
if (m_index > m_parent->getChildCount())
|
|
m_index = m_parent->getChildCount();
|
|
|
|
m_parent->insertChild(m_index, m_node);
|
|
m_executed = true;
|
|
return true;
|
|
}
|
|
|
|
bool NtxInsertNodeCmd::undo()
|
|
{
|
|
if (!m_executed)
|
|
return false;
|
|
|
|
auto idx = m_parent->getChildIndex(m_node);
|
|
if (idx == static_cast<size_t>(-1))
|
|
return false;
|
|
|
|
m_parent->removeChild(idx);
|
|
m_executed = false;
|
|
return true;
|
|
}
|
|
|
|
bool NtxInsertNodeCmd::canExecute() const
|
|
{
|
|
return m_parent && m_node && !m_executed;
|
|
}
|
|
|
|
// =========================================================================
|
|
// NtxRemoveNodeCmd
|
|
// =========================================================================
|
|
|
|
NtxRemoveNodeCmd::NtxRemoveNodeCmd(NtxNodePtr node)
|
|
: m_node(std::move(node))
|
|
{
|
|
setDescription("Remove node");
|
|
}
|
|
|
|
bool NtxRemoveNodeCmd::execute()
|
|
{
|
|
if (!canExecute())
|
|
return false;
|
|
|
|
m_parent = m_node->getParent();
|
|
if (!m_parent)
|
|
return false;
|
|
|
|
auto pos = m_node->ownPos();
|
|
if (!pos)
|
|
return false;
|
|
|
|
m_index = *pos;
|
|
m_parent->removeChild(m_index);
|
|
m_executed = true;
|
|
return true;
|
|
}
|
|
|
|
bool NtxRemoveNodeCmd::undo()
|
|
{
|
|
if (!m_executed || !m_parent)
|
|
return false;
|
|
|
|
m_parent->insertChild(m_index, m_node);
|
|
m_executed = false;
|
|
return true;
|
|
}
|
|
|
|
bool NtxRemoveNodeCmd::canExecute() const
|
|
{
|
|
return m_node && m_node->getParent() && !m_executed;
|
|
}
|
|
|
|
// =========================================================================
|
|
// NtxMacroCommand
|
|
// =========================================================================
|
|
|
|
NtxMacroCommand::NtxMacroCommand(const NtxString& description)
|
|
{
|
|
setDescription(description);
|
|
}
|
|
|
|
NtxCommandUPtr NtxMacroCommand::create(
|
|
const NtxString& description,
|
|
std::vector<NtxCommandUPtr> commands)
|
|
{
|
|
auto macro = std::make_unique<NtxMacroCommand>(description);
|
|
for (auto& cmd : commands)
|
|
macro->add(std::move(cmd));
|
|
return macro;
|
|
}
|
|
|
|
void NtxMacroCommand::add(NtxCommandUPtr cmd)
|
|
{
|
|
if (cmd)
|
|
m_commands.push_back(std::move(cmd));
|
|
}
|
|
|
|
bool NtxMacroCommand::execute()
|
|
{
|
|
m_executedCount = 0;
|
|
|
|
for (auto& cmd : m_commands)
|
|
{
|
|
if (!cmd->execute())
|
|
{
|
|
// Rollback: Bereits ausgeführte rückgängig machen
|
|
for (size_t i = m_executedCount; i > 0; --i)
|
|
m_commands[i - 1]->undo();
|
|
m_executedCount = 0;
|
|
return false;
|
|
}
|
|
++m_executedCount;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool NtxMacroCommand::undo()
|
|
{
|
|
for (size_t i = m_executedCount; i > 0; --i)
|
|
{
|
|
if (!m_commands[i - 1]->undo())
|
|
return false;
|
|
}
|
|
m_executedCount = 0;
|
|
return true;
|
|
}
|
|
|
|
bool NtxMacroCommand::canExecute() const
|
|
{
|
|
if (m_commands.empty())
|
|
return false;
|
|
for (const auto& cmd : m_commands)
|
|
{
|
|
if (!cmd->canExecute())
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace ntx
|