[GME-commit] GMESRC/GME/Mga MgaComplexOps.h,NONE,1.1 MgaFolders.rgs,NONE,1.1 MgaLibOps.h,NONE,1.1 Mga.cpp,1.10,1.11 Mga.dsp,1.23,1.24 Mga.rc,1.6,1.7 MgaComplexOps.cpp,1.7,1.8 MgaFCO.h,1.16,1.17 MgaFolder.cpp,1.19,1.20 MgaFolder.h,1.5,1.6 MgaLibOps.cpp,1.6,1.7 MgaProject.cpp,1.48,1.49 MgaProject.h,1.22,1.23 MgaTrukk.h,1.17,1.18 resource.h,1.7,1.8

gme-commit at list.isis.vanderbilt.edu gme-commit at list.isis.vanderbilt.edu
Wed Jun 2 17:43:22 CDT 2004


Update of /var/lib/gme/GMESRC/GME/Mga
In directory braindrain:/tmp/cvs-serv31667

Modified Files:
	Mga.cpp Mga.dsp Mga.rc MgaComplexOps.cpp MgaFCO.h 
	MgaFolder.cpp MgaFolder.h MgaLibOps.cpp MgaProject.cpp 
	MgaProject.h MgaTrukk.h resource.h 
Added Files:
	MgaComplexOps.h MgaFolders.rgs MgaLibOps.h 
Log Message:
1.MgaFolders collection introduced (for the Selective Closure functionality)
2.Folder copy and move implemented


CVS User: zolmol

--- NEW FILE: MgaComplexOps.h ---
#ifndef MGACOMPLEXOPS_H_1093481093485091384
#define MGACOMPLEXOPS_H_1093481093485091384

void CheckConflict(CoreObj &b, CoreObj &root);
int GetRealSubtypeDist(CoreObj oldobj);

void ObjTreeCopy(CMgaProject *mgaproject, CoreObj self, CoreObj &nobj, coreobjpairhash &crealist);
void ObjTreeCopyFoldersToo(CMgaProject *mgaproject, CoreObj self, CoreObj &nobj, coreobjpairhash &crealist);

void ObjTreeCopyFromExt(CMgaProject *mgaproject, const CoreObj &orig, CoreObj &nobj, PointerFixup &fixup);

void ObjTreeCollect(CMgaProject *mgaproject, CoreObj &self, coreobjhash &crealist, int code );
void ObjTreeCollectFoldersToo(CMgaProject *mgaproject, CoreObj &self, coreobjhash &crealist, int code );

void ObjTreeDist(CoreObj self, int derdist);
void ReDeriveNewObjs(CMgaProject *mgaproject, vector<CoreObj> &orignobjs, int cnt, int targetlevel);
void shiftlist(coreobjpairhash &list1, coreobjhash &list2);

void ObjTreeCheckRelations(CMgaProject *mgaproject, CoreObj &self, coreobjhash &internals);
void ObjTreeCheckRelationsFoldersToo(CMgaProject *mgaproject, CoreObj &self, coreobjhash &internals);

void ObjTreeCheckINTORelations(CMgaProject *mgaproject, CoreObj &self, coreobjhash &internals);
void ObjTreeCheckINTORelationsFoldersToo(CMgaProject *mgaproject, CoreObj &self, coreobjhash &internals);

// the counterpart of this is declared in the MgaFCO.h
bool ObjTreeReconnectFoldersToo(CoreObj self, coreobjpairhash &crealist, CoreObj const &derivtgt = NULLCOREOBJ);

void DeriveMoveds(CMgaProject *mgaproject, vector<CoreObj> &orignobjs, vector<int> &extmoved, int cnt, int targetlevel);


#endif //MGACOMPLEXOPS_H_1093481093485091384
// created by ZolMol
--- NEW FILE: MgaFolders.rgs ---
HKCR
{
	Mga.MgaFolders.1 = s 'MgaFolders Class'
	{
		CLSID = s '{c592f6f0-c1fd-11d3-9ad2-00aa00b6fe26}'
	}
	Mga.MgaFolders = s 'MgaFolders Class'
	{
		CLSID = s '{c592f6f0-c1fd-11d3-9ad2-00aa00b6fe26}'
		CurVer = s 'Mga.MgaFolders.1'
	}
	NoRemove CLSID
	{
		ForceRemove {c592f6f0-c1fd-11d3-9ad2-00aa00b6fe26} = s 'MgaFolders Class'
		{
			ProgID = s 'Mga.MgaFolders.1'
			VersionIndependentProgID = s 'Mga.MgaFolders'
			ForceRemove 'Programmable'
			InprocServer32 = s '%MODULE%'
			{
				val ThreadingModel = s 'Apartment'
			}
			'TypeLib' = s '{270B4F86-B17C-11D3-9AD1-00AA00B6FE26}'
		}
	}
}

--- NEW FILE: MgaLibOps.h ---

class PointerFixup
{
	coreobjpairhash identity_map;

	typedef struct
	{
		CoreObj target;
		CoreObj created;
		attrid_type attrid;
	} resolve_entry;

	vector<resolve_entry> resolve_entries;

public:
	inline void identify(const CoreObj &original, const CoreObj &created)
	{
		ASSERT( original != NULL && created != NULL );

		identity_map.insert(coreobjpairhash::value_type(original, created));
	}

	void resolve(const CoreObj &original, const CoreObj &created,
		attrid_type attrid)
	{
		if( LINKREF_ATTR(attrid) )
			return;

		CoreObj target = original[attrid]; 
		if( target == NULL )
			return;

		coreobjpairhash::iterator i = identity_map.find(target);
		if( i != identity_map.end() )
			created[attrid] = i->second;	// already created
		else								// resolve it later
		{
			resolve_entry entry;
			entry.target = target;
			entry.created = created;
			entry.attrid = attrid;
			resolve_entries.push_back(entry);
		}
	}

	inline void clear()
	{
		resolve_entries.clear();
		identity_map.clear();
	}

	void fixPointers()
	{
		vector<resolve_entry>::const_iterator i = resolve_entries.begin();
		while( i != resolve_entries.end() )
		{
			CoreObj& new_target = identity_map[i->target];
			ASSERT( new_target != NULL );

			(i->created)[i->attrid] = new_target;

			++i;
		}
		clear();
	}
};
Index: Mga.cpp
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/Mga.cpp,v
retrieving revision 1.10
retrieving revision 1.11
diff -C2 -d -r1.10 -r1.11
*** Mga.cpp	17 Dec 2003 13:45:03 -0000	1.10
--- Mga.cpp	2 Jun 2004 21:43:19 -0000	1.11
***************
*** 26,29 ****
--- 26,30 ----
  OBJECT_ENTRY(CLSID_MgaO, FCO)
  OBJECT_ENTRY(CLSID_MgaFCOs, CMgaFCOs)
+ OBJECT_ENTRY(CLSID_MgaFolders, CMgaFolders)
  OBJECT_ENTRY(CLSID_MgaObjects, CMgaObjects)
  OBJECT_ENTRY(CLSID_MgaRegNodes, CMgaRegNodes)

Index: Mga.dsp
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/Mga.dsp,v
retrieving revision 1.23
retrieving revision 1.24
diff -C2 -d -r1.23 -r1.24
*** Mga.dsp	17 Dec 2003 13:45:29 -0000	1.23
--- Mga.dsp	2 Jun 2004 21:43:19 -0000	1.24
***************
*** 217,220 ****
--- 217,224 ----
  # Begin Source File
  
+ SOURCE=.\MgaComplexOps.h
+ # End Source File
+ # Begin Source File
+ 
  SOURCE=.\MgaConnection.h
  # End Source File
***************
*** 286,289 ****
--- 290,297 ----
  
  SOURCE=.\MgaFCOs.rgs
+ # End Source File
+ # Begin Source File
+ 
+ SOURCE=.\MgaFolders.rgs
  # End Source File
  # Begin Source File

Index: Mga.rc
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/Mga.rc,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** Mga.rc	14 Nov 2001 16:57:00 -0000	1.6
--- Mga.rc	2 Jun 2004 21:43:19 -0000	1.7
***************
*** 101,104 ****
--- 101,105 ----
  IDR_MGAOBJECTS          REGISTRY DISCARDABLE    "MgaObjects.rgs"
  IDR_MGAREGNODES         REGISTRY DISCARDABLE    "MgaRegnodes.rgs"
+ IDR_MGAFOLDERS          REGISTRY DISCARDABLE    "MgaFolders.rgs"
  
  /////////////////////////////////////////////////////////////////////////////

Index: MgaComplexOps.cpp
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/MgaComplexOps.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** MgaComplexOps.cpp	18 Mar 2003 12:17:17 -0000	1.7
--- MgaComplexOps.cpp	2 Jun 2004 21:43:19 -0000	1.8
***************
*** 198,203 ****
  }
  
  
! void ObjTreeCopy(CMgaProject *mgaproject, CoreObj self, CoreObj &nobj, coreobjpairhash &crealist) {
  	metaid_type s;
  	COMTHROW(mgaproject->dataproject->CreateObject(s = GetMetaID(self), &nobj.ComPtr()));
--- 198,224 ----
  }
  
+ // by ZolMol -invented by
+ void ObjTreeCollectFoldersToo(CMgaProject *mgaproject, CoreObj &self, coreobjhash &crealist, int code ) {
+ 	metaid_type s = s = GetMetaID(self);
+ 	if(s >= DTID_MODEL && s <= DTID_FOLDER) {
+ 		crealist.insert(coreobjhash::value_type(self, 0));
+ 		setcheck(mgaproject, self, code);
+ 	}
+ 	if(s == DTID_MODEL) {
+ 			CoreObjs children = self[ATTRID_FCOPARENT + ATTRID_COLLECTION];
+ 			ITERATE_THROUGH(children) {
+ 				ObjTreeCollectFoldersToo(mgaproject, ITER, crealist, code);
+ 			}
+ 	}
+ 	if(s == DTID_FOLDER) {
+ 			CoreObjs children = self[ATTRID_FCOPARENT + ATTRID_COLLECTION];
+ 			ITERATE_THROUGH(children) {
+ 				ObjTreeCollectFoldersToo(mgaproject, ITER, crealist, code);
+ 			}
+ 	}
+ }
  
! void ObjTreeCopy(CMgaProject *mgaproject, CoreObj self, CoreObj &nobj, coreobjpairhash &crealist)
! {
  	metaid_type s;
  	COMTHROW(mgaproject->dataproject->CreateObject(s = GetMetaID(self), &nobj.ComPtr()));
***************
*** 236,239 ****
--- 257,296 ----
  
  
+ void ObjTreeCopyFoldersToo(CMgaProject *mgaproject, CoreObj self, CoreObj &nobj, coreobjpairhash &crealist) {
+ 	metaid_type s;
+ 	COMTHROW(mgaproject->dataproject->CreateObject(s = GetMetaID(self), &nobj.ComPtr()));
+ 	if(s >= DTID_MODEL && s <= DTID_FOLDER) {
+ 		crealist.insert(coreobjpairhash::value_type(self, nobj));
+ 		setcheck(mgaproject, nobj, CHK_NEW);
+ 		CoreObjMark(nobj, OBJEVENT_CREATED);
+ 	}
+ 
+ 	CComPtr<ICoreAttributes> atts;
+ 	COMTHROW(self->get_Attributes(&atts));
+ 	MGACOLL_ITERATE(ICoreAttribute, atts) {
+ 			attrid_type ai;
+ 			CComPtr<ICoreMetaAttribute> mattr;
+ 			COMTHROW(MGACOLL_ITER->get_MetaAttribute(&mattr));
+ 			COMTHROW(mattr->get_AttrID(&ai));
+ 			if(ai < ATTRID_COLLECTION) {
+ 				// remove library flags from a copy
+ 				if(ai == ATTRID_PERMISSIONS) nobj[ai] = self[ai] & INSTANCE_FLAG;
+ 				else nobj[ai] = static_cast<CComVariant>(self[ai]);
+ 			}
+ 			else {
+ 				ai -= ATTRID_COLLECTION;
+ 				if(LINKREF_ATTR(ai)) {
+ 					CoreObjs collmembers = self[ai + ATTRID_COLLECTION];
+ 					ITERATE_THROUGH(collmembers) {
+ 						CoreObj nchild;
+ 						ObjTreeCopy(mgaproject, ITER, nchild, crealist);
+ 						nchild[ai] = nobj;
+ 					}
+ 				}
+ 			}
+ 
+ 	} MGACOLL_ITERATE_END;
+ }
+ 
  // get the derived-chain distance of the closest real basetype (or if there is none, the length of the full base chain) 
  // if the object is not derived, or it is a real subtype/instance (i.e derived not because of its parent) 0 is returned
***************
*** 432,435 ****
--- 489,550 ----
  }
  
+ bool ObjTreeReconnectFoldersToo(CoreObj self, coreobjpairhash &crealist, CoreObj const &derivtgt) {
+ 	typedef struct { metaid_type mid; int search, reconnect; } table;
+ 	static const table tab[] = {
+ 		{DTID_FOLDER,	ATTRID_FCOPARENT,	0},
+ 		{DTID_MODEL,	ATTRID_FCOPARENT,	0},
+ 		{DTID_REFERENCE, 0,					ATTRID_REFERENCE},
+ 		{DTID_SET,		ATTRID_SETMEMBER,	0},
+ 		{DTID_SETNODE,	0,					ATTRID_XREF },
+ 		{DTID_CONNECTION, ATTRID_CONNROLE,	0},
+ 		{DTID_CONNROLE, ATTRID_CONNSEG,		ATTRID_XREF},
+ 		{DTID_CONNROLESEG, 0,				ATTRID_SEGREF}
+ 	};
+ 
+ 
+ 	bool containedexternal = false;
+ 	metaid_type n = GetMetaID(self);
+ 
+ 	for(int i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
+ 		if(tab[i].mid == n) {
+ 			const table *ll = &tab[i];
+ 			if(ll->search) {
+ 				CoreObjs children = self[ll->search+ATTRID_COLLECTION];
+ 				if(n == DTID_CONNROLE) {
+ 					children.Sort();
+ 				}
+ 				ITERATE_THROUGH(children) {
+ 					if(ObjTreeReconnect(ITER,crealist, derivtgt)) {
+ 						containedexternal = true;
+ 						if(n == DTID_CONNROLE) break; // stop processing rolesegments after an ext ref.
+ 					}
+ 				}
+ 			}
+ 			if(!containedexternal && ll->reconnect) {
+ 			  // the relationship pointer will to be reconnected if
+ 				// - the object has no master (only possible with copied objects)
+ 				// - or the relation in the most original base is internal
+ 			  if(!self.GetMaster() || IsInternalRelation(self)) {  
+ 				    CoreObj oldr = self[ll->reconnect];
+ 					coreobjpairhash::iterator i = crealist.find(oldr);
+ 					if(i != crealist.end()) {  
+ // if it is a reference to a newly created object: use lookup
+ 						self[ll->reconnect] = (*i).second;
+ 					}
+ 					else if(derivtgt) {  
+ 						ASSERT(CoreObj(derivtgt[ATTRID_DERIVED]));
+ 						ASSERT(derivtgt[ATTRID_RELID] < RELIDSPACE);
+ 						CoreObj newr;
+ 						GetDerivedEquivalent(oldr, derivtgt, newr);
+ 						self[ll->reconnect] = newr;
+ 					}
+ 			  }
+ 			  else containedexternal = true;
+ 			}
+ 			break;
+ 		}
+ 	}
+ 	return containedexternal;
+ }
  
  
***************
*** 501,506 ****
  }
  
  /////////////////
! // ObjTreeCheckRelations
  /////////////////
  // Removes incoming relations (or whole objects) that point into a newly copied/derived/moved tree
--- 616,671 ----
  }
  
+ void ObjTreeCheckRelationsFoldersToo(CMgaProject *mgaproject, CoreObj &self, coreobjhash &internals) {
+ 	typedef struct { metaid_type mid; int search, check, mm; } table;
+ 	static const table tab[] = {
+ 		{DTID_FOLDER, ATTRID_FCOPARENT, 0},
+ 		{DTID_MODEL, ATTRID_FCOPARENT, 0},
+ 		{DTID_REFERENCE, 0, ATTRID_REFERENCE, MM_REF},
+ 		{DTID_SET, ATTRID_SETMEMBER, 0},
+ 		{DTID_SETNODE, 0, ATTRID_XREF, MM_SET },
+ 		{DTID_CONNECTION, ATTRID_CONNROLE, 0},
+ 		{DTID_CONNROLE, ATTRID_CONNSEG, ATTRID_XREF, MM_CONN},
+ 		{DTID_CONNROLESEG, 0, ATTRID_SEGREF}
+ 	};
+ 
+ 	metaid_type n = GetMetaID(self);
+ 
+ 	for(int i = 0; i < sizeof(tab) / sizeof(tab[0]); i++) {
+ 		if(tab[i].mid == n) {
+ 			const table *ll = &tab[i];
+ 			if(ll->search) {
+ 				CoreObjs children = self[ll->search+ATTRID_COLLECTION];
+ 				ITERATE_THROUGH(children) {
+ 					if(ITER.IsDeleted()) continue;
+ 					ObjTreeCheckRelationsFoldersToo(mgaproject, ITER, internals);
+ 				}
+ 			}
+ 			if(ll->check && !self.IsDeleted()) {
+ 				CoreObj tgt = self[ll->check];
+ 				int mm2 = (internals.find(tgt) != internals.end()) ? MM_INTERNAL : MM_OUTOF;
+ 				switch(MODEMASK(ll->mm, mm2)) {
+ 				case MM_ERROR: COMTHROW(E_MGA_OP_REFUSED);
+ 				case MM_CLEAR: 
+ 					self[ll->check] = NULLCOREOBJ;
+ 					CoreObj selfobj = self.GetMgaObj();
+ 					if( (GetMetaID(selfobj) == DTID_CONNECTION && ObjForCore(selfobj)->simpleconn()) ||
+ 						MODEFLAG(ll->mm, MM_FULLDELETE)) {
+ 							ObjForCore(selfobj)->inDeleteObject();
+ 					}
+ 					else {
+ 						if(n != DTID_REFERENCE) {
+ 							if(n == DTID_CONNROLESEG) self = self[ATTRID_CONNSEG];
+ 							SingleObjTreeDelete(self);
+ 						}
+ 					}
+ 				}
+ 			}
+ 			break;
+ 		}
+ 	}
+ }
+ 
  /////////////////
! // ObjTreeCheckINTORelations
  /////////////////
  // Removes incoming relations (or whole objects) that point into a newly copied/derived/moved tree
***************
*** 577,580 ****
--- 742,805 ----
  }
  
+ void ObjTreeCheckINTORelationsFoldersToo(CMgaProject *mgaproject, CoreObj &self, coreobjhash &internals) {
+ 	metaid_type n = GetMetaID(self);
+ 	ASSERT(n >= DTID_MODEL && n <= DTID_FOLDER);
+ 	if ( n >= DTID_MODEL && n <= DTID_SET)
+ 	{
+ 		CoreObjs xrefs = self[ATTRID_XREF + ATTRID_COLLECTION]; 
+ 		ITERATE_THROUGH(xrefs) {
+ 			metaid_type st = GetMetaID(ITER);
+ 			if(st == DTID_SETNODE || st == DTID_CONNROLE) {
+ 				CoreObj rel_owner = ITER.GetMgaObj();
+ 				if(internals.find(rel_owner) == internals.end()) {
+ 					int ttt = st == DTID_CONNROLE ? MM_CONN : MM_SET;
+ 					setcheck(mgaproject, rel_owner, CHK_CHANGED);
+ 					switch(MODEMASK(ttt, MM_INTO)) {
+ 					case MM_ERROR: COMTHROW(E_MGA_OP_REFUSED);
+ 						break;
+ 					case MM_CLEAR: 
+ 						if( st == DTID_CONNROLE && ObjForCore(rel_owner)->simpleconn() ||
+ 							MODEFLAG(ttt, MM_FULLDELETE)) {
+ 							ObjForCore(rel_owner)->inDeleteObject();
+ 						} 
+ 						else {
+ 							CoreObjMark(self, st == DTID_CONNROLE ? OBJEVENT_DISCONNECTED : OBJEVENT_SETEXCLUDED);
+ 							CoreObjMark(rel_owner, OBJEVENT_RELATION);
+ 							SingleObjTreeDelete(ITER);
+ 						}
+ 						break;
+ 					}
+ 				}	
+ 			}
+ 		}
+ 		{
+ 			CoreObjs refs = self[ATTRID_REFERENCE + ATTRID_COLLECTION]; 
+ 			ITERATE_THROUGH(refs) {
+ 				CoreObj rel_owner = ITER;
+ 				if(internals.find(rel_owner) == internals.end()) {
+ 					setcheck(mgaproject, rel_owner, CHK_CHANGED);
+ 					switch(MODEMASK(MM_REF, MM_INTO)) {
+ 					case MM_ERROR: COMTHROW(E_MGA_OP_REFUSED);
+ 					case MM_CLEAR: 
+ 						if(MODEFLAG(MM_REF, MM_FULLDELETE)) {
+ 							ObjForCore(rel_owner)->inDeleteObject();
+ 						}
+ 						else { 
+ 							rel_owner[ATTRID_REFERENCE] = NULLCOREOBJ;
+ 							CoreObjMark(self, OBJEVENT_REFRELEASED);
+ 							CoreObjMark(rel_owner, OBJEVENT_RELATION);
+ 						}
+ 					}
+ 				}
+ 			}
+ 		}
+ 	}
+ 	if(n == DTID_MODEL || n == DTID_FOLDER) {
+ 		CoreObjs children = self[ATTRID_FCOPARENT + ATTRID_COLLECTION];
+ 		ITERATE_THROUGH(children) {
+ 			ObjTreeCheckINTORelationsFoldersToo(mgaproject, ITER, internals);
+ 		}
+ 	}
+ }
  
  void ObjTreeNotify(CMgaProject *mgaproject, CoreObj &self) {
***************
*** 876,926 ****
  // !!! RECURSIVE 
  ///////////////////
! void DeriveMoveds(CMgaProject *mgaproject, vector<CoreObj> &orignobjs, vector<int> &extmoved, int cnt, int targetlevel) {
  	if(cnt < 1) return;
  	CoreObj orig = orignobjs[0][ATTRID_FCOPARENT];
! 	CoreObjs deriveds = orig[ATTRID_DERIVED+ATTRID_COLLECTION];
! 	ITERATE_THROUGH(deriveds) {
! 		int i;
! 		CoreObj subtypebase = ITER.FollowChain(ATTRID_FCOPARENT, targetlevel);
! 		coreobjpairhash derivcrealist;
! 		coreobjhash derivmovedlist;
! 		long instance = ITER[ATTRID_PERMISSIONS] & INSTANCE_FLAG;
! 		vector<CoreObj> newderiveds(cnt);
! 		for(i = 0; i< cnt; i++) {
! 			if(extmoved[i] < 0) {	// the movedobject is a newcomer in the basetype, derive new obj in subtype
! 				ObjTreeDerive(mgaproject, orignobjs[i], newderiveds[i], derivcrealist, instance);
! 				newderiveds[i][ATTRID_FCOPARENT]=ITER;
! 				ObjTreeInternalize(mgaproject, newderiveds[i], subtypebase, targetlevel+1);
! 			}
! 			else {
! 				CoreObj tgt(ITER);	// locate the corresponding object in subtype and move it
! 				CoreObjs ders = orignobjs[i][ATTRID_DERIVED+ATTRID_COLLECTION];
! 				ITERATE_THROUGH(ders) {
! 					CoreObj der(ITER);
! 					if(COM_EQUAL(subtypebase, ITER.FollowChain(ATTRID_FCOPARENT, extmoved[i]))) {
! 							newderiveds[i] = ITER;
! 							CoreObjMark(ITER[ATTRID_FCOPARENT], OBJEVENT_LOSTCHILD);
! 							ITER[ATTRID_FCOPARENT] = tgt;
! 							ITER[ATTRID_ROLEMETA] = orignobjs[i][ATTRID_ROLEMETA];
! 							ObjTreeCollect(mgaproject, ITER, derivmovedlist, CHK_MOVED);
! 							break;
  					}
  				}
- 				ASSERT(ITER_BROKEN);
  			}
! 		}
! 		CoreObjMark(ITER, OBJEVENT_NEWCHILD);
! // Reroute references
! 		for(i = 0; i< cnt; i++) {
! 			ObjTreeReconnect(newderiveds[i], derivcrealist, subtypebase);
! 		}
! 		shiftlist(derivcrealist, derivmovedlist);
! 		for(i = 0; i< cnt; i++) {
! 			ObjTreeCheckRelations(mgaproject, newderiveds[i], derivmovedlist);			
! 		}
! 		DeriveMoveds(mgaproject, newderiveds, extmoved, cnt, targetlevel);
  
! 		for(i = 0; i< cnt; i++) {
! 			ObjTreeCheckINTORelations(mgaproject, newderiveds[i], derivmovedlist);			
  		}
  	}
--- 1101,1158 ----
  // !!! RECURSIVE 
  ///////////////////
! void DeriveMoveds(CMgaProject *mgaproject, vector<CoreObj> &orignobjs, vector<int> &extmoved, int cnt, int targetlevel)
! {
  	if(cnt < 1) return;
+ 
  	CoreObj orig = orignobjs[0][ATTRID_FCOPARENT];
! 	metaid_type n = GetMetaID( orig);
! 
! 	if (n >= DTID_MODEL && n <= DTID_SET)
! 	{
! 		CoreObjs deriveds = orig[ATTRID_DERIVED+ATTRID_COLLECTION];
! 		ITERATE_THROUGH(deriveds) {
! 			int i;
! 			CoreObj subtypebase = ITER.FollowChain(ATTRID_FCOPARENT, targetlevel);
! 			coreobjpairhash derivcrealist;
! 			coreobjhash derivmovedlist;
! 			long instance = ITER[ATTRID_PERMISSIONS] & INSTANCE_FLAG;
! 			vector<CoreObj> newderiveds(cnt);
! 			for(i = 0; i< cnt; i++) {
! 				if(extmoved[i] < 0) {	// the movedobject is a newcomer in the basetype, derive new obj in subtype
! 					ObjTreeDerive(mgaproject, orignobjs[i], newderiveds[i], derivcrealist, instance);
! 					newderiveds[i][ATTRID_FCOPARENT]=ITER;
! 					ObjTreeInternalize(mgaproject, newderiveds[i], subtypebase, targetlevel+1);
! 				}
! 				else {
! 					CoreObj tgt(ITER);	// locate the corresponding object in subtype and move it
! 					CoreObjs ders = orignobjs[i][ATTRID_DERIVED+ATTRID_COLLECTION];
! 					ITERATE_THROUGH(ders) {
! 						CoreObj der(ITER);
! 						if(COM_EQUAL(subtypebase, ITER.FollowChain(ATTRID_FCOPARENT, extmoved[i]))) {
! 								newderiveds[i] = ITER;
! 								CoreObjMark(ITER[ATTRID_FCOPARENT], OBJEVENT_LOSTCHILD);
! 								ITER[ATTRID_FCOPARENT] = tgt;
! 								ITER[ATTRID_ROLEMETA] = orignobjs[i][ATTRID_ROLEMETA];
! 								ObjTreeCollect(mgaproject, ITER, derivmovedlist, CHK_MOVED);
! 								break;
! 						}
  					}
+ 					ASSERT(ITER_BROKEN);
  				}
  			}
! 			CoreObjMark(ITER, OBJEVENT_NEWCHILD);
! 	// Reroute references
! 			for(i = 0; i< cnt; i++) {
! 				ObjTreeReconnect(newderiveds[i], derivcrealist, subtypebase);
! 			}
! 			shiftlist(derivcrealist, derivmovedlist);
! 			for(i = 0; i< cnt; i++) {
! 				ObjTreeCheckRelations(mgaproject, newderiveds[i], derivmovedlist);			
! 			}
! 			DeriveMoveds(mgaproject, newderiveds, extmoved, cnt, targetlevel);
  
! 			for(i = 0; i< cnt; i++) {
! 				ObjTreeCheckINTORelations(mgaproject, newderiveds[i], derivmovedlist);			
! 			}
  		}
  	}
***************
*** 928,933 ****
  
  
- 
- 
  //##ModelId=3C5AA097037A
  HRESULT FCO::MoveFCOs(IMgaFCOs *movelist, IMgaMetaRoles *rlist,IMgaFCOs **objs) {
--- 1160,1163 ----
***************
*** 937,1073 ****
  		long cnt;
  		COMTHROW(movelist->get_Count(&cnt));
! 		if(rlist) {
! 			long rlcnt;
! 			COMTHROW(rlist->get_Count(&rlcnt));
! 			if(rlcnt != cnt) COMTHROW(E_MGA_BAD_COLLENGTH);
! 		}
! 		metaid_type targettype = GetMetaID(self);
! 		int targetlevel = 0;
! 		CoreObj rootp;
! // Pre check:
! 		if(targettype == DTID_MODEL) {
! 			if(self[ATTRID_PERMISSIONS]  & ~EXEMPT_FLAG) COMTHROW(E_MGA_NOT_CHANGEABLE);
! 			GetRootOfDeriv(self, rootp, &targetlevel);
! 			MGACOLL_ITERATE(IMgaFCO, movelist) {
! 				CoreObj cur = CoreObj(MGACOLL_ITER);
! 				if(IsContained(self, cur)) COMTHROW(E_MGA_OP_REFUSED);
! 				if(cur[ATTRID_RELID] >= RELIDSPACE) COMTHROW(E_MGA_OP_REFUSED); 
! 				if(rootp) {
! 					CheckConflict(cur, rootp);
! 				}
  			} MGACOLL_ITERATE_END;
  		}
  
  // move trees
! 		coreobjhash moveslist;
! 		int i = 0;
  
! 		vector<CoreObj> nobjs(cnt);
! 		vector<int> moved_into(cnt);  // >= 0 for objects moved inside the tree, -1 for newcomers
! 		MGACOLL_ITERATE(IMgaFCO, movelist) {
! 			CoreObj cur = nobjs[i] = CoreObj(MGACOLL_ITER);
! 			CoreObj movedobjrootp;
! 			int movedobjlevel;
! 			GetRootOfDeriv(cur, movedobjrootp, &movedobjlevel);
! 			int derdist = GetRealSubtypeDist(cur);
! 			if(derdist) COMTHROW(E_MGA_OP_REFUSED);
! //			if(derdist)	ObjTreeDist(cur, derdist);  // move
  
! 			CoreObj curp = cur[ATTRID_FCOPARENT];
! 			if(!COM_EQUAL(curp, self)) {
! 				CoreObjMark(curp, OBJEVENT_LOSTCHILD);
! 				assignnewchild(cur);
! 				CoreObjMark(cur, OBJEVENT_PARENT);
! 			}
! 			ObjTreeCollect(mgaproject, cur, moveslist, CHK_MOVED);
! 			metaref_type trole = METAREF_NULL;
! 			if(targettype != DTID_FOLDER) {
! 				ASSERT(targettype == DTID_MODEL);
! 				CComPtr<IMgaMetaRole> r;
! 				if(rlist) COMTHROW(rlist->get_Item(i+1, &r));
! 				if(!r) {   // NO metanaem given, inherit that of original object
! 					CComPtr<IMgaMetaFCO> mf; 
! 					COMTHROW(get_Meta(&mf));
! 					CComQIPtr<IMgaMetaModel> parentmeta = mf;
! 					if(!parentmeta) COMTHROW(E_MGA_META_INCOMPATIBILITY);
! 					cur[ATTRID_ROLEMETA];
! 					metaref_type t;
! 					t = (nobjs[i])[ATTRID_ROLEMETA];
! 					if(!t) COMTHROW(E_MGA_NO_ROLE);
! 					CComQIPtr<IMgaMetaRole> metar = mgaproject->FindMetaRef(t);
! 					if(!metar) COMTHROW(E_MGA_META_INCOMPATIBILITY);
! 					CComBSTR rolename;
! 					COMTHROW(metar->get_Name(&rolename));
! 					COMTHROW(parentmeta->get_RoleByName(rolename, &r));
! 					if(!r) COMTHROW(E_MGA_NO_ROLE);
! 				}
! 				{
! 					metaref_type kt;
! 					CComPtr<IMgaMetaFCO> mfco;
! 					COMTHROW(r->get_Kind(&mfco));
! 					COMTHROW(mfco->get_MetaRef(&kt));
! 					if(kt != cur[ATTRID_META]) COMTHROW(E_MGA_META_INCOMPATIBILITY);
  				}
  
! 				COMTHROW(r->get_MetaRef(&trole));
! 				if(trole == METAREF_NULL)  COMTHROW(E_MGA_INVALID_ROLE);
! 			}
! 			cur[ATTRID_ROLEMETA] = trole;
  
! 			// Determine what to do with subtypes of the objects moved 
! 			CoreObjs ders = cur[ATTRID_DERIVED+ATTRID_COLLECTION];
! 			if(!rootp || !COM_EQUAL(movedobjrootp, rootp)) {     // ********* moving out of a type
! 				moved_into[i] = -1;				   // ******** true if moving into a type
! 				if(movedobjlevel < 1) {	// not derived, or derived as self
! 										// if the object to be moved is a root of derivs,
! 										// and not moved to a model, thst model must not have any subtypes/instances
! 					if(ders.Count() &&
! 						targettype == DTID_MODEL && 
! 						CoreObjs(self[ATTRID_DERIVED+ATTRID_COLLECTION]).Count()) {
! 							COMTHROW(E_MGA_OP_REFUSED);  
  					}
! 				}
! 				else {
! 					ITERATE_THROUGH(ders) {				   // ******* erase all previous subtypes
! 						ObjForCore(ITER)->inDeleteObject();
  					}
  				}
! 			}
! 			else moved_into[i] = movedobjlevel;        // ***** the object remains under the same rootmodel
! 			i++;
! 		} MGACOLL_ITERATE_END;
  
! 		for(i = 0; i< cnt; i++) {
! 			ObjTreeCheckRelations(mgaproject, nobjs[i], moveslist);			
! 		}
  
! 		if(targettype == DTID_MODEL) {
! 			DeriveMoveds(mgaproject, nobjs, moved_into, cnt, targetlevel);
! 		}
  
  // Reroute references
! 		for(i = 0; i< cnt; i++) {
! 			ObjTreeCheckINTORelations(mgaproject, nobjs[i], moveslist);			
! 		}
  
  
! 		docheck(mgaproject);
  
  // Assemble return array:
! 		CREATEEXCOLLECTION_FOR(MgaFCO, q);
! 		for(i = 0; i< cnt; i++) {
! 			CComPtr<IMgaFCO> n;
! 			ObjForCore(nobjs[i])->getinterface(&n);
! 			q->Add(n); 
! 		}
! 
! 		
! 		if(objs) {
! 			*objs = q.Detach();
! 		}
  
  
  
! 		SelfMark(OBJEVENT_NEWCHILD);
  
  	} COMCATCH_IN_TRANSACTION(;);
--- 1167,1326 ----
  		long cnt;
  		COMTHROW(movelist->get_Count(&cnt));
! 
! 		bool valid = ( cnt > 0);
! 		if ( cnt == 1)
! 		{
! 			valid = false;
! 			// check whether the source folder is the target as well
! 			CComPtr<IMgaFCO> mf;
! 			MGACOLL_ITERATE( IMgaFCO, movelist) {
! 				mf = MGACOLL_ITER;
  			} MGACOLL_ITERATE_END;
+ 
+ 			VARIANT_BOOL is_equal;
+ 			IMgaFCO * thisptr;
+ 			getinterface( &thisptr);
+ 			COMTHROW( mf->get_IsEqual( thisptr, &is_equal));
+ 
+ 			if (is_equal == VARIANT_FALSE) // not equal
+ 				//COMTHROW( E_MGA_INVALID_ARG); // do not copy/move onto itself
+ 				valid = true;
  		}
  
+ 		if ( valid) 
+ 		{
+ 			if(rlist) {
+ 				long rlcnt;
+ 				COMTHROW(rlist->get_Count(&rlcnt));
+ 				if(rlcnt != cnt) COMTHROW(E_MGA_BAD_COLLENGTH);
+ 			}
+ 			metaid_type targettype = GetMetaID(self);
+ 			int targetlevel = 0;
+ 			CoreObj rootp;
+ // Pre check:
+ 			if(targettype == DTID_MODEL) {
+ 				if(self[ATTRID_PERMISSIONS]  & ~EXEMPT_FLAG) COMTHROW(E_MGA_NOT_CHANGEABLE);
+ 				GetRootOfDeriv(self, rootp, &targetlevel);
+ 				MGACOLL_ITERATE(IMgaFCO, movelist) {
+ 					CoreObj cur = CoreObj(MGACOLL_ITER);
+ 					if(IsContained(self, cur)) COMTHROW(E_MGA_OP_REFUSED);
+ 					if(cur[ATTRID_RELID] >= RELIDSPACE) COMTHROW(E_MGA_OP_REFUSED); 
+ 					if(rootp) {
+ 						CheckConflict(cur, rootp);
+ 					}
+ 				} MGACOLL_ITERATE_END;
+ 			}
+ 
  // move trees
! 			coreobjhash moveslist;
! 			int i = 0;
  
! 			vector<CoreObj> nobjs(cnt);
! 			vector<int> moved_into(cnt);  // >= 0 for objects moved inside the tree, -1 for newcomers
! 			MGACOLL_ITERATE(IMgaFCO, movelist) {
! 				CoreObj cur = nobjs[i] = CoreObj(MGACOLL_ITER);
! 				CoreObj movedobjrootp;
! 				int movedobjlevel;
! 				GetRootOfDeriv(cur, movedobjrootp, &movedobjlevel);
! 				int derdist = GetRealSubtypeDist(cur);
! 				if(derdist) COMTHROW(E_MGA_OP_REFUSED);
! 	//			if(derdist)	ObjTreeDist(cur, derdist);  // move
  
! 				CoreObj curp = cur[ATTRID_FCOPARENT];
! 				if(!COM_EQUAL(curp, self)) {
! 					CoreObjMark(curp, OBJEVENT_LOSTCHILD);
! 					assignnewchild(cur);
! 					CoreObjMark(cur, OBJEVENT_PARENT);
  				}
+ 				ObjTreeCollect(mgaproject, cur, moveslist, CHK_MOVED);
+ 				metaref_type trole = METAREF_NULL;
+ 				if(targettype != DTID_FOLDER) {
+ 					ASSERT(targettype == DTID_MODEL);
+ 					CComPtr<IMgaMetaRole> r;
+ 					if(rlist) COMTHROW(rlist->get_Item(i+1, &r));
+ 					if(!r) {   // NO metanaem given, inherit that of original object
+ 						CComPtr<IMgaMetaFCO> mf; 
+ 						COMTHROW(get_Meta(&mf));
+ 						CComQIPtr<IMgaMetaModel> parentmeta = mf;
+ 						if(!parentmeta) COMTHROW(E_MGA_META_INCOMPATIBILITY);
+ 						cur[ATTRID_ROLEMETA];
+ 						metaref_type t;
+ 						t = (nobjs[i])[ATTRID_ROLEMETA];
+ 						if(!t) COMTHROW(E_MGA_NO_ROLE);
+ 						CComQIPtr<IMgaMetaRole> metar = mgaproject->FindMetaRef(t);
+ 						if(!metar) COMTHROW(E_MGA_META_INCOMPATIBILITY);
+ 						CComBSTR rolename;
+ 						COMTHROW(metar->get_Name(&rolename));
+ 						COMTHROW(parentmeta->get_RoleByName(rolename, &r));
+ 						if(!r) COMTHROW(E_MGA_NO_ROLE);
+ 					}
+ 					{
+ 						metaref_type kt;
+ 						CComPtr<IMgaMetaFCO> mfco;
+ 						COMTHROW(r->get_Kind(&mfco));
+ 						COMTHROW(mfco->get_MetaRef(&kt));
+ 						if(kt != cur[ATTRID_META]) COMTHROW(E_MGA_META_INCOMPATIBILITY);
+ 					}
  
! 					COMTHROW(r->get_MetaRef(&trole));
! 					if(trole == METAREF_NULL)  COMTHROW(E_MGA_INVALID_ROLE);
! 				}
! 				cur[ATTRID_ROLEMETA] = trole;
  
! 				// Determine what to do with subtypes of the objects moved 
! 				CoreObjs ders = cur[ATTRID_DERIVED+ATTRID_COLLECTION];
! 				if(!rootp || !COM_EQUAL(movedobjrootp, rootp)) {     // ********* moving out of a type
! 					moved_into[i] = -1;				   // ******** true if moving into a type
! 					if(movedobjlevel < 1) {	// not derived, or derived as self
! 											// if the object to be moved is a root of derivs,
! 											// and not moved to a model, thst model must not have any subtypes/instances
! 						if(ders.Count() &&
! 							targettype == DTID_MODEL && 
! 							CoreObjs(self[ATTRID_DERIVED+ATTRID_COLLECTION]).Count()) {
! 								COMTHROW(E_MGA_OP_REFUSED);  
! 						}
  					}
! 					else {
! 						ITERATE_THROUGH(ders) {				   // ******* erase all previous subtypes
! 							ObjForCore(ITER)->inDeleteObject();
! 						}
  					}
  				}
! 				else moved_into[i] = movedobjlevel;        // ***** the object remains under the same rootmodel
! 				i++;
! 			} MGACOLL_ITERATE_END;
  
! 			for(i = 0; i< cnt; i++) {
! 				ObjTreeCheckRelations(mgaproject, nobjs[i], moveslist);			
! 			}
  
! 			if(targettype == DTID_MODEL) {
! 				DeriveMoveds(mgaproject, nobjs, moved_into, cnt, targetlevel);
! 			}
  
  // Reroute references
! 			for(i = 0; i< cnt; i++) {
! 				ObjTreeCheckINTORelations(mgaproject, nobjs[i], moveslist);			
! 			}
  
  
! 			docheck(mgaproject);
  
  // Assemble return array:
! 			CREATEEXCOLLECTION_FOR(MgaFCO, q);
! 			for(i = 0; i< cnt; i++) {
! 				CComPtr<IMgaFCO> n;
! 				ObjForCore(nobjs[i])->getinterface(&n);
! 				q->Add(n); 
! 			}
  
+ 			
+ 			if(objs) {
+ 				*objs = q.Detach();
+ 			}
  
  
! 			SelfMark(OBJEVENT_NEWCHILD);
! 		} // if valid
  
  	} COMCATCH_IN_TRANSACTION(;);

Index: MgaFCO.h
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/MgaFCO.h,v
retrieving revision 1.16
retrieving revision 1.17
diff -C2 -d -r1.16 -r1.17
*** MgaFCO.h	14 Jan 2003 21:00:00 -0000	1.16
--- MgaFCO.h	2 Jun 2004 21:43:19 -0000	1.17
***************
*** 97,100 ****
--- 97,103 ----
   STDMETHOD(put_Name)( BSTR newVal)					{ return inFCO->put_Name(newVal); }
   STDMETHOD(get_Meta)( IMgaMetaFCO **pVal)			{ return inFCO->get_Meta(pVal); }
+  //by ZolMol
+  //STDMETHOD(get_FolderMeta)( IMgaMetaFolder **pVal)		{ return inFCO->get_Meta(pVal); }
+ 
   STDMETHOD(get_ParentModel)( IMgaModel **pVal)		{ return inFCO->get_ParentModel(pVal); }
   STDMETHOD(get_ParentFolder)( IMgaFolder **pVal)		{ return inFCO->get_ParentFolder(pVal); }
***************
*** 366,369 ****
--- 369,378 ----
  	HRESULT CreateRootObject(IMgaMetaFCO *meta, IMgaFCO **nobj);
  	HRESULT get_MetaFolder(IMgaMetaFolder **pVal);
+ 	// by ZolMol
+ 	HRESULT CopyFolders(IMgaFolders *copylist, IMgaFolders **objs);
+ 	HRESULT MoveFolders(IMgaFolders *copylist, IMgaFolders **objs);
+ 	HRESULT RefreshParent( IMgaFolder * f);
+ 	
+ 
  	// MODEL
  	HRESULT CreateChildObject( IMgaMetaRole *role, IMgaFCO **newobj);
***************
*** 374,378 ****
  
  // FOLDER & MODEL
! 		HRESULT ContainerCreateFCO(IMgaMetaFCO *meta, CoreObj &FCO);
  	HRESULT GetChildrenOfKind(BSTR kn, IMgaFCOs **pVal);
  	HRESULT GetDescendantFCOs(IMgaFilter* filt, IMgaFCOs **pVal); 
--- 383,387 ----
  
  // FOLDER & MODEL
! 	HRESULT ContainerCreateFCO(IMgaMetaFCO *meta, CoreObj &FCO);
  	HRESULT GetChildrenOfKind(BSTR kn, IMgaFCOs **pVal);
  	HRESULT GetDescendantFCOs(IMgaFilter* filt, IMgaFCOs **pVal); 
***************
*** 562,565 ****
--- 571,575 ----
  
  typedef CCoreCollectionEx<IMgaFCOs, vector<IMgaFCO*>, IMgaFCO, IMgaFCO, &CLSID_MgaFCOs, IDR_MGAFCOS> CMgaFCOs;
+ typedef CCoreCollectionEx<IMgaFolders, vector<IMgaFolder*>, IMgaFolder, IMgaFolder, &CLSID_MgaFolders, IDR_MGAFOLDERS> CMgaFolders;
  typedef CCoreCollectionEx<IMgaObjects, vector<IMgaObject*>, IMgaObject, IMgaObject, &CLSID_MgaObjects, IDR_MGAOBJECTS> CMgaObjects;
  typedef CCoreCollectionEx<IMgaRegNodes, vector<IMgaRegNode*>, IMgaRegNode, IMgaRegNode, &CLSID_MgaRegNodes, IDR_MGAREGNODES> CMgaRegNodes;

Index: MgaFolder.cpp
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/MgaFolder.cpp,v
retrieving revision 1.19
retrieving revision 1.20
diff -C2 -d -r1.19 -r1.20
*** MgaFolder.cpp	11 Mar 2002 22:17:00 -0000	1.19
--- MgaFolder.cpp	2 Jun 2004 21:43:19 -0000	1.20
***************
*** 2,6 ****
  #include "stdafx.h"
  #include "MgaFCO.h"
! 
  
  /////////////////////////////////////////////////////////////////////////////
--- 2,7 ----
  #include "stdafx.h"
  #include "MgaFCO.h"
! #include "MgaLibOps.h" // by ZolMol
! #include "MgaComplexOps.h" // by ZolMol
  
  /////////////////////////////////////////////////////////////////////////////
***************
*** 43,48 ****
--- 44,250 ----
  
  
+ //
+ // by ZolMol
+ // called from CMgaFolder::CopyFolders
+ //
+ HRESULT FCO::CopyFolders(IMgaFolders *copylist, IMgaFolders **objs)
+ {
+ 	COMTRY_IN_TRANSACTION {
+ 		CheckWrite();
+ 		CHECK_MYINPTRSPARFOLDER(copylist);
+ 		long cnt;
+ 		COMTHROW(copylist->get_Count(&cnt));
+ 
+ 		metaid_type targettype = GetMetaID(self);
+ 
+ // Pre check:
+ 		if(targettype == DTID_FOLDER)
+ 		{
+ 			if(self[ATTRID_PERMISSIONS] & ~EXEMPT_FLAG) 
+ 				COMTHROW(E_MGA_NOT_CHANGEABLE);
+ 		}
+ 
+ // Copy trees
+ 		coreobjpairhash crealist;
+ 		int i = 0;
+ 
+ 		vector<CoreObj> nobjs(cnt);
+ 		MGACOLL_ITERATE(IMgaFolder, copylist) {
+ 			CoreObj oldobj = CoreObj(MGACOLL_ITER);
+ 			ObjTreeCopyFoldersToo(mgaproject, oldobj, nobjs[i], crealist);  // copy
+ 			assignnewchild(nobjs[i]);
+ 			metaref_type tkind = METAREF_NULL;
+ 			if(targettype != DTID_FOLDER) ASSERT(0);
+ 			
+ 			// NO metarole needed, operate with kinds only
+ 			CComPtr<IMgaMetaFolder> mf; 
+ 			COMTHROW(get_MetaFolder(&mf));
+ 			CComQIPtr<IMgaMetaFolder> parentmeta = mf;
+ 			if(!parentmeta) COMTHROW(E_MGA_META_INCOMPATIBILITY);
+ 			COMTHROW( parentmeta->get_MetaRef(&tkind));
+ 
+ 			if(tkind == METAREF_NULL)  COMTHROW(E_MGA_INVALID_ROLE); //E_MGA_INVALID_KIND ? instead
+ 
+ 			(nobjs[i])[ATTRID_META] = tkind;
+ 			i++;
+ 		} MGACOLL_ITERATE_END;
+ 
+ // Reroute references
+ 		for(i = 0; i< cnt; i++) {
+ 			ObjTreeReconnectFoldersToo(nobjs[i], crealist);			
+ 		}
+ 
+ 		coreobjhash newcrealist;
+ 		shiftlist(crealist, newcrealist);
+ 
+ 		for(i = 0; i< cnt; i++) {
+ 			ObjTreeCheckRelationsFoldersToo(mgaproject, nobjs[i], newcrealist);			
+ 		}
+ 
+ 		docheck(mgaproject);
+ 
+ // Assemble return array:
+ 		if(objs) {
+ 			CREATEEXCOLLECTION_FOR(MgaFolder, q);
+ 			for(i = 0; i< cnt; i++) {
+ 				CComPtr<IMgaFolder> ff;
+ 				ObjForCore(nobjs[i])->getinterface(&ff);
+ 				q->Add(ff); 
+ 			}
+ 			*objs = q.Detach();
+ 		}
+ 
+ 		SelfMark(OBJEVENT_NEWCHILD);
+ 
+ 	} COMCATCH_IN_TRANSACTION(;);
+ }
+ 
+ HRESULT FCO::MoveFolders( IMgaFolders *movelist, IMgaFolders **objs)
+ {
+ 	COMTRY_IN_TRANSACTION {
+ 		CheckWrite();
+ 		CHECK_MYINPTRSPARFOLDER(movelist);
+ 		long cnt;
+ 		COMTHROW(movelist->get_Count(&cnt));
+ 
+ 		bool valid = (cnt > 0);
+ 		if ( cnt == 1)
+ 		{
+ 			valid = false;
+ 			// check whether the source folder is the target as well
+ 			CComPtr<IMgaFolder> mf;
+ 			MGACOLL_ITERATE( IMgaFolder, movelist) {
+ 				mf = MGACOLL_ITER;
+ 			} MGACOLL_ITERATE_END;
+ 
+ 			VARIANT_BOOL is_equal;
+ 			IMgaFolder * thisptr;
+ 			getinterface( &thisptr);
+ 			COMTHROW( mf->get_IsEqual( thisptr, &is_equal));
+ 
+ 			if (is_equal == VARIANT_FALSE) // not equal
+ 				//COMTHROW( E_MGA_INVALID_ARG); // do not copy/move onto itself
+ 				valid = true;
+ 		}
+ 		
+ 		if ( valid)
+ 		{
+ 
+ 			metaid_type targettype = GetMetaID(self);
+ 			int targetlevel = 0;
+ 			CoreObj rootp;
+ 
+ // Pre check:
+ 			if(targettype == DTID_FOLDER) 
+ 			{
+ 				if(self[ATTRID_PERMISSIONS]  & ~EXEMPT_FLAG) 
+ 					COMTHROW(E_MGA_NOT_CHANGEABLE);
+ 			}
+ 
+ 
+ // move trees
+ 			coreobjhash moveslist; // will contain the movements which are needed to proceed
+ 			int i = 0;
+ 
+ 			vector<CoreObj> nobjs(cnt);
+ 			vector<int> moved_into(cnt);  // >= 0 for objects moved inside the tree, -1 for newcomers
+ 			MGACOLL_ITERATE(IMgaFolder, movelist) {
+ 
+ 				CoreObj cur = nobjs[i] = CoreObj(MGACOLL_ITER);
+ 
+ 				CoreObj curr_parent = cur[ATTRID_FCOPARENT];
+ 				
+ 
+ 				if( !COM_EQUAL( curr_parent, self)) {
+ 					CoreObjMark( curr_parent, OBJEVENT_LOSTCHILD); // the old parent will lose its child
+ 					assignnewchild( cur);
+ 					CoreObjMark( cur, OBJEVENT_PARENT); // obj has been moved
+ 				}
+ 
+ 				ObjTreeCollectFoldersToo( mgaproject, cur, moveslist, CHK_MOVED);
+ 				metaref_type tkind = METAREF_NULL;
+ 				
+ 				if(targettype != DTID_FOLDER) 
+ 					ASSERT(0);
+ 
+ 				CComPtr<IMgaMetaFolder> mf; 
+ 				COMTHROW(get_MetaFolder(&mf));
+ 				CComQIPtr<IMgaMetaFolder> parentmeta = mf;
+ 
+ 				if(!parentmeta) 
+ 					COMTHROW(E_MGA_META_INCOMPATIBILITY); // might be optimized by removing the parentmeta
+ 
+ 				COMTHROW( parentmeta->get_MetaRef(&tkind));
+ 
+ 				cur[ATTRID_META];
+ 
+ 				if(tkind == METAREF_NULL)
+ 					COMTHROW(E_MGA_INVALID_ROLE);
+ 				
+ 				cur[ATTRID_META] = tkind;
+ 
+ 				i++;
+ 			} MGACOLL_ITERATE_END;
+ 
+ 			for(i = 0; i< cnt; i++) {
+ 				ObjTreeCheckRelationsFoldersToo(mgaproject, nobjs[i], moveslist);
+ 			}
+ 
+ 			if(targettype == DTID_FOLDER) {
+ 				DeriveMoveds(mgaproject, nobjs, moved_into, cnt, targetlevel);
+ 			}
  
+ // Reroute references
+ 			for(i = 0; i< cnt; i++) {
+ 				ObjTreeCheckINTORelationsFoldersToo(mgaproject, nobjs[i], moveslist);			
+ 			}
+ 
+ 			docheck(mgaproject);
  
+ // Assemble return array:
+ 			CREATEEXCOLLECTION_FOR(MgaFolder, q);
+ 			for(i = 0; i< cnt; i++) {
+ 				CComPtr<IMgaFolder> n;
+ 				ObjForCore(nobjs[i])->getinterface(&n);
+ 				q->Add(n); 
+ 			}
+ 			
+ 			if(objs) {
+ 				*objs = q.Detach();
+ 			}
+ 			
+ 			//SelfMark(OBJEVENT_NEWCHILD); - omitted, done by separate method: RefreshParent
+ 
+ 		} // if valid
+ 
+ 	} COMCATCH_IN_TRANSACTION(;);
+ }
+ 
+ HRESULT FCO::RefreshParent( IMgaFolder * folder)
+ {
+ 	COMTRY_IN_TRANSACTION {
+ 		SelfMark(OBJEVENT_NEWCHILD);
+ 	} COMCATCH_IN_TRANSACTION(;);
+ }
  
  HRESULT FCO::get_ChildFolders(IMgaFolders **pVal) {

Index: MgaFolder.h
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/MgaFolder.h,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -d -r1.5 -r1.6
*** MgaFolder.h	11 Mar 2002 22:17:00 -0000	1.5
--- MgaFolder.h	2 Jun 2004 21:43:19 -0000	1.6
***************
*** 77,80 ****
--- 77,86 ----
  	//##ModelId=3C5AA08F02E4
  	STDMETHOD(MoveFCOs)(IMgaFCOs *list, IMgaFCOs **objs) { return inFCO->MoveFCOs(list, NULL, objs); } 
+ 	//##ModelId=3C5AA08F02D0
+ 	STDMETHOD(CopyFolders)(IMgaFolders *list, IMgaFolders **objs) { return inFCO->CopyFolders(list, /*NULL,*/ objs); } 
+ 	//##ModelId=3C5AA08F02E4
+ 	STDMETHOD(MoveFolders)(IMgaFolders *list, IMgaFolders **objs) { return inFCO->MoveFolders(list, /*NULL,*/ objs); } 
+ 	//STDMETHOD(MoveFCOsAndFolders)(IMgaFolders *list, IMgaFCOs *list2, IMgaFolders **objs, IMgaFCOs **objs2) { return inFCO->MoveFCOsAndFolders(list, list2, objs, objs2); } 
+ 	STDMETHOD(RefreshParent)(IMgaFolder *parent) { return inFCO->RefreshParent( parent); }
  
  	//##ModelId=3C5AA08F0301
***************
*** 130,133 ****
--- 136,141 ----
  	//##ModelId=3C5AA09000BE
  	STDMETHOD(get_Meta)(IMgaMetaFCO * *pVal) { return E_MGA_NOT_SUPPORTED; }
+ 	// by ZolMol
+ 	//STDMETHOD(get_FolderMeta)(IMgaMetaFolder * *pVal) { return inFCO->get_MetaFolder( pVal); }
  
  };

Index: MgaLibOps.cpp
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/MgaLibOps.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -C2 -d -r1.6 -r1.7
*** MgaLibOps.cpp	14 Jan 2003 21:00:00 -0000	1.6
--- MgaLibOps.cpp	2 Jun 2004 21:43:19 -0000	1.7
***************
*** 5,9 ****
  #include "MgaReference.h"
  #include "MgaConnection.h"
! 
  
  
--- 5,9 ----
  #include "MgaReference.h"
  #include "MgaConnection.h"
! #include "MgaLibOps.h" // by ZolMol
  
  
***************
*** 47,51 ****
  
  /* *************************** Pointer Fixup ************************************** */
! 
  class PointerFixup
  {
--- 47,52 ----
  
  /* *************************** Pointer Fixup ************************************** */
! /*
! by ZolMol
  class PointerFixup
  {
***************
*** 113,117 ****
  	}
  };
! 
  /* *************************** Attach ********************************************* */
  
--- 114,118 ----
  	}
  };
! */
  /* *************************** Attach ********************************************* */
  

Index: MgaProject.cpp
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/MgaProject.cpp,v
retrieving revision 1.48
retrieving revision 1.49
diff -C2 -d -r1.48 -r1.49
*** MgaProject.cpp	22 Apr 2004 12:25:52 -0000	1.48
--- MgaProject.cpp	2 Jun 2004 21:43:19 -0000	1.49
***************
*** 1420,1423 ****
--- 1420,1432 ----
  }
  
+ // by ZolMol
+ STDMETHODIMP CMgaProject::CheckFolderCollection(IMgaFolders *coll) {
+ 	MGACOLL_ITERATE(IMgaFolder, coll) {
+ 		HRESULT s;
+ 		if((s = MGACOLL_ITER->CheckProject(this)) != S_OK) return s;
+ 	}
+ 	MGACOLL_ITERATE_END;
+ 	return S_OK;
+ }
  
  

Index: MgaProject.h
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/MgaProject.h,v
retrieving revision 1.22
retrieving revision 1.23
diff -C2 -d -r1.22 -r1.23
*** MgaProject.h	9 Mar 2004 22:15:32 -0000	1.22
--- MgaProject.h	2 Jun 2004 21:43:19 -0000	1.23
***************
*** 147,150 ****
--- 147,151 ----
  										   VARIANT_BOOL *ro_mode);
  	STDMETHOD(CheckCollection)(IMgaFCOs *coll);
+ 	STDMETHOD(CheckFolderCollection)(IMgaFolders *coll);
  	STDMETHOD(get_Clients)(IMgaClients **clients);
  	STDMETHOD(RegisterClient)(BSTR name, IDispatch *OLEServer, IMgaClient **client);

Index: MgaTrukk.h
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/MgaTrukk.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -C2 -d -r1.17 -r1.18
*** MgaTrukk.h	21 Nov 2002 05:07:00 -0000	1.17
--- MgaTrukk.h	2 Jun 2004 21:43:19 -0000	1.18
***************
*** 62,65 ****
--- 62,68 ----
  #define CHECK_MYINPTRSPAR(p) { if(p == NULL)				 COMTHROW( E_MGA_INPTR_NULL); \
  								COMTHROW( mgaproject->CheckCollection(p)); }
+ //by ZolMol
+ #define CHECK_MYINPTRSPARFOLDER(p) { if(p == NULL)				 COMTHROW( E_MGA_INPTR_NULL); \
+ 								COMTHROW( mgaproject->CheckFolderCollection(p)); }
  #define CHECK_INSTRPAR(p)	 { if(p == NULL)			p = NULLSTR; }
  #define CHECK_OUTSTRPAR(p)   { if(p == NULL) COMTHROW(E_MGA_OUTPTR_NULL); if(*p != NULL) COMTHROW(E_MGA_OUTPTR_NONEMPTY); }

Index: resource.h
===================================================================
RCS file: /var/lib/gme/GMESRC/GME/Mga/resource.h,v
retrieving revision 1.7
retrieving revision 1.8
diff -C2 -d -r1.7 -r1.8
*** resource.h	17 Dec 2003 13:45:03 -0000	1.7
--- resource.h	2 Jun 2004 21:43:19 -0000	1.8
***************
*** 9,12 ****
--- 9,13 ----
  #define IDR_MGAFCOS                     204
  #define IDR_MGAREGNODES                 205
+ #define IDR_MGAFOLDERS                  206
  
  // Next default values for new objects
***************
*** 14,18 ****
  #ifdef APSTUDIO_INVOKED
  #ifndef APSTUDIO_READONLY_SYMBOLS
! #define _APS_NEXT_RESOURCE_VALUE        206
  #define _APS_NEXT_COMMAND_VALUE         32768
  #define _APS_NEXT_CONTROL_VALUE         201
--- 15,19 ----
  #ifdef APSTUDIO_INVOKED
  #ifndef APSTUDIO_READONLY_SYMBOLS
! #define _APS_NEXT_RESOURCE_VALUE        207
  #define _APS_NEXT_COMMAND_VALUE         32768
  #define _APS_NEXT_CONTROL_VALUE         201



More information about the GME-commit mailing list