Example #1
0
void UndoEngine::GetModificationsRecursive(std::vector<UndoEvent> &ret,ObjList* newtree, ObjList* oldtree)
{
	std::set<HeeksObjId> new_children;
	std::set<HeeksObjId> old_children;
	std::map<HeeksObjId,HeeksObj*> new_children_map;
	std::map<HeeksObjId,HeeksObj*> old_children_map;


	HeeksObj *new_obj = newtree->GetFirstChild();
	while(new_obj)
	{
		HeeksObjId id = GetHeeksObjId(new_obj);
		new_children.insert(id);
		new_children_map[id] = new_obj;
		new_obj = newtree->GetNextChild();
	}

	HeeksObj *old_obj = oldtree->GetFirstChild();
	while(old_obj)
	{
		HeeksObjId id = GetHeeksObjId(old_obj);
		old_children.insert(id);
		old_children_map[id] = old_obj;
		old_obj = oldtree->GetNextChild();
	}

	std::set<HeeksObjId>::iterator it;
	for(it = new_children.begin(); it != new_children.end(); it++)
	{
		HeeksObj* obj = new_children_map[*it];
		m_tree.m_treemap[*it] = obj;
		if(old_children.find(*it) == old_children.end())
		{
			//TODO, this is actually tricky, when an item is added, it may be added in multiple places in the tree
			//we must make sure that multiple pointers get setup to this object, we also must deep copy
			HeeksObj* copy = obj->MakeACopyWithID();
			ret.push_back(UndoEvent(EventTypeAdd,newtree,copy));
			m_oldtree.m_treemap[*it] = copy;
		}
		else
		{
			//TODO: check if item is modified, if it is an objlist, descend
			if(!obj->GetSkipForUndo() && obj->IsDifferent(old_children_map[*it]))
			{
				HeeksObj* copy = obj->MakeACopyWithID();
				ret.push_back(UndoEvent(EventTypeModified,newtree,copy,old_children_map[*it]));
				m_oldtree.m_treemap[*it] = copy;
			}
			else
			{
				if(obj->IsList())
				{
					ObjList* newlist = (ObjList*)obj;
					ObjList* oldlist = (ObjList*)old_children_map[*it];
					if(newlist->DescendForUndo())
					{
						GetModificationsRecursive(ret,newlist,oldlist);
					}
				}
			}
		}
	}

	for(it = old_children.begin(); it != old_children.end(); it++)
	{
		HeeksObj* obj = old_children_map[*it];
		if(new_children.find(*it) == new_children.end())
			ret.push_back(UndoEvent(EventTypeRemove,newtree,obj->MakeACopyWithID()));
		m_oldtree.m_treemap[*it] = obj;
	}

	//DealWithTransients();
	wxGetApp().ClearTransients();
}