Exemple #1
0
CAction* CLayoutEditor::PerformAction(CAction *action, BOOL bRepeat)
{
	// variables
	long id, gid, prevObj, objLayer;
	long i, oid;
	CLayer *lyr;
	CObj *o, *o2;
	CObjType *oT;
	CObjList objs;
	CString text;
	BOOL b, tb;
	BOOL bMoreInstances;
	POSITION pos, pos2;

	g_pLayoutView = this;
	g_pFrame = layout;
	g_pApp = application;

	long tid, tprevObj, tobjLayer, tglobalID;

	// do stuff
	CArchive *ar = action->Unprepare1();
	CAction *actionNew = new CAction();
	if (bRepeat)
		actionNew->m_bGroup = FALSE;
	CArchive *arNew = actionNew->Prepare1();

	switch (action->m_type) 
	{
	case ACTION_MOVESIZE:
		*ar >> id;
		o = GetObject(id);
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_MOVESIZE;
		tid = o->GetInstanceID();
		*arNew << tid;
		o->Serialize(*arNew);
		// END UNDO INFO //

		o->Serialize(*ar);

		InitializeObject(o);
		g_PropertyBar->Update(this, TYPE_OBJECT, &m_sel, layout, &layout->objects, application); // show object props
		break;

	case ACTION_CHANGETYPE:
		*ar >> id;
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_CHANGETYPE;
		*arNew << id;
		application->object_types[id]->Serialize(*arNew);
		// END UNDO INFO //
		
		application->object_types[id]->Serialize(*ar);

		g_PropertyBar->Update(this, TYPE_OBJECT, &m_sel, layout, &layout->objects, application); // show object props
		break;

	case ACTION_CHANGELAYER:
		*ar >> id;
		
		pos = layout->layers.GetHeadPosition();
		for (i = 0; i < layout->layers.GetCount(); i++)
		{
			lyr = layout->layers.GetPrev(pos);
			if( lyr->m_layerID == id)
				break;
		}
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_CHANGELAYER;
		*arNew << id;
		lyr->Serialize(*arNew);
		// END UNDO INFO //

		lyr->Serialize(*ar);

		g_PropertyBar->Update(this, TYPE_LAYER, &m_sel, layout, &layout->objects, application, 0, lyr); // show object props
		break;
		
	case ACTION_SETVISIBLE:
		*ar >> id >> b;
		o = GetObject(id);
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_SETVISIBLE;
		tid = o->GetInstanceID();
		tb = !b;
		*arNew << tid << tb;
		// END UNDO INFO //

		o->SetVisible(b);
		break;
		
	case ACTION_SETLOCK:
		*ar >> id >> b;
		o = GetObject(id);
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_SETLOCK;
		tid = o->GetInstanceID();
		tb = !b;
		*arNew << tid << tb;
		// END UNDO INFO //

		o->SetVisible(b);
		break;
		
	case ACTION_CHANGEZORDER:

		// START UNDO INFO //
		actionNew->m_type = ACTION_CHANGEZORDER;
		this->SerializeAllZLists(arNew);
		// END UNDO INFO //

		SerializeAllZLists(ar);

		g_pLayerBar->m_layerDlg.RefreshLayers();

		// we need to tell the layer dlg to refresh or something!
		break;

	case ACTION_CREATE:
		{
			*ar >> id >> objLayer >> prevObj;
			o = new CObj();
			o->Serialize(*ar);
			
			if(objLayer!= -1 && prevObj != -1)	//group items dont go into the zorder
			{
				if(objLayer >= 0)
				{
					pos = layout->layers.GetHeadPosition();
					for (i = 0; i < layout->layers.GetCount(); i++) {
						lyr = layout->layers.GetNext(pos);
						if (lyr->m_layerID == objLayer) {
							lyr->m_zOrder.InsertAfter(lyr->m_zOrder.FindIndex(prevObj), id);
							break;
						}
					}
				}
				else
				{
					CObj* group = layout->GetObj(-objLayer); // layer is negative for object groups
					group->m_groupObjects.InsertAfter(group->m_groupObjects.FindIndex(prevObj), id);
					break;	
				}			
			}
		
			InitializeObject(o);

			layout->objects[id] = o;

			// START UNDO INFO //
			actionNew->m_type = ACTION_DELETE;
			tid = o->GetInstanceID();
			*arNew << tid;
			// END UNDO INFO //

			pMainWnd->ObjectTypesChanged();

			g_PropertyBar->Update(this, TYPE_LAYOUT, NULL, layout, NULL, application); 
		}

		g_pLayerBar->m_layerDlg.RefreshLayers();
		break;

	case ACTION_CREATETYPE:// long ObjectIdentifier, CObjType oT, long id, layer, prevobjid, CObj o
		{
			*ar >> gid;
			oT = new CObjType();
			oT->Serialize(*ar);
			application->object_types[gid] = oT;

			*ar >> id >> objLayer >> prevObj;
			o = new CObj();
			o->Serialize(*ar);
			if(objLayer!= -1 && prevObj != -1)	//group items dont go into the zorder
			{
				if(objLayer >= 0)
				{
					pos = layout->layers.GetHeadPosition();
					for (i = 0; i < layout->layers.GetCount(); i++)
					{
						lyr = layout->layers.GetNext(pos);
						if (lyr->m_layerID == objLayer) {
							lyr->m_zOrder.InsertAfter(lyr->m_zOrder.FindIndex(prevObj), id);
							break;
						}
					}
				}
				else
				{
					CObj* group = layout->GetObj(-objLayer); // layer is negative for object groups
					group->m_groupObjects.InsertAfter(group->m_groupObjects.FindIndex(prevObj), id);
					break;	
				}
			}
			layout->objects[id] = o;


			// We need to call initialize!
			InitializeObject(o);

			// START UNDO INFO //
			actionNew->m_type = ACTION_DELETE;
			tid = o->GetInstanceID();
			*arNew << tid;
			// END UNDO INFO //

			g_PropertyBar->Update(this, TYPE_LAYOUT, NULL, layout, NULL, application); 
		}

		pMainWnd->ObjectTypesChanged();
		g_pLayerBar->m_layerDlg.RefreshLayers();
		break;

	case ACTION_DELETE:
		{
			*ar >> id;
			o = GetObject(id);
			if(!o)
				return 0; // this actually happens in groups sometimes but is now accounted for

			tglobalID = o->GetGlobalID();

			// remove from zorder
			lyr = GetObjectLayer(id);
			if(lyr)
			{
				 pos2 = lyr->m_zOrder.Find(id);
				 tprevObj = lyr->m_zOrder.GetPrev(pos2);
				 tobjLayer = lyr->m_layerID;
				lyr->m_zOrder.RemoveAt(lyr->m_zOrder.Find(id));
			}
			else if(o->m_bInGroup)
			{
				 pos2 = o->m_group->m_groupObjects.Find(id);
				 tprevObj = o->m_group->m_groupObjects.GetPrev(pos2);
				 tobjLayer = 0 - o->m_group->GetInstanceID(); // we use negative values of the instance id of objects
				 o->m_group->m_groupObjects.RemoveAt(o->m_group->m_groupObjects.Find(id));
			}	

			bMoreInstances = FALSE; // check if any more instances exist
			pos = layout->objects.GetStartPosition();
			long nKey;
			while (pos != NULL) 
			{
				layout->objects.GetNextAssoc(pos, nKey, o2);

				if (o2->GetGlobalID() == tglobalID && o2->GetInstanceID() != id) 
				{
					bMoreInstances = TRUE;
					break;
				}
			}

			if (bMoreInstances == FALSE) // no more exist, delete object type
			{
				CObjType* oT = application->object_types[tglobalID];

				// START UNDO INFO //
				actionNew->m_type = ACTION_CREATETYPE;

				*arNew << tglobalID; //object type
				oT->Serialize(*arNew);

				long tid = o->GetInstanceID(); //object
				*arNew << tid << tobjLayer << tprevObj;
				o->Serialize(*arNew);
				// END UNDO INFO //

				//delete oT;
				application->m_DeletedObjectTypes[tglobalID] = application->object_types[tglobalID];
				application->object_types.RemoveKey(tglobalID);

				if (oT->tree)
				{
					pMainWnd->project_bar.tree.DeleteItem(oT->tree);
					oT->tree = NULL;
				}
			}
			else
			{
				// START UNDO INFO //
				actionNew->m_type = ACTION_CREATE;

				long tid = o->GetInstanceID();
				*arNew << tid << tobjLayer << tprevObj;
				o->Serialize(*arNew);
				// END UNDO INFO //
			}

			// okay time to recursively kill !
			pos = o->m_groupObjects.GetHeadPosition();
			//CObj *o2;
			for (int k = 0; k < o->m_groupObjects.GetCount(); k++) 
			{
				long groupitemid = o->m_groupObjects.GetNext(pos);
				DeleteObjectRecursive(groupitemid);

				// basically the serialization function automatically saves all the children items. We want to 
				// delete them but not back them up...thats where the DeleteOBjectRecursive function is handy :)
			}	

			delete o;
			layout->objects.RemoveKey(id);

			pMainWnd->ObjectTypesChanged();

			g_pLayerBar->m_layerDlg.RefreshLayers();

			g_PropertyBar->Update(this, TYPE_LAYOUT, NULL, layout, NULL, application); 
		}

		break;
		
	case ACTION_GROUP:
		*ar >> gid;
		objs.Serialize(*ar);
		m_sel.RemoveAll();
		pos = objs.GetHeadPosition();
		for (i = 0; i < objs.GetCount(); i++) {
			id = objs.GetNext(pos);
			m_sel.AddTail(id);
		}

		// taken from GroupSel(), penis removed //
		o2 = GetObject(gid);
		pos = m_sel.GetHeadPosition();
		for (i = 0; i < m_sel.GetCount(); i++) { // loop through selected objects
			o = GetObject(m_sel.GetNext(pos));
			if (o->m_bInGroup == FALSE) { // selected object is not in another [open] group
				o->m_bInGroup = TRUE;
				o->m_group = o2;
				lyr = GetObjectLayer(o->GetInstanceID());
				
				tid = o->GetInstanceID();
				if(lyr)
				{
					lyr->m_zOrder.RemoveAt(lyr->m_zOrder.Find(tid)); // move object from its layer to the group
				}
				o2->m_groupObjects.AddTail(tid);
				
			}
		}
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_UNGROUP;
		*arNew << gid;
		// END UNDO INFO //
		g_pLayerBar->m_layerDlg.RefreshLayers();
		break;
		
	case ACTION_UNGROUP:
		*ar >> gid;
		o = GetObject(gid);
		
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_GROUP;
		*arNew << gid;
		o->m_groupObjects.Serialize(*arNew);
		// END UNDO INFO //


		//BLOCK: UNGROUP
		// remove from zorder
//		CObj *o2;
		//POSITION pos2;
		CLayer *lyr;
		if (!o->m_bInGroup) {
			lyr = GetObjectLayer(gid);
			if(!lyr)
			{
				CErrorDlg	Error;
				Error.Error("Error in undo", "In ACTION_UNGROUP we were unable to work out what layer the group was on. Please report this to scirra");
				return 0;
			}
			pos2 = lyr->m_zOrder.Find(gid); // get location in layer to put group objects
		}

		pos = o->m_groupObjects.GetHeadPosition();
		for (int j = 0; j < o->m_groupObjects.GetCount(); j++) {
			o2 = GetObject(o->m_groupObjects.GetNext(pos));
			if (o->m_bInGroup)
				o2->m_group = o->m_group;
			else {
				o2->m_bInGroup = FALSE;
				o2->m_group = NULL;
				id = o2->GetInstanceID();
				lyr->m_zOrder.InsertAfter(pos2, id);
			}
		}
		o->m_groupObjects.RemoveAll();


	










/*
		// taken from Ungroup(), penis removed //
		if (!o->m_bInGroup) {
			lyr = GetObjectLayer(gid);
			if(!lyr)
			{
			CErrorDlg	Error;
			Error.Error("Error in undo", "In ACTION_UNGROUP we were unable to work out what layer the group was on. Please report this to scirra");
				return 0;
			}
			pos2 = lyr->m_zOrder.Find(gid); // get location in layer to put group objects
		}
		pos = o->m_groupObjects.GetHeadPosition();
		for (i = 0; i < o->m_groupObjects.GetCount(); i++) {
			o2 = GetObject(o->m_groupObjects.GetNext(pos));
			if (o->m_bInGroup)
				o2->m_group = o->m_group;
			else {
				o2->m_bInGroup = FALSE;
				o2->m_group = NULL;
				id = o2->GetInstanceID();
				lyr->m_zOrder.InsertAfter(pos2, id);
			}
		}
		o->m_groupObjects.RemoveAll();

		{	// this allows us to remove the group type and the group object - davo
	//	CUndo* temp = m_undo;
	//	m_undo = 0;
		//DeleteObject(gid);
	//	m_undo = temp; 
		}*/



		g_pLayerBar->m_layerDlg.RefreshLayers();


		break;
		
	case ACTION_GROUPOPEN:
		*ar >> id >> b;
		o = GetObject(id);
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_GROUPOPEN;
		tid = o->GetInstanceID();
		tb = !b;
		*arNew << tid << tb;
		// END UNDO INFO //

		o->m_bGroupOpen = b;
		g_pLayerBar->m_layerDlg.RefreshLayers();
		break;
		
	case ACTION_GROUPREMOVE:
		*ar >> gid >> oid >> objLayer >> prevObj;
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_GROUPADD;
		*arNew << gid << oid;
		// END UNDO INFO //

		o = GetObject(oid);
		o2 = GetObject(gid);
		o->m_groupObjects.RemoveAt(o->m_groupObjects.Find(oid));
		o->UpdateGroupInfo(FALSE);
		o2->m_bInGroup = FALSE;
		o2->m_group = NULL;
		for (i = 0; i < layout->layers.GetCount(); i++) {
			lyr = layout->layers.GetNext(pos);
			if (lyr->m_layerID == objLayer) {
				lyr->m_zOrder.InsertAfter(lyr->m_zOrder.FindIndex(prevObj), oid);
				break;
			}
		}
		g_pLayerBar->m_layerDlg.RefreshLayers();
		break;
		
	case ACTION_GROUPADD:
		*ar >> gid >> oid;

		o = GetObject(oid);
		o2 = GetObject(gid);
		o->m_bInGroup = TRUE;
		o->m_group = o2;
		lyr = GetObjectLayer(oid);
		if(!lyr)
		{
			CErrorDlg Error;
			Error.Error("Error", "Unable to work out what layer the object is on in ACTION_GROUPADD, please report this to scirra");
			return 0;
		}
		pos = lyr->m_zOrder.Find(oid);
		prevObj = lyr->m_zOrder.GetPrev(pos);
		
		// START UNDO INFO //
		actionNew->m_type = ACTION_GROUPREMOVE;
		*arNew << gid << oid << lyr->m_layerID << prevObj;
		// END UNDO INFO //

		lyr->m_zOrder.RemoveAt(lyr->m_zOrder.Find(oid));
		o->m_group->m_groupObjects.AddTail(oid);
		g_pLayerBar->m_layerDlg.RefreshLayers();
		break;
	}

	action->Unprepare2();
	actionNew->Prepare2();

	if(action == 0)
	{
		int a = 0;
		a --;
	}
	if(actionNew == 0)
	{
		int a = 0;
		a--;
	}
	return actionNew;
}
void CLayerDlg::OnLayerDel() 
{
	if(!m_layerListBox.layout_editor)
		return;
	if(m_layerListBox.GetCurSel() == -1)
		return;

	CLayer *layer = (CLayer*)m_layerListBox.GetItemDataPtr(m_layerListBox.GetCurSel());
		if (layer->m_layerType == LAYER_NONFRAME) return;

	if (m_layerListBox.layout_editor->layout->layers.GetCount() == 2) 
	{
		CErrorDlg error;
		error.Error("Error removing layer", "You can't remove the last layer.");
		return;
	}

	bool do_delete = false;

	if (layer) 
	{
		CExtMsgBox msg(NULL, CONF_DELETE, CONFIRMATION, __EXT_MB_YESNO | __EXT_MB_ICONINFORMATION | __EXT_MB_DO_NOT_ASK_AGAIN, 0, "DeleteLayer", __EXT_MB_EX_CHECK_BOX_IS_NOT_CHECKED_INTIALLY);

		int result = msg.DoModal();

		if (result == IDYES)
			do_delete = true;

		else
			msg.ResetMsgBox();
	}

	if (do_delete)
	{
		POSITION pos = layer->m_zOrder.GetHeadPosition();
		vector<long> deletelist;
		for (int i = 0; i < layer->m_zOrder.GetCount(); i++) {
			deletelist.push_back(layer->m_zOrder.GetNext(pos));
		}

		for(int i = 0; i < deletelist.size(); i++)
		{
			m_layerListBox.layout_editor->DeleteObject(deletelist.at(i), TRUE);
		}

		// START UNDO INFO //
		CAction *action = new CAction();
		action->m_type = ACTION_CHANGEZORDER;
		CArchive *ar = action->Prepare1();
		m_layerListBox.layout_editor->SerializeAllZLists(ar);
		
		action->Prepare2();
		m_layerListBox.layout_editor->m_undo->AddAction(action);
		// END UNDO INFO //

		m_layerListBox.layout_editor->layout->layers.RemoveAt(m_layerListBox.layout_editor->layout->layers.Find(layer));
		m_layerListBox.DeleteString(m_layerListBox.GetCurSel());

		m_layerListBox.SetCurSel(0);
		OnSelchange();

		g_PropertyBar->Update(layout_editor, TYPE_LAYER, NULL, NULL,NULL, layout_editor->application, 0, layout_editor->layout->layers.GetAt(layout_editor->layout->layers.GetTailPosition())); // update the property editor

		m_layerListBox.layout_editor->Invalidate();

		CChildFrame* pCF = (CChildFrame*)m_layerListBox.layout_editor->GetParentFrame();
		pCF->object_bar.Refresh();

		layout_editor->layout->SetChanged(true);
	}
}