GME
13
|
00001 // MgaProject.cpp : Implementation of CMgaProject 00002 #include "stdafx.h" 00003 #include "MgaUtil.h" 00004 #include "CommonComponent.h" 00005 #include "MgaFCO.h" 00006 #include "MgaFilter.h" 00007 #include "stdio.h" 00008 #include "MgaComplexOps.h" 00009 #include "MgaLibOps.h" 00010 00011 void LockingStart(CComPtr<ICoreProject> &tempproject) { 00012 CComPtr<ICoreTerritory> lm; 00013 COMTHROW(tempproject->CreateTerritory( &lm)); 00014 COMTHROW(tempproject->PushTerritory( lm)); 00015 } 00016 00018 // CMgaProject 00020 00021 CMgaProject::CMgaProject() { 00022 INITSIG('P'); 00023 #ifdef DEBUG 00024 MGA_TRACE("Constructed: %s - %08X\n", sig, this); 00025 #endif 00026 opened = CLOSED; 00027 dataproject = NULL; 00028 preferences = 0; 00029 opmask = 0x0026662A; 00030 mgaproject = this; 00031 checkoff = false; 00032 transactioncount = 0; 00033 autoaddons = false; 00034 inautoaddoncreate = false; 00035 mgaversion = 0; 00036 aurcnt = 0; 00037 guidstat = CLEAN; 00038 } 00039 00040 STDMETHODIMP CMgaProject::FinalConstruct() { 00041 COMTRY { 00042 // IDispatchImpl<IMgaProject, &IID_IMgaProject, &LIBID_MGALib> *xthis = this; 00043 COMTHROW( CoCreateInstance(__uuidof(CoreProject), (IMgaProject *)this, CLSCTX_ALL, IID_IUnknown, (LPVOID *) &inner) ); 00044 #ifndef _ATL_DEBUG_INTERFACES 00045 COMTHROW(inner.QueryInterface(&dataproject)); 00046 dataproject->Release(); // release reference to ourselves 00047 #else 00048 dataprojectNull = false; 00049 #endif 00050 } COMCATCH(;); 00051 } 00052 00053 CMgaProject::~CMgaProject() { 00054 #ifdef DEBUG 00055 MGA_TRACE("Destructed: %s - %08X\n", sig, this); 00056 #endif 00057 MARKSIG('9'); 00058 ASSERT(allterrs.empty()); 00059 if(opened != CLOSED) { 00060 Close(); 00061 } 00062 } 00063 00067 00068 STDMETHODIMP CMgaProject::get_MetaObj(metaref_type id, IMgaMetaBase **pVal) { 00069 COMTRY { 00070 COMTHROW(metapr != 0 ? S_OK : E_MGA_PROJECT_NOT_OPEN); 00071 SetNmspaceInMeta(); 00072 COMTHROW(metapr->get_FindObject(id, pVal)); 00073 } 00074 COMCATCH(;); 00075 } 00076 00077 // THROWS 00078 CComPtr<IMgaMetaBase> CMgaProject::FindMetaRef(metaref_type l) { 00079 CComPtr<IMgaMetaBase> hh; 00080 COMTHROW(metapr != 0 ? S_OK : E_MGA_PROJECT_NOT_OPEN); 00081 SetNmspaceInMeta(); 00082 COMTHROW(metapr->get_FindObject(l, &hh)); 00083 // HRESULT hr = metapr->get_FindObject(l, &hh); 00084 // if(hr != S_OK && hr != E_NOTFOUND) COMTHROW(hr); 00085 return hh; 00086 } 00087 00088 00092 00093 00094 HRESULT CMgaProject::CreateSetupData(BSTR rootname, BSTR paradigmname, VARIANT guid) { 00095 COMTRY_IN_TRANSACTION { 00096 00097 // check if meta is valid 00098 CoreObj dataroot, rootfolder; 00099 CComBSTR parversion; 00100 00101 // set values in 00102 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 00103 dataroot[ATTRID_CDATE] = dataroot[ATTRID_MDATE] = Now(); 00104 dataroot[ATTRID_PARADIGM] = paradigmname; 00105 dataroot[ATTRID_MGAVERSION] = mgaversion; 00106 COMTHROW(metapr->get_Version(&parversion)); 00107 dataroot[ATTRID_PARVERSION] = parversion; 00108 dataroot[ATTRID_NAME] = rootname; 00109 if( guid.vt != (VT_UI1 | VT_ARRAY) || GetArrayLength(guid) != sizeof(::GUID) ) 00110 COMTHROW(E_INVALIDARG); 00111 dataroot[ATTRID_PARGUID] = guid; 00112 dataroot[ATTRID_VERSION] = CComBSTR(""); // default version string 00113 00114 // create data root things 00115 COMTHROW(dataproject->CreateObject(DTID_FOLDER,&rootfolder.ComPtr())); 00116 assignGuid( this, rootfolder); // assign a guid to the root folder 00117 rootfolder[ATTRID_NAME] = rootname; 00118 rootfolder[ATTRID_FPARENT] = dataroot; 00119 if(!(preferences & MGAPREF_MANUAL_RELIDS)) rootfolder[ATTRID_RELID] = 1; 00120 CComPtr<IMgaMetaFolder> mf; 00121 metaref_type mr; 00122 COMTHROW(metapr->get_RootFolder(&mf)); 00123 COMTHROW(mf->get_MetaRef(&mr)); 00124 rootfolder[ATTRID_META] = mr; 00125 notifyqueueprocessed = true; 00126 } COMCATCH_IN_TRANSACTION(;); 00127 00128 } 00129 00130 00131 static int guidcmp(VARIANT &qGUID, VARIANT &pGUID) { 00132 ::GUID g1, g2; 00133 CopyTo(qGUID, g1); 00134 CopyTo(pGUID, g2); 00135 return memcmp(&g1, &g2, sizeof(g1)); 00136 } 00137 00138 00139 inline HRESULT EMAP(HRESULT hr, HRESULT from, HRESULT to) { HRESULT h = hr; if(h == from) h = to; return h; } 00140 inline HRESULT EDEF(HRESULT hr, HRESULT to) { HRESULT h = hr; if(h != S_OK) h = to; return h; } 00141 00142 00143 void CMgaProject::OpenParadigm(BSTR s, VARIANT *pGUID) { 00144 CComPtr<IMgaRegistrar> mgareg; 00145 COMTHROW(mgareg.CoCreateInstance(OLESTR("Mga.MgaRegistrar"))); 00146 _bstr_t connstr; 00147 { 00148 HRESULT hr = mgareg->QueryParadigm(s, connstr.GetAddress(), pGUID, REGACCESS_PRIORITY); 00149 if (FAILED(hr)) 00150 { 00151 CComPtr<IErrorInfo> info; 00152 GetErrorInfo(0, &info); 00153 throw _com_error(E_MGA_PARADIGM_NOTREG, info, true); 00154 } 00155 } 00156 ASSERT(connstr); 00157 COMTHROW(metapr.CoCreateInstance(OLESTR("Mga.MgaMetaProject"))); 00158 // #ifdef _ATL_DEBUG_INTERFACES 00159 // COMTHROW(metapr.CoCreateInstance(OLESTR("Mga.MgaMetaProject"), NULL, CLSCTX_LOCAL_SERVER)); 00160 HRESULT hr = metapr->Open(connstr); 00161 if (FAILED(hr)) 00162 { 00163 _bstr_t err; 00164 if (GetErrorInfo(err.GetAddress())) 00165 throw_com_error(E_MGA_PARADIGM_INVALID, static_cast<const wchar_t*>(err)); // change HRESULT 00166 COMTHROW(E_MGA_PARADIGM_INVALID); 00167 } 00168 CComVariant metaGUID; 00169 COMTHROW(metapr->get_GUID(&metaGUID)); 00170 if (guidcmp(metaGUID, *pGUID)) 00171 throw_com_error(E_MGA_PARADIGM_INVALID, L".mta file paradigm GUID does not match registered GUID"); 00172 parconn = connstr.GetBSTR(); 00173 } 00174 00175 00176 STDMETHODIMP CMgaProject::OpenParadigm(BSTR s, BSTR ver) { 00177 COMTRY { 00178 CComVariant vguid; 00179 { 00180 CComPtr<IMgaRegistrar> mgareg; 00181 COMTHROW(mgareg.CoCreateInstance(OLESTR("Mga.MgaRegistrar"))); 00182 { 00183 HRESULT hr = mgareg->GUIDFromVersion(s, ver, &vguid, REGACCESS_PRIORITY); 00184 if (FAILED(hr)) 00185 { 00186 CComPtr<IErrorInfo> info; 00187 GetErrorInfo(0, &info); 00188 throw _com_error(E_MGA_PARADIGM_NOTREG, info, true); 00189 } 00190 } 00191 } 00192 OpenParadigm(s,&vguid); 00193 } COMCATCH(;); 00194 } 00195 00196 STDMETHODIMP CMgaProject::CreateEx(BSTR projectname, BSTR paradigmname, VARIANT paradigmGUID) { 00197 COMTRY { 00198 if(opened != CLOSED) COMTHROW(E_MGA_PROJECT_OPEN); 00199 00200 mgaversion = 2; 00201 // Set generic for meta 00202 CComPtr<ICoreMetaProject> genericproject; 00203 CreateCoreMetaProject(genericproject, mgaversion > 1); // create version 2 from now on 00204 00205 CComVariant connGUID; 00206 if(paradigmGUID.vt != VT_EMPTY) connGUID = paradigmGUID; 00207 OpenParadigm(paradigmname, &connGUID); 00208 00209 int undosize = getMaxUndoSize(); 00210 COMTHROW(dataproject->CreateProject2(projectname, undosize, genericproject)); 00211 opened = UNCHANGED; 00212 guidstat = DIRTY; 00213 00214 CComPtr<IMgaTerritory> lm; 00215 COMTHROW(CreateTerritory(NULL, &lm)); 00216 COMTHROW(BeginTransaction(lm, TRANSACTION_GENERAL)); 00217 00218 HRESULT suhr = S_OK; 00219 try { 00220 CComBSTR fname("RootFolder"); 00221 // BGY: commented out because xml backend has different connection string format 00222 /*LPCOLESTR p = wcsrchr(projectname, '\\'); 00223 if(p) { 00224 p++; 00225 LPCOLESTR p2 = wcschr(p, '.'); 00226 if(p2 == NULL) p2 = p + wcslen(p); 00227 fname = CComBSTR(p2-p, p); 00228 }*/ 00229 suhr = CreateSetupData(fname, paradigmname, connGUID); 00230 COMTHROW(lm->Flush()); 00231 COMTHROW(CommitTransaction()); 00232 } catch(hresult_exception &e) { 00233 lm->Flush(); 00234 AbortTransaction(); 00235 throw e; 00236 } 00237 COMTHROW(dataproject->FlushUndoQueue()); 00238 COMTHROW(suhr); 00239 projconn = projectname; 00240 StartAutoAddOns(); 00241 try { 00242 COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY)); 00243 GlobalNotify(GLOBALEVENT_OPEN_PROJECT); 00244 COMTHROW(lm->Flush()); 00245 COMTHROW(CommitTransaction()); 00246 } catch(hresult_exception &e) { 00247 lm->Flush(); 00248 AbortTransaction(); 00249 throw e; 00250 } 00251 MARKSIG('2'); 00252 } 00253 COMCATCH( 00254 opened = CLOSED; 00255 guidstat = CLEAN; 00256 if (dataproject) { 00257 dataproject->CloseProject(VARIANT_TRUE); 00258 dataproject->DeleteProject(projectname); 00259 } 00260 if (metapr) 00261 metapr->Close(); 00262 metapr = 0; 00263 projconn.Empty(); 00264 parconn.Empty(); 00265 // We've already called SetErrorInfo, don't call it again 00266 if (e.hr == E_MGA_COMPONENT_ERROR) { 00267 return e.hr; 00268 } 00269 ) 00270 } 00271 00272 00273 // if paradigname != "": 00274 // change paradigmname if different 00275 // if paradigmguid == 0 update to the current version (even if no name change!); 00276 // if paradigmguid != null and != oldguid update guid (use new paradigmname to locate paradigm in any case) 00277 // if no guid change skip check 00278 STDMETHODIMP CMgaProject::OpenEx(BSTR projectname, BSTR paradigmname, VARIANT paradigmGUID) { 00279 COMTRY { 00280 if(opened != CLOSED) COMTHROW(E_MGA_PROJECT_OPEN); 00281 CComBSTR s; 00282 CComVariant pGUID; 00283 CComBSTR ver; 00284 CComPtr<ICoreMetaProject> genericproject; 00285 CreateCoreMetaProject(genericproject, true); // will upgrade if old version 00286 VARIANT_BOOL ro; 00287 00288 int undosize = getMaxUndoSize(); 00289 COMTHROW(dataproject->OpenProject2(projectname, undosize, genericproject, &ro)); 00290 00291 projconn = projectname; 00292 00293 opened = UNCHANGED; 00294 guidstat = CLEAN; 00295 CComPtr<IMgaTerritory> lm; 00296 COMTHROW(CreateTerritory(NULL, &lm)); 00297 COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY)); 00298 00299 try { 00300 00301 CoreObj dataroot; 00302 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 00303 s=dataroot[ATTRID_PARADIGM]; 00304 mgaversion = dataroot[ATTRID_MGAVERSION]; 00305 if( mgaversion <= 1L) // Core layer changed the project by adding ATTRID_GUID1..4 for CCoreBinFile 00306 opened = CHANGED; 00307 00308 pGUID=CComVariant(dataroot[ATTRID_PARGUID]); 00309 ver = dataroot[ATTRID_PARVERSION]; 00310 COMTHROW(lm->Flush()); 00311 COMTHROW(CommitTransaction()); 00312 } catch(hresult_exception &e) { 00313 lm->Flush(); 00314 AbortTransaction(); 00315 throw e; 00316 } 00317 00318 CComBSTR soldname = s; 00319 CComVariant soldguid = pGUID; 00320 00321 if(SysStringLen(paradigmname) != 0) { 00322 ver.Empty(); 00323 s = paradigmname; 00324 } 00325 if (paradigmGUID.vt != VT_EMPTY) { 00326 ver.Empty(); 00327 if (CComVariant(true) == paradigmGUID) 00328 pGUID = NULLVARIANT; // use current version 00329 else 00330 pGUID = paradigmGUID; 00331 } 00332 if (s.Length()) { 00333 if (ver.Length()) { 00334 // Version string has precedence 00335 COMTHROW(OpenParadigm(s,ver)); 00336 pGUID.Clear(); 00337 COMTHROW(metapr->get_GUID(&pGUID)); 00338 } 00339 else { 00340 OpenParadigm(s, &pGUID); 00341 ver.Empty(); 00342 COMTHROW(metapr->get_Version(&ver)); 00343 } 00344 bool guidchanged = false; 00345 if(guidcmp(soldguid, pGUID)) { 00346 COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY)); 00347 try { 00348 CComPtr<IMgaFolder> rf; 00349 COMTHROW(get_RootFolder(&rf)); 00350 HRESULT hr = ObjFor(rf)->CheckTree(); 00351 if (FAILED(hr)) 00352 { 00353 throw_last_com_error(hr); 00354 } 00355 rf = 0; 00356 COMTHROW(CommitTransaction()); 00357 } catch(hresult_exception &e) { 00358 lm->Flush(); 00359 AbortTransaction(); 00360 throw e; 00361 } catch(_com_error&) { 00362 lm->Flush(); 00363 AbortTransaction(); 00364 throw; 00365 } 00366 00367 guidchanged = true; 00368 } 00369 if(s != soldname || guidchanged) { 00370 if(ro) COMTHROW(E_MGA_READ_ONLY_ACCESS); 00371 COMTHROW(BeginTransaction(lm, TRANSACTION_GENERAL)); 00372 try { 00373 CoreObj dataroot; 00374 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 00375 dataroot[ATTRID_PARADIGM] = s; 00376 dataroot[ATTRID_PARGUID] = pGUID; 00377 dataroot[ATTRID_PARVERSION] = ver; 00378 COMTHROW(CommitTransaction()); 00379 opened = CHANGED; 00380 guidstat = DIRTY; 00381 } catch(hresult_exception &e) { 00382 lm->Flush(); 00383 AbortTransaction(); 00384 throw e; 00385 } 00386 } 00387 } 00388 else COMTHROW(E_INVALID_USAGE); 00389 StartAutoAddOns(); 00390 try { 00391 COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY)); 00392 GlobalNotify(GLOBALEVENT_OPEN_PROJECT); 00393 COMTHROW(lm->Flush()); 00394 COMTHROW(CommitTransaction()); 00395 } catch(hresult_exception &e) { 00396 lm->Flush(); 00397 AbortTransaction(); 00398 throw e; 00399 } 00400 MARKSIG('2'); 00401 } 00402 COMCATCH( 00403 opened = CLOSED; 00404 guidstat = CLEAN; 00405 if (dataproject) 00406 dataproject->CloseProject(VARIANT_TRUE); 00407 if (metapr) 00408 metapr->Close(); 00409 metapr = 0; 00410 projconn.Empty(); 00411 parconn.Empty(); 00412 // We've already called SetErrorInfo, don't call it again 00413 if (e.hr == E_MGA_COMPONENT_ERROR) { 00414 return e.hr; 00415 } 00416 ) 00417 } 00418 00419 STDMETHODIMP CMgaProject::Open(BSTR projectname, VARIANT_BOOL *ro_mode) 00420 { 00421 COMTRY { 00422 if(opened != CLOSED) COMTHROW(E_MGA_PROJECT_OPEN); 00423 CComBSTR s; 00424 CComVariant pGUID; 00425 CComBSTR ver; 00426 CComPtr<ICoreMetaProject> genericproject; 00427 CreateCoreMetaProject(genericproject, true); // will upgrade if old version 00428 00429 int undosize = getMaxUndoSize(); 00430 COMTHROW(dataproject->OpenProject2(projectname, undosize, genericproject, ro_mode)); 00431 00432 projconn = projectname; 00433 00434 opened = UNCHANGED; 00435 guidstat = CLEAN; 00436 CComPtr<IMgaTerritory> lm; 00437 COMTHROW(CreateTerritory(NULL, &lm)); 00438 COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY)); 00439 00440 try { 00441 00442 CoreObj dataroot; 00443 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 00444 s=dataroot[ATTRID_PARADIGM]; 00445 mgaversion = dataroot[ATTRID_MGAVERSION]; 00446 if( mgaversion <= 1L) // Core layer changed the project by adding ATTRID_GUID1..4 for CCoreBinFile 00447 opened = CHANGED; 00448 00449 pGUID=CComVariant(dataroot[ATTRID_PARGUID]); 00450 ver=dataroot[ATTRID_PARVERSION]; 00451 COMTHROW(lm->Flush()); 00452 COMTHROW(CommitTransaction()); 00453 } catch(hresult_exception &e) { 00454 lm->Flush(); 00455 AbortTransaction(); 00456 throw e; 00457 } 00458 00459 if(s.Length()) { 00460 HRESULT hr = S_OK; 00461 if (ver.Length()) { 00462 // Version string has precedence 00463 hr = OpenParadigm(s,ver); 00464 } 00465 else { 00466 OpenParadigm(s, &pGUID); 00467 } 00468 if (FAILED(hr)) 00469 { 00470 CComPtr<IErrorInfo> info; 00471 GetErrorInfo(0, &info); 00472 throw _com_error(hr, info, true); 00473 } 00474 } 00475 else COMTHROW(E_MGA_MODULE_INCOMPATIBILITY); 00476 00477 CComVariant nGUID; 00478 COMTHROW(metapr->get_GUID(&nGUID)); 00479 00480 if(guidcmp(pGUID, nGUID)) { 00481 COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY)); 00482 try { 00483 CComPtr<IMgaFolder> rf; 00484 COMTHROW(get_RootFolder(&rf)); 00485 COMTHROW(ObjFor(rf)->CheckTree()); 00486 rf = 0; 00487 COMTHROW(CommitTransaction()); 00488 } catch(hresult_exception &e) { 00489 lm->Flush(); 00490 AbortTransaction(); 00491 throw e; 00492 } 00493 00494 if (*ro_mode == VARIANT_FALSE) { 00495 COMTHROW(BeginTransaction(lm, TRANSACTION_GENERAL)); 00496 try { 00497 CoreObj dataroot; 00498 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 00499 dataroot[ATTRID_PARGUID] = nGUID; 00500 COMTHROW(CommitTransaction()); 00501 opened = CHANGED; 00502 guidstat = DIRTY; 00503 } catch(hresult_exception &e) { 00504 lm->Flush(); 00505 AbortTransaction(); 00506 throw e; 00507 } 00508 } 00509 } 00510 00511 StartAutoAddOns(); 00512 00513 try { 00514 COMTHROW(BeginTransaction(lm, TRANSACTION_READ_ONLY)); 00515 GlobalNotify(GLOBALEVENT_OPEN_PROJECT); 00516 COMTHROW(CommitTransaction()); 00517 } catch(hresult_exception &e) { 00518 lm->Flush(); 00519 AbortTransaction(); 00520 throw e; 00521 } 00522 00523 MARKSIG('2'); 00524 } 00525 COMCATCH( 00526 opened = CLOSED; 00527 if (dataproject) 00528 dataproject->CloseProject(VARIANT_TRUE); 00529 if (metapr) 00530 metapr->Close(); 00531 metapr = 0; 00532 projconn.Empty(); 00533 parconn.Empty(); 00534 // We've already called SetErrorInfo, don't call it again 00535 if (e.hr == E_MGA_COMPONENT_ERROR) { 00536 return e.hr; 00537 } 00538 ) 00539 } 00540 00541 STDMETHODIMP CMgaProject::QueryProjectInfo(BSTR projectname, long *mgaversion, 00542 BSTR *paradigmname, 00543 BSTR *parversion, 00544 VARIANT *paradigmGUID, 00545 VARIANT_BOOL *ro_mode) 00546 { 00547 CComPtr<ICoreProject> dp; 00548 COMTRY { 00549 CHECK_INSTRPAR(projectname); 00550 CHECK_OUTPAR(mgaversion); 00551 CHECK_OUTSTRPAR(paradigmname); 00552 CHECK_OUTSTRPAR(parversion); 00553 CHECK_OUTPAR(paradigmGUID); 00554 CHECK_OUTPAR(ro_mode); 00555 00556 CComPtr<ICoreMetaProject> genericproject; 00557 CreateCoreMetaProject(genericproject); // use mgaversion = 1 project model 00558 00559 COMTHROW(dp.CoCreateInstance(__uuidof(CoreProject))); 00560 COMTHROW(dp->OpenProject(projectname, genericproject, ro_mode)); 00561 00562 CComPtr<ICoreTerritory> tt; 00563 COMTHROW(dp->CreateTerritory(&tt)); 00564 COMTHROW(dp->BeginTransaction(TRANSTYPE_READFIRST)); 00565 00566 try { 00567 COMTHROW(dp->PushTerritory(tt)); 00568 00569 CoreObj dataroot; 00570 COMTHROW(dp->get_RootObject(&dataroot.ComPtr())); 00571 *paradigmname = CComBSTR(dataroot[ATTRID_PARADIGM]).Detach(); 00572 *parversion = CComBSTR(dataroot[ATTRID_PARVERSION]).Detach(); 00573 CComVariant(dataroot[ATTRID_PARGUID]).Detach(paradigmGUID); 00574 *mgaversion = dataroot[ATTRID_MGAVERSION]; 00575 COMTHROW(dp->PopTerritory()); 00576 } catch(hresult_exception &) { 00577 // FIXME 00578 ; 00579 } 00580 dp->AbortTransaction(TRANSTYPE_ANY); 00581 dp->CloseProject(VARIANT_FALSE); 00582 } 00583 COMCATCH( 00584 if(dp) dp->CloseProject(VARIANT_FALSE); 00585 ) 00586 } 00587 00588 STDMETHODIMP CMgaProject::Save(BSTR newname, VARIANT_BOOL keepoldname) 00589 { 00590 COMTRY { 00591 if(baseterr) 00592 COMTHROW(E_MGA_ALREADY_IN_TRANSACTION); 00593 { 00594 CComPtr<IMgaTerritory> t; 00595 COMTHROW(CreateTerritory(NULL, &t)); 00596 // if mga_ver<=1 the Core layer changed the project by adding ATTRID_GUID1..4 00597 // (mgaversion <= 1L) -> (opened >= CHANGED) 00598 ASSERT( !(mgaversion <= 1L) || opened >= CHANGED); 00599 00600 if(opened >= CHANGED) { 00601 COMTHROW(BeginTransaction(t, TRANSACTION_GENERAL)); 00602 try { 00603 CoreObj self; 00604 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00605 UpdateMGAVersion( self); 00606 FixupGUID(); 00607 GlobalNotify(GLOBALEVENT_SAVE_PROJECT); 00608 COMTHROW(CommitTransaction()); 00609 } catch(hresult_exception &) { 00610 t->Flush(); 00611 AbortTransaction(); 00612 } 00613 } 00614 } 00615 HRESULT hr = dataproject->SaveProject(newname, keepoldname); 00616 if (FAILED(hr)) 00617 return hr; 00618 if(CComBSTR(newname).Length()) { 00619 if (!keepoldname) { 00620 projconn = newname; 00621 opened = UNCHANGED; 00622 transactioncount = 0; 00623 } 00624 00625 } else { 00626 opened = UNCHANGED; 00627 transactioncount = 0; 00628 } 00629 } 00630 COMCATCH(;); 00631 } 00632 00633 STDMETHODIMP CMgaProject::Close(VARIANT_BOOL abort) 00634 { 00635 if(opened == CLOSED) { 00636 ASSERT(("Project is closed but transaction is active", !baseterr)); 00637 return S_OK; 00638 } 00639 00640 COMTRY { 00641 if(baseterr) COMTHROW(AbortTransaction()); 00642 { 00643 CComPtr<IMgaTerritory> t; 00644 COMTHROW(CreateTerritory(NULL, &t)); 00645 bool write = !abort && opened >= CHANGED; 00646 COMTHROW(BeginTransaction(t, write ? TRANSACTION_GENERAL : TRANSACTION_READ_ONLY)); 00647 try { 00648 if(write) { 00649 CoreObj self; 00650 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00651 FixupGUID(); 00652 } 00653 GlobalNotify(GLOBALEVENT_CLOSE_PROJECT); 00654 COMTHROW(CommitTransaction()); 00655 } catch(hresult_exception &) { 00656 t->Flush(); 00657 AbortTransaction(); 00658 } 00659 } 00660 00661 StopAutoAddOns(); // PETER: Moved these two lines here, otherwise addons won't receive notifications 00662 RemoveClients(); // 00663 00664 if(dataproject) COMTHROW(dataproject->CloseProject(abort)); 00665 00666 if(metapr) { 00667 COMTHROW(metapr->Close()); 00668 metapr = 0; 00669 } 00670 00671 MARKSIG('8'); 00672 opened = CLOSED; 00673 guidstat = CLEAN; 00674 projconn.Empty(); 00675 parconn.Empty(); 00676 transactioncount = 0; 00677 } 00678 COMCATCH( opened = CLOSEERROR;); // You cannot rollback a failed Close completely, so I did not even try it. 00679 } 00680 00681 #undef mgaproject 00682 00683 00684 // ---------------------------------------- 00685 // Access the root nodes of data and meta 00686 // ---------------------------------------- 00687 STDMETHODIMP CMgaProject::get_RootFolder(IMgaFolder **pVal) 00688 { 00689 COMTRY { 00690 CHECK_OUTPTRPAR(pVal); 00691 CoreObj dataroot; 00692 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 00693 CoreObjs s = dataroot[ATTRID_FPARENT + ATTRID_COLLECTION]; 00694 ITERATE_THROUGH(s) { 00695 CComPtr<ICoreMetaObject> m; 00696 metaid_type t; 00697 COMTHROW(ITER->get_MetaObject(&m)); 00698 COMTHROW(m->get_MetaID(&t)); 00699 if(t == DTID_FOLDER) { 00700 ObjForCore(ITER)->getinterface(pVal); 00701 break; 00702 } 00703 } 00704 if(*pVal == NULL) COMTHROW(E_MGA_MODULE_INCOMPATIBILITY); 00705 } 00706 COMCATCH(;); 00707 } 00708 00709 00710 STDMETHODIMP CMgaProject::get_RootMeta(IMgaMetaProject **pVal) 00711 { 00712 COMTRY { 00713 if(metapr == 0) COMTHROW( E_MGA_PROJECT_NOT_OPEN ); 00714 SetNmspaceInMeta(); 00715 *pVal = metapr; (*pVal)->AddRef(); 00716 } COMCATCH(;); 00717 } 00718 00719 // ---------------------------------------- 00720 // Filter and search functions 00721 // ---------------------------------------- 00722 HRESULT CMgaProject::CreateFilter(IMgaFilter **newfilter) { 00723 COMTRY { 00724 CHECK_OUTPTRPAR(newfilter); 00725 CComPtr<CMgaFilter> filter; 00726 CreateComObject(filter); 00727 filter->setproject(this); 00728 *newfilter = filter.Detach(); 00729 } COMCATCH(;); 00730 } 00731 00732 void recursefolders(CoreObj folder, CMgaFilter * filter, EXCOLLECTIONTYPE_FOR(MgaFCO) *q) { 00733 { 00734 ITERATE_THROUGH(folder[ATTRID_FCOPARENT+ATTRID_COLLECTION]) { 00735 if(ITER.IsFCO()) filter->searchFCOs(ITER, q); 00736 else recursefolders(ITER, filter, q); 00737 } 00738 } 00739 } 00740 00741 STDMETHODIMP CMgaProject::AllFCOs(IMgaFilter *filter, IMgaFCOs ** fcos) { 00742 COMTRY { 00743 CHECK_OUTPTRPAR(fcos); 00744 CHECK_INPTRPAR(filter); // project is checked in the following lines 00745 CComPtr<IMgaProject> p; 00746 COMTHROW(filter->get_Project(&p)); 00747 if(!COM_EQUAL(p, (IMgaProject *)this)) COMTHROW(E_MGA_FOREIGN_PROJECT); 00748 00749 CREATEEXCOLLECTION_FOR(MgaFCO, q); 00750 CComPtr<IMgaFolder> rootf; 00751 COMTHROW(get_RootFolder(&rootf)); 00752 recursefolders(CoreObj(rootf), reinterpret_cast<CMgaFilter *>(filter), q); 00753 *fcos = q.Detach(); 00754 } 00755 COMCATCH(;); 00756 } 00757 00758 STDMETHODIMP CMgaProject::GetFCOByID(BSTR id, IMgaFCO **pVal) { 00759 COMTRY { 00760 CComPtr<IMgaObject> p; 00761 COMTHROW(GetObjectByID(id,&p)); 00762 COMTHROW(p.QueryInterface(pVal)); 00763 } COMCATCH(;); 00764 } 00765 00766 STDMETHODIMP CMgaProject::GetObjectByID(BSTR id, IMgaObject **pVal) 00767 { 00768 00769 COMTRY { 00770 CHECK_INSTRPAR(id); 00771 CHECK_OUTPTRPAR(pVal); 00772 metaid_type mm; // short 00773 objid_type ss; // long 00774 if (SysStringLen(id) == 0) 00775 { 00776 COMTHROW(E_MGA_BAD_ID); 00777 } 00778 if( swscanf(id,OLESTR("id-%04hx-%08lx"), &mm, &ss) != 2 || 00779 mm < DTID_MODEL || mm > DTID_FOLDER) COMTHROW(E_MGA_BAD_ID); 00780 CoreObj obj; 00781 COMTHROW(dataproject->get_Object(mm,ss,&obj.ComPtr())); 00782 if (obj) 00783 ObjForCore(obj)->getinterface(pVal); 00784 else 00785 COMTHROW(E_MGA_BAD_ID); 00786 } COMCATCH(;); 00787 } 00788 00789 STDMETHODIMP CMgaProject::GetFCOsByName(BSTR name, IMgaFCOs **pVal) 00790 { 00791 00792 COMTRY { 00793 // ADD CODE 00794 // (*pVal)->Open() 00795 COMTHROW(E_MGA_NOT_IMPLEMENTED); 00796 } 00797 COMCATCH(;); 00798 } 00799 00800 STDMETHODIMP CMgaProject::GetFolderByPath(BSTR path, IMgaFolder **pVal) 00801 { 00802 00803 COMTRY { 00804 // ADD CODE 00805 // (*pVal)->Open() 00806 COMTHROW(E_MGA_NOT_IMPLEMENTED); 00807 } 00808 COMCATCH(;); 00809 } 00810 00811 // see FCO::get_ObjectByPath for details in MgaFolder.cpp 00812 STDMETHODIMP CMgaProject::get_ObjectByPath(BSTR path, IMgaObject **pVal) { 00813 COMTRY { 00814 CHECK_INSTRPAR(path); 00815 CHECK_OUTPTRPAR(pVal); 00816 CComPtr<IMgaFolder> f; 00817 COMTHROW(get_RootFolder(&f)); 00818 COMTHROW(f->get_ObjectByPath(path, pVal)); 00819 } COMCATCH(;); 00820 } 00821 00822 STDMETHODIMP CMgaProject::get_NthObjectByPath(long n_th, BSTR path, IMgaObject **pVal) { 00823 COMTRY { 00824 CHECK_INSTRPAR(path); 00825 CHECK_OUTPTRPAR(pVal); 00826 CComPtr<IMgaFolder> f; 00827 COMTHROW(get_RootFolder(&f)); 00828 COMTHROW(f->get_NthObjectByPath(n_th, path, pVal)); 00829 } COMCATCH(;); 00830 } 00831 00832 // ---------------------------------------- 00833 // Access project properties 00834 // ---------------------------------------- 00835 STDMETHODIMP CMgaProject::GetStatistics(BSTR *statstr) 00836 { 00837 00838 COMTRY { 00839 // ADD CODE 00840 } 00841 COMCATCH(;); 00842 } 00843 00844 00845 00846 STDMETHODIMP CMgaProject::get_CreateTime(BSTR *pVal) 00847 { 00848 00849 COMTRY { 00850 CoreObj self; 00851 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00852 *pVal = CComBSTR(self[ATTRID_CDATE]).Detach(); 00853 } 00854 COMCATCH(;); 00855 } 00856 00857 STDMETHODIMP CMgaProject::get_ChangeTime(BSTR *pVal) 00858 { 00859 00860 COMTRY { 00861 CoreObj self; 00862 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00863 *pVal = CComBSTR(self[ATTRID_MDATE]).Detach(); 00864 } 00865 COMCATCH(;); 00866 } 00867 00868 STDMETHODIMP CMgaProject::get_Author(BSTR *pVal) 00869 { 00870 00871 COMTRY { 00872 CoreObj self; 00873 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00874 *pVal = CComBSTR(self[ATTRID_CREATOR]).Detach(); 00875 } 00876 COMCATCH(;); 00877 } 00878 00879 STDMETHODIMP CMgaProject::put_Author(BSTR newVal) 00880 { 00881 00882 COMTRY_IN_TRANSACTION { 00883 CoreObj self; 00884 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00885 self[ATTRID_CREATOR] = newVal; 00886 notifyqueueprocessed = true; 00887 COMTHROW(GlobalNotify(GLOBALEVENT_PROJECT_PROPERTIES)); 00888 } 00889 COMCATCH_IN_TRANSACTION(;); 00890 } 00891 00892 STDMETHODIMP CMgaProject::get_MetaGUID(VARIANT *pVal) 00893 { 00894 00895 COMTRY 00896 { 00897 CHECK_OUTPAR(pVal); 00898 CoreObj self; 00899 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00900 CComVariant p = self[ATTRID_PARGUID]; 00901 00902 if( p.vt != (VT_UI1 | VT_ARRAY) || GetArrayLength(p) != sizeof(::GUID) ) 00903 { 00904 ::GUID guid; 00905 memset(&guid, 0, sizeof(::GUID)); 00906 00907 CopyTo(guid, p); 00908 } 00909 p.Detach(pVal); 00910 } 00911 COMCATCH(;) 00912 } 00913 00914 STDMETHODIMP CMgaProject::get_MetaName(BSTR *pVal) 00915 { 00916 00917 COMTRY 00918 { 00919 CHECK_OUTSTRPAR(pVal); 00920 CoreObj self; 00921 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00922 CComBSTR p = self[ATTRID_PARADIGM]; 00923 00924 *pVal=p.Detach(); 00925 } 00926 COMCATCH(;) 00927 } 00928 00929 STDMETHODIMP CMgaProject::get_MetaVersion(BSTR *pVal) 00930 { 00931 00932 COMTRY 00933 { 00934 CHECK_OUTSTRPAR(pVal); 00935 CoreObj self; 00936 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00937 CComBSTR p = self[ATTRID_PARVERSION]; 00938 00939 *pVal=p.Detach(); 00940 } 00941 COMCATCH(;) 00942 } 00943 00944 STDMETHODIMP CMgaProject::get_GUID(VARIANT *pVal) 00945 { 00946 00947 COMTRY 00948 { 00949 CHECK_OUTPAR(pVal); 00950 00951 FixupGUID(false); 00952 00953 CoreObj self; 00954 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00955 CComVariant p = self[ATTRID_GUID]; 00956 00957 00958 if (guidstat == PENDING) { 00959 p = pendingguid; 00960 } 00961 00962 if( p.vt != (VT_UI1 | VT_ARRAY) || GetArrayLength(p) != sizeof(::GUID) ) 00963 { 00964 ::GUID guid; 00965 memset(&guid, 0, sizeof(::GUID)); 00966 00967 CopyTo(guid, p); 00968 } 00969 p.Detach(pVal); 00970 } 00971 COMCATCH(;) 00972 } 00973 00974 00975 STDMETHODIMP CMgaProject::put_GUID(VARIANT newVal) 00976 { 00977 COMTRY_IN_TRANSACTION { 00978 CHECK_INPAR(newVal); 00979 CoreObj self; 00980 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 00981 00982 if( newVal.vt != (VT_UI1 | VT_ARRAY) || GetArrayLength(newVal) != sizeof(::GUID) ) 00983 COMTHROW(E_INVALIDARG); 00984 00985 self[ATTRID_GUID] = newVal; 00986 guidstat = MANUAL; 00987 notifyqueueprocessed = true; 00988 COMTHROW(GlobalNotify(GLOBALEVENT_PROJECT_PROPERTIES)); 00989 } 00990 COMCATCH_IN_TRANSACTION(;); 00991 } 00992 00993 00994 STDMETHODIMP CMgaProject::get_Comment(BSTR *pVal) 00995 { 00996 00997 COMTRY { 00998 CoreObj self; 00999 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 01000 *pVal = CComBSTR(self[ATTRID_EXTDATA]).Detach(); 01001 } 01002 COMCATCH(;); 01003 } 01004 01005 STDMETHODIMP CMgaProject::put_Comment(BSTR newVal) 01006 { 01007 01008 COMTRY_IN_TRANSACTION { 01009 CoreObj self; 01010 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 01011 self[ATTRID_EXTDATA] = newVal; 01012 notifyqueueprocessed = true; 01013 COMTHROW(GlobalNotify(GLOBALEVENT_PROJECT_PROPERTIES)); 01014 } 01015 COMCATCH_IN_TRANSACTION(;); 01016 } 01017 01018 STDMETHODIMP CMgaProject::put_Name(BSTR newVal) 01019 { 01020 01021 COMTRY_IN_TRANSACTION { 01022 CHECK_INSTRPAR(newVal); 01023 CoreObj self; 01024 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 01025 self[ATTRID_NAME] = newVal; 01026 notifyqueueprocessed = true; 01027 COMTHROW(GlobalNotify(GLOBALEVENT_PROJECT_PROPERTIES)); 01028 } 01029 COMCATCH_IN_TRANSACTION(;); 01030 } 01031 01032 STDMETHODIMP CMgaProject::put_Version(BSTR newVal) 01033 { 01034 01035 COMTRY_IN_TRANSACTION { 01036 CHECK_INSTRPAR(newVal); 01037 CoreObj self; 01038 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 01039 self[ATTRID_VERSION] = newVal; 01040 notifyqueueprocessed = true; 01041 COMTHROW(GlobalNotify(GLOBALEVENT_PROJECT_PROPERTIES)); 01042 } 01043 COMCATCH_IN_TRANSACTION(;); 01044 } 01045 01046 01047 STDMETHODIMP CMgaProject::get_Name(BSTR *pVal) 01048 { 01049 01050 COMTRY { 01051 CHECK_OUTSTRPAR(pVal); 01052 CoreObj self; 01053 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 01054 CComBSTR s = self[ATTRID_NAME]; 01055 *pVal = s.Detach(); 01056 } 01057 COMCATCH(;); 01058 } 01059 01060 STDMETHODIMP CMgaProject::get_Version(BSTR *pVal) 01061 { 01062 01063 COMTRY { 01064 CHECK_OUTSTRPAR(pVal); 01065 CoreObj self; 01066 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 01067 CComBSTR s = self[ATTRID_VERSION]; 01068 *pVal = s.Detach(); 01069 } 01070 COMCATCH(;); 01071 } 01072 01073 01074 STDMETHODIMP CMgaProject::get_ProjectConnStr(BSTR *pVal) 01075 { 01076 COMTRY { 01077 CHECK_OUTSTRPAR(pVal); 01078 CComBSTR s = projconn; 01079 *pVal = s.Detach(); 01080 } 01081 COMCATCH(;); 01082 } 01083 01084 STDMETHODIMP CMgaProject::get_ParadigmConnStr(BSTR *pVal) 01085 { 01086 COMTRY { 01087 CHECK_OUTSTRPAR(pVal); 01088 CComBSTR s = parconn; 01089 *pVal = s.Detach(); 01090 } 01091 COMCATCH(;); 01092 } 01093 01094 01096 // ---------------------------------------- 01097 // TRANSACTION HANDLING & NOTIFICATION 01098 // ----------------------------------------//////////////////////////////////////////////////////////////////////////////////////////// 01100 01101 01102 01103 STDMETHODIMP CMgaProject::CreateTerritory(IMgaEventSink *sink, IMgaTerritory **pp, IMgaEventSink *rwsink) { 01104 COMTRY { 01105 CHECK_OUTPTRPAR(pp); 01106 // MUST NOT RETURN 01107 CComPtr<ICoreTerritory> tt; 01108 COMTHROW(dataproject->CreateTerritory(&tt)); // terge ?? 01109 // MUST SUCCEED 01110 CComPtr< CMgaTerritory > ster; 01111 CreateComObject(ster); 01112 ster->coreterr = tt; 01113 ster->mgaproject = this;; 01114 allterrs.push_front(ster); 01115 ster->handler=sink; 01116 ster->rwhandler=rwsink; 01117 *pp = ster.Detach(); 01118 } 01119 COMCATCH(;); 01120 } 01121 01122 STDMETHODIMP CMgaProject::CreateTerritoryWithoutSink(IMgaTerritory **pp) { 01123 return CreateTerritory(NULL, pp, NULL); 01124 } 01125 01126 STDMETHODIMP CMgaProject::CreateAddOn(IMgaEventSink *sink, IMgaAddOn **pp) { 01127 COMTRY { 01128 CHECK_INPTRPAR(sink); 01129 CHECK_OUTPTRPAR(pp); 01130 // MUST NOT RETURN 01131 01132 01133 if(!reserveterr) { 01134 CComPtr<IMgaTerritory> r; 01135 COMTHROW(CreateTerritory(NULL, &r)); 01136 reserveterr = static_cast<CMgaTerritory *>(r.p); 01137 } 01138 // MUST SUCCEED 01139 CComPtr< CMgaAddOn > saddon; 01140 CreateComObject(saddon); 01141 saddon->mgaproject = this; 01142 saddon->progid = autoaddoncreate_progid; 01143 alladdons.push_front(saddon); 01144 saddon->handler=sink; 01145 if(inautoaddoncreate) { 01146 saddon->SetAutomatic(); 01147 } 01148 *pp = saddon.Detach(); 01149 } 01150 COMCATCH(;); 01151 01152 } 01153 01154 01155 01156 STDMETHODIMP CMgaProject::get_ActiveTerritory(IMgaTerritory **aterr) { 01157 COMTRY { 01158 CHECK_OUTPTRPAR(aterr); 01159 if((*aterr = baseterr) != NULL) (*aterr)->AddRef(); 01160 } COMCATCH(;) 01161 } 01162 01163 STDMETHODIMP CMgaProject::get_AddOns(IMgaAddOns **addons) { 01164 COMTRY { 01165 CHECK_OUTPTRPAR(addons); 01166 CREATECOLLECTION_FOR(IMgaAddOn, q); 01167 for(addoncoll::iterator j = alladdons.begin(); j != alladdons.end(); ++j) { 01168 q->Add(*j); 01169 } 01170 *addons = q.Detach(); 01171 } COMCATCH(;) 01172 } 01173 01174 STDMETHODIMP CMgaProject::get_Clients(IMgaClients **clients) { 01175 COMTRY { 01176 CHECK_OUTPTRPAR(clients); 01177 CREATECOLLECTION_FOR(IMgaClient, q); 01178 for(clientcoll::iterator j = allclients.begin(); j != allclients.end(); ++j) { 01179 q->Add(*j); 01180 } 01181 *clients = q.Detach(); 01182 } COMCATCH(;) 01183 } 01184 01185 STDMETHODIMP CMgaProject::RegisterClient(BSTR name, IDispatch *OLEServer, IMgaClient **pVal) { 01186 COMTRY { 01187 CHECK_INPTRPAR(OLEServer); 01188 CHECK_INSTRPAR(name); 01189 01190 CComPtr< CMgaClient > client; 01191 CreateComObject(client); 01192 client->active = true; 01193 client->mgaproject = this; 01194 client->ole_server = OLEServer; 01195 client->name = name; 01196 allclients.push_front(client); 01197 *pVal = client.Detach(); 01198 // TODO register only if not registered 01199 } 01200 COMCATCH(;); 01201 } 01202 01203 STDMETHODIMP CMgaProject::GetClientByName(BSTR name, IMgaClient **pVal) { 01204 COMTRY { 01205 CHECK_INSTRPAR(name); 01206 clientcoll::iterator j; 01207 for(j = allclients.begin(); j != allclients.end(); ++j) { 01208 CComPtr< CMgaClient > client(*j); 01209 if (client->name == name) { 01210 *pVal = client.Detach(); 01211 break; 01212 } 01213 } 01214 if(j == allclients.end()) 01215 return E_MGA_NAME_NOT_FOUND; 01216 } 01217 COMCATCH(;); 01218 } 01219 01220 01221 STDMETHODIMP CMgaProject::get_Territories(IMgaTerritories **terrs) { 01222 COMTRY { 01223 CHECK_OUTPTRPAR(terrs); 01224 CREATECOLLECTION_FOR2(IMgaTerritory, IMgaTerritories, q); 01225 for(tercoll::iterator j = allterrs.begin(); j != allterrs.end(); ++j) { 01226 q->Add(*j); 01227 } 01228 *terrs = q.Detach(); 01229 } COMCATCH(;) 01230 } 01231 01232 STDMETHODIMP CMgaProject::get_AddOnComponents(IMgaComponents **comps) { 01233 COMTRY { 01234 CHECK_OUTPTRPAR(comps); 01235 CREATECOLLECTION_FOR(IMgaComponent, q); 01236 for(compcoll::iterator j = autocomps.begin(); j != autocomps.end(); ++j) { 01237 q->Add(*j); 01238 } 01239 *comps = q.Detach(); 01240 } COMCATCH(;) 01241 } 01242 01243 STDMETHODIMP CMgaProject::EnableAutoAddOns(VARIANT_BOOL bEnable) { 01244 COMTRY { 01245 if(baseterr) COMTHROW(E_MGA_ALREADY_IN_TRANSACTION); 01246 bool bnew = (bEnable == VARIANT_TRUE); 01247 if(bnew == autoaddons) return S_OK; 01248 autoaddons = bnew; 01249 if(opened != CLOSED) { 01250 if(autoaddons) StartAutoAddOns(); 01251 else StopAutoAddOns(); 01252 } 01253 } COMCATCH(;) 01254 } 01255 01256 01257 void CMgaProject::StartAutoAddOns() { 01258 if(!autoaddons) return; 01259 #ifdef DEBUG 01260 for(addoncoll::iterator j = alladdons.begin(); j != alladdons.end(); ++j) { 01261 ASSERT(!(*j)->IsAutomatic()); 01262 } 01263 #endif 01264 CComPtr<IMgaRegistrar> reg; 01265 CComBSTR paradigm; 01266 COMTHROW(metapr->get_Name(¶digm)); 01267 CComVariant progids; 01268 COMTHROW(reg.CoCreateInstance(OLESTR("Mga.MgaRegistrar"))); 01269 COMTHROW(reg->get_AssociatedComponents(paradigm, COMPONENTTYPE_ADDON, REGACCESS_BOTH, &progids)); 01270 long p = GetArrayLength(progids); 01271 ASSERT(p >= 0); 01272 if(p) { 01273 std::vector<CComBstrObj> vec; 01274 vec.resize(p); 01275 CopyTo(progids, &vec[0], (&vec[0])+vec.size()); 01276 inautoaddoncreate = true; 01277 CComBSTR errs; 01278 for(std::vector<CComBstrObj>::iterator i = vec.begin(); i < vec.end(); ++i) { 01279 try { 01280 CComPtr<IMgaComponent> addon; 01281 autoaddoncreate_progid = *i; 01282 COMTHROW(CreateMgaComponent(addon, *i)); // Was: COMTHROW( addon.CoCreateInstance(*i) ); 01283 ASSERT( addon != NULL ); 01284 01285 COMTHROW( addon->Initialize(this)); 01286 autocomps.push_front(addon.Detach()); 01287 } catch(hresult_exception &e) { 01288 BSTR err = NULL; 01289 GetErrorInfo(e.hr, &err); 01290 errs += " "; 01291 errs += i->p; 01292 errs += ": "; 01293 errs += err; 01294 } 01295 } 01296 inautoaddoncreate = false; 01297 autoaddoncreate_progid = L""; 01298 if (errs) { 01299 SetErrorInfo(_bstr_t(L"Could not create AddOn: ") + static_cast<const wchar_t*>(errs)); 01300 COMTHROW(E_MGA_COMPONENT_ERROR); // change error type 01301 } 01302 } 01303 // SetAutomatic(); 01304 01305 } 01306 01307 01308 MIDL_INTERFACE("805D7A98-D4AF-3F0F-967F-E5CF45312D2C") 01309 IDisposable : public IDispatch { 01310 public: 01311 virtual VOID STDMETHODCALLTYPE Dispose() = 0; 01312 }; 01313 01314 void CMgaProject::StopAutoAddOns() { 01315 while(!autocomps.empty()) { 01316 CComPtr<IMgaComponent> addon; 01317 addon.Attach(autocomps.front()); 01318 autocomps.pop_front(); 01319 CComPtr<IDisposable> disposable; 01320 if (SUCCEEDED(addon->QueryInterface(&disposable))) 01321 { 01322 disposable->Dispose(); 01323 } 01324 addon.Release(); 01325 } 01326 #ifdef DEBUG 01327 for(addoncoll::iterator j = alladdons.begin(); j != alladdons.end();++j) { 01328 ASSERT(!(*j)->IsAutomatic()); 01329 } 01330 #endif 01331 } 01332 01333 void CMgaProject::RemoveClients() { 01334 while(!allclients.empty()) { 01335 CComPtr< CMgaClient > client; 01336 client = allclients.front(); 01337 client->active = false; 01338 allclients.pop_front(); 01339 } 01340 } 01341 01342 01343 STDMETHODIMP CMgaProject::get_ProjectStatus(long *status) { 01344 COMTRY { 01345 CHECK_OUTPAR(status); 01346 if(opened == CLOSED) { 01347 *status = 0; 01348 } 01349 else if(opened == CLOSEERROR) { 01350 *status = 0x80000000; 01351 } 01352 else { 01353 *status = 1 + (opened == CHANGED ? 4 : 0) + (baseterr ? 8 : 0) + (read_only ? 16 : 0); 01354 } 01355 } COMCATCH(;); 01356 } 01357 01358 STDMETHODIMP CMgaProject::BeginTransaction(IMgaTerritory *ter, transactiontype_enum mode) 01359 { 01360 COMTRY { 01361 ASSERT(temporalobjs.empty()); 01362 while (temporalobjs.size()) 01363 temporalobjs.pop(); 01364 ASSERT(changedobjs.empty()); 01365 while (changedobjs.size()) 01366 changedobjs.pop(); 01367 ASSERT(notifyobjs.empty()); 01368 while (notifyobjs.size()) 01369 notifyobjs.pop(); 01370 CComPtr<IMgaTerritory> ttemp; 01371 if(baseterr) 01372 COMTHROW(E_MGA_ALREADY_IN_TRANSACTION); 01373 if(!ter) { 01374 COMTHROW(CreateTerritory(NULL,&ttemp)); 01375 ter = ttemp; 01376 } 01377 ASSERT(mode == TRANSACTION_GENERAL || mode == TRANSACTION_READ_ONLY || mode == TRANSACTION_NON_NESTED); 01378 CComPtr<IMgaProject> p; 01379 COMTHROW(ter->get_Project(&p)); 01380 if (p != this) 01381 COMTHROW(E_MGA_FOREIGN_OBJECT); 01382 CMgaTerritory *t = static_cast<CMgaTerritory *>(ter); 01383 if (!t->coreterr) 01384 COMTHROW(E_MGA_TARGET_DESTROYED); 01385 read_only = (mode == TRANSACTION_READ_ONLY); 01386 non_nestable = (mode == TRANSACTION_NON_NESTED); 01387 // this call fails if the project has been closed (maybe we're being called by an FCO destructor) 01388 HRESULT hr = dataproject->BeginTransaction(read_only? TRANSTYPE_READFIRST : TRANSTYPE_FIRST); 01389 if (FAILED(hr)) 01390 COMRETURN(hr); 01391 checkofftemporary = false; 01392 in_nested = false; 01393 must_abort = false; 01394 hr = dataproject->PushTerritory(t->coreterr); 01395 if (FAILED(hr)) 01396 COMRETURN(hr); 01397 baseterr = activeterr = t; 01398 notifyqueueprocessed = false; 01399 MARKSIG('3'); 01400 } 01401 COMCATCH(;); 01402 } 01403 01404 STDMETHODIMP CMgaProject::BeginTransactionInNewTerr( transactiontype_enum mode, IMgaTerritory **ter) 01405 { 01406 COMTRY { 01407 if(baseterr) COMTHROW(E_MGA_ALREADY_IN_TRANSACTION); 01408 01409 // create a new territory 01410 CComPtr<IMgaTerritory> ttemp; 01411 COMTHROW(CreateTerritory(NULL,&ttemp)); 01412 01413 // begin transaction 01414 BeginTransaction( ttemp, mode); 01415 01416 // [out, return] parameter 01417 *ter = ttemp.Detach(); 01418 } 01419 COMCATCH(;); 01420 } 01421 01422 STDMETHODIMP CMgaProject::CommitTransaction() 01423 { 01424 COMTRY { 01425 ASSERT(!in_nested); 01426 if (!baseterr) 01427 COMTHROW(E_MGA_NOT_IN_TRANSACTION); 01428 if (checkoff) 01429 COMTHROW(CheckSupress(VARIANT_FALSE)); 01430 while (!temporalobjs.empty()) { 01431 temporalobjs.front()->objrecordchange(); 01432 temporalobjs.pop(); 01433 } 01434 if(!notifyobjs.empty()) { 01435 CoreObj self; 01436 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 01437 // self[ATTRID_MDATE] = Now(); 01438 } 01439 HRESULT hr = CommitNotify(); 01440 if (!temporalobjs.empty()) // CommitNotify may make changes. Notify only territories 01441 { 01442 while (!temporalobjs.empty()) { 01443 temporalobjs.front()->objrecordchange(); 01444 temporalobjs.pop(); 01445 } 01446 while (!changedobjs.empty()) { 01447 FCOPtr f = changedobjs.front(); 01448 changedobjs.pop(); 01449 } 01450 CommitNotify(); 01451 ASSERT(temporalobjs.empty()); 01452 } 01453 if (FAILED(hr)) 01454 return hr; 01455 COMTHROW(dataproject->PopTerritory()); 01456 short nestedCount; 01457 COMTHROW(dataproject->get_NestedTransactionCount(&nestedCount)); 01458 if (nestedCount == 1 && !read_only) 01459 COMTHROW(GlobalNotify(GLOBALEVENT_COMMIT_TRANSACTION)); 01460 COMTHROW(dataproject->CommitTransaction(read_only ? TRANSTYPE_READFIRST: TRANSTYPE_FIRST)); 01461 baseterr = activeterr= NULL; 01462 read_only = false; 01463 01464 if(notifyqueueprocessed) { 01465 transactioncount++; 01466 opened = CHANGED; 01467 if (guidstat == MANUAL) { 01468 guidstat = CLEAN; 01469 } 01470 else { 01471 guidstat = DIRTY; 01472 } 01473 } 01474 MARKSIG('7'); 01475 } 01476 COMCATCH(;); 01477 } 01478 01479 01480 01481 STDMETHODIMP CMgaProject::AbortTransaction() { 01482 COMTRY { 01483 ASSERT(!in_nested); 01484 if(!baseterr) COMTHROW(E_MGA_NOT_IN_TRANSACTION); 01485 aurcnt++; 01486 //COMTHROW(dataproject->PopTerritory()); BGY: see committransaction, it is already popped 01487 COMTHROW(dataproject->AbortTransaction(read_only ? TRANSTYPE_READFIRST:TRANSTYPE_FIRST)); 01488 baseterr = activeterr= NULL; 01489 deferredchecks.clear(); 01490 checkoff = false; 01491 while(!changedobjs.empty()) { 01492 changedobjs.front()->objforgetrwnotify(); 01493 changedobjs.front()->apool.clear(); 01494 changedobjs.pop(); 01495 } 01496 while(!notifyobjs.empty()) { 01497 notifyobjs.front()->objforgetnotify(); 01498 notifyobjs.pop(); 01499 } 01500 while(!temporalobjs.empty()) { 01501 temporalobjs.front()->objforgetchange(); 01502 temporalobjs.pop(); 01503 } 01504 read_only = true; 01505 { 01506 CComPtr<IMgaTerritory> t; 01507 COMTHROW(CreateTerritory(NULL, &t)); 01508 // If this fails, Mga likely didn't close a nested tx 01509 // ASSERT(dataproject->GetNestedTrCount == 1) 01510 COMTHROW(BeginTransaction(t, TRANSACTION_READ_ONLY)); 01511 GlobalNotify(GLOBALEVENT_ABORT_TRANSACTION); 01512 COMTHROW(CommitTransaction()); 01513 } 01514 read_only = false; 01515 MARKSIG('6'); 01516 } 01517 COMCATCH(read_only = false;); 01518 } 01519 01520 01521 STDMETHODIMP CMgaProject::CheckSupress(VARIANT_BOOL s) { 01522 COMTRY_IN_TRANSACTION { 01523 if (s) 01524 checkoff = true; 01525 else 01526 { 01527 for(objhash::iterator i = deferredchecks.begin(); i != deferredchecks.end(); ++i) { 01528 if (GetMetaID((*i)->self) == DTID_FOLDER) 01529 COMTHROW((*i)->Check()); 01530 else 01531 (*i)->CheckRCS(); 01532 } 01533 deferredchecks.clear(); 01534 checkoff = false; 01535 } 01536 } COMCATCH_IN_TRANSACTION(;); 01537 } 01538 01539 01540 STDMETHODIMP CMgaProject::GlobalNotify(globalevent_enum msg) { 01541 COMTRY { 01542 { 01543 addoncoll::iterator i = alladdons.begin(), end = alladdons.end(); 01544 if(i != end) { 01545 COMTHROW(pushterr(*reserveterr)); 01546 // The addon may Destroy() itself or release a reference while being notified 01547 // But other addons are expected to remain in the list 01548 while(i != end) { 01549 CComPtr<CMgaAddOn> addon(*i++); // set the iterator to the next addon (since it may be deleted) 01550 if(msg == GLOBALEVENT_NOTIFICATION_READY && addon->notified == false) continue; 01551 if(addon->handler->GlobalEvent(msg)!= S_OK) { 01552 ASSERT(("Global notification failed", false)); 01553 } 01554 } 01555 COMTHROW(popterr()); 01556 } 01557 } 01558 tercoll::iterator i = allterrs.begin(), end = allterrs.end(); 01559 for(;i != end; ++i) { 01560 if(msg == GLOBALEVENT_NOTIFICATION_READY && (*i)->notified == false) continue; 01561 else (*i)->notified = false; 01562 if((*i)->handler) { 01563 COMTHROW(pushterr(**i)); 01564 (*i)->handler->GlobalEvent(msg); // Silently ignore failures 01565 COMTHROW(popterr()); 01566 } 01567 } 01568 } COMCATCH(;); 01569 } 01570 01571 STDMETHODIMP CMgaProject::Notify(globalevent_enum event) { 01572 COMTRY { 01573 if (baseterr) 01574 COMTHROW(E_MGA_ALREADY_IN_TRANSACTION); 01575 01576 CComPtr<IMgaTerritory> t; 01577 COMTHROW(CreateTerritory(NULL, &t)); 01578 COMTHROW(BeginTransaction(t, TRANSACTION_READ_ONLY)); 01579 GlobalNotify(event); 01580 COMTHROW(CommitTransaction()); 01581 } 01582 COMCATCH(;); 01583 } 01584 01585 01586 STDMETHODIMP CMgaProject::CommitNotify() { 01587 if(read_only) { 01588 ASSERT(changedobjs.empty() && notifyobjs.empty()); 01589 return S_OK; 01590 } 01591 COMTRY { 01592 if(!baseterr) 01593 COMTHROW(E_MGA_NOT_IN_TRANSACTION); 01594 01595 if(!changedobjs.empty()) 01596 notifyqueueprocessed = true; 01597 while(!changedobjs.empty()) { 01598 FCOPtr f = changedobjs.front(); 01599 changedobjs.pop(); 01600 01601 HRESULT hr = f->objrwnotify(); 01602 if (FAILED(hr)) 01603 { 01604 read_only = false; 01605 return hr; 01606 } 01607 } 01608 01609 read_only = true; 01610 while(!notifyobjs.empty()) { 01611 FCOPtr f = notifyobjs.front(); 01612 notifyobjs.pop(); 01613 if(f->objnotify() != S_OK) { 01614 ASSERT(("Notification failed", false)); 01615 } 01616 } 01617 COMTHROW(GlobalNotify(GLOBALEVENT_NOTIFICATION_READY)); 01618 read_only = false; 01619 } COMCATCH( read_only = false;); 01620 } 01621 01622 01623 01624 bool CMgaProject::alreadynested() { return in_nested; } 01625 01626 HRESULT CMgaProject::beginnested() { 01627 ASSERT(!in_nested); 01628 01629 ASSERT(objstocheck.empty()); 01630 objstocheck.clear(); 01631 01632 HRESULT hr; 01633 if (non_nestable) 01634 hr = must_abort ? E_MGA_MUST_ABORT : S_OK; 01635 else 01636 hr = dataproject->BeginTransaction(TRANSTYPE_NESTED); 01637 01638 MARKSIG('4'); 01639 if (hr == S_OK) 01640 in_nested = true; 01641 return hr; 01642 } 01643 01644 HRESULT CMgaProject::commitnested() { 01645 ASSERT(in_nested); 01646 01647 ASSERT(objstocheck.empty()); 01648 objstocheck.clear(); 01649 01650 HRESULT hr = S_OK; 01651 if (!non_nestable) 01652 hr = dataproject->CommitTransaction(TRANSTYPE_NESTED); 01653 MARKSIG('6'); 01654 if (hr != S_OK) 01655 abortnested(); 01656 else { 01657 in_nested = false; 01658 while(!temporalobjs.empty()) { 01659 temporalobjs.front()->objrecordchange(); 01660 temporalobjs.pop(); 01661 } 01662 } 01663 return hr; 01664 } 01665 01666 HRESULT CMgaProject::abortnested() { 01667 ASSERT(in_nested); 01668 objstocheck.clear(); 01669 in_nested = false; 01670 while(!temporalobjs.empty()) { 01671 temporalobjs.front()->objforgetchange(); 01672 temporalobjs.pop(); 01673 } 01674 MARKSIG('5'); 01675 must_abort = true; 01676 if (non_nestable) 01677 return S_OK; 01678 else 01679 return dataproject->AbortTransaction(TRANSTYPE_NESTED); 01680 } 01681 01682 01683 HRESULT CMgaProject::pushterr(CMgaTerritory &ter) { 01684 COMTRY { 01685 ASSERT(("Territorys overwrite each other",activeterr==baseterr)); 01686 activeterr = &ter; 01687 COMTHROW(dataproject->PushTerritory(ter.coreterr)); 01688 } COMCATCH(;); 01689 } 01690 01691 HRESULT CMgaProject::popterr() { 01692 COMTRY { 01693 activeterr= baseterr; 01694 COMTHROW(dataproject->PopTerritory()); 01695 } COMCATCH(;); 01696 } 01697 01698 01699 01700 STDMETHODIMP CMgaProject::Undo() { 01701 COMTRY { 01702 if(baseterr) COMTHROW(E_MGA_ALREADY_IN_TRANSACTION); 01703 COMTHROW(dataproject->UndoTransaction()); 01704 if(!--transactioncount) { 01705 opened = UNCHANGED; 01706 guidstat = CLEAN; 01707 } 01708 { 01709 aurcnt++; 01710 CComPtr<IMgaTerritory> t; 01711 COMTHROW(CreateTerritory(NULL, &t)); 01712 COMTHROW(BeginTransaction(t, TRANSACTION_READ_ONLY)); 01713 GlobalNotify(GLOBALEVENT_UNDO); 01714 COMTHROW(CommitTransaction()); 01715 } 01716 } 01717 COMCATCH(;); 01718 } 01719 01720 STDMETHODIMP CMgaProject::Redo() { 01721 01722 COMTRY { 01723 if(baseterr) COMTHROW(E_MGA_ALREADY_IN_TRANSACTION); 01724 COMTHROW(dataproject->RedoTransaction()); 01725 transactioncount++; 01726 opened = CHANGED; 01727 guidstat = DIRTY; 01728 { 01729 aurcnt++; 01730 CComPtr<IMgaTerritory> t; 01731 COMTHROW(CreateTerritory(NULL, &t)); 01732 COMTHROW(BeginTransaction(t, TRANSACTION_READ_ONLY)); 01733 GlobalNotify(GLOBALEVENT_REDO); 01734 COMTHROW(CommitTransaction()); 01735 } 01736 } 01737 COMCATCH(;); 01738 } 01739 01740 STDMETHODIMP CMgaProject::UndoRedoSize(short *undosize, short *redosize ) { 01741 COMTRY { 01742 COMTHROW(dataproject->get_UndoQueueSize(undosize)); 01743 COMTHROW(dataproject->get_RedoQueueSize(redosize)); 01744 } 01745 COMCATCH(;); 01746 } 01747 01748 01749 STDMETHODIMP CMgaProject::FlushUndoQueue() { 01750 01751 if( dataproject == NULL ) 01752 COMRETURN(E_FAIL); 01753 01754 COMTRY { 01755 if(baseterr) COMTHROW(E_MGA_ALREADY_IN_TRANSACTION); 01756 COMTHROW( dataproject->FlushUndoQueue() ); 01757 } 01758 COMCATCH(;) 01759 } 01760 01761 STDMETHODIMP CMgaProject::UpdateSourceControlInfo( BSTR param) 01762 { 01763 CComPtr<IMgaTerritory> lm; 01764 COMTRY { 01765 COMTHROW(CreateTerritory(NULL, &lm)); 01766 COMTHROW(BeginTransaction(lm, TRANSACTION_GENERAL)); 01767 01768 // hack: core will recognize this action as a source control status update 01769 CComBSTR hack_str = "UpdateSourceControlInfo"; 01770 CComBSTR para_str( param); 01771 if( para_str.Length() > 0) 01772 COMTHROW(hack_str.Append( para_str)); 01773 CoreObj dataroot; 01774 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 01775 dataroot[ATTRID_MDATE] = hack_str; 01776 01777 COMTHROW(CommitTransaction()); 01778 } 01779 COMCATCH(;) 01780 } 01781 01782 STDMETHODIMP CMgaProject::SourceControlActiveUsers() 01783 { 01784 CComPtr<IMgaTerritory> lm; 01785 COMTRY { 01786 COMTHROW(CreateTerritory(NULL, &lm)); 01787 COMTHROW(BeginTransaction(lm, TRANSACTION_GENERAL)); 01788 01789 // hack: core will recognize this value as a command, will show a dlg with user names 01790 CComBSTR hack_str = "ShowActiveUsers"; 01791 01792 CoreObj dataroot; 01793 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 01794 dataroot[ATTRID_MDATE] = hack_str; 01795 01796 COMTHROW(CommitTransaction()); 01797 01798 } 01799 COMCATCH(;) 01800 } 01801 01802 STDMETHODIMP CMgaProject::SourceControlObjectOwner( BSTR p_optionalID) 01803 { 01804 CComPtr<IMgaTerritory> lm; 01805 COMTRY { 01806 COMTHROW(CreateTerritory(NULL, &lm)); 01807 COMTHROW(BeginTransaction(lm, TRANSACTION_GENERAL)); 01808 01809 // hack: core will recognize this value as a command, will show a dlg with owneruser 01810 CComBSTR hack_str = "WhoControlsThisObj"; 01811 CComBSTR para_str( p_optionalID); 01812 if( para_str.Length() > 0) 01813 COMTHROW(hack_str.Append( para_str)); 01814 CoreObj dataroot; 01815 COMTHROW(dataproject->get_RootObject(&dataroot.ComPtr())); 01816 dataroot[ATTRID_MDATE] = hack_str; 01817 01818 COMTHROW(CommitTransaction()); 01819 } 01820 COMCATCH(;) 01821 } 01822 01823 void CMgaProject::ObjMark(IMgaObject *s, long mask) { 01824 ObjFor(s)->SelfMark(mask); 01825 } 01826 01827 void CMgaProject::FixupGUID(bool write) { 01828 if (guidstat == DIRTY) { 01829 ::GUID newGUID; 01830 COMTHROW(CoCreateGuid(&newGUID)); 01831 pendingguid.Clear(); 01832 CopyTo(newGUID, pendingguid); 01833 guidstat = PENDING; 01834 } 01835 if ((guidstat == PENDING) && write) { 01836 ASSERT(baseterr); 01837 CoreObj self; 01838 COMTHROW(dataproject->get_RootObject(&self.ComPtr())); 01839 self[ATTRID_GUID] = pendingguid; 01840 guidstat = CLEAN; 01841 } 01842 } 01843 01844 void CMgaProject::UpdateMGAVersion(CoreObj& p_dataroot) 01845 { 01846 mgaversion = p_dataroot[ATTRID_MGAVERSION]; 01847 if( mgaversion <= 1L) 01848 { 01849 // update done by CreateCoreMetaProject so update the ATTRID_MGAVERSION too 01850 mgaversion = p_dataroot[ATTRID_MGAVERSION] = 2L; 01851 } 01852 } 01853 01854 void CMgaProject::SetNmspaceInMeta() 01855 { 01856 try { 01857 ASSERT( metapr); 01858 if( metapr) 01859 { 01860 COMTHROW( metapr->SetNmspc( getNmspc())); 01861 } 01862 } 01863 catch( hresult_exception& ) { 01864 ASSERT(0); 01865 } 01866 } 01867 01868 01869 CComBSTR CMgaProject::getNmspc() 01870 { 01871 CComBSTR bstr_nm; 01872 try { 01873 CComPtr<IMgaTerritory> terr; 01874 COMTHROW( get_ActiveTerritory( &terr)); 01875 if( terr) 01876 { 01877 COMTHROW( terr->GetNamespace( &bstr_nm)); 01878 } 01879 } 01880 catch( hresult_exception& ) { 01881 bstr_nm.Empty(); 01882 } 01883 return bstr_nm; 01884 } 01885 01886 CComBSTR CMgaProject::prefixWNmspc( CComBSTR pKindname) 01887 { 01888 CComBSTR kindname_m; 01889 CComBSTR nm = getNmspc(); 01890 if( nm.Length() > 0)// or if not found('::') 01891 { 01892 COMTHROW(kindname_m.AppendBSTR( nm)); 01893 COMTHROW(kindname_m.Append( "::")); 01894 } 01895 01896 COMTHROW(kindname_m.AppendBSTR( pKindname)); 01897 01898 return kindname_m; 01899 } 01900 01901 STDMETHODIMP CMgaProject::CheckCollection(IMgaFCOs *coll) { 01902 COMTRY { 01903 MGACOLL_ITERATE(IMgaFCO, coll) { 01904 HRESULT s; 01905 if((s = MGACOLL_ITER->CheckProject(this)) != S_OK) return s; 01906 } 01907 MGACOLL_ITERATE_END; 01908 } 01909 COMCATCH(;) 01910 } 01911 01912 // by ZolMol 01913 STDMETHODIMP CMgaProject::CheckFolderCollection(IMgaFolders *coll) { 01914 COMTRY { 01915 MGACOLL_ITERATE(IMgaFolder, coll) { 01916 HRESULT s; 01917 if((s = MGACOLL_ITER->CheckProject(this)) != S_OK) return s; 01918 } 01919 MGACOLL_ITERATE_END; 01920 } 01921 COMCATCH(;) 01922 } 01923 01924 01925 01926 01927 01928 01929 01930 01931 01932 01933 01934 01935 01936 01937 01938 // ---------------------------------------- 01939 // OBSOLETE stuff: Clearlocks 01940 // ---------------------------------------- 01941 01942 #include <set> 01943 #include "../core/CoreUtilities.h" 01944 01945 bool 01946 #if _MSC_VER >= 1700 01947 constexpr 01948 #endif 01949 std::less<metaobjidpair_type>::operator ()(const metaobjidpair_type &a,const metaobjidpair_type &b) const { 01950 return (a.metaid == b.metaid) ? a.objid < b.objid : a.metaid < b.metaid; 01951 } 01952 01953 void ClearLocks(ICoreStorage * storage, std::set<metaobjidpair_type> &mset, short mi, long oi, bool clear) { 01954 01955 metaobjidpair_type mm; 01956 mm.metaid = mi, mm.objid = oi; 01957 01958 if(mset.find(mm) != mset.end()) return; 01959 mset.insert(mm); 01960 CComPtr<ICoreMetaProject> mp; 01961 COMTHROW(storage->get_MetaProject(&mp)); 01962 CComPtr<ICoreMetaObject> mo; 01963 COMTHROW(mp->get_Object(mi, &mo)); 01964 CComPtr<ICoreMetaAttributes> atts; 01965 COMTHROW(mo->get_Attributes(&atts)); 01966 long count = 0; 01967 COMTHROW( atts->get_Count(&count) ); 01968 std::unique_ptr<CComPtr<ICoreMetaAttribute>[]> array(new CComPtr<ICoreMetaAttribute>[count]); 01969 CComPtr<ICoreMetaAttribute> *arrptr, *arrend = array.get(); 01970 if(count > 0) { 01971 COMTHROW( atts->GetAll((unsigned long)count, &(*array.get())) ); 01972 } 01973 arrend = array.get()+count; 01974 for(arrptr = array.get(); arrptr != arrend; arrptr++) { 01975 unsigned char t; 01976 COMTHROW((*arrptr)->get_ValueType(&t)); 01977 switch(t) { 01978 case VALTYPE_LOCK: 01979 COMTHROW(storage->put_MetaID(mi)); 01980 COMTHROW(storage->OpenObject(oi)); 01981 COMTHROW(storage->put_MetaAttribute((*arrptr))); 01982 { 01983 CComVariant vv; 01984 COMTHROW(storage->get_AttributeValue(&vv)); 01985 ASSERT(vv.vt == VT_I2); 01986 if(vv.iVal) { 01987 COMTHROW(storage->put_AttributeValue(CComVariant(0))); 01988 } 01989 } 01990 break; 01991 case VALTYPE_COLLECTION: 01992 COMTHROW(storage->put_MetaID(mi)); 01993 COMTHROW(storage->OpenObject(oi)); 01994 COMTHROW(storage->put_MetaAttribute((*arrptr))); 01995 { 01996 CComVariant v; 01997 COMTHROW(storage->get_AttributeValue(&v)); 01998 metaobjidpair_type *i = NULL; 01999 metaobjidpair_type *e = NULL; 02000 GetArrayBounds(v, i, e); 02001 while( i != e ) { 02002 ClearLocks(storage, mset, (short)(*i).metaid, (*i).objid, clear); 02003 i++; 02004 } 02005 } 02006 } 02007 } 02008 } 02009 02010 02011 02012 STDMETHODIMP CMgaProject::CheckLocks(BSTR filename, VARIANT_BOOL clearlocks) { 02013 CComPtr<ICoreStorage> storage; 02014 CComPtr<ICoreMetaProject> genericproject; 02015 COMTRY { 02016 CreateCoreMetaProject(genericproject); // use mgaversion = 1 project model 02017 COMTHROW(storage.CoCreateInstance( OLESTR("Mga.CoreRepository"))); 02018 COMTHROW(storage->put_MetaProject(genericproject)); 02019 COMTHROW(storage->OpenProject(filename, NULL)); 02020 COMTHROW(storage->BeginTransaction()); 02021 std::set<metaobjidpair_type> ccc; 02022 ClearLocks(storage, ccc, 1, 1, clearlocks ? true : false); 02023 COMTHROW(storage->CommitTransaction()); 02024 } COMCATCH(;) 02025 } 02026 02027 int CMgaProject::getMaxUndoSize() 02028 { 02029 int retval = 10; // keep in sync with the default value in CoreProject.h 02030 try 02031 { 02032 CComPtr<IMgaRegistrar> mgareg; 02033 COMTHROW(mgareg.CoCreateInstance(OLESTR("Mga.MgaRegistrar"))); 02034 CComBSTR undo_size; 02035 COMTHROW( mgareg->GetUndoQueueSize( REGACCESS_USER, &undo_size)); 02036 if (undo_size != NULL && undo_size != L"") { 02037 int val = _wtoi(undo_size); 02038 if (val > 0 && val < 100) // requirement is to be above 0 and below 100 02039 retval = val; 02040 } 02041 } 02042 catch( hresult_exception&) 02043 { 02044 retval = 10; 02045 } 02046 02047 return retval; 02048 } 02049 02050 STDMETHODIMP CMgaProject::GetTopLibraries(BSTR pDispGuid, IMgaFolders **pVal) 02051 { 02052 COMTRY { 02053 CHECK_INSTRPAR( pDispGuid); 02054 CREATECOLLECTION_FOR(IMgaFolder,q); 02055 02056 CComPtr<IMgaFolder> rootf; 02057 COMTHROW( get_RootFolder( &rootf)); 02058 CoreObj crf( rootf); 02059 CoreObjs children = crf[ATTRID_FPARENT+ATTRID_COLLECTION]; 02060 ITERATE_THROUGH(children) { 02061 if( ITER.GetMetaID() != DTID_FOLDER) continue; 02062 long perm = ITER[ATTRID_PERMISSIONS]; 02063 if( perm & LIBROOT_FLAG) 02064 { 02065 auto lib = ObjForCore(ITER); 02066 if( lib) 02067 { 02068 CComBSTR gd; 02069 COMTHROW( lib->GetGuidDisp( &gd)); 02070 02071 if( gd == pDispGuid) 02072 { 02073 CComPtr<IMgaFolder> fld; 02074 lib->getinterface( &fld); 02075 q->Add( fld); 02076 } 02077 } 02078 } 02079 } 02080 *pVal = q.Detach(); 02081 } 02082 COMCATCH(;); 02083 } 02084