GME  13
GMEDoc.cpp
Go to the documentation of this file.
00001 // GMEDoc.cpp : implementation of the CGMEDoc class
00002 //
00003 
00004 #include "stdafx.h"
00005 
00006 #include "GMEApp.h"
00007 #include "GMEstd.h"
00008 
00009 #include "Mainfrm.h"
00010 #include "GMEDoc.h"
00011 #include "GMEView.h"
00012 #include "GuiObject.h"
00013 #include "GuiMeta.h"
00014 #include "GMEEventLogger.h"
00015 #include "Parser.h"
00016 #include "ChildFrm.h"
00017 #include "GMEChildFrame.h"
00018 
00019 
00020 #ifdef _DEBUG
00021 #define new DEBUG_NEW
00022 #undef THIS_FILE
00023 static char THIS_FILE[] = __FILE__;
00024 #endif
00025 
00027 // CGMEDoc
00028 
00029 CGMEDoc* CGMEDoc::theInstance = 0;
00030 
00031 IMPLEMENT_DYNCREATE(CGMEDoc, CDocument)
00032 
00033 BEGIN_MESSAGE_MAP(CGMEDoc, CDocument)
00034         //{{AFX_MSG_MAP(CGMEDoc)
00035         ON_COMMAND(ID_MODE_AUTOCONNECT, OnModeAutoconnect)
00036         ON_UPDATE_COMMAND_UI(ID_MODE_AUTOCONNECT, OnUpdateModeAutoconnect)
00037         ON_COMMAND(ID_MODE_DISCONNECT, OnModeDisconnect)
00038         ON_UPDATE_COMMAND_UI(ID_MODE_DISCONNECT, OnUpdateModeDisconnect)
00039         ON_COMMAND(ID_MODE_EDIT, OnModeEdit)
00040         ON_UPDATE_COMMAND_UI(ID_MODE_EDIT, OnUpdateModeEdit)
00041         ON_COMMAND(ID_MODE_SET, OnModeSet)
00042         ON_UPDATE_COMMAND_UI(ID_MODE_SET, OnUpdateModeSet)
00043         ON_COMMAND(ID_MODE_VISUALIZE, OnModeVisualize)
00044         ON_UPDATE_COMMAND_UI(ID_MODE_VISUALIZE, OnUpdateModeVisualize)
00045         ON_COMMAND(ID_MODE_ZOOM, OnModeZoom)
00046         ON_UPDATE_COMMAND_UI(ID_MODE_ZOOM, OnUpdateModeZoom)
00047         ON_COMMAND(ID_MODE_SHORTCONNECT, OnModeShortConnect)
00048         ON_UPDATE_COMMAND_UI(ID_MODE_SHORTCONNECT, OnUpdateModeShortConnect)
00049         ON_COMMAND(ID_MODE_SHORTDISCONNECT, OnModeShortDisconnect)
00050         ON_UPDATE_COMMAND_UI(ID_MODE_SHORTDISCONNECT, OnUpdateModeShortDisconnect)
00051         ON_UPDATE_COMMAND_UI(ID_FILE_CLOSE, OnUpdateFileClose)
00052         ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh)
00053         ON_COMMAND(ID_BUTTON33020, OnBtnBack)
00054         ON_COMMAND(ID_BUTTON33021, OnBtnFrwd)
00055         ON_COMMAND(ID_BUTTON33022, OnBtnHome)
00056         ON_UPDATE_COMMAND_UI(ID_BUTTON33020, OnUpdateBtnBack)
00057         ON_UPDATE_COMMAND_UI(ID_BUTTON33021, OnUpdateBtnFrwd)
00058         ON_UPDATE_COMMAND_UI(ID_BUTTON33022, OnUpdateBtnHome)
00059         ON_COMMAND(ID_BUTTON33027, OnBtnCloseActive)
00060         ON_COMMAND(ID_BUTTON33028, OnBtnCloseAll)
00061         ON_COMMAND(ID_BUTTON33033, OnBtnCloseAllButOne)
00062         ON_COMMAND(ID_BUTTON33035, OnBtnCycleAspect)
00063         ON_COMMAND(ID_BUTTON33037, OnBtnCycleAllAspects)
00064         ON_COMMAND(ID_BUTTON33044, OnBtnCycleViews)
00065         //}}AFX_MSG_MAP
00066 END_MESSAGE_MAP()
00067 
00069 // CGMEDoc construction/destruction
00070 
00071 CGMEDoc::CGMEDoc()
00072 {
00073         theInstance = this;
00074 
00075         m_isClosing = false;
00076 
00077         editMode = GME_EDIT_MODE;
00078 
00079         // Making the navigation and mode toolbars visible
00080         CMainFrame::theInstance->ShowNavigationAndModeToolbars(true);
00081 
00082         try {
00083             COMTHROW( resolver.CoCreateInstance(L"Mga.MgaResolver"));
00084         }
00085         catch(hresult_exception e) {
00086                 AfxMessageBox(_T("Fatal error: cannot create MGA Resolver component!"),MB_OK | MB_ICONSTOP);
00087         }
00088 }
00089 
00090 CGMEDoc::~CGMEDoc()
00091 {
00092         theInstance = 0;
00093 }
00094 
00095 bool CGMEDoc::CreateFcoList(CGuiObjectList* list,CComPtr<IMgaFCOs> &fcos,CGMEView *view)
00096 {
00097         try {
00098                 view->BeginTransaction(TRANSACTION_READ_ONLY);
00099                 ASSERT(view);
00100 
00101                 CComPtr<IMgaFCOs> coll;
00102                 COMTHROW(coll.CoCreateInstance(OLESTR("Mga.MgaFCOs")));
00103                 POSITION pos = list->GetHeadPosition();
00104                 while(pos) {
00105                         COMTHROW(coll->Append(list->GetNext(pos)->mgaFco));
00106                 }
00107                 COMTHROW(view->currentModel->AddInternalConnections(coll,&fcos));
00108                 view->CommitTransaction();
00109         }
00110         catch(hresult_exception e) {
00111                 view->AbortTransaction(e.hr);
00112                 return false;
00113         }
00114         return true;
00115 }
00116 
00117 bool CGMEDoc::CreateFcoList2(CGuiFcoList* list,CComPtr<IMgaFCOs> &fcos,CGMEView *view, long* p_howmany, bool* array[8])
00118 {
00119         bool all_containers = *array[ 0 ];
00120         bool all_refs           = *array[ 1 ];
00121         bool all_sets           = *array[ 2 ];
00122         bool all_conns      = *array[ 3 ];
00123 
00124         bool any_container      = *array[ 4 ];
00125         bool any_ref            = *array[ 5 ];
00126         bool any_set            = *array[ 6 ];
00127         bool any_conn           = *array[ 7 ];
00128 
00129         long how_many = 0, now_how_many = 0;
00130         try {
00131                 view->BeginTransaction(TRANSACTION_READ_ONLY);
00132                 ASSERT(view);
00133 
00134                 CComPtr<IMgaFCOs> coll;
00135                 COMTHROW(coll.CoCreateInstance(OLESTR("Mga.MgaFCOs")));
00136                 POSITION pos = list->GetHeadPosition();
00137                 while(pos) {
00138                         CComObjPtr<IMgaFCO> one_fco = list->GetNext(pos)->mgaFco;
00139                         COMTHROW(coll->Append( one_fco));
00140 
00141                         objtype_enum type_info;
00142                         COMTHROW( one_fco->get_ObjType(&type_info)); 
00143 
00144                         all_containers &= (type_info == OBJTYPE_MODEL || type_info == OBJTYPE_FOLDER);
00145                         all_refs  &= (type_info == OBJTYPE_REFERENCE);
00146                         all_sets  &= (type_info == OBJTYPE_SET);
00147                         all_conns &= (type_info == OBJTYPE_CONNECTION);
00148 
00149                         any_container |= (type_info == OBJTYPE_MODEL || type_info == OBJTYPE_FOLDER);
00150                         any_ref  |= (type_info == OBJTYPE_REFERENCE);
00151                         any_set  |= (type_info == OBJTYPE_SET);
00152                         any_conn |= (type_info == OBJTYPE_CONNECTION);
00153                         
00154                         ++how_many;
00155                 }
00156                 COMTHROW(view->currentModel->AddInternalConnections(coll,&fcos));
00157 
00158                 // some connections might have been added
00159                 COMTHROW( fcos->get_Count( &now_how_many) ); 
00160                 
00161                 if( now_how_many > how_many)
00162                         any_conn = true;
00163 
00164                 view->CommitTransaction();
00165         }
00166         catch(hresult_exception e) {
00167                 view->AbortTransaction(e.hr);
00168                 return false;
00169         }
00170         
00171         *p_howmany = now_how_many;
00172 
00173         *array[ 0 ] = all_containers;
00174         *array[ 1 ] = all_refs;
00175         *array[ 2 ] = all_sets;
00176         *array[ 3 ] = all_conns;
00177         *array[ 4 ] = any_container;
00178         *array[ 5 ] = any_ref;
00179         *array[ 6 ] = any_set;
00180         *array[ 7 ] = any_conn;
00181 
00182         return true;
00183 }
00184 
00185 bool CGMEDoc::CreateAnnotationList(CGuiAnnotatorList* list,CComPtr<IMgaRegNodes> &anns,CGMEView *view)
00186 {
00187         try {
00188                 view->BeginTransaction(TRANSACTION_READ_ONLY);
00189                 ASSERT(view);
00190                 COMTHROW(anns.CoCreateInstance(OLESTR("Mga.MgaRegNodes")));
00191                 POSITION pos = list->GetHeadPosition();
00192                 while(pos) {
00193                         COMTHROW(anns->Append(list->GetNext(pos)->rootNode));
00194                 }
00195                 view->CommitTransaction();
00196         }
00197         catch(hresult_exception e) {
00198                 view->AbortTransaction(e.hr);
00199                 return false;
00200         }
00201         return true;
00202 }
00203 
00204 void CGMEDoc::CopyToClipboard(CGuiObjectList* list, CGuiAnnotatorList *annList,CGMEDataDescriptor* desc,CGMEView *view)
00205 {
00206         ASSERT( list && desc );
00207 
00208         CGMEDataSource* pDataSource = new CGMEDataSource(theApp.mgaProject);
00209         CComPtr<IMgaFCOs> fcos;
00210         CreateFcoList(list,fcos,view);
00211         CComPtr<IMgaRegNodes> anns;
00212         CreateAnnotationList(annList, anns,view);
00213         pDataSource->SetNodes(fcos);
00214         pDataSource->SetAnnotations(anns);
00215         pDataSource->CacheDescriptor(desc);
00216         pDataSource->SetClipboard();
00217         
00218 }
00219 
00220 void CGMEDoc::CopyClosureToClipboard( CGuiObjectList* list, CGuiAnnotatorList *annList, CGMEDataDescriptor* desc, CGMEView *view)
00221 {
00222         ASSERT( list && desc );
00223 
00224         CComPtr<IMgaFCOs> fcos;
00225         CreateFcoList( list, fcos, view);
00226 
00227         CComPtr<IMgaClosure> cl;
00228 
00229         VARIANT_BOOL _refersTo           ; VARIANT_BOOL _referredBy;
00230         VARIANT_BOOL _connections        ; VARIANT_BOOL _connsThroughRefport;
00231         VARIANT_BOOL _setMembers         ; VARIANT_BOOL _memberOfSets;
00232         VARIANT_BOOL _modelContainment   ; VARIANT_BOOL _partOfModels;
00233         VARIANT_BOOL _folderContainment  ; VARIANT_BOOL _partOfFolders;
00234         VARIANT_BOOL _baseTypeOf         ; VARIANT_BOOL _derivedTypesOf;
00235         long _libraryElementHandling;         // 0: stubs; 1: stop; 2: continue
00236         long _wrappingMode;                   // 0: miniproject; 1: automatic; 2: as is
00237         long _kindFilter;                     // -1 = all; otherwise calculate the 0b000rsamf mask; where f = Folders; m = Models; a = Atoms; s = Sets; r = References
00238         long _markThem;
00239         long _options;
00240         VARIANT_BOOL _directionDown;
00241         VARIANT_BOOL _copyToFile;             // file or clipboard
00242         VARIANT_BOOL _okPressed;              // how ended the dialog
00243         CComBSTR _userSelFileName;
00244 
00245         COMTHROW( cl.CoCreateInstance(L"Mga.MgaClosure") );
00246 
00247         // ask the last closure id in a RO transaction
00248         view->BeginTransaction( TRANSACTION_READ_ONLY);
00249         try {
00250                 COMTHROW( cl->GetLastClosureId( theApp.mgaProject, &_markThem));
00251                 view->CommitTransaction();
00252         } catch( hresult_exception& e) {
00253                 view->AbortTransaction( e.hr);
00254                 _markThem = -2; // will be increased to -1
00255         }
00256 
00257         ++_markThem; // propose this as the next closure id
00258 
00259         COMTHROW( cl->SelectiveClosureDlg
00260                 ( VARIANT_FALSE
00261                 , &_refersTo           , &_referredBy
00262                 , &_connections        , &_connsThroughRefport
00263                 , &_setMembers         , &_memberOfSets
00264                 , &_modelContainment   , &_partOfModels
00265                 , &_folderContainment  , &_partOfFolders
00266                 , &_baseTypeOf         , &_derivedTypesOf
00267                 , &_libraryElementHandling          // 0: stubs; 1: stop; 2: continue
00268                 , &_wrappingMode                    // 0: miniproject; 1: automatic; 2: as is
00269                 , &_kindFilter                      // -1 = all; otherwise calculate the 0b000rsamf mask; where f = Folders; m = Models; a = Atoms; s = Sets; r = References
00270                 , &_markThem                        // -1 = do not mark; otherwise mark it with the value
00271                 , &_options
00272                 , &_directionDown
00273                 , &_copyToFile              // file or clipboard
00274                 , &_okPressed               // how ended the dialog
00275                 , &_userSelFileName
00276                 ));
00277         if( _okPressed == VARIANT_FALSE) return;
00278 
00279         if( _markThem != -1) // save this if elements need to be marked
00280         {
00281                 view->BeginTransaction();
00282                 try {
00283                         COMTHROW( cl->PutLastClosureId( theApp.mgaProject, _markThem));
00284                         view->CommitTransaction();
00285                 } catch( hresult_exception& e) {
00286                         view->AbortTransaction( e.hr);
00287                 }
00288         }
00289 
00290         CComObjPtr<IMgaFCOs> sel_fcos, top_fcos;
00291         CComObjPtr<IMgaFolders> sel_folders, top_folders;
00292         VARIANT_BOOL tops_filled = VARIANT_FALSE;
00293         CComBstrObj acc_kinds;
00294 
00295         COMTHROW( cl->SelectiveClosureCalc
00296                 ( fcos          , 0
00297                 , _refersTo          , _referredBy
00298                 , _connections       , _connsThroughRefport
00299                 , _setMembers        , _memberOfSets
00300                 , _modelContainment  , _partOfModels
00301                 , _folderContainment , _partOfFolders
00302                 , _baseTypeOf        , _derivedTypesOf
00303                 , _libraryElementHandling          // 0: stubs, 1: stop, 2: continue
00304                 , _wrappingMode                    // 0: miniproject, 1: automatic, 2: as is
00305                 , _kindFilter                      // -1 = all, otherwise calculate the 0b000rsamf mask, where f = Folders, m = Models, a = Atoms, s = Sets, r = References
00306                 , _markThem                        // -1 = do not mark;
00307                 , _directionDown
00308                 , PutOut( sel_fcos), PutOut( sel_folders)
00309                 , PutOut( top_fcos), PutOut( top_folders)
00310                 , &tops_filled
00311                 , PutOut( acc_kinds)
00312                 ));
00313 
00314         if( !sel_fcos && !sel_folders) return;
00315 
00316         if( _copyToFile == VARIANT_TRUE) 
00317         {
00318                 CComPtr<IMgaDumper> dumper;
00319                 COMTHROW( dumper.CoCreateInstance(L"Mga.MgaDumper") );
00320 
00321                 if( _wrappingMode == 0)
00322                 {
00323                         COMTHROW( dumper->DumpClos( sel_fcos, sel_folders, _userSelFileName, _options));
00324                 }
00325                 else if( _wrappingMode == 1 || _wrappingMode == 2)
00326                 {
00327                         if ( tops_filled == VARIANT_TRUE)
00328                                 COMTHROW( dumper->DumpClosR( sel_fcos, sel_folders, _userSelFileName, top_fcos, top_folders, _options, 0, acc_kinds));
00329                         else 
00330                                 // dump like in miniproject case from The RootFolder
00331                                 // if the data is copied to clipboard then the DumpClosR will call the 
00332                                 // DumpClos when it will realize the topfco and topfolders are empty
00333                                 COMTHROW( dumper->DumpClos( sel_fcos, sel_folders, _userSelFileName, _options));
00334                 }
00335         }
00336         else // _copyToFile == VARIANT_FALSE 
00337         {
00338                 CGMEClosureDataSource * pDataSource = new CGMEClosureDataSource( theApp.mgaProject);
00339 
00340                 if ( sel_fcos)          pDataSource->SetNodes( sel_fcos);
00341                 if ( sel_folders)       pDataSource->SetFolders( sel_folders);
00342                 
00343                 if ( top_fcos)          pDataSource->SetTopNodes( top_fcos);
00344                 if ( top_folders)       pDataSource->SetTopNodes( top_folders);
00345 
00346                 pDataSource->SetOptions( _options);
00347                 pDataSource->SetAcceptingKinds( acc_kinds);
00348 
00349                 CComPtr<IMgaRegNodes> anns; 
00350                 CreateAnnotationList( annList, anns, view);
00351                 pDataSource->SetAnnotations( anns);
00352                 pDataSource->CacheDescriptor( desc);
00353                 pDataSource->SetClipboard();
00354                 pDataSource->FlushClipboard();
00355         }
00356 }
00357 
00358 void CGMEDoc::CopySmartToClipboard( CGuiFcoList* list, CGuiAnnotatorList *annList, CGMEDataDescriptor* desc, CGMEView *view)
00359 {
00360         int k = 0;
00361         bool all_containers = true;
00362         bool all_refs = true;
00363         bool all_sets = true;
00364         bool all_conns = true;
00365 
00366         bool any_container = false;
00367         bool any_ref = false;
00368         bool any_set = false;
00369         bool any_conn = false;
00370 
00371         ASSERT( list && desc );
00372 
00373         CComPtr<IMgaFCOs> fcos;
00374         bool* b_array[8] = { &all_containers, &all_refs, &all_sets, &all_conns, &any_container, &any_ref, &any_set, &any_conn };
00375         long number_of_elems = 0;
00376 
00377         if( !CreateFcoList2( list, fcos, view, &number_of_elems, b_array)) return;
00378 
00379         if( number_of_elems == 0) 
00380         {
00381                 AfxMessageBox(_T("No object selected"), MB_ICONERROR);
00382                 return;
00383         }
00384 
00385         
00386         CComPtr<IMgaClosure> cl;
00387         CComObjPtr<IMgaFCOs> sel_fcos, top_fcos;
00388         CComObjPtr<IMgaFolders> sel_folders, top_folders;
00389         long options;
00390         CComBstrObj acckinds; 
00391         CComBstrObj path; 
00392 
00393         // commented out when new smart copy introduced
00394         // if container selected then it must be lonely (no multiple selection)
00395         // if container selected no other kinds allowed
00396         //if( any_container && !all_containers || number_of_elems > 1 && all_containers)
00397         //{
00398         //      AfxMessageBox(_T("Invalid selection for smart copy. You can select either one container or several non-containers."), MB_ICONERROR);
00399         //      return;
00400         //}
00401 
00402         if( any_container) k |= 1024;
00403 
00404         if( any_ref) k |= 2048;
00405         if( any_set) k |= 4096;
00406         if( any_conn) k |= 8192;
00407 
00408         COMTHROW( cl.CoCreateInstance(L"Mga.MgaClosure") );
00409         
00410         COMTHROW( cl->SmartCopy( 
00411                 fcos, 
00412                 0, 
00413                 PutOut( sel_fcos), 
00414                 PutOut( sel_folders), 
00415                 PutOut( top_fcos), 
00416                 PutOut( top_folders), 
00417                 k, 
00418                 &options, 
00419                 PutOut( acckinds),
00420                 PutOut( path)
00421                 ));
00422         
00423         if ( sel_fcos || sel_folders) // if both null the operation is not needed (either dumped to file already or unsuccessful)
00424         {
00425                 CRectList dummyAnnList;
00426 
00427                 CGMEClosureDataSource * pDataSource = new CGMEClosureDataSource( theApp.mgaProject);
00428 
00429                 if ( sel_fcos)          pDataSource->SetNodes( sel_fcos);
00430                 if ( sel_folders)       pDataSource->SetFolders( sel_folders);
00431                 
00432                 if ( top_fcos)          pDataSource->SetTopNodes( top_fcos);
00433                 if ( top_folders)       pDataSource->SetTopNodes( top_folders);
00434 
00435                 pDataSource->SetOptions( options);
00436                 pDataSource->SetAbsPathPart( path);
00437                 pDataSource->SetAcceptingKinds( acckinds);
00438 
00439                 CComPtr<IMgaRegNodes> anns; 
00440                 CreateAnnotationList( annList, anns, view);
00441                 pDataSource->SetAnnotations( anns);
00442                 pDataSource->CacheDescriptor( desc);
00443                 pDataSource->SetClipboard();
00444                 pDataSource->FlushClipboard();
00445         }
00446 }
00447 
00448 DROPEFFECT CGMEDoc::DoDragDrop(CGuiObjectList* list, CGuiAnnotatorList *annList, CGMEDataDescriptor* desc,
00449         DWORD dwEffects, LPCRECT lpRectStartDrag,CGMEView *view)
00450 {
00451         ASSERT( list && desc && annList );
00452 
00453         CGMEDataSource dataSource(theApp.mgaProject);
00454         CComPtr<IMgaFCOs> fcos;
00455         CreateFcoList(list,fcos,view);
00456         CComPtr<IMgaRegNodes> anns;
00457         CreateAnnotationList(annList, anns,view);
00458         dataSource.SetNodes(fcos);
00459         dataSource.SetAnnotations(anns);
00460         dataSource.CacheDescriptor(desc);
00461         DROPEFFECT de = dataSource.DoDragDrop(dwEffects,lpRectStartDrag);
00462         return de;
00463 }
00464 
00465 DROPEFFECT CGMEDoc::DoDragDrop(CGuiObject *guiObj, CGMEDataDescriptor* desc,
00466         DWORD dwEffects, LPCRECT lpRectStartDrag)
00467 {
00468         CGMEDataSource dataSource(theApp.mgaProject);
00469         dataSource.SetMetaRole(guiObj->metaRole);
00470         dataSource.CacheDescriptor(desc);
00471         DROPEFFECT de = dataSource.DoDragDrop(dwEffects,lpRectStartDrag);
00472         return de;
00473 }
00474 
00475 #if !defined (ACTIVEXGMEVIEW)
00476 CGMEView
00477 #else
00478 CGMEChildFrame
00479 #endif
00480 *CGMEDoc::FindView(CComPtr<IMgaModel> model)
00481 {
00482         if(model != 0) {
00483                 POSITION pos = GetFirstViewPosition();
00484                 while (pos != NULL) {
00485 #if !defined (ACTIVEXGMEVIEW)
00486                         CGMEView* view = (CGMEView *)GetNextView(pos);
00487                         VARIANT_BOOL b; 
00488                         // COMTHROW(model->get_IsEqual(view->GetCurrentModel(), &b));  Territory problems
00489                         // bool b = model.IsEqualObject(view->GetCurrentModel());
00490                         view->BeginTransaction(TRANSACTION_READ_ONLY);
00491                         // FIXME: need to adopt when inserting a model from model editor context menu
00492                         COMTHROW(view->GetCurrentModel()->get_IsEqual(model, &b));
00493                         view->CommitTransaction();
00494                         if(b)
00495                                 return view;
00496 #else
00497                         CGMEChildFrame* pView = (CGMEChildFrame *)GetNextView(pos);
00498                         VARIANT_BOOL b;
00499                         long status;
00500                         COMTHROW(theApp.mgaProject->get_ProjectStatus(&status));
00501                         bool inTrans = (status & 0x08L) != 0;
00502                         CComPtr<IMgaTerritory> terr;
00503                         if (!inTrans) {
00504                                 COMTHROW(theApp.mgaProject->CreateTerritory(NULL, &terr));
00505                                 COMTHROW(theApp.mgaProject->BeginTransaction(terr, TRANSACTION_READ_ONLY));
00506                         } else {
00507                                 COMTHROW(theApp.mgaProject->get_ActiveTerritory(&terr));
00508                         }
00509 
00510                         CComPtr<IMgaModel> mgaModel = pView->GetMgaModel();
00511                         if (mgaModel)
00512                                 COMTHROW(mgaModel->get_IsEqual(model, &b));
00513                         if (!inTrans) {
00514                                 theApp.mgaProject->CommitTransaction();
00515                         }
00516                         if (mgaModel && b)
00517                                 return pView;
00518 #endif
00519                 }
00520         }
00521         return 0;
00522 }
00523 
00524 void CGMEDoc::DoOnViewRefresh(void)
00525 {
00526         OnViewRefresh();
00527 }
00528 
00529 void CGMEDoc::InvalidateAllViews(bool thorough,bool /*fullAutoRoute*/)
00530 {
00531         POSITION pos = GetFirstViewPosition();
00532         while (pos != NULL) {
00533 #if !defined (ACTIVEXGMEVIEW)
00534                 CGMEView* pView = (CGMEView *)GetNextView(pos);
00535 /*
00536                 if(!pView->IsIconic())
00537                         fullAutoRoute ? pView->AutoRoute() : pView->IncrementalAutoRoute();
00538 */
00539                 pView->Invalidate(thorough);
00540 #endif
00541         }
00542         if(thorough) {
00543                 CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
00544                 CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();
00545                 ((CGMEView *)(pChild->GetActiveView()))->Invalidate(thorough);
00546         }
00547 }
00548 
00549 void CGMEDoc::ShowObject(CComPtr<IUnknown> alienObject, BOOL inParent)
00550 {
00551         // Be prepared for in-transaction and out-transaction scenarios
00552         // mgaFCO must be transfered to current territory
00553 
00554         // Additional note (JIRA GME-219):
00555         // In case this function is used through the IGMEOLEApp interface, the call won't be successful, because
00556         // CMainFrame::CreateNewView will initiate a CGMEView::OnInitialUpdate (docTemplate->InitialUpdateFrame),
00557         // which cannot handle an open transaction
00558 
00559         bool isModel = true;
00560         if(alienObject == NULL) {
00561                 return;
00562         }
00563 
00564         if (!theApp.mgaProject) {
00565                 return;
00566         }
00567 
00568         CComPtr<IMgaFCO> fco;
00569         CComPtr<IMgaModel> model;
00570         
00571         
00572         long status;
00573         COMTHROW(theApp.mgaProject->get_ProjectStatus(&status));
00574         bool inTrans = (status & 0x08L) != 0;
00575         CComPtr<IMgaTerritory> terr;
00576 
00577         if (!SUCCEEDED(alienObject.QueryInterface(&model))) {  // Alien object is not a modell
00578                 isModel = false;
00579                 if (SUCCEEDED(alienObject.QueryInterface(&fco))) {
00580                         
00581                         try {
00582                                 if (!inTrans) {
00583                                         COMTHROW(theApp.mgaProject->CreateTerritory(NULL, &terr, NULL));
00584                                         COMTHROW(theApp.mgaProject->BeginTransaction(terr, TRANSACTION_GENERAL));
00585                                 }
00586                                 else {
00587                                         COMTHROW(theApp.mgaProject->get_ActiveTerritory(&terr));
00588                                 }
00589                                 CComPtr<IMgaFCO> tmpfco = fco;
00590                                 fco = NULL;
00591                                 COMTHROW(terr->OpenFCO(tmpfco, &fco));
00592                         }
00593                         catch (hresult_exception e) {
00594                                 return;
00595                         }
00596 
00597                         try {
00598                                 CComPtr<IMgaObject> parent;
00599                                 COMTHROW(fco->GetParent(&parent, NULL));
00600                                 model = NULL;
00601                                 COMTHROW(parent.QueryInterface(&model));
00602                         }
00603                         catch (hresult_exception e) {
00604                                 model = NULL;
00605                                 if (!inTrans) 
00606                                         theApp.mgaProject->AbortTransaction();
00607                         }
00608 
00609                         if (!inTrans) {
00610                                 theApp.mgaProject->CommitTransaction();
00611                         }
00612                 }
00613         }
00614 
00615         if (model  &&  isModel  &&  inParent)
00616         {
00617 
00618                 try 
00619                 {
00620                         if (!inTrans) {
00621                                 COMTHROW(theApp.mgaProject->CreateTerritory(NULL, &terr, NULL));
00622                                 COMTHROW(theApp.mgaProject->BeginTransaction(terr, TRANSACTION_GENERAL));
00623                                 CComPtr<IMgaModel> tmpmod = model; // put model into the active territory
00624                                 model = NULL;
00625                                 CComPtr<IMgaFCO> fco_mod;
00626                                 COMTHROW(terr->OpenFCO(tmpmod, &fco_mod)); // OpenFCO fills an IMgaFCO
00627                                 COMTHROW( fco_mod.QueryInterface( &model));// casted to IMgaModel
00628                         }
00629                         CComPtr<IMgaObject> parent;
00630                         COMTHROW(model->GetParent(&parent, NULL));
00631                         COMTHROW(model.QueryInterface(&fco));
00632                         model = NULL;
00633                         COMTHROW(parent.QueryInterface(&model));
00634                         // it might be invoked from the ActiveBrowser (on a top model)
00635                         // in which case line above must throw if parent is a folder
00636 
00637                         if (!inTrans) 
00638                                 theApp.mgaProject->CommitTransaction();
00639                 }
00640                 catch (hresult_exception e) 
00641                 {
00642                         model = NULL;
00643                         if (!inTrans) 
00644                                 theApp.mgaProject->AbortTransaction();
00645                 }
00646         }
00647         if (model) {
00648 #if !defined (ACTIVEXGMEVIEW)
00649                 CGMEView *view  = NULL;
00650 #else
00651                 CGMEChildFrame* view = NULL;
00652 #endif
00653 
00654                 if (!theApp.multipleView) {
00655                         view = FindView(model);
00656                         if(!view) {
00657                                 SetNextToView(model,_T(""), fco);
00658                         }
00659                         else {
00660 #if !defined (ACTIVEXGMEVIEW)
00661                                 view->SetCenterObject(fco);
00662 #endif
00663                                 if( theApp.isHistoryEnabled())
00664                                 {
00665                                         //clear history
00666                                         clearForwHistory();
00667                                 }
00668                         }
00669                 }
00670                 else {
00671                         SetNextToView(model,_T(""), fco);
00672                 }
00673 
00674                 CMainFrame::theInstance->CreateNewView(view, model);
00675                 // PETER: This is needed to get the focus (SetFocus does not work, since it uses SendMessage())
00676                 ::PostMessage(CMainFrame::theInstance->GetSafeHwnd(), WM_SETFOCUS, 0, 0);
00677         }
00678 }
00679 
00680 void CGMEDoc::ShowObject(LPCTSTR objectID)
00681 {
00682         CComBSTR bstrID(objectID);
00683         CComPtr<IMgaObject> object;
00684         CComPtr<IUnknown> unk;
00685         bool inTrans = false;
00686 
00687 
00688         try {
00689                 long status;
00690                 COMTHROW(theApp.mgaProject->get_ProjectStatus(&status));
00691                 inTrans = (status & 0x08L) != 0;
00692                 CComPtr<IMgaTerritory> terr;
00693                 if (!inTrans) {
00694                         COMTHROW(theApp.mgaProject->CreateTerritory(NULL, &terr, NULL));
00695                         COMTHROW(theApp.mgaProject->BeginTransaction(terr, TRANSACTION_GENERAL));
00696                 }
00697                 else {
00698                         COMTHROW(theApp.mgaProject->get_ActiveTerritory(&terr));
00699                 }
00700 
00701                 COMTHROW(theApp.mgaProject->GetObjectByID(bstrID, &object));
00702                 COMTHROW(object.QueryInterface(&unk));
00703 
00704                 // CheckRead() to see if this object was deleted
00705                 long relid;
00706                 COMTHROW(object->get_RelID(&relid));
00707                 if (!inTrans) {
00708                         theApp.mgaProject->CommitTransaction();
00709                 }
00710         }
00711         catch (hresult_exception e) {
00712                 if (!inTrans) 
00713                         theApp.mgaProject->AbortTransaction();
00714                 return;
00715         }
00716 
00717         
00718         ShowObject(unk);
00719 }
00720 
00721 GMEModeCode CGMEDoc::GetEditMode() const
00722 {
00723         return editMode;
00724 }
00725 
00726 void CGMEDoc::SetEditMode(GMEModeCode mode, const CString& statusMsg)
00727 {
00728         editMode = mode;
00729         CMainFrame::theInstance->WriteStatusMode(statusMsg);
00730         ViewModeChange();
00731 }
00732 
00733 int  CGMEDoc::HowManyViewsAreOpen()
00734 {
00735         int i = 0;
00736         POSITION pos = GetFirstViewPosition();
00737         if(pos) {
00738                 while (pos != NULL) {
00739                         CGMEView* pView = (CGMEView *)GetNextView(pos);
00740                         ++i;
00741                 }
00742         }
00743         return i;
00744 }
00745 
00746 void CGMEDoc::ResetAllViews()
00747 {
00748         POSITION pos = GetFirstViewPosition();
00749         if(pos) {
00750                 while (pos != NULL) {
00751 #if !defined (ACTIVEXGMEVIEW)
00752                         CGMEView* pView = (CGMEView *)GetNextView(pos);
00753                         pView->Reset(true);
00754 #endif
00755                 }
00756 //              InvalidateAllViews(true);
00757         }
00758 }
00759 
00760 void CGMEDoc::ChangeAspects(int index, CString aspName)
00761 {
00762         POSITION pos = GetFirstViewPosition();
00763         if (pos) {
00764                 while (pos != NULL) {
00765 #if defined(ACTIVEXGMEVIEW)
00766                         CGMEChildFrame* pView = (CGMEChildFrame *)GetNextView(pos);
00767                         pView->ChangeAspect(index);
00768 #else
00769                         CGMEView* pView = (CGMEView *)GetNextView(pos);
00770                         pView->ChangeAspect(aspName);
00771 #endif
00772                 }
00773         }
00774 }
00775 
00776 void CGMEDoc::ConvertPathToCustom(CComPtr<IUnknown>& pMgaObject)
00777 {
00778 
00779         POSITION pos = GetFirstViewPosition();
00780         if (pos) {
00781                 while (pos != NULL) {
00782                         CGMEView* pView = (CGMEView*)GetNextView(pos);
00783 
00784                         pView->BeginTransaction();
00785                         try {
00786                                 pView->ConvertPathToCustom(pMgaObject);
00787                                 pView->CommitTransaction();
00788                         } catch(hresult_exception& e) {
00789                                 pView->AbortTransaction(e.hr);
00790                         }
00791                 }
00792         }
00793 }
00794 
00795 void CGMEDoc::ViewModeChange()
00796 {
00797         POSITION pos = GetFirstViewPosition();
00798         while (pos != NULL) {
00799 #if !defined (ACTIVEXGMEVIEW)
00800                 CGMEView* pView = (CGMEView *)GetNextView(pos);
00801                 pView->ModeChange();
00802 #endif
00803         }
00804 
00805         // make sure that the currently open model has the focus
00806         CMainFrame::theInstance->SetFocus();
00807 }
00808 
00810 // CGMEDoc diagnostics
00811 
00812 #ifdef _DEBUG
00813 void CGMEDoc::AssertValid() const
00814 {
00815         CDocument::AssertValid();
00816 }
00817 
00818 void CGMEDoc::Dump(CDumpContext& dc) const
00819 {
00820         CDocument::Dump(dc);
00821 }
00822 #endif //_DEBUG
00823 
00825 // CGMEDoc commands
00826 
00827 void CGMEDoc::SetMode(long mode)
00828 {
00829         switch (mode)
00830         {
00831         case 0: // edit
00832                 OnModeEdit();
00833                 break;
00834         case 1: // connect
00835                 OnModeAutoconnect();
00836                 break;
00837         case 2: // disconnect
00838                 OnModeDisconnect();
00839                 break;
00840         case 3: // set
00841                 OnModeSet();
00842                 break;
00843         case 4: // zoom
00844                 OnModeZoom();
00845                 break;
00846         case 5: // visualize
00847                 OnModeVisualize();
00848                 break;
00849         case 6: // short-connect
00850                 OnModeShortConnect();
00851                 break;
00852         case 7: // short-disconnect
00853                 OnModeShortDisconnect();
00854                 break;
00855         }
00856 
00857         m_isClosing = false; // in case was turned true
00858 }
00859 
00860 void CGMEDoc::OnModeAutoconnect() 
00861 {
00862         CGMEEventLogger::LogGMEEvent("CGMEDoc::OnModeAutoconnect\r\n");
00863         SetEditMode(GME_AUTOCONNECT_MODE, _T("AUTOCONNECT"));
00864 }
00865 
00866 void CGMEDoc::OnUpdateModeAutoconnect(CCmdUI* pCmdUI) 
00867 {
00868         pCmdUI->SetCheck(editMode == GME_AUTOCONNECT_MODE);
00869 }
00870 
00871 void CGMEDoc::OnModeDisconnect() 
00872 {
00873         CGMEEventLogger::LogGMEEvent("CGMEDoc::OnModeDisconnect\r\n");
00874         SetEditMode(GME_DISCONNECT_MODE, _T("DISCONNECT"));
00875 }
00876 
00877 void CGMEDoc::OnUpdateModeDisconnect(CCmdUI* pCmdUI) 
00878 {
00879         pCmdUI->SetCheck(editMode == GME_DISCONNECT_MODE);
00880 }
00881 
00882 void CGMEDoc::OnModeEdit() 
00883 {
00884         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnModeEdit\r\n"));
00885         SetEditMode(GME_EDIT_MODE, _T("EDIT"));
00886 }
00887 
00888 void CGMEDoc::OnUpdateModeEdit(CCmdUI* pCmdUI) 
00889 {
00890         pCmdUI->SetCheck(editMode == GME_EDIT_MODE);
00891 }
00892 
00893 void CGMEDoc::OnModeSet() 
00894 {
00895         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnModeSet\r\n"));
00896         SetEditMode(GME_SET_MODE, _T("SET"));
00897 }
00898 
00899 void CGMEDoc::OnUpdateModeSet(CCmdUI* pCmdUI) 
00900 {
00901         pCmdUI->SetCheck(editMode == GME_SET_MODE);
00902 }
00903 
00904 void CGMEDoc::OnModeZoom() 
00905 {
00906         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnModeZoom\r\n"));
00907         SetEditMode(GME_ZOOM_MODE, _T("ZOOM"));
00908 }
00909 
00910 void CGMEDoc::OnUpdateModeZoom(CCmdUI* pCmdUI) 
00911 {
00912         pCmdUI->SetCheck(editMode == GME_ZOOM_MODE);
00913 }
00914 
00915 void CGMEDoc::OnModeVisualize() 
00916 {
00917         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnModeVisualize\r\n"));
00918         SetEditMode(GME_VISUAL_MODE, _T("VISUALIZE"));
00919 }
00920 
00921 void CGMEDoc::OnUpdateModeVisualize(CCmdUI* pCmdUI) 
00922 {
00923         pCmdUI->SetCheck(editMode == GME_VISUAL_MODE);
00924 }
00925 
00926 void CGMEDoc::OnModeShortConnect()
00927 {
00928         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnModeShortConnect\r\n"));
00929         SetEditMode(GME_SHORTAUTOCONNECT_MODE, _T("AUTOCONNECT"));
00930 }
00931 
00932 void CGMEDoc::OnUpdateModeShortConnect(CCmdUI* pCmdUI)
00933 {
00934         pCmdUI->SetCheck(editMode == GME_SHORTAUTOCONNECT_MODE);
00935 }
00936 
00937 void CGMEDoc::OnModeShortDisconnect()
00938 {
00939         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnModeShortDisconnect\r\n"));
00940         SetEditMode(GME_SHORTDISCONNECT_MODE, _T("DISCONNECT"));
00941 }
00942 
00943 void CGMEDoc::OnUpdateModeShortDisconnect(CCmdUI* pCmdUI)
00944 {
00945         pCmdUI->SetCheck(editMode == GME_SHORTDISCONNECT_MODE);
00946 }
00947 
00948 void CGMEDoc::OnUpdateFileClose(CCmdUI* pCmdUI) 
00949 {
00950         POSITION pos = GetFirstViewPosition();
00951         pCmdUI->Enable(pos != NULL);
00952 }
00953 
00954 void CGMEDoc::OnCloseDocument(bool suppressErrors) 
00955 {
00956         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnCloseDocument\r\n"));
00957         m_isClosing = true;
00958         POSITION pos = GetFirstViewPosition();
00959         while (pos) {
00960 #if !defined (ACTIVEXGMEVIEW)
00961                 CGMEView* view = dynamic_cast<CGMEView*>(GetNextView(pos));
00962                 ASSERT(view);
00963                 bool canClose = view->SendCloseModelEvent();
00964                 if ((!suppressErrors) && (!canClose)) {
00965                         // View cannot be closed, eg.: constraint violations
00966                         return;
00967                 }
00968 #endif
00969         }
00970 
00971         
00972         CDocument::OnCloseDocument();
00973         resolver = NULL;
00974         theApp.CloseProject();
00975         delete this;
00976 }
00977 
00978 BOOL CGMEDoc::OnNewDocument()
00979 {
00980         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnNewDocument\r\n"));
00981         if (!CDocument::OnNewDocument())
00982                 return FALSE;
00983 
00984         // TODO: add reinitialization code here
00985         // (SDI documents will reuse this document)
00986 
00987         return TRUE;
00988 }
00989 
00990 BOOL CGMEDoc::OnOpenDocument(LPCTSTR /*lpszPathName*/)
00991 {
00992         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnOpenDocument\r\n"));
00993         if (!CDocument::OnNewDocument())
00994                 return FALSE;
00995         
00996         // TODO: Add your specialized creation code here
00997         m_isClosing = false;
00998         
00999         return TRUE;
01000 }
01001 
01002 void CGMEDoc::OnViewRefresh()
01003 {
01004         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::OnViewRefresh\r\n"));
01005         ResetAllViews();
01006         CGMEBrowser::theInstance->RefreshAll();
01007 }
01008 
01009 // ---------------------------------------------------
01010 // ----------- History related methods ---------------
01011 // ---------------------------------------------------
01012 void CGMEDoc::back()
01013 {
01014         if( theApp.isHistoryEnabled() && m_historian.isEnabledBack())
01015         {
01016                 Historian::HistoryElem prev, curr;
01017                 m_historian.popB( prev, curr);
01018                 m_historian.pushF( curr);
01019                 if( !prev.id().empty())
01020                 {
01021                         presentModel( prev.id().c_str(), prev.aspect().c_str());
01022                 }
01023                 else
01024                         CGMEConsole::theInstance->Message( _T("Could not go further backward"), 1);
01025         }
01026 }
01027 
01028 void CGMEDoc::forw()
01029 {
01030         if( theApp.isHistoryEnabled() && m_historian.isEnabledFrwd())
01031         {
01032                 Historian::HistoryElem e;
01033                 m_historian.popF( e);
01034                 m_historian.pushB( e); // this time we should preserve forward stack
01035                 if( !e.id().empty())
01036                 {
01037                         presentModel( e.id().c_str(), e.aspect().c_str());
01038                 }
01039                 else
01040                         CGMEConsole::theInstance->Message( _T("Could not go further forward"), 1);
01041         }
01042 }
01043 
01044 void CGMEDoc::home()
01045 {
01046         if( theApp.isHistoryEnabled() && !m_historian.isEmptyB())
01047         {
01048                 Historian::HistoryElem home;
01049                 m_historian.frontB( home);
01050                 if( !home.id().empty())
01051                 {
01052                         presentModel( home.id().c_str(), home.aspect().c_str());
01053                 }
01054                 else
01055                         CGMEConsole::theInstance->Message( _T("Could not go home"), 1);
01056 
01057                 //m_historian.totalBrainWash();
01058         }
01059 }
01060 
01061 void CGMEDoc::clearTotalHistory()
01062 {
01063         m_historian.totalBrainWash();
01064 }
01065 
01066 void CGMEDoc::clearForwHistory() // could be called: userAction
01067 {
01068         m_historian.frwdBrainWash();
01069 }
01070 
01071 void CGMEDoc::closeActiveWnd()
01072 {
01073 #if !defined (ACTIVEXGMEVIEW)
01074         CGMEView* v = CGMEView::GetActiveView();
01075         if( !v) return;
01076         v->alive = false;
01077         v->frame->SetSendEvent(true);
01078         v->frame->PostMessage(WM_CLOSE);
01079 #endif
01080 }
01081 
01082 void CGMEDoc::closeAllWnd()
01083 {
01084         POSITION pos = GetFirstViewPosition();
01085         while (pos != NULL) {
01086 #if !defined (ACTIVEXGMEVIEW)
01087                 CGMEView* v = (CGMEView *) GetNextView( pos);
01088                 v->alive = false;
01089                 v->frame->SetSendEvent(true);
01090                 v->frame->SendMessage(WM_CLOSE);
01091 #endif
01092         }
01093 }
01094 
01095 void CGMEDoc::closeAllButActiveWnd()
01096 {
01097         CGMEView* actv = CGMEView::GetActiveView();
01098 
01099         POSITION pos = GetFirstViewPosition();
01100         while (pos != NULL) {
01101 #if !defined (ACTIVEXGMEVIEW)
01102                 CGMEView* v = (CGMEView *) GetNextView( pos);
01103                 if( v != actv)
01104                 {
01105                         v->alive = false;
01106                         v->frame->SetSendEvent(true);
01107                         v->frame->SendMessage(WM_CLOSE);
01108                 }
01109 #endif
01110         }
01111 }
01112 
01113 void CGMEDoc::cycleAspect()
01114 {
01115 #if !defined (ACTIVEXGMEVIEW)
01116         CGMEView* actv = CGMEView::GetActiveView();
01117         if( actv)
01118                 actv->CycleAspect();
01119 #endif
01120 }
01121 
01122 void CGMEDoc::cycleAllAspects()
01123 {
01124 #if !defined (ACTIVEXGMEVIEW)
01125         CGMEView* actv = CGMEView::GetActiveView();
01126         if( actv)
01127                 actv->CycleAllAspects();
01128 #endif
01129 }
01130 
01131 void CGMEDoc::cycleViews()
01132 {
01133 #if !defined (ACTIVEXGMEVIEW)
01134         CGMEView* nexv = 0;
01135         CGMEView* actv = CGMEView::GetActiveView();
01136         POSITION pos = GetFirstViewPosition();
01137         while (pos != NULL) {
01138                 CGMEView* v = (CGMEView *) GetNextView( pos);
01139                 if( v == actv)
01140                 {
01141                         if( pos == NULL) // if at the end, go to the first
01142                                 pos = GetFirstViewPosition();
01143                         nexv = (CGMEView *) GetNextView( pos);
01144                         break;
01145                 }
01146         }
01147 
01148         if( nexv)
01149         {
01150                 //nexv->SetFocus();
01151                 CMainFrame::theInstance->CreateNewView( nexv, nexv->GetCurrentModel());
01152                 ::PostMessage(CMainFrame::theInstance->GetSafeHwnd(), WM_SETFOCUS, 0, 0);
01153         }
01154 #endif
01155 }
01156 
01157 void CGMEDoc::tellHistorian( CComBSTR& modid, CString asp)
01158 {
01159         if( !theApp.isHistoryEnabled()) return;
01160         if( theApp.multipleView) return; // do not bother with history in this scenario
01161         if( !modid || modid.Length() == 0) return;
01162 
01163         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::tellHistorian(str,asp)\r\n"));
01164 
01165         Historian::HistoryElem e( (LPCTSTR) PutInCString( modid), (LPCTSTR) asp);
01166         m_historian.erasePrevOccurencesB( e);
01167         m_historian.pushB( e);
01168 }
01169 
01170 void CGMEDoc::tellHistorian( CComPtr<IMgaModel>& model, CString asp)
01171 { 
01172         if( !theApp.isHistoryEnabled()) return;
01173         if( theApp.multipleView) return; // do not bother with history in this scenario
01174         if( !model)              return;
01175 
01176         CGMEEventLogger::LogGMEEvent(_T("CGMEDoc::tellHistorian(ptr,asp)\r\n"));
01177 
01178         try     {
01179                 long status;
01180                 COMTHROW(theApp.mgaProject->get_ProjectStatus(&status));
01181                 bool inTrans = (status & 0x08L) != 0;
01182                 CComPtr<IMgaTerritory> terr;
01183                 if (!inTrans) {
01184                         COMTHROW(theApp.mgaProject->CreateTerritory(NULL, &terr, NULL));
01185                         COMTHROW(theApp.mgaProject->BeginTransaction(terr, TRANSACTION_READ_ONLY));
01186                 }
01187                 else {
01188                         COMTHROW(theApp.mgaProject->get_ActiveTerritory(&terr));
01189                 }
01190 
01191                 status = OBJECT_ZOMBIE;
01192                 
01193                 CComPtr<IMgaFCO>  nfco;
01194                 COMTHROW( terr->OpenFCO( CComPtr<IMgaFCO>( model), &nfco));
01195                 COMTHROW( nfco->get_Status( &status));
01196                 if( status == OBJECT_EXISTS) 
01197                 {
01198                         CComBSTR id;
01199                         COMTHROW( nfco->get_ID( &id));
01200                         
01201                         Historian::HistoryElem e( (LPCTSTR) PutInCString( id), (LPCTSTR) asp);
01202                         m_historian.erasePrevOccurencesB( e);
01203                         m_historian.pushB( e);
01204                 }
01205 
01206                 if (!inTrans) {
01207                         theApp.mgaProject->CommitTransaction();
01208                 }
01209         } catch(...) {
01210                 ASSERT(0);
01211                 m_historian.totalBrainWash();
01212         }
01213 }
01214 
01215 void CGMEDoc::eraseFromHistory( LPCTSTR p_id)
01216 {
01217         if( !theApp.isHistoryEnabled()) return;
01218 
01219         m_historian.eraseOccurences( p_id);
01220 }
01221 
01222 void CGMEDoc::presentModel( LPCTSTR p_objectId, LPCTSTR p_aspectName)
01223 {
01224         if( !theApp.isHistoryEnabled()) return;
01225 
01226         if( theApp.multipleView) return; // do not bother with history in this scenario
01227         if( !theApp.mgaProject)  return;
01228 
01229         bool               inTrans( false);
01230         CComBSTR           model_id( p_objectId);
01231         CComPtr<IMgaFCO>   object;
01232         CComPtr<IMgaModel> model;
01233 
01234         try {
01235                 long status;
01236                 COMTHROW(theApp.mgaProject->get_ProjectStatus(&status));
01237                 inTrans = (status & 0x08L) != 0;
01238                 CComPtr<IMgaTerritory> terr;
01239                 if (!inTrans) {
01240                         COMTHROW(theApp.mgaProject->CreateTerritory(NULL, &terr, NULL));
01241                         COMTHROW(theApp.mgaProject->BeginTransaction(terr, TRANSACTION_READ_ONLY));
01242                 }
01243                 else
01244                         COMTHROW(theApp.mgaProject->get_ActiveTerritory(&terr));
01245 
01246                 COMTHROW( theApp.mgaProject->GetFCOByID( model_id, &object));
01247                 status = OBJECT_ZOMBIE;
01248                 // check if object really exists
01249                 if( object)
01250                 {
01251                         COMTHROW( object.QueryInterface( &model));
01252                         COMTHROW( object->get_Status( &status));
01253                 }
01254 
01255                 if( status != OBJECT_EXISTS || !model)
01256                         throw hresult_exception( -1);
01257 
01258                 if( !inTrans)
01259                         theApp.mgaProject->CommitTransaction();
01260         }
01261         catch (hresult_exception e) {
01262                 if (!inTrans) 
01263                         theApp.mgaProject->AbortTransaction();
01264 
01265                 eraseFromHistory( p_objectId);
01266                 return;
01267         }
01268 
01269         ASSERT( model);
01270 #if !defined (ACTIVEXGMEVIEW)
01271         CGMEView *view  = FindView(model);
01272 #else
01273         CGMEChildFrame* view = FindView(model);
01274 #endif
01275         if( !view)
01276         {
01277                 SetNextToView( model, p_aspectName, CComPtr<IMgaFCO>()); // p_aspectName used here
01278         }
01279 #if !defined (ACTIVEXGMEVIEW)
01280         else if( view->currentAspect && view->currentAspect->name != p_aspectName)
01281         {
01282                 view->ChangeAspect( p_aspectName, false);
01283         }
01284 #endif
01285 
01286         // PETER: This is needed to get the focus (SetFocus does not work, since it uses SendMessage())
01287         CMainFrame::theInstance->CreateNewView(view, model);
01288         ::PostMessage(CMainFrame::theInstance->GetSafeHwnd(), WM_SETFOCUS, 0, 0);
01289 }
01290 
01291 //**********************************************************************************************
01292 //**********************************************************************************************
01293 //*********   C L A S S        H I S T O R I A N     *******************************************
01294 //**********************************************************************************************
01295 //**********************************************************************************************
01296 void CGMEDoc::Historian::pushB( const HistoryElem& e)
01297 {
01298         HistoryElem f = m_backStack.empty()? HistoryElem() : m_backStack.back();
01299         if( f != e)
01300                 m_backStack.push_back( e);
01301 }
01302 void CGMEDoc::Historian::pushF( const HistoryElem& e)
01303 {
01304         HistoryElem f = m_frwdStack.empty()? HistoryElem() : m_frwdStack.back();
01305         if( f != e)
01306                 m_frwdStack.push_back( e);
01307 }
01308 
01309 void CGMEDoc::Historian::popB( HistoryElem& p_prev, HistoryElem& p_current)
01310 {
01311         if( m_backStack.size() <= 1) return;
01312         p_current = m_backStack.back();
01313         m_backStack.pop_back(); // get rid of current
01314         p_prev = m_backStack.back();
01315 }
01316 
01317 void CGMEDoc::Historian::popF( HistoryElem& e)
01318 {
01319         if( m_frwdStack.size() < 1) return;
01320         e = m_frwdStack.back();
01321         m_frwdStack.pop_back();
01322 }
01323 
01324 void CGMEDoc::Historian::frontB( HistoryElem& p_front)
01325 {
01326         if( m_backStack.size() == 0) return;
01327         p_front = m_backStack.front();
01328 }
01329 
01330 bool CGMEDoc::Historian::isEmptyB() const
01331 {
01332         return m_backStack.size() == 0;
01333 }
01334 
01335 bool CGMEDoc::Historian::isEnabledBack() const
01336 {
01337         return m_backStack.size() > 1;
01338 }
01339 
01340 bool CGMEDoc::Historian::isEnabledFrwd() const
01341 {
01342         return m_frwdStack.size() > 0;
01343 }
01344 
01345 bool CGMEDoc::Historian::isEnabledHome() const
01346 {
01347         return !isEmptyB();
01348 }
01349 
01350 void CGMEDoc::Historian::totalBrainWash()
01351 {
01352         m_frwdStack.clear();
01353         m_backStack.clear();
01354 }
01355 
01356 void CGMEDoc::Historian::frwdBrainWash()
01357 {
01358         m_frwdStack.clear();
01359 }
01360 
01361 void CGMEDoc::Historian::erasePrevOccurencesB( const HistoryElem& elem)
01362 {
01363         HISTLIST_ITER it;
01364         
01365         // backward stack
01366         it = m_backStack.begin();
01367         while( it != m_backStack.end())
01368         {
01369                 if( *it == elem)
01370                         it = m_backStack.erase( it); // will progress it
01371                 else
01372                         ++it;
01373         }
01374 
01375         // FIXME: MAX_LEN != MAX_LEN is always false
01376         const int MAX_LEN = -1;
01377         while( MAX_LEN != -1 && m_backStack.size() > MAX_LEN)
01378         {
01379                 m_backStack.pop_front();
01380         }
01381 }
01382 
01383 void CGMEDoc::Historian::eraseOccurences( const std::wstring& p_id)
01384 {
01385         HISTLIST_ITER it;
01386         
01387         // backward stack
01388         it = m_backStack.begin();
01389         while( it != m_backStack.end())
01390         {
01391                 if( it->id() == p_id)
01392                         it = m_backStack.erase( it); // will progress it
01393                 else
01394                         ++it;
01395         }
01396 
01397         // forward stack
01398         it = m_frwdStack.begin();
01399         while( it != m_frwdStack.end())
01400         {
01401                 if( it->id() == p_id)
01402                         it = m_frwdStack.erase( it); // will progress it
01403                 else
01404                         ++it;
01405         }
01406 
01407 }
01408 //**********************************************************************************************
01409 //**********************************************************************************************
01410 
01411 void CGMEDoc::OnBtnBack()
01412 {
01413         back();
01414 }
01415 
01416 void CGMEDoc::OnBtnFrwd()
01417 {
01418         forw();
01419 }
01420 
01421 void CGMEDoc::OnBtnHome()
01422 {
01423         home();
01424 }
01425 
01426 void CGMEDoc::OnUpdateBtnBack(CCmdUI* pCmdUI)
01427 {
01428         pCmdUI->Enable( theApp.isHistoryEnabled() && m_historian.isEnabledBack());
01429 }
01430 
01431 void CGMEDoc::OnUpdateBtnFrwd(CCmdUI* pCmdUI)
01432 {
01433         pCmdUI->Enable( theApp.isHistoryEnabled() && m_historian.isEnabledFrwd());
01434 }
01435 
01436 void CGMEDoc::OnUpdateBtnHome(CCmdUI* pCmdUI)
01437 {
01438         pCmdUI->Enable( theApp.isHistoryEnabled() && m_historian.isEnabledHome());
01439 }
01440 
01441 void CGMEDoc::OnBtnCloseActive()
01442 {
01443         closeActiveWnd();
01444 }
01445 
01446 void CGMEDoc::OnBtnCloseAll()
01447 {
01448         closeAllWnd();
01449 }
01450 
01451 void CGMEDoc::OnBtnCloseAllButOne()
01452 {
01453         closeAllButActiveWnd();
01454 }
01455 
01456 void CGMEDoc::OnBtnCycleAspect()
01457 {
01458         cycleAspect();
01459 }
01460 
01461 void CGMEDoc::OnBtnCycleAllAspects()
01462 {
01463         cycleAllAspects();
01464 }
01465 
01466 void CGMEDoc::OnBtnCycleViews()
01467 {
01468         cycleViews();
01469 }