GME
13
|
00001 #include "stdafx.h" 00002 #include "MakeClosure.h" 00003 00004 #include <string> 00005 #include <map> 00006 #include <set> 00007 #include <algorithm> 00008 #include <iterator> 00009 // 00010 // C O M M E N T 00011 // In this file the term "The RootFolder" means the default root folder any project is placed in 00012 // Not to be confused with top folder which means the folder staying on the top of the selected 00013 // object hierarchy 00014 // 00015 const std::string rootfolder_str = "RootFolder"; 00016 const wchar_t* CMakeClosure::m_markerNode = L"inClosure"; 00017 00018 inline void nop( IMgaMetaFCO * f) 00019 { 00020 #ifdef _DEBUG 00021 CComObjPtr<IMgaMetaFCO> ff( f); 00022 CComBstrObj name; std::string s; 00023 COMTHROW( ff->get_Name( PutOut( name))); 00024 CopyTo( name, s); 00025 s = s + "|"; 00026 #endif 00027 } 00028 00029 inline void nop( IMgaMetaFolder * f) 00030 { 00031 #ifdef _DEBUG 00032 CComObjPtr<IMgaMetaFolder> ff( f); 00033 CComBstrObj name; std::string s; 00034 COMTHROW( ff->get_Name( PutOut( name))); 00035 CopyTo( name, s); 00036 s = s + "|"; 00037 #endif 00038 } 00039 00040 inline void nop( IMgaMetaModel * f) 00041 { 00042 #ifdef _DEBUG 00043 CComObjPtr<IMgaMetaModel> ff( f); 00044 CComBstrObj name; std::string s; 00045 COMTHROW( ff->get_Name( PutOut( name))); 00046 CopyTo( name, s); 00047 s = s + "|"; 00048 #endif 00049 } 00050 00051 inline void nop( IMgaFCO * f) 00052 { 00053 #ifdef _DEBUG 00054 CComObjPtr<IMgaFCO> ff( f); 00055 CComBstrObj name; std::string s; 00056 COMTHROW( ff->get_Name( PutOut( name))); 00057 CopyTo( name, s); 00058 s = s + "|"; 00059 #endif 00060 } 00061 00062 inline void nop( IMgaFolder * f) 00063 { 00064 #ifdef _DEBUG 00065 CComObjPtr<IMgaFolder> ff( f); 00066 CComBstrObj name; std::string s; 00067 COMTHROW( ff->get_Name( PutOut( name))); 00068 CopyTo( name, s); 00069 s = s + "|"; 00070 #endif 00071 } 00072 00073 inline void nop( IMgaModel * f) 00074 { 00075 #ifdef _DEBUG 00076 CComObjPtr<IMgaModel> ff( f); 00077 CComBstrObj name; std::string s; 00078 COMTHROW( ff->get_Name( PutOut( name))); 00079 CopyTo( name, s); 00080 s = s + "|"; 00081 #endif 00082 } 00083 00084 // ----------------------------------------------------------- 00085 // --------------------------- GmeEqual ---------------------- 00086 // ----------------------------------------------------------- 00087 GmeEqual::GmeEqual( CComObjPtr<IMgaObject> obj) 00088 : m_objToFind( obj), m_which( 1) 00089 { } 00090 00091 00092 GmeEqual::GmeEqual( CComObjPtr<IMgaFCO> fco) 00093 : m_fcoToFind( fco), m_which( 2) 00094 { } 00095 00096 00097 GmeEqual::GmeEqual( CComObjPtr<IMgaFolder> folder) 00098 : m_folderToFind( folder), m_which( 3) 00099 { } 00100 00101 00102 GmeEqual::GmeEqual( CComObjPtr<IMgaModel> model) 00103 : m_modelToFind( model), m_which( 4) 00104 { } 00105 00106 00107 bool GmeEqual::operator() ( CComObjPtr<IMgaObject>& op ) 00108 { 00109 ASSERT( m_which == 1); // which variable is set 00110 00111 VARIANT_BOOL is_equal; 00112 COMTHROW( m_objToFind->get_IsEqual( op, &is_equal)); 00113 00114 if (is_equal != VARIANT_FALSE) 00115 return true; 00116 00117 return false; 00118 } 00119 00120 bool GmeEqual::operator() ( CComObjPtr<IMgaFCO>& op ) 00121 { 00122 ASSERT( m_which == 2); // which variable is set 00123 00124 VARIANT_BOOL is_equal; 00125 COMTHROW( m_fcoToFind->get_IsEqual( op, &is_equal)); 00126 00127 if (is_equal != VARIANT_FALSE) 00128 return true; 00129 00130 return false; 00131 } 00132 00133 bool GmeEqual::operator() ( CComObjPtr<IMgaFolder>& op ) 00134 { 00135 ASSERT( m_which == 3); // which variable is set 00136 00137 VARIANT_BOOL is_equal; 00138 COMTHROW( m_folderToFind->get_IsEqual( op, &is_equal)); 00139 00140 if (is_equal != VARIANT_FALSE) 00141 return true; 00142 00143 return false; 00144 } 00145 00146 bool GmeEqual::operator() ( CComObjPtr<IMgaModel>& op ) 00147 { 00148 ASSERT( m_which == 4); // which variable is set 00149 00150 VARIANT_BOOL is_equal; 00151 COMTHROW( m_modelToFind->get_IsEqual( op, &is_equal)); 00152 00153 if (is_equal != VARIANT_FALSE) 00154 return true; 00155 00156 return false; 00157 } 00158 00159 // ----------------------------------------------------------- 00160 // --------------------------- CMakeClosure ------------------ 00161 // ----------------------------------------------------------- 00162 long CMakeClosure::process() 00163 { 00164 CHECK_IN( m_project); // the constructor initialized it 00165 COMTRY 00166 { 00167 initTrans(); 00168 00169 if( isValidSelection()) doClosure(); 00170 00171 doneTrans( false); 00172 } 00173 COMCATCH( doneTrans(true) ); 00174 } 00175 00176 void CMakeClosure::doClosure() 00177 { 00178 if ( m_bDirection) // down 00179 { 00180 preProcess(); 00181 processFolders(); 00182 processFCOs(); 00183 postValidateSelection(); 00184 postProcess(); 00185 } 00186 else // up -> so first process the fcos 00187 { 00188 preProcess(); 00189 processFCOs(); 00190 processFolders(); 00191 postValidateSelection(); 00192 postProcess(); 00193 } 00194 } 00195 00196 void CMakeClosure::preProcess() 00197 { 00198 send2Console("[Closure Copy] Working..."); 00199 } 00200 00201 void CMakeClosure::postProcess() 00202 { 00203 // wrapping needed 00204 if ( m_iContainerOption == 0) // miniproject wrapping 00205 { 00206 selectTop(); 00207 totalWrap(); 00208 clearTopObjs(); // no need for the top objects, this is a sign to dump from the RootFolder 00209 00210 send2Console("[Closure Copy] The miniproject can be either Imported or Pasted in a new/existing project."); 00211 } 00212 else if ( m_iContainerOption == 1) // automatic wrapping 00213 { 00214 selectTop(); 00215 autoWrap(); // resets the Top top values 00216 checkMeta( m_topFolds, m_topFcos); 00217 00218 std::string res_str; 00219 getAccKindsInString( res_str); 00220 if( !res_str.empty()) send2Console( "[Closure Copy] The following kinds may accept the copied data: " + res_str + "."); 00221 else send2Console( "[Closure Copy] Possible accepting kind not found based on the meta."); 00222 } 00223 else if ( m_iContainerOption == 2) // as is, no wrapping 00224 { 00225 selectTop(); 00226 checkMeta( m_topFolds, m_topFcos); 00227 00228 std::string res_str; 00229 getAccKindsInString( res_str); 00230 if( !res_str.empty()) send2Console( "[Closure Copy] The following kinds may accept the copied data: " + res_str + "."); 00231 else send2Console( "[Closure Copy] Possible accepting kind not found based on the meta."); 00232 } 00233 } 00234 00235 void CMakeClosure::selectTop() 00236 { 00237 CComObjPtrVector<IMgaFCO> &parentless = m_topFcos; 00238 CComObjPtrVector<IMgaFolder> &parentless_folders = m_topFolds; 00239 00240 // selecting parentless ( = top) fcos 00241 CComObjPtrVector<IMgaFCO>::iterator i = m_selFcos.begin(); 00242 for( ; i != m_selFcos.end(); ++i) 00243 { 00244 CComObjPtr<IMgaModel> parent; 00245 COMTHROW( (*i)->get_ParentModel( PutOut( parent))); 00246 if ( parent) // not a root object 00247 { 00248 CComObjPtr<IMgaFCO> fco; 00249 COMTHROW( ::QueryInterface( parent, fco)); 00250 00251 ASSERT( fco); 00252 00253 // check if model parent is in the selected set of objects 00254 // and if *i is already in the parentless 00255 if ( std::find_if( m_selFcos.begin(), m_selFcos.end(), GmeEqual( fco)) == m_selFcos.end() && 00256 std::find_if( parentless.begin(), parentless.end(), GmeEqual( *i)) == parentless.end()) 00257 { 00258 parentless.push_back( *i); 00259 } 00260 } 00261 else // it may be contained by a folder 00262 { 00263 CComObjPtr<IMgaFolder> parent; 00264 COMTHROW( (*i)->get_ParentFolder( PutOut( parent))); 00265 if ( parent) 00266 { 00267 // check if folder parent is in the selected set of objects 00268 // and if *i is already in the parentless 00269 if ( std::find_if( m_selFolds.begin(), m_selFolds.end(), GmeEqual( parent)) == m_selFolds.end() && 00270 std::find_if( parentless.begin(), parentless.end(), GmeEqual( *i)) == parentless.end()) 00271 { 00272 parentless.push_back( *i); 00273 } 00274 } 00275 else 00276 { 00277 ASSERT( 0); 00278 } // what the heck: *i is an fco and does not have a valid model or a valid folder parent? 00279 } 00280 } 00281 00282 // selecting parentless folders 00283 CComObjPtrVector<IMgaFolder>::iterator k = m_selFolds.begin(); 00284 for( ; k != m_selFolds.end(); ++k) 00285 { 00286 CComObjPtr<IMgaFolder> parent; 00287 COMTHROW( (*k)->get_ParentFolder( PutOut( parent))); 00288 if ( parent) // is not a root object 00289 { 00290 // check if parent is in the selected set of objects 00291 if ( std::find_if( m_selFolds.begin(), m_selFolds.end(), GmeEqual( parent)) == m_selFolds.end() && 00292 std::find_if( parentless_folders.begin(), parentless_folders.end(), GmeEqual( *k)) == parentless_folders.end()) 00293 { 00294 parentless_folders.push_back( *k); 00295 } 00296 } 00297 //else root: The RootFolder is not considered anymore a top object, see noTopObjs() method 00298 } 00299 } 00300 00301 void CMakeClosure::processFolders() 00302 { 00303 unsigned int curr_start = 0; 00304 bool continju = true; 00305 while (continju) 00306 { 00307 continju = false; 00308 CComObjPtrVector<IMgaFolder>::iterator i = m_selFolds.begin(); 00309 for( unsigned int j = curr_start; j < m_selFolds.size() && i != m_selFolds.end(); ++j, ++i) 00310 { 00311 procObj( m_selFolds[j]); 00312 } 00313 00314 continju = !m_newlySelFolds.empty() || !m_newlySelFcos.empty(); 00315 if ( continju) 00316 { 00317 curr_start = m_selFolds.size(); 00318 m_selFolds.insert( m_selFolds.end(), m_newlySelFolds.begin(), m_newlySelFolds.end()); 00319 m_selFcos.insert( m_selFcos.end(), m_newlySelFcos.begin(), m_newlySelFcos.end()); 00320 } 00321 00322 m_newlySelFcos.clear(); 00323 m_newlySelFolds.clear(); 00324 } 00325 } 00326 00327 void CMakeClosure::processFCOs() 00328 { 00329 unsigned int curr_start = 0; 00330 bool continju = true; 00331 while (continju) 00332 { 00333 continju = false; 00334 CComObjPtrVector<IMgaFCO>::iterator i = m_selFcos.begin(); 00335 for( unsigned int j = curr_start; j < m_selFcos.size() && i != m_selFcos.end(); ++j, ++i) 00336 { 00337 procObj( m_selFcos[j]); 00338 } 00339 00340 continju = !m_newlySelFolds.empty() || !m_newlySelFcos.empty(); 00341 if ( continju) 00342 { 00343 curr_start = m_selFcos.size(); 00344 m_selFolds.insert( m_selFolds.end(), m_newlySelFolds.begin(), m_newlySelFolds.end()); 00345 m_selFcos.insert( m_selFcos.end(), m_newlySelFcos.begin(), m_newlySelFcos.end()); 00346 } 00347 m_newlySelFcos.clear(); 00348 m_newlySelFolds.clear(); 00349 } 00350 } 00351 00352 //--------------------------------------------------------------------------------------- 00353 //-------------------------------------------------processor methods--------------------- 00354 //--------------------------------------------------------------------------------------- 00355 void CMakeClosure::procFolder( IMgaFolder *folder) 00356 { 00357 ASSERT( folder != NULL ); 00358 insertNew( folder); 00359 00360 if ( m_bFolderContainment) 00361 { 00362 insertNew( folder, &IMgaFolder::get_ChildFolders); 00363 insertNew( folder, &IMgaFolder::get_ChildFCOs); 00364 } 00365 } 00366 00367 void CMakeClosure::procModel( IMgaModel *model) 00368 { 00369 ASSERT( model != NULL ); 00370 insertNew( CComObjPtr<IMgaModel>( model)); 00371 00372 if ( m_bContainment) 00373 { 00374 insertNew( model, &IMgaModel::get_ChildFCOs); 00375 } 00376 } 00377 00378 void CMakeClosure::procReference( IMgaReference *reference) 00379 { 00380 ASSERT( reference != NULL ); 00381 insertNew( CComObjPtr<IMgaFCO>( reference)); 00382 00383 CComObjPtr<IMgaFCO> fco; 00384 COMTHROW( reference->get_Referred( PutOut( fco)) ); 00385 00386 if ( m_bRefersTo && fco) // test if null reference 00387 { 00388 bool inlib = isInLibrary( fco); // a referred fco may be in a library 00389 if ( inlib && m_iIntoLibraries == LIB_CONT || !inlib) 00390 insertNew( fco); 00391 } 00392 } 00393 00394 00395 void CMakeClosure::procSet( IMgaSet *one_set) 00396 { 00397 ASSERT( one_set != NULL ); 00398 insertNew( one_set); 00399 00400 CComObjPtrVector<IMgaFCO> members; 00401 COMTHROW( one_set->get_Members( PutOut( members)) );//zz1 00402 00403 if ( m_bSetMember) 00404 { 00405 insertNew( members); 00406 } 00407 } 00408 00409 void CMakeClosure::procAtom( IMgaAtom *atom) 00410 { 00411 ASSERT( atom != NULL ); 00412 insertNew( atom); 00413 } 00414 00415 00416 bool CMakeClosure::isValidSelection() 00417 { 00418 // check each object for validity 00419 CComObjPtrVector<IMgaFCO>::iterator fco_it = m_selFcos.begin(); 00420 while( fco_it != m_selFcos.end()) 00421 { 00422 if( !isValidFCO( *fco_it)) 00423 fco_it = m_selFcos.erase( fco_it); 00424 else 00425 ++fco_it; 00426 } 00427 00428 return m_selFcos.size() + m_selFolds.size() > 0; 00429 } 00430 00431 bool CMakeClosure::isValidFCO( IMgaFCO * fco) 00432 { 00433 objtype_enum objtype; 00434 COMTHROW( fco->get_ObjType( &objtype) ); 00435 if( objtype == OBJTYPE_CONNECTION) 00436 { 00437 CComObjPtr<IMgaConnection> c; 00438 COMTHROW( ::QueryInterface( fco, c) ); 00439 return isValidConnection( c); 00440 } 00441 00442 return true; 00443 } 00444 00445 /*static*/ CComPtr<IGMEOLEApp> CMakeClosure::get_GME(CComObjPtr<IMgaProject> project) 00446 { 00447 CComPtr<IGMEOLEApp> gme; 00448 if (/*mb_is_interactive &&*/ (project != NULL)) { 00449 CComBSTR bstrName("GME.Application"); 00450 CComPtr<IMgaClient> pClient; 00451 HRESULT hr = project->GetClientByName(bstrName, &pClient); 00452 if (SUCCEEDED(hr) && pClient) { 00453 CComPtr<IDispatch> pDispatch; 00454 hr = pClient->get_OLEServer(&pDispatch); 00455 if (SUCCEEDED(hr) && pDispatch) { 00456 hr = pDispatch.QueryInterface(&gme); 00457 if (FAILED(hr)) { 00458 gme = NULL; 00459 } 00460 } 00461 } 00462 } 00463 return gme; 00464 } 00465 00466 bool CMakeClosure::isSimpleConnection( IMgaConnection * connection) 00467 { 00468 bool res = true; 00469 CComObjPtrVector<IMgaConnPoint> v; 00470 COMTHROW( connection->get_ConnPoints( PutOut( v)) );//zz1 00471 00472 for( CComObjPtrVector<IMgaConnPoint>::iterator i = v.begin(); res && i != v.end(); ++i) 00473 { 00474 CComObjPtr<IMgaConnPoint> connpoint = *i; 00475 00476 CComObjPtrVector<IMgaFCO> refs; 00477 COMTHROW( connpoint->get_References(PutOut( refs)) );//zz1 00478 if( !refs.empty()) // it is a connection thru reference ports 00479 res = false; 00480 } 00481 00482 return res; 00483 } 00484 00485 00486 bool CMakeClosure::isValidConnection( IMgaConnection * connection) 00487 { 00488 bool res = true; 00489 00490 CComObjPtrVector<IMgaConnPoint> v; 00491 COMTHROW( connection->get_ConnPoints( PutOut( v)) );//zz1 00492 00493 for( CComObjPtrVector<IMgaConnPoint>::iterator i = v.begin(); res && i != v.end(); ++i) 00494 { 00495 CComObjPtr<IMgaConnPoint> connpoint = *i; 00496 00497 // general constraints (which apply for each case: LIB_* 00498 CComObjPtrVector<IMgaFCO> refs; 00499 COMTHROW( connpoint->get_References(PutOut( refs)) );//zz1 00500 for( CComObjPtrVector<IMgaFCO>::iterator ref_i = refs.begin(); res && ref_i != refs.end(); ++ref_i ) 00501 { 00502 if( !m_bRefPortConnection) 00503 { 00504 res = false;//this is a connection between at least one reference port, so if the corresponding option is not set (m_bRefPortConnection) then we consider it invalid 00505 00506 if( m_GME) 00507 { 00508 CComBSTR bstr, id, nm; 00509 COMTHROW( connection->get_ID( &id)); 00510 COMTHROW( connection->get_Name( &nm)); 00511 COMTHROW(bstr.Append("Closure: <A HREF=\"mga:")); 00512 COMTHROW(bstr.AppendBSTR( id)); 00513 COMTHROW(bstr.Append("\">")); 00514 COMTHROW(bstr.AppendBSTR( nm)); 00515 COMTHROW(bstr.Append("</A> disregarded. Connection involving reference ports. Use the \"Connection thru refport\" option to include it.")); 00516 00517 COMTHROW(m_GME->ConsoleMessage(bstr, MSG_ERROR)); 00518 } 00519 00520 } 00521 } 00522 00523 // constraints for lib_stop case 00524 if( m_iIntoLibraries == LIB_STOP) 00525 { 00526 CComObjPtr<IMgaFCO> target; // the src or dst of a connection 00527 COMTHROW( connpoint->get_Target( PutOut( target)) ); 00528 if( target && isInLibrary( target)) 00529 res = false; // this is a connection with one end in a library which in lib_stop case is not good 00530 } 00531 } 00532 00533 return res; 00534 } 00535 00536 bool CMakeClosure::postValidateSelection() 00537 { 00538 // check each object for validity... 00539 return true; 00540 } 00541 00542 bool CMakeClosure::postValidateFCO( IMgaFCO * fco) 00543 { 00544 return true; 00545 } 00546 00547 bool CMakeClosure::postValidateConnection( IMgaConnection * connection) 00548 { 00549 return true; 00550 } 00551 00552 void CMakeClosure::procConnection( IMgaConnection *connection) 00553 { 00554 ASSERT( connection != NULL ); 00555 00556 bool simple = isSimpleConnection( connection); 00557 if ( simple && m_bConnection || !simple && m_bRefPortConnection) 00558 { 00559 CComObjPtrVector<IMgaConnPoint> v; 00560 COMTHROW( connection->get_ConnPoints( PutOut( v)) );//zz1 00561 00562 insertNew( CComObjPtr<IMgaFCO>( connection)); 00563 for( CComObjPtrVector<IMgaConnPoint>::iterator i = v.begin(); i != v.end(); ++i) 00564 { 00565 procConnPoint( *i); 00566 } 00567 } 00568 } 00569 00570 // if called from procConnection then the validity is checked 00571 // if called from procMyConnections then it is checked as well 00572 void CMakeClosure::procConnPoint( IMgaConnPoint *connpoint) 00573 { 00574 ASSERT( connpoint != NULL ); 00575 00576 CComObjPtr<IMgaFCO> target; // the src or dst of a connection 00577 COMTHROW( connpoint->get_Target( PutOut( target)) ); 00578 00579 CComObjPtr<IMgaConnection> conn; // the connection itself 00580 COMTHROW( connpoint->get_Owner( PutOut( conn)) ); 00581 00582 CComObjPtr<IMgaFCO> conn_fco; 00583 COMTHROW( conn.QueryInterface( conn_fco)); 00584 00585 CComObjPtrVector<IMgaFCO> refs; // the reference chain the connection is drawn 00586 COMTHROW( connpoint->get_References( PutOut( refs)) );//zz1 00587 00588 if ( refs.empty()) // simple connection, no reference ports involved 00589 { 00590 insertNew( target); 00591 insertNew( conn_fco); 00592 } 00593 else // refport conn, so insert everything 00594 { 00595 bool inlib; 00596 inlib = isInLibrary( target); 00597 if ( inlib && m_iIntoLibraries == LIB_CONT || !inlib) insertNew( target); 00598 00599 inlib = isInLibrary( conn_fco); // the connection might be in the library (=both endtargets are as well in the library) 00600 if ( inlib && m_iIntoLibraries == LIB_CONT || !inlib) 00601 { 00602 insertNew( conn_fco); 00603 insertNew( refs); 00604 } 00605 } 00606 } 00607 00608 // this method is needed after an fco is processed to insert the attaching connections as well 00609 void CMakeClosure::procMyConnections( IMgaFCO * fco) 00610 { 00611 if ( m_bConnection || m_bRefPortConnection) 00612 { 00613 CComObjPtrVector<IMgaConnPoint> my_conns; 00614 COMTHROW( fco->get_PartOfConns( PutOut( my_conns)) );//zz1 00615 for( CComObjPtrVector<IMgaConnPoint>::iterator i = my_conns.begin(); i != my_conns.end(); ++i) 00616 { 00617 CComObjPtr<IMgaConnection> conn; // the connection itself 00618 COMTHROW( (*i)->get_Owner( PutOut( conn)) ); 00619 bool simple = isSimpleConnection( conn); 00620 if( simple && m_bConnection || !simple && m_bRefPortConnection) 00621 procConnPoint( *i);//the validity of each connection is tested 00622 } 00623 } 00624 } 00625 00626 void CMakeClosure::procMyContainerSets( IMgaFCO * fco) 00627 { 00628 if ( m_bMemberOfSets) 00629 { 00630 CComObjPtrVector<IMgaFCO> my_sets; 00631 COMTHROW( fco->get_MemberOfSets( PutOut( my_sets)) );//zz1 00632 insertNew( my_sets); 00633 } 00634 } 00635 00636 void CMakeClosure::procMyReferences( IMgaFCO * fco) 00637 { 00638 if ( m_bReferredBy) 00639 { 00640 CComObjPtrVector<IMgaFCO> my_references; 00641 COMTHROW( fco->get_ReferencedBy( PutOut( my_references)) );//zz1 00642 insertNew( my_references); 00643 } 00644 } 00645 00646 void CMakeClosure::procMyParent( IMgaFCO * fco) 00647 { 00648 CComObjPtr<IMgaModel> mod; 00649 COMTHROW( fco->get_ParentModel( PutOut( mod)) ); 00650 if ( mod) 00651 { 00652 if ( m_bPartOfModels) 00653 { 00654 insertNew( mod); 00655 } 00656 } 00657 else 00658 { 00659 CComObjPtr<IMgaFolder> fold; 00660 COMTHROW( fco->get_ParentFolder( PutOut( fold)) ); 00661 if ( fold) 00662 { 00663 if ( m_bPartOfFolders) 00664 { 00665 insertNew( fold); 00666 } 00667 } 00668 // else rootfolder 00669 } 00670 } 00671 00672 void CMakeClosure::procMyParent( IMgaFolder * folder) 00673 { 00674 CComObjPtr<IMgaFolder> parent; 00675 COMTHROW( folder->get_ParentFolder( PutOut( parent)) ); 00676 if ( parent) 00677 { 00678 if ( m_bPartOfFolders) 00679 { 00680 insertNew( parent); 00681 } 00682 } 00683 // else rootfolder 00684 } 00685 00686 template<class T> 00687 void CMakeClosure::markObj( CComObjPtr<T> obj) 00688 { 00689 if( m_markWith != -1) 00690 { 00691 CComBSTR buf0; 00692 COMTHROW( obj->get_RegistryValue( CComBSTR( m_markerNode), &buf0)); 00693 00694 // check if the new marker appears already in the marker list 00695 std::wstring str_buf = buf0.Length() ? buf0 : L""; 00696 00697 TCHAR buf1[12]; 00698 swprintf_s( buf1, L",%i", m_markWith); 00699 std::wstring new_mrk( buf1); 00700 00701 str_buf += L","; // will ease the eos comparison 00702 new_mrk += L","; // and the exact match is guaranteed 00703 00704 if( str_buf.find( new_mrk) == std::string::npos) // if marker not present 00705 { 00706 COMTHROW(buf0.Append( buf1)); // insert new marker into list & update 00707 COMTHROW( obj->put_RegistryValue( CComBSTR( m_markerNode), buf0)); 00708 } 00709 } 00710 } 00711 00712 void CMakeClosure::procObj( IMgaObject* obj) 00713 { 00714 ASSERT( obj != NULL ); 00716 if ( m_iIntoLibraries != LIB_CONT && isInLibrary( obj)) // if no intention to step into libraries and the object is in a library then return 00717 return; 00718 00719 objtype_enum objtype; 00720 COMTHROW( obj->get_ObjType( &objtype) ); 00721 00722 switch( objtype) 00723 { 00724 case OBJTYPE_MODEL: 00725 case OBJTYPE_ATOM: 00726 case OBJTYPE_REFERENCE: 00727 case OBJTYPE_CONNECTION: 00728 case OBJTYPE_SET: 00729 { 00730 CComObjPtr<IMgaFCO> p; 00731 COMTHROW( ::QueryInterface( obj, p) ); 00732 00733 markObj( p); 00734 00735 if ( m_bConnection) procMyConnections( p); 00736 if ( m_bMemberOfSets) procMyContainerSets( p); 00737 if ( m_bReferredBy) procMyReferences( p); 00738 00739 procMyParent( p); // we don't know what kind of parent the fco has: Model or Folder 00740 00741 if ( m_bBaseTypes) procMyBaseTypes( p); 00742 if ( m_bDerivedTypes) procMyDerivedTypes( p); 00743 break; 00744 } 00745 00746 case OBJTYPE_FOLDER: 00747 { 00748 CComObjPtr<IMgaFolder> p; 00749 COMTHROW( ::QueryInterface( obj, p) ); 00750 00751 markObj( p); 00752 00753 if ( m_bPartOfFolders) procMyParent( p); 00754 break; 00755 } 00756 00757 default: 00758 HR_THROW(E_INVALID_MGA); 00759 }; 00760 00761 00762 switch( objtype) 00763 { 00764 case OBJTYPE_MODEL: 00765 { 00766 if ( m_bContainment) 00767 { 00768 CComObjPtr<IMgaModel> m; 00769 COMTHROW( ::QueryInterface( obj, m) ); 00770 00771 procModel( m); 00772 } 00773 break; 00774 } 00775 00776 case OBJTYPE_ATOM: 00777 { 00778 CComObjPtr<IMgaAtom> a; 00779 COMTHROW( ::QueryInterface( obj, a) ); 00780 procAtom( a); 00781 break; 00782 } 00783 00784 case OBJTYPE_REFERENCE: 00785 { 00786 if ( m_bRefersTo) 00787 { 00788 CComObjPtr<IMgaReference> r; 00789 COMTHROW( ::QueryInterface( obj, r) ); 00790 procReference( r); 00791 } 00792 break; 00793 } 00794 00795 case OBJTYPE_CONNECTION: 00796 { 00797 if ( m_bConnection) 00798 { 00799 CComObjPtr<IMgaConnection> c; 00800 COMTHROW( ::QueryInterface( obj, c) ); 00801 procConnection( c); 00802 } 00803 break; 00804 } 00805 00806 case OBJTYPE_SET: 00807 { 00808 if ( m_bSetMember) 00809 { 00810 CComObjPtr<IMgaSet> s; 00811 COMTHROW( ::QueryInterface( obj, s) ); 00812 procSet( s); 00813 } 00814 break; 00815 } 00816 00817 case OBJTYPE_FOLDER: 00818 { 00819 if ( m_bFolderContainment) 00820 { 00821 CComObjPtr<IMgaFolder> f; 00822 COMTHROW( ::QueryInterface( obj, f) ); 00823 procFolder( f); 00824 } 00825 break; 00826 } 00827 00828 default: 00829 HR_THROW(E_INVALID_MGA); 00830 }; 00831 } 00832 00833 void CMakeClosure::procMyBaseTypes( IMgaFCO * fco) 00834 { 00835 if ( !m_bBaseTypes) 00836 return; 00837 00838 CComObjPtr<IMgaFCO> base; 00839 COMTHROW( fco->get_DerivedFrom( PutOut( base))); 00840 if( base) 00841 { 00842 bool inlib = isInLibrary( base); // base types may be in a library 00843 if ( inlib && m_iIntoLibraries == LIB_CONT || !inlib) 00844 insertNew( base); 00845 } 00846 00847 } 00848 00849 void CMakeClosure::procMyDerivedTypes( IMgaFCO * fco) 00850 { 00851 if ( !m_bDerivedTypes) 00852 return; 00853 00854 CComObjPtrVector<IMgaFCO> der_fcos; 00855 COMTHROW( fco->get_DerivedObjects( PutOut( der_fcos)) );//zz1 00856 insertNew( der_fcos); 00857 } 00858 00859 void CMakeClosure::insertNew( const std::string& id, bool is_top /* = false */) 00860 { 00861 CComObjPtr<IMgaObject> obj; 00862 COMTHROW( m_project->GetObjectByID( PutInBstr( id), PutOut( obj)) ); 00863 if ( obj) 00864 { 00865 objtype_enum objtype; 00866 COMTHROW( obj->get_ObjType(&objtype) ); 00867 00868 switch( objtype) 00869 { 00870 case OBJTYPE_MODEL: 00871 case OBJTYPE_SET: 00872 case OBJTYPE_REFERENCE: 00873 case OBJTYPE_CONNECTION: 00874 case OBJTYPE_ATOM: 00875 { 00876 CComObjPtr<IMgaFCO> model; 00877 COMTHROW( ::QueryInterface(obj, model) ); 00878 ASSERT( model); 00879 00880 insertNew( model); 00881 if ( is_top) 00882 { 00883 nop( model); 00884 if ( std::find_if( m_topFcos.begin(), m_topFcos.end(), GmeEqual( model)) == m_topFcos.end()) 00885 m_topFcos.push_back( model); 00886 } 00887 00888 break; 00889 } 00890 case OBJTYPE_FOLDER: 00891 { 00892 CComObjPtr<IMgaFolder> folder; 00893 COMTHROW( ::QueryInterface( obj, folder)); 00894 ASSERT( folder); 00895 00896 insertNew( folder); 00897 if ( is_top) 00898 { 00899 nop( folder); 00900 if ( std::find_if( m_topFolds.begin(), m_topFolds.end(), GmeEqual( folder)) == m_topFolds.end()) 00901 m_topFolds.push_back( folder); 00902 } 00903 00904 break; 00905 } 00906 default: 00907 ASSERT( 0); 00908 } // switch 00909 } // if 00910 } 00911 00912 void CMakeClosure::insertNew( const CComObjPtr<IMgaFCO>& in) 00913 { 00914 nop( in); 00915 00916 if ( in != NULL 00917 && !findAmongNews( in) 00918 && !findAmongSelected( in) 00919 ) 00920 m_newlySelFcos.push_back( in); 00921 } 00922 00923 void CMakeClosure::insertNew( const CComObjPtr<IMgaFolder>& in) 00924 { 00925 nop( in); 00926 00927 if ( in != NULL 00928 && !findAmongNews( in) 00929 && !findAmongSelected( in) 00930 ) 00931 m_newlySelFolds.push_back( in); 00932 } 00933 00934 void CMakeClosure::insertNew( const CComObjPtr<IMgaModel>& in) 00935 { 00936 if ( in != NULL) 00937 { 00938 CComObjPtr<IMgaFCO> fco; 00939 COMTHROW( ::QueryInterface( in, fco)); 00940 00941 insertNew( fco); 00942 } 00943 } 00944 00945 void CMakeClosure::insertNew( const CComObjPtrVector<IMgaFCO>& in_v) 00946 { 00947 CComObjPtrVector<IMgaFCO>::const_iterator it = in_v.begin(); 00948 for( ; it != in_v.end(); ++it) 00949 insertNew( *it); 00950 } 00951 00952 void CMakeClosure::insertNew( const CComObjPtrVector<IMgaFolder>& in_v) 00953 { 00954 CComObjPtrVector<IMgaFolder>::const_iterator it = in_v.begin(); 00955 for( ; it != in_v.end(); ++it) 00956 insertNew( *it); 00957 } 00958 00959 bool CMakeClosure::findAmongSelected(const CComObjPtr<IMgaFCO>& in) 00960 { 00961 return std::find_if( m_selFcos.begin(), m_selFcos.end(), GmeEqual( in)) != m_selFcos.end(); 00962 } 00963 00964 bool CMakeClosure::findAmongSelected(const CComObjPtr<IMgaFolder>& in) 00965 { 00966 return std::find_if( m_selFolds.begin(), m_selFolds.end(), GmeEqual( in)) != m_selFolds.end(); 00967 } 00968 00969 bool CMakeClosure::findAmongNews(const CComObjPtr<IMgaFCO>& in) 00970 { 00971 return std::find_if( m_newlySelFcos.begin(), m_newlySelFcos.end(), GmeEqual( in)) != m_newlySelFcos.end(); 00972 } 00973 00974 bool CMakeClosure::findAmongNews(const CComObjPtr<IMgaFolder>& in) 00975 { 00976 return std::find_if( m_newlySelFolds.begin(), m_newlySelFolds.end(), GmeEqual( in)) != m_newlySelFolds.end(); 00977 } 00978 00979 bool CMakeClosure::isInLibrary( IMgaObject * obj) 00980 { 00981 VARIANT_BOOL vbLibrary; 00982 COMTHROW( obj->get_IsLibObject( &vbLibrary ) ); 00983 return ( vbLibrary ) ? true : false; 00984 } 00985 00986 // --------------------------------------------------------- wrappers 00987 void CMakeClosure::totalWrap() 00988 { 00989 CComObjPtrVector<IMgaFolder> fo_parents; // will collect the parents of all objects 00990 CComObjPtrVector<IMgaModel> mo_parents; 00991 00992 CComObjPtrVector<IMgaFCO>::iterator fco_it = m_topFcos.begin(); 00993 for( ; fco_it != m_topFcos.end(); ++fco_it) 00994 { 00995 processUpward( *fco_it, fo_parents, mo_parents); 00996 } 00997 //int sz = m_selFcos.size(); 00998 00999 CComObjPtrVector<IMgaFolder>::iterator fold_it = m_topFolds.begin(); 01000 for( ; fold_it != m_topFolds.end(); ++fold_it) 01001 { 01002 processUpward( *fold_it, fo_parents, mo_parents); 01003 } 01004 //sz = m_selFolds.size(); 01005 01006 //append the folder parents to selected folders 01007 //m_selFolds.insert( m_selFolds.end(), fo_parents.begin(), fo_parents.end()); 01008 CComObjPtrVector<IMgaFolder>::iterator fol_it = fo_parents.begin(); 01009 for( ; fol_it != fo_parents.end(); ++fol_it) 01010 { 01011 if ( std::find_if( m_selFolds.begin(), m_selFolds.end(), GmeEqual( *fol_it)) == m_selFolds.end()) 01012 m_selFolds.push_back( *fol_it); 01013 else 01014 ASSERT( 0); 01015 } 01016 01017 //append the model parents to selected fcos 01018 CComObjPtrVector<IMgaModel>::iterator mod_it = mo_parents.begin(); 01019 for( ; mod_it != mo_parents.end(); ++mod_it) 01020 { 01021 CComObjPtr<IMgaFCO> fco; 01022 COMTHROW( ::QueryInterface( *mod_it, fco)); 01023 if ( fco && std::find_if( m_selFcos.begin(), m_selFcos.end(), GmeEqual( fco)) == m_selFcos.end()) 01024 m_selFcos.push_back( fco); 01025 else 01026 ASSERT( 0); 01027 } 01028 } 01029 01030 std::string CMakeClosure::processUpward( IMgaObject *obj, CComObjPtrVector<IMgaFolder>& f_parents, CComObjPtrVector<IMgaModel>& m_parents) 01031 { 01032 ASSERT( obj != NULL ); 01033 01034 objtype_enum objtype; 01035 COMTHROW( obj->get_ObjType(&objtype) ); 01036 01037 switch(objtype) { 01038 case OBJTYPE_MODEL: 01039 case OBJTYPE_ATOM: 01040 case OBJTYPE_REFERENCE: 01041 case OBJTYPE_CONNECTION: 01042 case OBJTYPE_SET: 01043 { 01044 CComObjPtr<IMgaFCO> fco; 01045 COMTHROW( ::QueryInterface( obj, fco) ); 01046 ASSERT( fco); 01047 01048 bool topmost_m_set( false); 01049 CComObjPtr<IMgaModel> m, topmost_m; 01050 COMTHROW( fco->get_ParentModel( PutOut( m))); 01051 while ( m) 01052 { 01053 if ( std::find_if( m_parents.begin(), m_parents.end(), GmeEqual( m)) == m_parents.end()) 01054 m_parents.push_back( m); 01055 01056 topmost_m = m; topmost_m_set = true; 01057 CComObjPtr<IMgaModel> m_out; 01058 COMTHROW( m->get_ParentModel( PutOut( m_out))); 01059 m = m_out; 01060 } 01061 01062 CComObjPtr<IMgaFolder> f; 01063 if ( topmost_m_set) 01064 COMTHROW( topmost_m->get_ParentFolder( PutOut( f))); 01065 else 01066 COMTHROW( fco->get_ParentFolder( PutOut( f))); 01067 01068 while( f) 01069 { 01070 if ( std::find_if( f_parents.begin(), f_parents.end(), GmeEqual( f)) == f_parents.end()) 01071 f_parents.push_back( f); 01072 01073 CComObjPtr<IMgaFolder> f_out; 01074 COMTHROW( f->get_ParentFolder( PutOut( f_out))); 01075 f = f_out; 01076 } 01077 break; 01078 } 01079 case OBJTYPE_FOLDER: 01080 { 01081 CComObjPtr<IMgaFolder> folder, f; 01082 COMTHROW( ::QueryInterface( obj, folder)); 01083 ASSERT( folder); 01084 01085 COMTHROW( folder->get_ParentFolder( PutOut( f))); 01086 01087 while( f) 01088 { 01089 if ( std::find_if( f_parents.begin(), f_parents.end(), GmeEqual( f)) == f_parents.end()) 01090 f_parents.push_back( f); 01091 01092 CComObjPtr<IMgaFolder> f_out; 01093 COMTHROW( f->get_ParentFolder( PutOut( f_out))); 01094 f = f_out; 01095 } 01096 break; 01097 } 01098 default: 01099 HR_THROW(E_INVALID_MGA); 01100 }; // endswitch 01101 01102 return ""; 01103 } 01104 01105 void CMakeClosure::autoWrap() 01106 { 01107 if( m_topFcos.empty() && m_topFolds.empty()) // no top objects == root folder selected 01108 return; 01109 01110 CComObjPtrVector<IMgaFolder> f_parents; 01111 CComObjPtrVector<IMgaModel> m_parents; 01112 01113 std::map< int, std::string> path_map; 01114 std::map< int, std::string> name_map; 01115 01116 unsigned int k = 0; 01117 CComObjPtrVector<IMgaFCO>::iterator i = m_topFcos.begin(); 01118 for( ; i != m_topFcos.end(); ++i, ++k) 01119 { 01120 std::string res, resid; 01121 01122 // initialize the values 01123 CComBstrObj name, id; 01124 COMTHROW( (*i)->get_Name( PutOut(name)) ); 01125 COMTHROW( (*i)->get_ID( PutOut( id)) ); 01126 CopyTo( name, res); 01127 CopyTo( id, resid); 01128 res += '/'; 01129 resid += '/'; 01130 01131 01132 bool topmost_m_set = false; 01133 CComObjPtr<IMgaModel> m, topmost_m; 01134 COMTHROW( (*i)->get_ParentModel( PutOut( m))); 01135 while ( m) 01136 { 01137 CComBstrObj name, id; 01138 std::string s, ids; 01139 COMTHROW( m->get_Name( PutOut(name)) ); 01140 COMTHROW( m->get_ID( PutOut( id)) ); 01141 CopyTo( name, s); 01142 CopyTo( id, ids); 01143 res = s + '/' + res; 01144 resid = ids + '/' + resid; 01145 01146 01147 if ( std::find_if( m_parents.begin(), m_parents.end(), GmeEqual( m)) == m_parents.end()) 01148 m_parents.push_back( m); 01149 01150 topmost_m = m; topmost_m_set = true; 01151 CComObjPtr<IMgaModel> m_out; 01152 COMTHROW( m->get_ParentModel( PutOut( m_out))); 01153 m = m_out; 01154 } 01155 01156 CComObjPtr<IMgaFolder> f; 01157 if ( topmost_m_set) 01158 COMTHROW( topmost_m->get_ParentFolder( PutOut( f))); 01159 else 01160 COMTHROW( (*i)->get_ParentFolder( PutOut( f))); 01161 01162 while( f) 01163 { 01164 CComBstrObj name, id; 01165 std::string s, ids; 01166 COMTHROW( f->get_Name( PutOut( name)) ); 01167 COMTHROW( f->get_ID( PutOut( id)) ); 01168 CopyTo( name, s); 01169 CopyTo( id, ids); 01170 res = s + '/' + res; 01171 resid = ids + '/' + resid; 01172 01173 if ( std::find_if( f_parents.begin(), f_parents.end(), GmeEqual( f)) == f_parents.end()) 01174 f_parents.push_back( f); 01175 01176 CComObjPtr<IMgaFolder> f_out; 01177 COMTHROW( f->get_ParentFolder( PutOut( f_out))); 01178 f = f_out; 01179 } 01180 01181 path_map[ k] = resid; 01182 name_map[ k] = res; 01183 } 01184 01185 CComObjPtrVector<IMgaFolder>::iterator j = m_topFolds.begin(); 01186 for( ; j != m_topFolds.end(); ++j, ++k) 01187 { 01188 std::string res, resid; 01189 01190 // initialize the values 01191 CComBstrObj name, id; 01192 COMTHROW( (*j)->get_Name( PutOut(name)) ); 01193 COMTHROW( (*j)->get_ID( PutOut( id)) ); 01194 CopyTo( name, res); 01195 CopyTo( id, resid); 01196 res += '/'; 01197 resid += '/'; 01198 01199 01200 CComObjPtr<IMgaFolder> f; 01201 COMTHROW( (*j)->get_ParentFolder( PutOut( f))); 01202 01203 while( f) 01204 { 01205 CComBstrObj name, id; 01206 std::string s, ids; 01207 COMTHROW( f->get_Name( PutOut(name)) ); 01208 COMTHROW( f->get_ID( PutOut( id)) ); 01209 CopyTo( name, s); 01210 CopyTo( id, ids); 01211 res = s + '/' + res; 01212 resid = ids + '/' + resid; 01213 01214 if ( std::find_if( f_parents.begin(), f_parents.end(), GmeEqual( f)) == f_parents.end()) 01215 f_parents.push_back( f); 01216 01217 CComObjPtr<IMgaFolder> f_out; 01218 COMTHROW( f->get_ParentFolder( PutOut( f_out))); 01219 f = f_out; 01220 } 01221 01222 path_map[ k] = resid; 01223 name_map[ k] = res; 01224 } 01225 01226 ASSERT( k > 0); 01227 if ( k == 0) // no top objects == root folder selected 01228 return; 01229 01230 std::string common_path = path_map[ 0]; 01231 std::string common_name = name_map[ 0]; 01232 for( unsigned int l = 1; l < k; ++l) 01233 { 01234 std::string next_path = path_map[ l]; 01235 unsigned int minlen = std::min( next_path.length(), common_path.length()); 01236 01237 // the strings may look like 01238 // id-0065-001/id-0065-002/id-0065-003/ 01239 // id-0065-001/id-0065-002/id-0065-004/ 01240 // thus the common part of all may look like 01241 // id-0065-001/id-0065-002/id-0065-00 01242 // for this we use the position of the last slash 01243 unsigned int pos_of_last_slash = 0; 01244 unsigned int newlen = 0; 01245 01246 while( newlen < minlen && next_path[ newlen] == common_path[ newlen]) 01247 { 01248 if ( common_path[ newlen] == '/') 01249 pos_of_last_slash = newlen; 01250 01251 ++newlen; 01252 } 01253 common_path = common_path.substr( 0, pos_of_last_slash + 1); // tailing '/' needed 01254 01255 std::string next_name = name_map[ l]; 01256 minlen = std::min( next_name.length(), common_name.length()); 01257 01258 pos_of_last_slash = 0; 01259 newlen = 0; 01260 while( newlen < minlen && next_name[ newlen] == common_name[ newlen]) 01261 { 01262 if ( common_name[ newlen] == '/') 01263 pos_of_last_slash = newlen; 01264 01265 ++newlen; 01266 } 01267 01268 common_name = common_name.substr( 0, pos_of_last_slash + 1); // tailing '/' needed 01269 } 01270 01271 common_name = common_name.substr( 0, common_name.length() - 1); 01272 common_path = common_path.substr( 0, common_path.length() - 1); 01273 01274 std::string common_root_name; // the common model's name 01275 int pos = common_name.rfind( "/"); // tailing '/' removed previously 01276 common_root_name = common_name.substr( pos + 1, common_name.length() - pos - 1); 01277 01278 std::string common_root_id; // the common model's id 01279 pos = common_path.rfind( "/"); // tailing '/' removed previously 01280 common_root_id = common_path.substr( pos + 1, common_path.length() - pos - 1); 01281 01282 //AfxMessageBox( CString( "The common part of the paths is: ") + common_name.c_str() + CString( "\nThe last common part of the paths is: ") + common_root_name.c_str() ); 01283 01284 m_topFcos.clear(); // these two will be reset soon 01285 m_topFolds.clear(); 01286 m_newlySelFcos.clear(); 01287 m_newlySelFolds.clear(); 01288 01289 // are all selected objects children (not equal) of the common root? 01290 // checks if the common root is among the selected objects 01291 // ?indicates if the common root of the objects is a selected object itself 01292 bool are_all_seld_children_of_common_root = true; 01293 for( unsigned int l = 0; l < k; ++l) 01294 { 01295 // this happens when one of the sel objs is the grandparent/parent of all other sel objs 01296 // in this case the common_root is a selected object 01297 // and only this needs to be inserted in the m_topFCOs/Folders 01298 if ( path_map[ l].length() == common_path.length() + 1 ) 01299 are_all_seld_children_of_common_root = false; 01300 } 01301 01302 if ( !are_all_seld_children_of_common_root) // there is one root/top obj; otherwise the for cycle belwo will do the job 01303 insertNew( common_root_id, true); // inserting the common root/top object 01304 01305 01306 // inserting the objects which stay between the common root and the top objects in the containment hierarchy 01307 for( unsigned int l = 0; l < k; ++l) 01308 { 01309 std::string rest_of_path = path_map[ l]; 01310 rest_of_path = rest_of_path.substr( common_path.length() + 1, rest_of_path.length() - common_path.length() - 1); 01311 01312 bool first_after_the_common_root = true; 01313 while( !rest_of_path.empty()) 01314 { 01315 std::string next_id; 01316 pos = rest_of_path.find( '/'); // no leading '/' but a tailing '/' is there anyway 01317 ASSERT( pos); // pos != 0 01318 01319 if ( pos != -1) 01320 { 01321 next_id = rest_of_path.substr( 0, pos); 01322 rest_of_path = rest_of_path.substr( pos + 1, rest_of_path.length() - pos - 1); 01323 } 01324 else 01325 { 01326 ASSERT( 0); 01327 next_id = rest_of_path; 01328 rest_of_path = ""; // to end the loop 01329 } 01330 01331 insertNew( next_id, are_all_seld_children_of_common_root && first_after_the_common_root); 01332 first_after_the_common_root = false; 01333 } 01334 01335 // rest_of_path cannot be empty ( <=> first_after_the_common_root cannot be true) 01336 // with 'are_all_seld_children_of_common_root' being true 01337 // p: all selected are children (not equal) of the common root 01338 // q: the remaining path is not empty <==> first after the common root is false 01339 // ASSERT( p -> q) <=> ASSERT( !p || q) 01340 01341 ASSERT( !are_all_seld_children_of_common_root || !first_after_the_common_root); 01342 } 01343 01344 01345 // inserting into the list of selected objects the newly selected ones 01346 m_selFolds.insert( m_selFolds.end(), m_newlySelFolds.begin(), m_newlySelFolds.end()); 01347 m_selFcos.insert( m_selFcos.end(), m_newlySelFcos.begin(), m_newlySelFcos.end()); 01348 01349 m_newlySelFolds.clear(); 01350 m_newlySelFcos.clear(); 01351 } 01352 01353 void CMakeClosure::checkMeta( const CComObjPtrVector<IMgaFolder>& p_folds, const CComObjPtrVector<IMgaFCO>& p_fcos) 01354 { 01355 if ( p_folds.empty() && p_fcos.empty()) 01356 { 01357 m_acceptingKindsAndFolders.push_back( rootfolder_str); 01358 return; 01359 } 01360 01361 // 01362 // looking for potential folder containers 01363 unsigned int how_many_libraries = 0; 01364 std::set < std::string > goody_folds; 01365 bool goody_folds_init_done = false; 01366 for( CComObjPtrVector<IMgaFolder>::const_iterator fold_it = p_folds.begin(); fold_it != p_folds.end(); ++fold_it) 01367 { 01368 // obtaining its meta 01369 CComObjPtr<IMgaMetaFolder> f_meta; 01370 COMTHROW( (*fold_it)->get_MetaFolder( PutOut( f_meta))); 01371 01372 // check if exists library among the top folders 01373 CComBstrObj kind_name; 01374 COMTHROW( f_meta->get_Name( PutOut(kind_name)) ); 01375 std::string kind_nm; 01376 CopyTo( kind_name, kind_nm); 01377 if ( kind_nm == rootfolder_str) 01378 { 01379 ++how_many_libraries; 01380 continue; 01381 } 01382 01383 // will store the folder parents this folder may be part of 01384 std::set < std::string > actual; 01385 CComObjPtrVector<IMgaMetaFolder> act_vec; 01386 f_meta->get_UsedInFolders( PutOut( act_vec) );//zz1 01387 for( CComObjPtrVector<IMgaMetaFolder>::iterator a_i = act_vec.begin(); a_i != act_vec.end(); ++a_i) 01388 { 01389 CComBstrObj name; 01390 COMTHROW( (*a_i)->get_Name( PutOut(name)) ); 01391 std::string s; 01392 CopyTo( name, s); 01393 01394 actual.insert( s); 01395 } 01396 01397 // calculate the intersection of the possible parent folders 01398 if ( goody_folds_init_done) 01399 { 01400 std::set < std::string > res; 01401 std::set_intersection( goody_folds.begin(), goody_folds.end(), actual.begin(), actual.end(), std::inserter( res, res.begin())); 01402 goody_folds = res; 01403 } 01404 else 01405 { 01406 goody_folds = actual; 01407 goody_folds_init_done = true; 01408 } 01409 } 01410 01411 for( CComObjPtrVector<IMgaFCO>::const_iterator kind_it = p_fcos.begin(); kind_it != p_fcos.end(); ++kind_it) 01412 { 01413 // obtaining its meta 01414 CComObjPtr<IMgaMetaFCO> k_meta; 01415 COMTHROW( (*kind_it)->get_Meta( PutOut( k_meta))); 01416 01417 // will store the folder parents this fco may be part of 01418 std::set < std::string > actual; 01419 CComObjPtrVector<IMgaMetaFolder> act_vec; 01420 k_meta->get_UsedInFolders( PutOut( act_vec) );//zz1 01421 for( CComObjPtrVector<IMgaMetaFolder>::iterator a_i = act_vec.begin(); a_i != act_vec.end(); ++a_i) 01422 { 01423 CComBstrObj name; 01424 COMTHROW( (*a_i)->get_Name( PutOut(name)) ); 01425 std::string s; 01426 CopyTo( name, s); 01427 01428 actual.insert( s); 01429 } 01430 01431 // calculate the intersection of the possible parent folders ( goody_folds might be already filled from the cycle before) 01432 if ( goody_folds_init_done) // if goody_folds inited already 01433 { 01434 std::set < std::string > res; 01435 std::set_intersection( goody_folds.begin(), goody_folds.end(), actual.begin(), actual.end(), std::inserter( res, res.begin())); 01436 goody_folds = res; 01437 } 01438 else 01439 { 01440 goody_folds = actual; 01441 goody_folds_init_done = true; 01442 } 01443 } 01444 01445 if( how_many_libraries == 0) //regular case 01446 { 01447 // these folders may contain all objects ( topFCOs and topFolders) 01448 for( std::set< std::string > :: iterator git = goody_folds.begin(); git != goody_folds.end(); ++git) 01449 m_acceptingKindsAndFolders.push_back( *git); 01450 } 01451 else // there are some libraries as top folders, the only possible target to paste in is the roofolder 01452 { 01453 if( p_folds.size() == how_many_libraries || // there are no other folders OR 01454 goody_folds.end() != goody_folds.find( rootfolder_str)) // the RootFolder is a good target for the regular folders and kinds 01455 m_acceptingKindsAndFolders.push_back( rootfolder_str); 01456 } 01457 01458 01459 // 01460 // looking for potential model containers 01461 01462 if ( p_folds.empty()) // if folds needed to be inserted then models positively are not possible containers 01463 { 01464 // will store the intersection of accepting models 01465 std::set < std::string > goody_models; 01466 bool goody_models_init_done = false; 01467 CComObjPtrVector<IMgaFCO>::const_iterator fco_it = p_fcos.begin(); 01468 for( ; fco_it != p_fcos.end(); ++fco_it) 01469 { 01470 // will store the names of those models which may contain this kind (*fco_it) 01471 std::set < std::string > actual_models; 01472 CComObjPtr<IMgaMetaFCO> k_meta; 01473 COMTHROW( (*fco_it)->get_Meta( PutOut( k_meta))); 01474 01475 // when checking the possible container kinds it is enough if we check the kind 01476 // name matching, since an acceptable kind (even with different role) can be inserted 01477 // into a model (if ambiguities exist the resolver is invoked) 01478 // that is why the role the topFCOs have in the containing models is ignored 01479 01480 CComPtr<IMgaMetaRoles> roles; 01481 k_meta->get_UsedInRoles( &roles); // the fco may be used in these roles in the models (in this paradigm) 01482 MGACOLL_ITERATE(IMgaMetaRole, roles) { 01483 // the parent model may contain the kind 01484 CComObjPtr<IMgaMetaModel> m; 01485 COMTHROW( MGACOLL_ITER->get_ParentModel( PutOut( m))); 01486 01487 // take its name 01488 CComBstrObj name; 01489 COMTHROW( m->get_Name( PutOut(name)) ); 01490 std::string s; 01491 CopyTo( name, s); // we have the name of a kind that may appear in the model 01492 01493 actual_models.insert( s); 01494 } 01495 MGACOLL_ITERATE_END; 01496 01497 // calculate the intersection of the possible parent models 01498 if ( goody_models_init_done) // if set already 01499 { 01500 std::set < std::string > res; 01501 std::set_intersection( goody_models.begin(), goody_models.end(), actual_models.begin(), actual_models.end(), std::inserter( res, res.begin())); 01502 goody_models = res; 01503 } 01504 else 01505 { 01506 goody_models = actual_models; 01507 goody_models_init_done = true; 01508 } 01509 } 01510 01511 // these models may contain all objects ( topFCOs only since topFolders is empty) 01512 for( std::set < std::string > :: iterator gid = goody_models.begin(); gid != goody_models.end(); ++gid) 01513 { 01514 m_acceptingKindsAndFolders.push_back( *gid); 01515 } 01516 } 01517 } 01518 01519 // --------------------------------------------------------- transactions 01520 void CMakeClosure::initTrans() 01521 { 01522 //ASSERT( m_project == NULL ); // the constructor initialized it 01523 ASSERT( m_territory == NULL ); 01524 01525 m_territory = NULL; 01526 COMTHROW( m_project->CreateTerritory(NULL, PutOut(m_territory), NULL) ); 01527 01528 // needs write access, when guids are created for all objects in the closure 01529 COMTHROW( m_project->BeginTransaction(m_territory, TRANSACTION_GENERAL) ); 01530 01531 m_GME = get_GME(m_project); 01532 01533 // put the objects into the new territory 01534 CComObjPtrVector<IMgaFCO>::iterator fco_it = m_selFcos.begin(); 01535 for( ; fco_it != m_selFcos.end(); ++fco_it ) 01536 { 01537 CComObjPtr<IMgaObject> obj; 01538 COMTHROW(m_territory->OpenObj(*fco_it, PutOut(obj))); 01539 CComObjPtr<IMgaFCO> fco; 01540 COMTHROW(obj.QueryInterface(fco)); 01541 *fco_it = fco; 01542 } 01543 01544 CComObjPtrVector<IMgaFolder>::iterator fold_it = m_selFolds.begin(); 01545 for( ; fold_it != m_selFolds.end(); ++fold_it ) 01546 { 01547 CComObjPtr<IMgaObject> obj; 01548 COMTHROW(m_territory->OpenObj(*fold_it, PutOut(obj))); 01549 CComObjPtr<IMgaFolder> fold; 01550 COMTHROW(obj.QueryInterface(fold)); 01551 *fold_it = fold; 01552 } 01553 } 01554 01555 void CMakeClosure::doneTrans(bool abort) 01556 { 01557 if( m_territory != NULL ) 01558 m_territory->Destroy(); 01559 m_territory = NULL; 01560 01561 if( m_project != NULL ) 01562 { 01563 if( abort ) 01564 m_project->AbortTransaction(); 01565 else 01566 m_project->CommitTransaction(); 01567 } 01568 m_project = NULL; 01569 } 01570 01571 // --------------------------------------------------------- getters 01572 void CMakeClosure::getFCOs( IMgaFCOs **res_fcos) 01573 { 01574 CComPtr<IMgaFCOs> coll; 01575 COMTHROW(coll.CoCreateInstance(OLESTR("Mga.MgaFCOs"))); 01576 01577 CComObjPtrVector<IMgaFCO>::iterator i = m_selFcos.begin(); 01578 for( ; i != m_selFcos.end(); ++i) 01579 COMTHROW(coll->Append( *i)); 01580 01581 *res_fcos = coll.Detach(); 01582 } 01583 01584 void CMakeClosure::getFolders( IMgaFolders **res_folds) 01585 { 01586 CComPtr<IMgaFolders> coll; 01587 COMTHROW(coll.CoCreateInstance(OLESTR("Mga.MgaFolders"))); 01588 01589 CComObjPtrVector<IMgaFolder>::iterator i = m_selFolds.begin(); 01590 for( ; i != m_selFolds.end(); ++i) 01591 COMTHROW(coll->Append( *i)); 01592 01593 *res_folds = coll.Detach(); 01594 } 01595 01596 bool CMakeClosure::noTopObjs() 01597 { 01598 // this means that either the variables are not calculated 01599 // or The RootFolder is the common root object of all selected objects 01600 // in the latter case for dumping and parsing reasons (is not nice if 01601 // the clipboard contains a project dumped?) another dumper is used 01602 return m_topFcos.empty() && m_topFolds.empty(); 01603 } 01604 01605 void CMakeClosure::clearTopObjs() 01606 { 01607 m_topFcos.clear(); 01608 m_topFolds.clear(); 01609 } 01610 01611 void CMakeClosure::getTopFCOs( IMgaFCOs **res_fcos) 01612 { 01613 CComPtr<IMgaFCOs> coll; 01614 COMTHROW(coll.CoCreateInstance(OLESTR("Mga.MgaFCOs"))); 01615 01616 CComObjPtrVector<IMgaFCO>::iterator i = m_topFcos.begin(); 01617 for( ; i != m_topFcos.end(); ++i) 01618 COMTHROW(coll->Append( *i)); 01619 01620 *res_fcos = coll.Detach(); 01621 } 01622 01623 void CMakeClosure::getTopFolders( IMgaFolders **res_folds) 01624 { 01625 CComPtr<IMgaFolders> coll; 01626 COMTHROW(coll.CoCreateInstance(OLESTR("Mga.MgaFolders"))); 01627 01628 CComObjPtrVector<IMgaFolder>::iterator i = m_topFolds.begin(); 01629 for( ; i != m_topFolds.end(); ++i) 01630 COMTHROW(coll->Append( *i)); 01631 01632 *res_folds = coll.Detach(); 01633 } 01634 01635 bool CMakeClosure::isAnyAccepting() const 01636 { 01637 return m_acceptingKindsAndFolders.size() > 0; 01638 } 01639 01640 void CMakeClosure::getAccKindsInString( std::string& p_resStr) const 01641 { 01642 unsigned int i = 0; 01643 for( i = 0; i < m_acceptingKindsAndFolders.size(); ++i) 01644 { 01645 if(i) p_resStr += " "; 01646 01647 p_resStr += m_acceptingKindsAndFolders[i]; 01648 } 01649 } 01650 01651 const std::vector< std::string >& CMakeClosure::getAccKindsVector() const 01652 { 01653 return m_acceptingKindsAndFolders; 01654 } 01655 01656 void CMakeClosure::send2Console( const std::string& msg) 01657 { 01658 CComBSTR bstr( msg.c_str()); 01659 if( m_GME) m_GME->ConsoleMessage( bstr, MSG_INFO); 01660 else ASSERT(0);// m_GME is not valid 01661 }