You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

509 lines
12 KiB
C++

2 years ago
// XTPFlowGraphUndoManager.cpp : implementation of the CXTPFlowGraphUndoManager class.
//
// This file is a part of the XTREME TOOLKIT PRO MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "Common/Resource.h"
#include "Common/XTPDrawHelpers.h"
#include "Common/XTPPropExchange.h"
#include "Common/XTPImageManager.h"
#include "XTPFlowGraphElement.h"
#include "XTPFlowGraphControl.h"
#include "XTPFlowGraphNode.h"
#include "XTPFlowGraphNodes.h"
#include "XTPFlowGraphPage.h"
#include "XTPFlowGraphUndoManager.h"
#include "XTPFlowGraphConnection.h"
#include "XTPFlowGraphConnectionPoint.h"
#include "XTPFlowGraphConnectionPoints.h"
#include "XTPFlowGraphConnections.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
const int CONTEXT_NONE = 0;
const int CONTEXT_UNDO = 1;
const int CONTEXT_REDO = 2;
//////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoCommand
CXTPFlowGraphUndoCommand::CXTPFlowGraphUndoCommand(int nID)
: m_nID(nID)
{
}
CXTPFlowGraphUndoCommand::~CXTPFlowGraphUndoCommand()
{
}
void CXTPFlowGraphUndoCommand::Undo()
{
ASSERT(FALSE);
}
/////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoManager
CXTPFlowGraphUndoManager::CXTPFlowGraphUndoManager()
{
m_nUndoContext = CONTEXT_NONE;
m_pUndoGroup = NULL;
m_bEnabled = TRUE;
}
CXTPFlowGraphUndoManager::~CXTPFlowGraphUndoManager()
{
Clear();
SAFE_DELETE(m_pUndoGroup);
}
void CXTPFlowGraphUndoManager::Clear()
{
int i;
for (i = 0; i < m_arrUndoCommands.GetSize(); i++)
{
delete m_arrUndoCommands[i];
}
m_arrUndoCommands.RemoveAll();
for (i = 0; i < m_arrRedoCommands.GetSize(); i++)
{
delete m_arrRedoCommands[i];
}
m_arrRedoCommands.RemoveAll();
SAFE_DELETE(m_pUndoGroup);
}
void CXTPFlowGraphUndoManager::StartGroup()
{
if (m_pUndoGroup != NULL)
{
m_arrGroupStack.Add(m_pUndoGroup);
}
m_pUndoGroup = new CXTPFlowGraphUndoGroupCommand(this);
}
void CXTPFlowGraphUndoManager::EndGroup()
{
if (m_pUndoGroup->GetCount() == 0)
{
delete m_pUndoGroup;
}
else
{
if (m_arrGroupStack.GetSize() > 0)
m_arrGroupStack[m_arrGroupStack.GetSize() - 1]->Add(m_pUndoGroup);
else if (m_nUndoContext != CONTEXT_UNDO)
m_arrUndoCommands.Add(m_pUndoGroup);
else
m_arrRedoCommands.Add(m_pUndoGroup);
}
m_pUndoGroup = NULL;
if (m_arrGroupStack.GetSize())
{
m_pUndoGroup = m_arrGroupStack[m_arrGroupStack.GetSize() - 1];
m_arrGroupStack.RemoveAt(m_arrGroupStack.GetSize() - 1);
}
}
void CXTPFlowGraphUndoManager::AddUndoCommand(CXTPFlowGraphUndoCommand* pCommand)
{
if (!m_bEnabled)
{
delete pCommand;
return;
}
if (m_pUndoGroup)
{
m_pUndoGroup->Add(pCommand);
}
else if (m_nUndoContext != CONTEXT_UNDO)
{
m_arrUndoCommands.Add(pCommand);
}
else
{
m_arrRedoCommands.Add(pCommand);
}
if (m_nUndoContext == CONTEXT_NONE)
{
for (int i = 0; i < m_arrRedoCommands.GetSize(); i++)
{
delete m_arrRedoCommands[i];
}
m_arrRedoCommands.RemoveAll();
}
}
BOOL CXTPFlowGraphUndoManager::CanUndo() const
{
return m_arrUndoCommands.GetSize() > 0;
}
BOOL CXTPFlowGraphUndoManager::CanRedo() const
{
return m_arrRedoCommands.GetSize() > 0;
}
void CXTPFlowGraphUndoManager::Undo()
{
if (m_arrUndoCommands.GetSize() > 0)
{
m_nUndoContext = 1;
CXTPFlowGraphUndoCommand* pUndoCommand = m_arrUndoCommands[m_arrUndoCommands.GetSize() - 1];
pUndoCommand->Undo();
delete pUndoCommand;
m_arrUndoCommands.RemoveAt(m_arrUndoCommands.GetSize() - 1);
m_nUndoContext = 0;
}
}
void CXTPFlowGraphUndoManager::Redo()
{
if (m_arrRedoCommands.GetSize() > 0)
{
m_nUndoContext = 2;
CXTPFlowGraphUndoCommand* pUndoCommand = m_arrRedoCommands[m_arrRedoCommands.GetSize() - 1];
pUndoCommand->Undo();
delete pUndoCommand;
m_arrRedoCommands.RemoveAt(m_arrRedoCommands.GetSize() - 1);
m_nUndoContext = 0;
}
}
//////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoGroupCommand
CXTPFlowGraphUndoGroupCommand::CXTPFlowGraphUndoGroupCommand(CXTPFlowGraphUndoManager* pManager)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_GROUP)
{
m_pManager = pManager;
}
CXTPFlowGraphUndoGroupCommand::~CXTPFlowGraphUndoGroupCommand()
{
for (int i = (int)m_arrUndoCommands.GetSize() - 1; i >= 0; i--)
{
delete m_arrUndoCommands[i];
}
m_arrUndoCommands.RemoveAll();
}
void CXTPFlowGraphUndoGroupCommand::Add(CXTPFlowGraphUndoCommand* pCommand)
{
m_arrUndoCommands.Add(pCommand);
}
void CXTPFlowGraphUndoGroupCommand::Undo()
{
m_pManager->StartGroup();
for (int i = (int)m_arrUndoCommands.GetSize() - 1; i >= 0; i--)
{
m_arrUndoCommands[i]->Undo();
delete m_arrUndoCommands[i];
}
m_arrUndoCommands.RemoveAll();
m_pManager->EndGroup();
}
int CXTPFlowGraphUndoGroupCommand::GetCount() const
{
return (int)m_arrUndoCommands.GetSize();
}
//////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoAddNodeCommand
CXTPFlowGraphUndoAddNodeCommand::CXTPFlowGraphUndoAddNodeCommand(CXTPFlowGraphNode* pNode)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_ADDNODE)
{
m_pNode = pNode;
m_pNode->InternalAddRef();
}
CXTPFlowGraphUndoAddNodeCommand::~CXTPFlowGraphUndoAddNodeCommand()
{
m_pNode->InternalRelease();
}
void CXTPFlowGraphUndoAddNodeCommand::Undo()
{
m_pNode->Remove();
}
//////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoAddConnectionPointCommand
CXTPFlowGraphUndoAddConnectionPointCommand::CXTPFlowGraphUndoAddConnectionPointCommand(CXTPFlowGraphConnectionPoint* pConnectionPoint)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_ADDCONNECTIONPOINT)
{
m_pConnectionPoint = pConnectionPoint;
m_pConnectionPoint->InternalAddRef();
}
CXTPFlowGraphUndoAddConnectionPointCommand::~CXTPFlowGraphUndoAddConnectionPointCommand()
{
m_pConnectionPoint->InternalRelease();
}
void CXTPFlowGraphUndoAddConnectionPointCommand::Undo()
{
m_pConnectionPoint->Remove();
}
//////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoAddConnectionCommand
CXTPFlowGraphUndoAddConnectionCommand::CXTPFlowGraphUndoAddConnectionCommand(CXTPFlowGraphConnection* pConnection)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_ADDCONNECTION)
{
m_pConnection = pConnection;
m_pConnection->InternalAddRef();
}
CXTPFlowGraphUndoAddConnectionCommand::~CXTPFlowGraphUndoAddConnectionCommand()
{
m_pConnection->InternalRelease();
}
void CXTPFlowGraphUndoAddConnectionCommand::Undo()
{
m_pConnection->Remove();
}
//////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoDeleteNodeCommand
CXTPFlowGraphUndoDeleteNodeCommand::CXTPFlowGraphUndoDeleteNodeCommand(CXTPFlowGraphNode* pNode)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_DELETENODE)
{
m_pNode = pNode;
m_pNode->InternalAddRef();
m_pPage = pNode->GetPage();
}
CXTPFlowGraphUndoDeleteNodeCommand::~CXTPFlowGraphUndoDeleteNodeCommand()
{
m_pNode->InternalRelease();
}
void CXTPFlowGraphUndoDeleteNodeCommand::Undo()
{
m_pNode->InternalAddRef();
m_pPage->GetNodes()->AddNode(m_pNode);
}
//////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoDeleteConnectionPointCommand
CXTPFlowGraphUndoDeleteConnectionPointCommand::CXTPFlowGraphUndoDeleteConnectionPointCommand(CXTPFlowGraphConnectionPoint* pConnectionPoint)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_DELETECONNECTIONPOINT)
{
m_pConnectionPoint = pConnectionPoint;
m_pConnectionPoint->InternalAddRef();
m_pNode = m_pConnectionPoint->GetNode();
m_pNode->InternalAddRef();
m_nIndex = m_pConnectionPoint->m_nConnectionPointIndex;
}
CXTPFlowGraphUndoDeleteConnectionPointCommand::~CXTPFlowGraphUndoDeleteConnectionPointCommand()
{
m_pNode->InternalRelease();
m_pConnectionPoint->InternalRelease();
}
void CXTPFlowGraphUndoDeleteConnectionPointCommand::Undo()
{
if (m_pNode->GetPage() != NULL)
{
m_pNode->GetConnectionPoints()->AddConnectionPoint(m_pConnectionPoint, m_nIndex);
m_pConnectionPoint->InternalAddRef();
}
}
//////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoDeleteConnectionCommand
CXTPFlowGraphUndoDeleteConnectionCommand::CXTPFlowGraphUndoDeleteConnectionCommand(CXTPFlowGraphConnection* pConnection)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_DELETECONNECTION)
{
m_pConnection = pConnection;
m_pConnection->InternalAddRef();
m_pPage = pConnection->GetPage();
m_pInputPoint = m_pConnection->GetInputPoint();
if (m_pInputPoint) m_pInputPoint->InternalAddRef();
m_pOutputPoint = m_pConnection->GetOutputPoint();
if (m_pOutputPoint) m_pOutputPoint->InternalAddRef();
}
CXTPFlowGraphUndoDeleteConnectionCommand::~CXTPFlowGraphUndoDeleteConnectionCommand()
{
m_pConnection->InternalRelease();
if (m_pInputPoint) m_pInputPoint->InternalRelease();
if (m_pOutputPoint) m_pOutputPoint->InternalRelease();
}
void CXTPFlowGraphUndoDeleteConnectionCommand::Undo()
{
if (!(m_pInputPoint && m_pInputPoint->GetNode() && m_pInputPoint->GetNode()->GetPage() == m_pPage))
return;
if (!(m_pOutputPoint && m_pOutputPoint->GetNode() && m_pOutputPoint->GetNode()->GetPage() == m_pPage))
return;
m_pConnection->InternalAddRef();
m_pConnection->SetInputPoint(m_pInputPoint);
m_pConnection->SetOutputPoint(m_pOutputPoint);
m_pPage->GetConnections()->AddConnection(m_pConnection);
}
///////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoSetNodePositionCommand
CXTPFlowGraphUndoSetNodePositionCommand::CXTPFlowGraphUndoSetNodePositionCommand(CXTPFlowGraphNode* pNode, CPoint ptOldPosition)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_SETNODEPOSITION)
{
m_ptOldPosition = ptOldPosition;
m_pNode = pNode;
m_pNode->InternalAddRef();
}
CXTPFlowGraphUndoSetNodePositionCommand::~CXTPFlowGraphUndoSetNodePositionCommand()
{
m_pNode->InternalRelease();
}
void CXTPFlowGraphUndoSetNodePositionCommand::Undo()
{
m_pNode->SetLocation(m_ptOldPosition);
}
///////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoSetNodeSizeCommand
CXTPFlowGraphUndoSetNodeSizeCommand::CXTPFlowGraphUndoSetNodeSizeCommand(CXTPFlowGraphNode* pNode, CSize szOldSize)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_SETNODESIZE)
{
m_szOldSize = szOldSize;
m_pNode = pNode;
m_pNode->InternalAddRef();
}
CXTPFlowGraphUndoSetNodeSizeCommand::~CXTPFlowGraphUndoSetNodeSizeCommand()
{
m_pNode->InternalRelease();
}
void CXTPFlowGraphUndoSetNodeSizeCommand::Undo()
{
m_pNode->SetSize(m_szOldSize);
}
///////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoSetNodePositionCommand
CXTPFlowGraphUndoSetNodeCaptionCommand::CXTPFlowGraphUndoSetNodeCaptionCommand(CXTPFlowGraphElement* pNode, CString strOldCaption)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_SETNODECAPTION)
{
m_strOldCaption = strOldCaption;
m_pNode = pNode;
m_pNode->InternalAddRef();
}
CXTPFlowGraphUndoSetNodeCaptionCommand::~CXTPFlowGraphUndoSetNodeCaptionCommand()
{
m_pNode->InternalRelease();
}
void CXTPFlowGraphUndoSetNodeCaptionCommand::Undo()
{
m_pNode->SetCaption(m_strOldCaption);
}
///////////////////////////////////////////////////////////////////////////
// CXTPFlowGraphUndoSetConnectionPositionCommand
CXTPFlowGraphUndoSetConnectionPositionCommand::CXTPFlowGraphUndoSetConnectionPositionCommand(CXTPFlowGraphConnection* pConnection, CPoint ptOldPosition)
: CXTPFlowGraphUndoCommand(XTP_ID_FLOWGRAPHUNDO_SETCONNECTIONPOSITION)
{
m_ptOldPosition = ptOldPosition;
m_pConnection = pConnection;
m_pConnection->InternalAddRef();
}
CXTPFlowGraphUndoSetConnectionPositionCommand::~CXTPFlowGraphUndoSetConnectionPositionCommand()
{
m_pConnection->InternalRelease();
}
void CXTPFlowGraphUndoSetConnectionPositionCommand::Undo()
{
m_pConnection->SetControlPoint(m_ptOldPosition);
}