////////////////////////////////////////////////////////////////////////////// //文件 ActionModifiedItem.cpp //主要功能: // //程序编写: 2006-12-07 ///////////////////////////////////////////////////////////////////////////// #include "StdAfx.h" #include ".\actionmodifieditem.h" #include "SigmaDoc.h" #include "SigmaView.h" #include "Visitor.h" CActionModifiedItem::CActionModifiedItem(CSigmaDoc * ppDoc, UINT actionType) : CActionItem(ppDoc, actionType) { } NAction::CActionModifiedItem::CActionModifiedItem() :CActionItem(nullptr, 0) { } CActionModifiedItem::CActionModifiedItem(CSigmaDoc * ppDoc, UINT actionType, const CPositionList& list) : CActionItem(ppDoc, actionType) { BackupOldItem(list); } CActionModifiedItem::~CActionModifiedItem(void) { } int CActionModifiedItem::GetCount() { return (int)m_entries.size(); } void CActionModifiedItem::Undo() { CActionItem::Undo(); PerformOperation(&ModifiedEntry::pOldOne); } void CActionModifiedItem::Redo() { CActionItem::Redo(); PerformOperation(&ModifiedEntry::pNewOne); } void NAction::CActionModifiedItem::accept(CActionVisitor& visitor) { visitor.visit(*this); } void CActionModifiedItem::PerformOperation(std::unique_ptr ModifiedEntry::* member) { GetDoc()->ClearSelection(); for (const ModifiedEntry& entry : m_entries) { // 拿到 CXy 中的 COne 指针,它就是我们要 undo redo 的目标对象 COne* pOne = GetDoc()->GetDraw()->GetOneById(entry.id); // 这里根据 member 这个类成员指针来决定是取 pOldOne 还是 pNewOne,undo 时就是 pOldOne,redo 时就是 pNewOne const std::unique_ptr& pActionOne = entry.*member; if (pOne != nullptr && pActionOne != nullptr) { // 拷贝备份的内容到目标对象中 CloneOneAndInvalidate(pOne, pActionOne.get()); } } } void CActionModifiedItem::AfterRedoUndo(COne* pDestOne) { } void NAction::CActionModifiedItem::BackupOldOne(COne* pOne) { if (pOne != nullptr) { ModifiedEntry entry; entry.id = pOne->GetId(); entry.pOldOne = std::make_unique(); CloneOne(entry.pOldOne.get(), pOne); m_entries.push_back(std::move(entry)); } } void NAction::CActionModifiedItem::CloneOneAndInvalidate(COne* pOne, const COne* pActionOne) { CloneOne(pOne, const_cast(pActionOne)); CRect8 range(1e100, -1e100, -1e100, 1e100); pOne->GetRange(range); Invalidate(range); } bool CActionModifiedItem::BackupOldItem(POSITION pos, COne* pOne) { if (pos == nullptr || pOne == nullptr) { return false; } BackupOldOne(pOne); return true; } void CActionModifiedItem::CloneOne(COne* pDestOne, COne* pSourceOne) { *pDestOne = *pSourceOne; } void CActionModifiedItem::BackupOldItem(const CPositionList& list) { for (POSITION pos = list.GetHeadPosition(); pos != nullptr; list.GetNext(pos)) { POSITION pt = list.GetAt(pos); COne* pOne = GetDoc()->GetDraw()->GetAt(pt); BackupOldOne(pOne); } } void NAction::CActionModifiedItem::BackupNewItem() { for (ModifiedEntry& entry : m_entries) { COne* pNewOne = GetDoc()->GetDraw()->GetOneById(entry.id); if (pNewOne != nullptr) { entry.pNewOne = std::make_unique(); CloneOne(entry.pNewOne.get(), pNewOne); } } } /////////////////////////////////////////////////////////////////////////////////////////////////// CActionModifiedMesh::CActionModifiedMesh(CSigmaDoc * ppDoc, UINT actionType) : CActionModifiedItem(ppDoc, actionType) { } NAction::CActionModifiedMesh::CActionModifiedMesh() { } CActionModifiedMesh::CActionModifiedMesh(CSigmaDoc * ppDoc, UINT actionType, const CPositionList& list) : CActionModifiedItem(ppDoc, actionType, list) { } CActionModifiedMesh::~CActionModifiedMesh(void) { } void NAction::CActionModifiedMesh::accept(CActionVisitor& visitor) { visitor.visit(*this); } void CActionModifiedMesh::CloneOne(COne* pDestOne, COne* pSourceOne) { pDestOne->CloneOtherParameter(*pSourceOne); ASSERT(pSourceOne->GetType() == DOUBLEFOX_MESH); if(pDestOne->value == NULL) pDestOne->value=new CMesh(); ((CMesh*)pDestOne->value)->CloneOtherParamter(*(CMesh*)pSourceOne->value); } void CActionModifiedMesh::AfterRedoUndo(COne* pDestOne) { //刷新显示 ((CMesh*)pDestOne->value)->GetBitmap(); }