2.6 删除操作从直观上来说,删除操作应为创建操作的逆操作,所以其处理过程与创建操作相类似,应该好处理。当然,从解决问题角度出发,还是来看删除操作的撤销与重做的需求。要撤销删除操作,则相当于创建被删除的对象。这与创建操作的重做一样吗?仔细一想,不一样的。因为创建操作所创建的对象,可以认为是“裸”对象,即刚创建的对象还不会和外界发生联系,最主要的是没有连接关系,这些联系都是后续操作加上去的。但在删除操作时,被操作对象可能已有外部关系,则其撤销目标中也应恢复这些外部关系。当然,其重做过程处理就简单了,直接删除即可。再回想起创建导线操作,并考虑到后续的思维图元的需求,即操作除了被操作对象本身以外,还会关心其外部关系。那么,干脆在TCbwExecuteItem中添加一个XML节点以表示外部关系。 CbwXmlNode * FExternalRelationNode; // 外部关系XML节点在TCbwExecuteItem构造函数中创建FExternalRelationNode,而在Finish函数中添加外部关系的处理。为了与以前工作相兼容,先处理已实现过的创建操作、创建导线操作及排列操作。
外部关系已经设计并实现了,下一步就该让它发挥作用。首要的是能取得相应的关系。开放一个函数接口吧。
可以用创建导线来试一试效果。现用的撤销创建导线代码为
修改为
原重做代码为:
修改为
经测试,一切正常。回过头来,处理今天的正事:删除操作。为了能够撤销,肯定需要保存现场,即保存各对象,这件事得在操作之前处理,因为操作后,这些对象都已被删除了,再访问就会出现空指针或AV冲突,要是现在还能犯这等低级错误,可以面壁三天。
在Finish中,保存现场具体代码:
撤销删除操作时,步骤有二:一是恢复所有被删除对象,二是恢复所有外部关系。
而重做操作时,仅需取得相关被操作对象,然后删除就OK了.
最后进行测试,所有的处理过程完全正确。今天任务完成。