GME  13
GMEView.cpp
Go to the documentation of this file.
00001 // GMEView.cpp : implementation of the CGMEView class
00002 //
00003 
00004 #include "stdafx.h"
00005 #include "GMEApp.h"
00006 #include <math.h>
00007 #include <algorithm>
00008 #include <deque>
00009 #include <new>
00010 #include <sstream>
00011 #include "GMEstd.h"
00012 
00013 #include "GuiMeta.h"
00014 #include "GMEDoc.h"
00015 #include "PendingObjectPosRequest.h"
00016 #include "GMEView.h"
00017 #include "ChildFrm.h"
00018 #include "ModelGrid.h"
00019 #include "Mainfrm.h"
00020 #include "GMEBrowser.h"
00021 #include "GMEEventLogger.h"
00022 #include "GmePrintDialog.h"
00023 #include "ConnityDlg.h"
00024 #if defined(ADDCRASHTESTMENU)
00025 #include "CrashTest.h"
00026 #endif
00027 
00028 #include "Autoroute/AutoRouter.h"
00029 
00030 #include "GraphicsUtil.h"
00031 
00032 #include "GMEOLEModel.h"
00033 
00034 #include "Autoroute/AutoRouterGraph.h"  // just for testing auto router performance
00035 #include <sys/timeb.h>
00036 
00037 // The following is for Xerces, for DumpModelGeometryXML
00038 #include <xercesc/util/PlatformUtils.hpp>
00039 #include <xercesc/util/XMLString.hpp>
00040 #include <xercesc/dom/DOM.hpp>
00041 #include <xercesc/sax/HandlerBase.hpp>
00042 #include <xercesc/framework/LocalFileFormatTarget.hpp>
00043 #include <xercesc/util/IOException.hpp>
00044 #if defined(XERCES_NEW_IOSTREAMS)
00045 #include <iostream>
00046 #else
00047 #include <iostream.h>
00048 #endif
00049 #include <xercesc/util/OutOfMemoryException.hpp>
00050 
00051 #undef min
00052 #undef max
00053 
00054 CGraphics graphics;
00055 static CViewList viewsToKill;
00056 
00057 // CSGUIInterop.cpp
00058 void MoveReferenceWithRefportConnectionsAndWriteToConsole(IMgaFCO* target, IMgaReference* ref);
00059 
00060 #define MIN_ZOOM_RECT 12 // the minimal size of zoomable rectangle
00061 /*
00062 int setZoomPercents[GME_ZOOM_LEVEL_NUM] = {
00063         GME_ZOOM_LEVEL_0,
00064         GME_ZOOM_LEVEL_1,
00065         GME_ZOOM_LEVEL_2,
00066         GME_ZOOM_LEVEL_3,
00067         GME_ZOOM_LEVEL_4,
00068         GME_ZOOM_LEVEL_5,
00069         GME_ZOOM_LEVEL_6,
00070         GME_ZOOM_LEVEL_7
00071 };*/
00072 
00073 // #define END_SCROLL_OFFSET 50 // not used - instead EXTENT_ERROR_CORR
00074 
00076 // CViewDriver
00077 bool CViewDriver::attrNeedsRefresh = false;
00078 
00079 static int CountDeriveds(IMgaFCOPtr archetype)
00080 {
00081         int nDerived = 0;
00082         std::deque<IMgaFCOsPtr> derivedQueue;
00083         derivedQueue.push_back(archetype->DerivedObjects);
00084         while (derivedQueue.size())
00085         {
00086                 IMgaFCOsPtr deriveds = derivedQueue.front();
00087                 derivedQueue.pop_front();
00088                 nDerived += deriveds->Count;
00089                 MGACOLL_ITERATE(IMgaFCO, deriveds)
00090                 {
00091                         if (MGACOLL_ITER->Status == OBJECT_EXISTS)
00092                         {
00093                                 derivedQueue.push_back(MGACOLL_ITER->DerivedObjects);
00094                         }
00095                         else
00096                         {
00097                                 nDerived--;
00098                         }
00099                 }
00100                 MGACOLL_ITERATE_END
00101         }
00102         return nDerived;
00103 }
00104 
00105 static wchar_t* ObjTypeName[] = {
00106         L"Null",
00107         L"Model",
00108         L"Atom",
00109         L"Reference",
00110         L"Connection",
00111         L"Set",
00112         L"Folder",
00113         L"Aspect",
00114         L"Role",
00115         L"Attribute",
00116         L"Part",
00117 };
00118 
00119 STDMETHODIMP CViewDriver::GlobalEvent(globalevent_enum event)
00120 {
00121         POSITION ppos;
00122 
00123         if(view == 0)
00124                 return S_OK;
00125         if (view->executingPendingRequests)
00126                 return S_OK;
00127 
00128         CGMEView::inEventHandler = true;
00129         switch(event) {
00130         case GLOBALEVENT_UNDO:
00131         case GLOBALEVENT_REDO:
00132                 ppos = view->pendingRequests.GetHeadPosition();
00133                 while (ppos)
00134                         delete view->pendingRequests.GetNext(ppos);
00135                 view->pendingRequests.RemoveAll();
00136 
00137                 // PETER: Let's reset only the view....
00138                 VERIFY(view);
00139                 long status;
00140                 COMTHROW(view->currentModel->get_Status(&status));
00141                 if (status != OBJECT_EXISTS) {
00142                         view->alive = false;
00143                         view->frame->SetSendEvent(false);
00144                         view->frame->PostMessage(WM_CLOSE);
00145                 }
00146                 if (view->alive) {
00147                         view->Reset(true);
00148                         view->needsReset = false;
00149                 }
00150                 // view->GetDocument()->ResetAllViews();
00151                 // PETER END
00152                 break;
00153     case GLOBALEVENT_ABORT_TRANSACTION:
00154         view->Reset(true);
00155         break;    
00156         case GLOBALEVENT_NOTIFICATION_READY: 
00157                 VERIFY(view);
00158                 POSITION pos = viewsToKill.GetHeadPosition();
00159                 while(pos) {
00160                         CGMEView *v = viewsToKill.GetNext(pos);
00161                         v->alive = false;
00162                         v->frame->SetSendEvent(false);
00163                         v->frame->PostMessage(WM_CLOSE);
00164                 }
00165                 viewsToKill.RemoveAll();
00166                 if(view->alive && view->needsReset) {
00167                         view->Reset(true); // FIXME KMS: maybe post a message instead?
00168                         view->needsReset = false;
00169                 }
00170                 if(attrNeedsRefresh) {
00171                         attrNeedsRefresh = false;
00172                 }
00173                 break;        
00174         }
00175         CGMEView::inEventHandler = false;
00176         return S_OK;
00177 }
00178 
00179 STDMETHODIMP CViewDriver::ObjectEvent(IMgaObject *obj, unsigned long eventmask,VARIANT /*v*/)
00180 {
00181         if(view == 0)
00182                 return S_OK;
00183         CGMEView::inEventHandler = true;
00184 
00185         // Clear all invalidated PendingRequests
00186         POSITION ppos = view->pendingRequests.GetHeadPosition();
00187         while (ppos) {
00188                 POSITION tmp = ppos;
00189                 CPendingObjectPosRequest *req = dynamic_cast<CPendingObjectPosRequest *> (view->pendingRequests.GetNext(ppos));
00190                 if (req) {
00191                         if ( req->object->mgaFco == obj ) {
00192                                 view->pendingRequests.RemoveAt(tmp);
00193                                 delete req;
00194                         }
00195                 }
00196         }
00197 
00198         if(IsEqualObject(obj,view->currentModel)) {
00199                 // PARENT EVENT!!!
00200                 if(eventmask & OBJEVENT_DESTROYED) {
00201                         if( theApp.isHistoryEnabled() && view && view->GetDocument())
00202                         {
00203                                 CComBSTR id; 
00204                                 COMTHROW( obj->get_ID( &id)); // get the id of the deleted object
00205                                 view->GetDocument()->eraseFromHistory( PutInCString( id)); // clear from history
00206                         }
00207                         TRACE(_T("   OBJEVENT_DESTROYED\n"));
00208                         viewsToKill.AddTail(view);
00209                         attrNeedsRefresh = true;
00210                 }
00211                 if(eventmask & OBJEVENT_NEWCHILD) {
00212                         TRACE(_T("   OBJEVENT_NEWCHILD\n"));
00213                         view->needsReset = true;
00214                 }
00215                 if(eventmask & OBJEVENT_LOSTCHILD) {
00216                         TRACE(_T("   OBJEVENT_LOSTCHILD\n"));
00217                         view->needsReset = true;
00218                 }
00219                 if(eventmask & OBJEVENT_REGISTRY) {
00220                         view->needsReset = true;
00221                 }
00222                 if(eventmask & OBJEVENT_PROPERTIES) {
00223                         TRACE(_T("   OBJEVENT_PROPERTIES\n"));
00224                         view->SetName();
00225                         attrNeedsRefresh = true;
00226                 }
00227         }
00228         else if(IsEqualObject(obj,view->baseType)) {
00229                 if(eventmask & OBJEVENT_PROPERTIES) {
00230                         TRACE(_T("   OBJEVENT_PROPERTIES\n"));
00231                         view->SetTypeNameProperty();
00232                 }
00233         }
00234         else {
00235                 // CHILD EVENT!!!
00236                 if(eventmask & OBJEVENT_CREATED) {
00237                         view->needsReset = true;
00238                         TRACE(_T("   OBJEVENT_CREATED\n"));
00239                 }
00240                 else if(eventmask & OBJEVENT_DESTROYED) {
00241                         view->needsReset = true;
00242                         attrNeedsRefresh = true;
00243                         TRACE(_T("   OBJEVENT_DESTROYED\n"));
00244                 }
00245                 else if(eventmask & OBJEVENT_SETINCLUDED || eventmask & OBJEVENT_SETEXCLUDED) {
00246                         view->needsReset = true;
00247                 }
00248                 else if(eventmask & OBJEVENT_RELATION) {
00249                         view->needsReset = true;
00250                 }
00251                 else if(eventmask & OBJEVENT_REGISTRY) {
00252                         view->needsReset = true;
00253                 }
00254                 else if(eventmask & OBJEVENT_ATTR) {
00255                         view->needsReset = true;
00256                         attrNeedsRefresh = true;
00257                 }
00258                 else if(eventmask & OBJEVENT_PROPERTIES) {              // Because of the connectionlabels
00259                         view->needsReset = true;                                        // and attr browser
00260                         attrNeedsRefresh = true;
00261                 }
00262                 else {
00263                         CComPtr<IMgaObject> object = obj;
00264                         CComPtr<IMgaFCO> fco;
00265                         if(SUCCEEDED(object.QueryInterface(&fco))) {
00266                                 CGuiObject *guiObj = CGuiFco::FindObject(fco,view->children);
00267                                 CGuiConnection *conn = CGuiFco::FindConnection(fco,view->connections);
00268                                 if(guiObj) {
00269                                         if(eventmask & OBJEVENT_PROPERTIES) {
00270                                                 COMTHROW(object->get_Name(PutOut(guiObj->GetName())));
00271                                                 view->Invalidate();
00272                                         }
00273                                 }
00274                                 else if(conn) {
00275                                         if(eventmask & OBJEVENT_PROPERTIES) {
00276                                                 COMTHROW(object->get_Name(PutOut(conn->name)));
00277                                                 // ?? 
00278                                                 view->Invalidate();
00279                                         }
00280                                 }
00281                                 else
00282                                         view->needsReset = true; // e.g. port name change etc.
00283                         }
00284                 }
00285         }
00286         CGMEView::inEventHandler = false;
00287         return S_OK;
00288 }
00289 
00291 // CGMEView
00292 
00293 int CGMEView::offScreenCreated = 0;
00294 CDC * CGMEView::offScreen;
00295 CBitmap *CGMEView::ofsbmp;
00296 int CGMEView::instanceCount = 0;
00297 int CGMEView::inTransaction = 0;
00298 bool CGMEView::inRWTransaction = false;
00299 bool CGMEView::inEventHandler = false;
00300 
00301 
00302 HCURSOR CGMEView::autoconnectCursor;
00303 HCURSOR CGMEView::autoconnect2Cursor;
00304 HCURSOR CGMEView::disconnectCursor;
00305 HCURSOR CGMEView::disconnect2Cursor;
00306 HCURSOR CGMEView::setCursor;
00307 HCURSOR CGMEView::set2Cursor;
00308 HCURSOR CGMEView::zoomCursor;
00309 HCURSOR CGMEView::visualCursor;
00310 HCURSOR CGMEView::editCursor;
00311 
00312 bool                                            CGMEView::showConnectedPortsOnly = false;
00313 bool                                            CGMEView::derivedDrop = false;
00314 bool                                            CGMEView::instanceDrop = false;
00315 bool                                            CGMEView::m_bUseStretchBlt = false;
00316 Gdiplus::SmoothingMode          CGMEView::m_eEdgeAntiAlias = Gdiplus::SmoothingModeHighQuality;         // Edge smoothing mode
00317 Gdiplus::TextRenderingHint      CGMEView::m_eFontAntiAlias = Gdiplus::TextRenderingHintAntiAlias;       // Text renndering hint mode
00318 
00319 IMPLEMENT_DYNCREATE(CGMEView, CScrollZoomView)
00320 
00321 BEGIN_MESSAGE_MAP(CGMEView, CScrollZoomView)
00322         //{{AFX_MSG_MAP(CGMEView)
00323         ON_WM_DESTROY()
00324         ON_WM_SIZE()
00325         ON_WM_ERASEBKGND()
00326         ON_WM_SETCURSOR()
00327         ON_WM_DROPFILES()
00328         ON_EN_KILLFOCUS(IDC_NAME, OnKillfocusNameProp)
00329         ON_CBN_SELCHANGE(IDC_ASPECT, OnSelChangeAspectProp)
00330         ON_WM_LBUTTONUP()
00331         ON_WM_LBUTTONDOWN()
00332         ON_WM_RBUTTONDOWN()
00333         ON_WM_RBUTTONUP()
00334         ON_WM_LBUTTONDBLCLK()
00335         ON_WM_MOUSEWHEEL()
00336         ON_WM_APPCOMMAND()
00337         ON_COMMAND(ID_VIEW_PARENT, OnViewParent)
00338         ON_UPDATE_COMMAND_UI(ID_VIEW_PARENT, OnUpdateViewParent)
00339         ON_COMMAND(ID_VIEW_GRID, OnViewGrid)
00340         ON_UPDATE_COMMAND_UI(ID_VIEW_GRID, OnUpdateViewGrid)
00341         ON_COMMAND(ID_EDIT_NUDGEDOWN, OnEditNudgedown)
00342         ON_COMMAND(ID_EDIT_NUDGELEFT, OnEditNudgeleft)
00343         ON_COMMAND(ID_EDIT_NUDGERIGHT, OnEditNudgeright)
00344         ON_COMMAND(ID_EDIT_NUDGEUP, OnEditNudgeup)
00345         ON_COMMAND(ID_EDIT_DELETE, OnEditDelete)
00346         ON_UPDATE_COMMAND_UI(ID_EDIT_DELETE, OnUpdateEditDelete)
00347         ON_COMMAND(ID_CNTX_PROPERTIES, OnContextProperties)
00348         ON_COMMAND(ID_CNTX_ATTRIBUTES, OnCntxAttributes)
00349         ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
00350         ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
00351         ON_COMMAND(ID_EDIT_COPY, OnEditCopy)
00352         ON_COMMAND(ID_EDIT_COPYCLOSURE, OnEditCopyClosure)
00353         ON_COMMAND(ID_EDIT_COPYSMART, OnEditCopySmart)
00354         ON_UPDATE_COMMAND_UI(ID_EDIT_COPY, OnUpdateEditCopy)
00355         ON_UPDATE_COMMAND_UI(ID_EDIT_COPYCLOSURE, OnUpdateEditCopyClosure)
00356         ON_UPDATE_COMMAND_UI(ID_EDIT_COPYSMART, OnUpdateEditCopySmart)
00357         ON_COMMAND(ID_EDIT_CUT, OnEditCut)
00358         ON_UPDATE_COMMAND_UI(ID_EDIT_CUT, OnUpdateEditCut)
00359         ON_COMMAND(ID_EDIT_PASTE, OnEditPaste)
00360         ON_UPDATE_COMMAND_UI(ID_EDIT_PASTE, OnUpdateEditPaste)
00361         ON_COMMAND(ID_CNTX_COPY, OnCntxCopy)
00362         ON_COMMAND(ID_CNTX_COPYCLOSURE, OnCntxCopyClosure)
00363         ON_COMMAND(ID_CNTX_COPYSMART, OnCntxCopySmart)
00364         ON_COMMAND(ID_CNTX_CUT, OnCntxCut)
00365         ON_COMMAND(ID_CNTX_DELETE, OnCntxDelete)
00366         ON_COMMAND(ID_SELFCNTX_COPY, OnSelfcntxCopy)
00367         ON_UPDATE_COMMAND_UI(ID_SELFCNTX_COPY, OnUpdateSelfcntxCopy)
00368         ON_COMMAND(ID_SELFCNTX_COPYCLOSURE, OnSelfcntxCopyClosure)
00369         ON_COMMAND(ID_SELFCNTX_COPYSMART, OnSelfcntxCopySmart)
00370         ON_UPDATE_COMMAND_UI(ID_SELFCNTX_COPYCLOSURE, OnUpdateSelfcntxCopyClosure)
00371         ON_UPDATE_COMMAND_UI(ID_SELFCNTX_COPYSMART, OnUpdateSelfcntxCopySmart)
00372         ON_COMMAND(ID_SELFCNTX_CUT, OnSelfcntxCut)
00373         ON_UPDATE_COMMAND_UI(ID_SELFCNTX_CUT, OnUpdateSelfcntxCut)
00374         ON_COMMAND(ID_SELFCNTX_DELETE, OnSelfcntxDelete)
00375         ON_UPDATE_COMMAND_UI(ID_SELFCNTX_DELETE, OnUpdateSelfcntxDelete)
00376         ON_COMMAND(ID_SELFCNTX_PASTE, OnSelfcntxPaste)
00377         ON_UPDATE_COMMAND_UI(ID_SELFCNTX_PASTE, OnUpdateSelfcntxPaste)
00378         ON_UPDATE_COMMAND_UI(ID_CNTX_ATTRIBUTES, OnUpdateCntxAttributes)
00379         ON_COMMAND(ID_EDIT_CANCEL, OnEditCancel)
00380         ON_UPDATE_COMMAND_UI(ID_EDIT_CANCEL, OnUpdateEditCancel)
00381         ON_COMMAND(ID_CNTX_DISCONNECTALL, OnCntxDisconnectall)
00382         ON_UPDATE_COMMAND_UI(ID_CNTX_DISCONNECTALL, OnUpdateCntxDisconnectall)
00383         ON_COMMAND(ID_FILE_CLOSE, OnFileClose)
00384         ON_COMMAND(ID_CONNCNTX_PROPERTIES, OnConncntxProperties)
00385         ON_COMMAND(ID_CONNCNTX_DELETE, OnConncntxDelete)
00386         ON_COMMAND(ID_CONNCNTX_REVERSE, OnConncntxReverse)
00387         ON_UPDATE_COMMAND_UI(ID_CONNCNTX_REVERSE, OnUpdateConncntxReverse)
00388         ON_COMMAND(ID_CONNCNTX_FOLLOW, OnConnCntxFollow)
00389         ON_COMMAND(ID_CONNCNTX_JUMP_SRC, OnConnCntxRevfollow)
00390         ON_COMMAND(ID_PORTCNTX_FOLLOWCONNECTION, OnPortCntxFollowConnection)
00391         ON_COMMAND(ID_PORTCNTX_REVERSECONNECTION, OnPortCntxRevfollowConnection)
00392         ON_COMMAND(ID_PORTCNTX_DELETE, OnCntxPortDelete)
00393         ON_COMMAND(ID_CNTX_FOLLOWCONNECTION, OnCntxFollowConnection)
00394         ON_COMMAND(ID_CNTX_REVERSECONNECTION, OnCntxRevfollowConnection)
00395         ON_COMMAND(ID_CNTX_SHOWPORTINPARENT, OnCntxPortShowInParent)
00396         ON_COMMAND(ID_CNTX_LOCATEPORTINBROWSER, OnCntxPortLocateInBrw)
00397         ON_COMMAND(ID_JUMPALONGCONN, OnJumpAlongConnection)
00398         ON_COMMAND(ID_BACKALONGCONN, OnBackAlongConnection)
00399         ON_COMMAND(ID_TRYTOSNAPHORZVERTPATH, OnTryToSnapHorzVertPath)
00400         ON_COMMAND(ID_DELETECONNEDGECUSTOMDATA, OnDeleteConnEdgeCustomData)
00401         ON_COMMAND(ID_DELETECONNPOINTCUSTOMDATA, OnDeleteConnPointCustomData)
00402         ON_COMMAND(ID_DELETECONNCUSTOMDATA_THISASPECT, OnDeleteConnRouteCustomDataThisAspect)
00403         ON_COMMAND(ID_DELETECONNCUSTOMDATA_ALLASPECTS, OnDeleteConnRouteCustomDataAllAspects)
00404         ON_COMMAND(ID_JUMPTOFIRSTOBJ, OnJumpToFirstObject)
00405         ON_COMMAND(ID_JUMPTONEXTOBJ, OnJumpToNextObject)
00406         ON_COMMAND(ID_SHOWCONTEXTMENU, OnShowContextMenu)
00407         ON_COMMAND(ID_CNTX_CLEAR, OnCntxClear)
00408         ON_UPDATE_COMMAND_UI(ID_CNTX_CLEAR, OnUpdateCntxClear)
00409         ON_COMMAND(ID_CNTX_RESET, OnCntxReset)
00410         ON_UPDATE_COMMAND_UI(ID_CNTX_RESET, OnUpdateCntxReset)
00411         ON_UPDATE_COMMAND_UI(ID_CNTX_DELETE, OnUpdateCntxDelete)
00412         ON_UPDATE_COMMAND_UI(ID_CONNCNTX_DELETE, OnUpdateConncntxDelete)
00413         ON_UPDATE_COMMAND_UI(ID_CNTX_CUT, OnUpdateCntxCut)
00414         ON_UPDATE_COMMAND_UI(ID_PORTCNTX_FOLLOWCONNECTION, OnUpdatePortCntxFollowConnection)
00415         ON_UPDATE_COMMAND_UI(ID_PORTCNTX_REVERSECONNECTION, OnUpdatePortCntxRevfollowConnection)
00416         ON_UPDATE_COMMAND_UI(ID_CNTX_FOLLOWCONNECTION, OnUpdateCntxFollowConnection)
00417         ON_UPDATE_COMMAND_UI(ID_CNTX_REVERSECONNECTION, OnUpdateCntxRevfollowConnection)
00418         ON_UPDATE_COMMAND_UI(ID_JUMPALONGCONN, OnUpdateJumpAlongConnection)
00419         ON_UPDATE_COMMAND_UI(ID_BACKALONGCONN, OnUpdateBackAlongConnection)
00420         ON_UPDATE_COMMAND_UI(ID_TRYTOSNAPHORZVERTPATH, OnUpdateTryToSnapHorzVertPath)
00421         ON_UPDATE_COMMAND_UI(ID_DELETECONNEDGECUSTOMDATA, OnUpdateDeleteConnEdgeCustomData)
00422         ON_UPDATE_COMMAND_UI(ID_DELETECONNPOINTCUSTOMDATA, OnUpdateDeleteConnPointCustomData)
00423         ON_UPDATE_COMMAND_UI(ID_DELETECONNCUSTOMDATA_THISASPECT, OnUpdateDeleteConnRouteCustomDataThisAspect)
00424         ON_UPDATE_COMMAND_UI(ID_DELETECONNCUSTOMDATA_ALLASPECTS, OnUpdateDeleteConnRouteCustomDataAllAspects)
00425 #if defined(ADDCRASHTESTMENU)
00426         ON_COMMAND(ID_CRASHTEST_ILLEGALWRITE, OnCrashTestIllegalWrite)
00427         ON_COMMAND(ID_CRASHTEST_ILLEGALREAD, OnCrashTestIllegalRead)
00428         ON_COMMAND(ID_CRASHTEST_ILLEGALREADINCRUNTIME, OnCrashTestIllegalReadInCRuntime)
00429         ON_COMMAND(ID_CRASHTEST_ILLEGALCODEREAD, OnCrashTestIllegalCodeRead)
00430         ON_COMMAND(ID_CRASHTEST_DIVIDEBYZERO, OnCrashTestDivideByZero)
00431         ON_COMMAND(ID_CRASHTEST_ABORT, OnCrashTestAbort)
00432         ON_COMMAND(ID_CRASHTEST_TERMINATE, OnCrashTestTerminate)
00433         ON_UPDATE_COMMAND_UI(IDR_CRASH_TEST_MENU, OnUpdateCrashTestMenu)
00434         ON_UPDATE_COMMAND_UI(ID_CRASHTEST_ILLEGALWRITE, OnUpdateCrashTestIllegalWrite)
00435         ON_UPDATE_COMMAND_UI(ID_CRASHTEST_ILLEGALREAD, OnUpdateCrashTestIllegalRead)
00436         ON_UPDATE_COMMAND_UI(ID_CRASHTEST_ILLEGALREADINCRUNTIME, OnUpdateCrashTestIllegalReadInCRuntime)
00437         ON_UPDATE_COMMAND_UI(ID_CRASHTEST_ILLEGALCODEREAD, OnUpdateCrashTestIllegalCodeRead)
00438         ON_UPDATE_COMMAND_UI(ID_CRASHTEST_DIVIDEBYZERO, OnUpdateCrashTestDivideByZero)
00439         ON_UPDATE_COMMAND_UI(ID_CRASHTEST_ABORT, OnUpdateCrashTestAbort)
00440         ON_UPDATE_COMMAND_UI(ID_CRASHTEST_TERMINATE, OnUpdateCrashTestTerminate)
00441 #endif
00442         ON_COMMAND(ID_CNTX_PREFERENCES, OnCntxPreferences)
00443         ON_COMMAND(ID_EDIT_PREFERENCES, OnEditPreferences)
00444         ON_COMMAND(ID_HELP_HELP, OnHelpHelp)
00445         ON_COMMAND(ID_CNTX_HELP, OnCntxHelp)
00446         ON_COMMAND(ID_EDIT_SHOWTYPE, OnEditShowtype)
00447         ON_UPDATE_COMMAND_UI(ID_EDIT_SHOWTYPE, OnUpdateEditShowtype)
00448         ON_COMMAND(ID_EDIT_SHOWBASETYPE, OnEditShowbasetype)
00449         ON_UPDATE_COMMAND_UI(ID_EDIT_SHOWBASETYPE, OnUpdateEditShowbasetype)
00450         ON_COMMAND(ID_CNTX_SHOWTYPE, OnCntxShowtype)
00451         ON_UPDATE_COMMAND_UI(ID_CNTX_SHOWTYPE, OnUpdateCntxShowtype)
00452         ON_COMMAND(ID_CNTX_SHOWBASETYPE, OnCntxShowbasetype)
00453         ON_UPDATE_COMMAND_UI(ID_CNTX_SHOWBASETYPE, OnUpdateCntxShowbasetype)
00454         ON_COMMAND(ID_FILE_INTERPRET, OnFileInterpret)
00455         ON_COMMAND(ID_FILE_CHECK, OnFileCheck)
00456         ON_COMMAND(ID_FILE_CHECKSEL, OnFileCheckSelected)
00457         ON_COMMAND(ID_CNTX_INTERPRET, OnCntxInterpret)
00458         ON_COMMAND(ID_CNTX_CHECK, OnCntxCheck)
00459         ON_COMMAND(ID_CNTX_LOCATE, OnCntxLocate)
00460         ON_UPDATE_COMMAND_UI(ID_CNTX_INTERPRET, OnUpdateCntxInterpret)
00461         ON_UPDATE_COMMAND_UI(ID_CNTX_CHECK, OnUpdateCntxCheck)
00462         ON_UPDATE_COMMAND_UI(ID_CNTX_LOCATE, OnUpdateCntxLocate)
00463         ON_COMMAND(ID_CNTX_REGISTRY, OnCntxRegistry)
00464         ON_COMMAND(ID_EDIT_REGISTRY, OnEditRegistry)
00465         ON_COMMAND(ID_EDIT_SYNC, OnEditSync)
00466         ON_UPDATE_COMMAND_UI(ID_EDIT_SYNC, OnUpdateEditSync)
00467         ON_COMMAND(ID_EDIT_SELECTALL, OnEditSelectall)
00468         ON_UPDATE_COMMAND_UI(ID_FILE_CHECK, OnUpdateFileCheck)
00469         ON_UPDATE_COMMAND_UI(ID_FILE_CHECKSEL, OnUpdateFileCheckSelected)
00470         ON_UPDATE_COMMAND_UI(ID_FILE_SETTINGS, OnUpdateFileSettings)
00471         ON_COMMAND(ID_EDIT_PASTESPECIAL_ASINSTANCE, OnEditPastespecialAsinstance)
00472         ON_COMMAND(ID_EDIT_PASTESPECIAL_ASREFERENCE, OnEditPastespecialAsreference)
00473         ON_COMMAND(ID_EDIT_PASTESPECIAL_ASSUBTYPE, OnEditPastespecialAssubtype)
00474         ON_COMMAND(ID_EDIT_PASTESPECIAL_ASCLOSURE, OnEditPastespecialAsclosure)
00475         ON_COMMAND(ID_EDIT_PASTESPECIAL_SMART_ADDITIVE, OnEditPastespecialAdditive)
00476         ON_COMMAND(ID_EDIT_PASTESPECIAL_SMART_MERGE, OnEditPastespecialMerge)
00477         ON_UPDATE_COMMAND_UI(ID_EDIT_PASTESPECIAL_ASINSTANCE, OnUpdateEditPastespecialAsinstance)
00478         ON_UPDATE_COMMAND_UI(ID_EDIT_PASTESPECIAL_ASREFERENCE, OnUpdateEditPastespecialAsreference)
00479         ON_UPDATE_COMMAND_UI(ID_EDIT_PASTESPECIAL_ASSUBTYPE, OnUpdateEditPastespecialAssubtype)
00480         ON_UPDATE_COMMAND_UI(ID_EDIT_PASTESPECIAL_ASCLOSURE, OnUpdateEditPastespecialAsclosure)
00481         ON_UPDATE_COMMAND_UI(ID_EDIT_PASTESPECIAL_SMART_ADDITIVE, OnUpdateEditPastespecialAdditive)
00482         ON_UPDATE_COMMAND_UI(ID_EDIT_PASTESPECIAL_SMART_MERGE, OnUpdateEditPastespecialMerge)
00483         ON_COMMAND(ID_CNTX_PASTESPECIAL_ASINSTANCE, OnCntxPastespecialAsinstance)
00484         ON_UPDATE_COMMAND_UI(ID_CNTX_PASTESPECIAL_ASINSTANCE, OnUpdateCntxPastespecialAsinstance)
00485         ON_COMMAND(ID_CNTX_PASTESPECIAL_ASREFERENCE, OnCntxPastespecialAsreference)
00486         ON_UPDATE_COMMAND_UI(ID_CNTX_PASTESPECIAL_ASREFERENCE, OnUpdateCntxPastespecialAsreference)
00487         ON_COMMAND(ID_CNTX_PASTESPECIAL_ASSUBTYPE, OnCntxPastespecialAssubtype)
00488         ON_UPDATE_COMMAND_UI(ID_CNTX_PASTESPECIAL_ASSUBTYPE, OnUpdateCntxPastespecialAssubtype)
00489         ON_COMMAND(ID_CNTX_PASTESPECIAL_ASCLOSURE, OnCntxPastespecialAsclosure)
00490         ON_UPDATE_COMMAND_UI(ID_CNTX_PASTESPECIAL_ASCLOSURE, OnUpdateCntxPastespecialAsclosure)
00491         ON_COMMAND(ID_CNTX_PASTESPECIAL_SMART_ADDITIVE, OnCntxPastespecialAdditive)
00492         ON_UPDATE_COMMAND_UI(ID_CNTX_PASTESPECIAL_SMART_ADDITIVE, OnUpdateCntxPastespecialAdditive)
00493         ON_COMMAND(ID_CNTX_PASTESPECIAL_SMART_MERGE, OnCntxPastespecialMerge)
00494         ON_UPDATE_COMMAND_UI(ID_CNTX_PASTESPECIAL_SMART_MERGE, OnUpdateCntxPastespecialMerge)
00495         ON_COMMAND(ID_CNTX_REDIRECTIONPASTE, OnCntxRedirectionpaste)
00496         ON_UPDATE_COMMAND_UI(ID_CNTX_REDIRECTIONPASTE, OnUpdateCntxRedirectionpaste)
00497         ON_COMMAND(ID_KEY_CONNECT, OnKeyConnect)
00498         ON_COMMAND(ID_CNTX_CONNECT, OnCntxConnect)
00499         ON_UPDATE_COMMAND_UI(ID_CNTX_CONNECT, OnUpdateCntxConnect)
00500         ON_COMMAND(ID_RESET_STICKY, OnResetSticky)
00501         ON_WM_NCMOUSEMOVE()
00502         ON_WM_MOUSEMOVE()
00503         ON_WM_TIMER()
00504         ON_UPDATE_COMMAND_UI(ID_CNTX_INSERTANNOTATION, OnUpdateCntxInsertannotation)
00505         ON_COMMAND(ID_CNTX_INSERTANNOTATION, OnCntxInsertannotation)
00506         ON_COMMAND(ID_CNTX_ANNOTATIONS, OnCntxAnnotations)
00507         ON_COMMAND(ID_EDIT_ANNOTATIONS, OnEditAnnotations)
00508         ON_UPDATE_COMMAND_UI( ID_CNTX_SRCAR_NORTH, OnUpdateCntxAutoRouters )
00509         ON_COMMAND(ID_CNTX_SRCAR_SOUTH, OnCntxSrcarSouth)
00510         ON_COMMAND(ID_CNTX_SRCAR_NORTH, OnCntxSrcarNorth)
00511         ON_COMMAND(ID_CNTX_SRCAR_EAST, OnCntxSrcarEast)
00512         ON_COMMAND(ID_CNTX_SRCAR_WEST, OnCntxSrcarWest)
00513         ON_COMMAND(ID_CNTX_DSTAR_EAST, OnCntxDstarEast)
00514         ON_COMMAND(ID_CNTX_DSTAR_NORTH, OnCntxDstarNorth)
00515         ON_COMMAND(ID_CNTX_DSTAR_SOUTH, OnCntxDstarSouth)
00516         ON_COMMAND(ID_CNTX_DSTAR_WEST, OnCntxDstarWest)
00517         ON_COMMAND(ID_CNTX_SRCAR_CLEAR, OnCntxSrcarClear)
00518         ON_COMMAND(ID_CNTX_DSTAR_CLEAR, OnCntxDstarClear)
00519         ON_COMMAND(ID_CNTX_SRCAR_SET, OnCntxSrcarSet)
00520         ON_COMMAND(ID_CNTX_DSTAR_SET, OnCntxDstarSet)
00521         ON_UPDATE_COMMAND_UI( ID_CNTX_DSTAR_NORTH, OnUpdateCntxAutoRouters )
00522         ON_UPDATE_COMMAND_UI( ID_CNTX_SRCAR_SOUTH, OnUpdateCntxAutoRouters )
00523         ON_UPDATE_COMMAND_UI( ID_CNTX_DSTAR_SOUTH, OnUpdateCntxAutoRouters )
00524         ON_UPDATE_COMMAND_UI( ID_CNTX_SRCAR_WEST, OnUpdateCntxAutoRouters )
00525         ON_UPDATE_COMMAND_UI( ID_CNTX_DSTAR_WEST, OnUpdateCntxAutoRouters )
00526         ON_UPDATE_COMMAND_UI( ID_CNTX_SRCAR_EAST, OnUpdateCntxAutoRouters )
00527         ON_UPDATE_COMMAND_UI( ID_CNTX_DSTAR_EAST, OnUpdateCntxAutoRouters )
00528         ON_UPDATE_COMMAND_UI( ID_CNTX_SRCAR_CLEAR, OnUpdateCntxAutoRouters )
00529         ON_UPDATE_COMMAND_UI( ID_CNTX_DSTAR_CLEAR, OnUpdateCntxAutoRouters )
00530         ON_UPDATE_COMMAND_UI( ID_CNTX_SRCAR_SET, OnUpdateCntxAutoRouters )
00531         ON_UPDATE_COMMAND_UI( ID_CNTX_DSTAR_SET, OnUpdateCntxAutoRouters )
00532         ON_COMMAND(ID_PRINT_METAFILE, OnPrintMetafile)
00533         ON_COMMAND(ID_CNTX_NMPOS_SOUTH, OnCntxNamePositionSouth)
00534         ON_COMMAND(ID_CNTX_NMPOS_NORTH, OnCntxNamePositionNorth)
00535         ON_COMMAND(ID_CNTX_NMPOS_EAST, OnCntxNamePositionEast)
00536         ON_COMMAND(ID_CNTX_NMPOS_WEST, OnCntxNamePositionWest)
00537         ON_UPDATE_COMMAND_UI( ID_CNTX_NMPOS_SOUTH, OnUpdateCntxNamePositionSouth )
00538         ON_UPDATE_COMMAND_UI( ID_CNTX_NMPOS_NORTH, OnUpdateCntxNamePositionNorth )
00539         ON_UPDATE_COMMAND_UI( ID_CNTX_NMPOS_EAST, OnUpdateCntxNamePositionEast )
00540         ON_UPDATE_COMMAND_UI( ID_CNTX_NMPOS_WEST, OnUpdateCntxNamePositionWest )
00541         //}}AFX_MSG_MAP
00542         // Standard printing commands
00543         ON_COMMAND(ID_FILE_PRINT, CScrollZoomView::OnFilePrint)
00544         ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollZoomView::OnFilePrint)
00545         ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollZoomView::OnFilePrintPreview)
00546         ON_COMMAND(ID_KEY_ZOOMIN, OnZoomIn)
00547         ON_COMMAND(ID_KEY_ZOOMOUT, OnZoomOut)
00548         ON_COMMAND(ID_KEY_CYCLEOBJINSPFRWD, OnKeyCycleObjInspectorFrwd)
00549         ON_COMMAND(ID_KEY_CYCLEOBJINSPBKWD, OnKeyCycleObjInspectorBkwd)
00550         ON_MESSAGE(WM_USER_ZOOM, OnZoom)
00551         ON_MESSAGE(WM_USER_PANNREFRESH, OnPannRefresh)
00552         ON_MESSAGE(WM_PANN_SCROLL, OnPannScroll)
00553         ON_MESSAGE(WM_USER_DECOR_VIEWREFRESH_REQ, OnDecoratorViewRefreshRequest)
00554         ON_MESSAGE(WM_USER_EXECUTEPENDINGREQUESTS, OnExecutePendingRequests)
00555         ON_COMMAND(ID_VIEW_SHOWSELMODEL, OnShowSelectedModel)
00556         ON_COMMAND(ID_VIEW_FOCUSBROWSER, OnFocusBrowser)
00557         ON_COMMAND(ID_VIEW_RENAME, OnRename)
00558         ON_COMMAND(ID_VIEW_FOCUSINSPECTOR, OnFocusInspector)
00559         ON_COMMAND(ID_VIEW_CYCLEASPECTKEY, OnCycleAspect)
00560         ON_COMMAND(ID_VIEW_CYCLEASPECTBACKWARDSKEY, OnCycleAspectBackwards)
00561         ON_COMMAND(ID_VIEW_CYCLEALLASPECTS, OnCycleAllAspects)
00562         ON_COMMAND(ID_VIEW_HISTORYBACKKEY, OnHistoryBack)
00563         ON_COMMAND(ID_VIEW_HISTORYFORWKEY, OnHistoryForw)
00564         ON_COMMAND(ID_MULTIUSER_SHOWOWNER, OnViewMultiUserShowObjectOwner)
00565         ON_UPDATE_COMMAND_UI( ID_MULTIUSER_SHOWOWNER, OnUpdateViewMultiUserShowObjectOwner)
00566         ON_WM_KILLFOCUS()
00567 
00568         ON_COMMAND(ID_VIEW_SHOWCONNECTEDPORTSONLY, &CGMEView::OnViewShowconnectedportsonly)
00569         ON_UPDATE_COMMAND_UI(ID_VIEW_SHOWCONNECTEDPORTSONLY, &CGMEView::OnUpdateViewShowconnectedportsonly)
00570         END_MESSAGE_MAP()
00571 
00573 // CGMEView construction/destruction
00574 
00575 CGMEView::CGMEView()
00576 {
00577         m_isActive                                              = false;
00578         m_preview                                               = false;
00579         m_scalePrnPages                                 = 1;
00580         m_currPrnNumAsp                                 = 0;
00581         m_fullPrnAspNum                                 = 1;
00582         m_prevcurrasp                                   = NULL;
00583         m_prnpos                                                = NULL;
00584         m_lastPrnPage                                   = 0;
00585         m_zoomVal                                               = ZOOM_NO;
00586         m_bEnablePannWindowRefresh = false;
00587 
00588         initDone                                                = false;
00589         isModelAutoRouted                               = theApp.useAutoRouting;
00590         inTransaction                                   = 0;
00591 
00592         autoconnectCursor                               = AfxGetApp()->LoadCursor(IDC_AUTOCONNECT_CURSOR);
00593         autoconnect2Cursor                              = AfxGetApp()->LoadCursor(IDC_AUTOCONNECT2_CURSOR);
00594         disconnectCursor                                = AfxGetApp()->LoadCursor(IDC_DISCONNECT_CURSOR);
00595         disconnect2Cursor                               = AfxGetApp()->LoadCursor(IDC_DISCONNECT2_CURSOR);
00596         setCursor                                               = AfxGetApp()->LoadCursor(IDC_SET_CURSOR);
00597         set2Cursor                                              = AfxGetApp()->LoadCursor(IDC_SET2_CURSOR);
00598         zoomCursor                                              = AfxGetApp()->LoadCursor(IDC_ZOOM_CURSOR);
00599         visualCursor                                    = AfxGetApp()->LoadCursor(IDC_VISUAL_CURSOR);
00600         editCursor                                              = LoadCursor(0,IDC_ARROW);
00601 
00602         drawGrid                                                = false;
00603 
00604         SetIsCursorChangedByDecorator   (false);
00605         SetOriginalRectEmpty                    ();
00606         SetInElementDecoratorOperation  (false);
00607         SetInOpenedDecoratorTransaction (false);
00608         SetIsContextInitiatedOperation  (false);
00609         SetShouldCommitOperation                (false);
00610         SetDecoratorOrAnnotator                 (true);
00611         SetObjectInDecoratorOperation   (NULL);
00612         SetAnnotatorInDecoratorOperation(NULL);
00613         selectedObjectOfContext                 = NULL;
00614         selectedAnnotationOfContext             = NULL;
00615         selectedConnection                              = NULL;
00616         isLeftMouseButtonDown                   = false;
00617         isConnectionJustSelected                = false;
00618         isInConnectionCustomizeOperation= false;
00619         doNotDeselectAfterInPlaceEdit   = false;
00620         isCursorChangedByEdgeCustomize  = false;
00621         selectedContextConnection               = NULL;
00622 
00623         prevDropEffect                                  = DROPEFFECT_NONE;
00624         inDrag                                                  = false;
00625         contextMenuLocation                             = CPoint(0,0);
00626 
00627         guiMeta                                                 = 0;
00628         currentAspect                                   = 0;
00629         currentSet                                              = 0;
00630         last_Connection                                 = 0;
00631         lastObject                                              = 0;
00632         lastPort                                                = 0;
00633         dragSource                                              = 0;
00634 
00635         needsReset                                              = false;
00636         needsConnConversion                             = false;
00637         alive                                                   = true;
00638         bgColor                                                 = 0;
00639 
00640         instanceCount++;
00641 
00642         animRefCnt                                              = 0;
00643         timerID                                                 = 0;
00644 
00645         driver                                                  = new CComObject<CViewDriver>;
00646         driver->view                                    = this;
00647 
00648         executingPendingRequests                = false;
00649 
00650         contextSelection                                = 0;
00651         contextAnnotation                               = 0;
00652         contextPort                                             = 0;
00653 
00654         tmpConnectMode                                  = false;
00655         ClearSupressConnectionCheckAlert();
00656         ClearConnSpecs();
00657 
00658         CComPtr<IMgaRegistrar> registrar;
00659         COMTHROW(registrar.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar")));
00660         ASSERT(registrar != NULL);
00661         edgesmoothmode_enum edgeSmoothMode;
00662         COMTHROW(registrar->get_EdgeSmoothMode(REGACCESS_USER, &edgeSmoothMode));
00663         m_eEdgeAntiAlias = (Gdiplus::SmoothingMode)edgeSmoothMode;
00664         fontsmoothmode_enum fontSmoothMode;
00665         COMTHROW(registrar->get_FontSmoothMode(REGACCESS_USER, &fontSmoothMode));
00666         m_eFontAntiAlias = (Gdiplus::TextRenderingHint)fontSmoothMode;
00667 
00668         HKEY hKey;
00669         if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\GME\\GUI\\"),
00670                                          0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
00671         {
00672                 TCHAR szData[128];
00673                 DWORD dwKeyDataType;
00674                 DWORD dwDataBufSize = sizeof(szData)/sizeof(TCHAR);
00675 
00676                 // Supposed workaround for Vista black view problem: use StretchBlt instead of BitBlt
00677                 // Problem can arise in multi-monitor systems with NVidia cards (but who knows what other configs)
00678                 // If user wants to fall back to the faster BitBlt, he can force GME to use it by creating a
00679                 // string registry key with "0" value under the "HKCU\Software\GME\GUI\UseStretchBlt"
00680                 if (RegQueryValueEx(hKey, _T("UseStretchBlt"), NULL, &dwKeyDataType,
00681                                                         (LPBYTE) &szData, &dwDataBufSize) == ERROR_SUCCESS)
00682                 {
00683                         UINT uUseStretchBlt = _tcstoul(szData, NULL, 10);
00684                         m_bUseStretchBlt = (uUseStretchBlt != 0);
00685                 }
00686                 RegCloseKey(hKey);
00687         }
00688 }
00689 
00690 CGMEView::~CGMEView()
00691 {
00692         // a good idea to release ptrs
00693         baseType.Release();
00694         parent.Release();
00695         currentModel.Release();
00696 
00697         if(--instanceCount <= 0) {
00698                 // update & disable some components
00699                 theApp.UpdateCompList4CurrentKind( CGMEApp::m_no_model_open_string);
00700 
00701         ::RestoreDC(*offScreen, offScreenCreated);
00702                 delete offScreen;
00703                 delete ofsbmp;
00704                 offScreenCreated = 0;
00705                 if( CMainFrame::theInstance != NULL ) {
00706                         CMainFrame::theInstance->SetPartBrowserMetaModel(NULL);
00707                         CMainFrame::theInstance->SetPartBrowserBg(::GetSysColor(COLOR_APPWORKSPACE));
00708                 }
00709         }
00710         POSITION pos = children.GetHeadPosition();
00711         while(pos)
00712                 delete children.GetNext(pos);
00713 
00714         pos = annotators.GetHeadPosition();
00715         while(pos)
00716                 delete annotators.GetNext(pos);
00717 
00718         pos = pendingRequests.GetHeadPosition();
00719         while(pos)
00720                 delete pendingRequests.GetNext(pos);
00721         pendingRequests.RemoveAll();
00722 
00723         driver->view = 0;
00724 }
00725 
00726 BOOL CGMEView::PreCreateWindow(CREATESTRUCT& cs)
00727 {
00728         // TODO: Modify the Window class or styles here by modifying
00729         //  the CREATESTRUCT cs
00730 
00731         return CScrollZoomView::PreCreateWindow(cs);
00732 }
00733 
00735 // CGMEView drawing
00736 
00737 #define PANNING_RATIO_MIN       4 // ??
00738 void CGMEView::DoPannWinRefresh()
00739 {
00740         if (!m_bEnablePannWindowRefresh)
00741                 return;
00742 //      CMainFrame* main = (CMainFrame*)AfxGetMainWnd();
00743         CMainFrame* main = (CMainFrame*)theApp.m_pMainWnd;
00744 
00745         if (!main || !main->m_panningWindow.IsVisible() || CGMEView::GetActiveView() != this)
00746                 return;
00747 
00748         // the original size of the image
00749         CRect extent, objext, annext;
00750         CGuiObject::GetExtent(children,objext);
00751         CGuiAnnotator::GetExtent(annotators,annext);
00752         extent.UnionRect(&objext, &annext);
00753         extent.right = (int)(extent.right * EXTENT_ERROR_CORR); // ??
00754         extent.bottom = (int)(extent.bottom * EXTENT_ERROR_CORR); // ??
00755 
00756         CRect target = CRect(0, 0, extent.Width() / PANNING_RATIO_MIN, extent.Height() / PANNING_RATIO_MIN);
00757         // FIXME: if we detected Panning Window size change, we could do this and waste less:
00758         // target = main->m_panningWindow.GetWindowRect(&rectt);
00759 
00760         // make a bitmap DC
00761         HDC tmpDC = ::GetWindowDC(this->m_hWnd);
00762         HDC pannDC = CreateCompatibleDC(tmpDC);
00763         ASSERT(pannDC != NULL);
00764 
00765         HBITMAP pannBmp = ::CreateCompatibleBitmap(tmpDC, target.Width(), target.Height());
00766         if (pannBmp == NULL) {  // introd' by zolmol
00767                 if (pannDC != NULL)
00768                         ::DeleteDC(pannDC);
00769                 return;
00770         }
00771         HBITMAP oldBmp = (HBITMAP)::SelectObject(pannDC, pannBmp);
00772 
00773         // set background color
00774         ::SetMapMode(pannDC, MM_TEXT);
00775         // DWORD dw1 = GetSysColor(COLOR_WINDOW);
00776         // BYTE r1 = GetRValue(dw1);
00777         // BYTE g1 = GetGValue(dw1);
00778         // BYTE b1 = GetBValue(dw1);
00779         HBRUSH bgBrush = ::CreateSolidBrush(bgColor);
00780         ::FillRect(pannDC, target, bgBrush);
00781         ::DeleteObject(bgBrush);
00782 
00783         ::SetMapMode(pannDC, MM_ISOTROPIC);
00784         ::SetWindowExtEx(pannDC, extent.Width(), extent.Height(), NULL);
00785         ::SetViewportExtEx(pannDC, target.Width(), target.Height(), NULL);
00786 
00787         {
00788                 Gdiplus::Graphics gdip(pannDC);
00789                 gdip.SetPageUnit(Gdiplus::UnitPixel);
00790                 gdip.SetSmoothingMode(m_eEdgeAntiAlias);
00791                 gdip.SetTextRenderingHint(m_eFontAntiAlias);
00792 
00793                 // draw the image
00794                 POSITION pos = annotators.GetHeadPosition();
00795                 while (pos) {
00796                         CGuiAnnotator *annotator = annotators.GetNext(pos);
00797                         if (annotator->IsVisible()) {
00798                                 annotator->Draw(pannDC, &gdip);
00799                         }
00800                 }
00801         }
00802         {
00803                 POSITION pos = children.GetHeadPosition();
00804                 while (pos) {
00805                         CGuiFco* fco = children.GetNext(pos);
00806                         ASSERT(fco != NULL);
00807                         if (fco->IsVisible()) {
00808                                 CGuiConnection* conn = fco->dynamic_cast_CGuiConnection();
00809                                 if (!conn)
00810                                 {
00811                                         // GME-339: Gdiplus::Graphics may modify pDC (e.g. SetViewportOrgEx) when a new-style decorator runs
00812                                         // a modified pDC makes old-style (i.e. no DrawEx) decorators render incorrectly (e.g. when the scrollbar is scrolled)
00813                                         Gdiplus::Graphics gdip(pannDC);
00814                                         gdip.SetPageUnit(Gdiplus::UnitPixel);
00815                                         gdip.SetSmoothingMode(m_eEdgeAntiAlias);
00816                                         gdip.SetTextRenderingHint(m_eFontAntiAlias);
00817                                         fco->Draw(pannDC, &gdip);
00818                                 }
00819                         }
00820                 }
00821         }
00822 
00823         // force CPanningWindow to reset the DC 
00824         main->m_panningWindow.SetBitmapDC(this->m_hWnd, pannDC, oldBmp, extent, target, bgColor);
00825         notifyPanning(GetDeviceScrollPosition());
00826         ::ReleaseDC(this->m_hWnd, tmpDC);
00827 }
00828 
00829 void CGMEView::OnDraw(CDC* pDC)
00830 {
00831         CGMEDoc* pDoc = GetDocument();
00832         ASSERT_VALID(pDoc);
00833 
00834         onScreen = pDC;
00835         if(!onScreen->IsPrinting()  &&  !IsPreview()) { 
00836                 CRect onScreenClipBox;
00837                 onScreen->GetClipBox(&onScreenClipBox);
00838                 if (onScreenClipBox.IsRectEmpty()) // empty check is enough: windows may never overlap, since they don't float
00839                         return;
00840                 pDC = offScreen;
00841                 OnPrepareDC(pDC);
00842         }
00843 
00844         {
00845                 Gdiplus::Graphics gdip(pDC->m_hDC);
00846                 gdip.SetPageUnit(Gdiplus::UnitPixel);
00847                 gdip.SetSmoothingMode(m_eEdgeAntiAlias);
00848                 gdip.SetTextRenderingHint(m_eFontAntiAlias);
00849 
00850                 if(drawGrid && !pDC->IsPrinting() && !IsPreview() && 
00851                                 m_zoomVal >= ZOOM_NO)
00852                 {
00853                         CRect objext, annext, extent;
00854                         CGuiObject::GetExtent(children, objext);
00855                         CGuiAnnotator::GetExtent(annotators, annext);
00856                         extent.UnionRect(&objext, &annext);
00857                         extent.right = (int)(extent.right*EXTENT_ERROR_CORR); // ??
00858                         extent.bottom = (int)(extent.bottom*EXTENT_ERROR_CORR); // ??
00859                         CSize s(extent.right, extent.bottom);
00860 //                      s.cx = s.cx + END_SCROLL_OFFSET;
00861 //                      s.cy = s.cy + END_SCROLL_OFFSET;
00862                         CRect rect;
00863                         GetClientRect(&rect);
00864                         graphics.DrawGrid(&gdip, GME_GRID_SIZE, GME_GRID_SIZE,
00865                                                           max(s.cx,rect.right), max(s.cy,rect.bottom));
00866                 }
00867 
00868                 /*
00869                 // DEBUG
00870 
00871                 CPoint spt = GetScrollPosition();
00872                 pDC->LPtoDP(&spt);
00873                 CRect clientRect;
00874                 GetClientRect(&clientRect);
00875                 clientRect += spt;
00876                 COLORREF col = RGB(10,10,10);
00877                 for (int x = clientRect.left; x < clientRect.right; x++) {
00878                         for (int y = clientRect.top; y < clientRect.bottom; y++) {
00879                                 CPoint ppp(x, y);
00880                                 CoordinateTransfer(ppp);
00881                                 if (!modelGrid.IsAvailable(ppp.x, ppp.y)) {
00882                                         CPoint np((x - spt.x)*zoom, (y-spt.y)*zoom);
00883                                         pDC->DPtoLP(&np);
00884                                         pDC->SetPixel(np, col);
00885                                 }
00886                         }
00887                 }
00888                 //END-DEBUG
00889                 */
00890 
00891 
00892                 POSITION pos = annotators.GetHeadPosition();
00893                 while (pos) {
00894                         CGuiAnnotator *annotator = annotators.GetNext(pos);
00895                         if (annotator->IsVisible()) {
00896                                 annotator->Draw(pDC->m_hDC, &gdip);
00897                         }
00898                 }
00899 
00900                 CRect visible;
00901                 if (pDC->IsPrinting())
00902                 {
00903                         visible = CRect(0, 0, INT_MAX, INT_MAX);
00904                 }
00905                 else
00906                 {
00907                         CRect clientRect;
00908                         GetClientRect(clientRect);
00909                         CPoint clientSize = clientRect.Size();
00910                         CPoint scrollpos = GetDeviceScrollPosition();
00911                         visible = CRect(scrollpos, scrollpos + clientSize);
00912                         visible.InflateRect(10 * 100 / m_scalePercent, 10 * 100 / m_scalePercent);
00913                         visible = CRect(std::max(0l, visible.left), std::max(0l, visible.top),
00914                                 visible.right, visible.bottom);
00915                 }
00916 
00917                 pos = children.GetHeadPosition();
00918                 int miss = 0;
00919                 while (pos) {
00920                         CGuiFco* fco = children.GetNext(pos);
00921                   ASSERT(fco != NULL);
00922                         if (fco->IsVisible()) {
00923                                 CGuiConnection* conn = fco->dynamic_cast_CGuiConnection();
00924 
00925                                 CRect loc(0, 0, INT_MAX, INT_MAX);
00926                                 if (fco->dynamic_cast_CGuiObject())
00927                                 {
00928                                         CRect fcoLoc = fco->dynamic_cast_CGuiObject()->GetCurrentAspect()->GetLocation();
00929                                         fcoLoc = fcoLoc.MulDiv(m_scalePercent, 100);
00930                                         CRect labelLoc = fco->dynamic_cast_CGuiObject()->GetCurrentAspect()->GetNameLocation();
00931                                         labelLoc = labelLoc.MulDiv(m_scalePercent, 100);
00932                                         loc.UnionRect(fcoLoc, labelLoc);
00933                                 }
00934                                 if (!conn && CRect().IntersectRect(visible, loc)) {
00935                                         // GME-339: Gdiplus::Graphics may modify pDC (e.g. SetViewportOrgEx) when a new-style decorator runs
00936                                         // a modified pDC makes old-style (i.e. no DrawEx) decorators render incorrectly (e.g. when the scrollbar is scrolled)
00937                                         gdip.~Graphics();
00938                                         ::new ((void*)&gdip) Gdiplus::Graphics(pDC->m_hDC);
00939                                         gdip.SetPageUnit(Gdiplus::UnitPixel);
00940                                         gdip.SetSmoothingMode(m_eEdgeAntiAlias);
00941                                         gdip.SetTextRenderingHint(m_eFontAntiAlias);
00942                                         fco->Draw(pDC->m_hDC, &gdip);
00943                                 }
00944                                 else
00945                                         miss++;
00946                         }
00947                 }
00948                 DrawConnections(pDC->m_hDC, &gdip);
00949 
00950                 if(pDoc->GetEditMode() == GME_EDIT_MODE || pDoc->GetEditMode() == GME_SET_MODE) {
00951                         if( ( (selected.GetCount() > 0) || (selectedAnnotations.GetCount() > 0) ) 
00952                                                 && !pDC->IsPrinting() && !IsPreview()) {
00953                                 POSITION pos = selected.GetHeadPosition();
00954                                 CRectTracker tracker;
00955                                 OnPrepareDC(pDC);       // It's needed somehow, in spite of previous OnPrepareDC
00956                                 CGuiObject *obj;
00957                                 while(pos) {
00958                                         obj = selected.GetNext(pos);
00959                                         tracker.m_rect = obj->GetLocation();
00960                                         pDC->LPtoDP(&tracker.m_rect);
00961                                         tracker.m_nStyle = CRectTracker::solidLine;
00962                                         if (obj->IsResizable())
00963                                                 tracker.m_nStyle |= CRectTracker::resizeInside;
00964                                         tracker.Draw(pDC);
00965                                 }
00966 
00967                                 pos = selectedAnnotations.GetHeadPosition();
00968                                 CGuiAnnotator *ann;
00969                                 while(pos) {
00970                                         ann = selectedAnnotations.GetNext(pos);
00971                                         if (ann->IsVisible())   // the selectedAnnotation might become hidden in this aspect
00972                                         {
00973                                                 tracker.m_rect = ann->GetLocation();
00974                                                 pDC->LPtoDP(&tracker.m_rect);
00975                                                 tracker.m_nStyle = CRectTracker::solidLine;
00976                                                 if (ann->IsResizable())
00977                                                         tracker.m_nStyle |= CRectTracker::resizeInside;
00978                                                 tracker.Draw(pDC);
00979                                         }
00980                                 }
00981                         }
00982                 }
00983 
00984                 if (GetFocus() == this && ((pDoc->GetEditMode() == GME_AUTOCONNECT_MODE || pDoc->GetEditMode() == GME_SHORTAUTOCONNECT_MODE) || (tmpConnectMode))) {
00985                         if (connSrc) {
00986                                 CRect rect = connSrc->GetLocation();
00987                                 if (connSrcPort) {
00988                                         rect = connSrcPort->GetLocation() + rect.TopLeft();
00989                                 }
00990                                 Gdiplus::Pen* xorPen = graphics.GetGdipPen2(&gdip, GME_DARKRED_COLOR, GME_LINE_SOLID, m_zoomVal > ZOOM_NO, GME_CONNSELECT_WIDTH);
00991                                 pDC->DPtoLP(rect);
00992                                 gdip.DrawRectangle(xorPen, rect.left - .5f, rect.top - .5f, (float)rect.Width(), (float)rect.Height());
00993 
00994                                 if ((connSrcHotSide != GME_CENTER) && (!connSrcPort)) {
00995                                         CPoint hotSpot;
00996                                         switch (connSrcHotSide) {
00997                                         case GME_SOUTH:
00998                                                 hotSpot.x = rect.CenterPoint().x;
00999                                                 hotSpot.y = rect.bottom;
01000                                                 break;
01001                                         case GME_NORTH:
01002                                                 hotSpot.x = rect.CenterPoint().x;
01003                                                 hotSpot.y = rect.top;
01004                                                 break;
01005                                         case GME_WEST:
01006                                                 hotSpot.x = rect.left;
01007                                                 hotSpot.y = rect.CenterPoint().y;
01008                                                 break;
01009                                         case GME_EAST:
01010                                                 hotSpot.x = rect.right;
01011                                                 hotSpot.y = rect.CenterPoint().y;
01012                                                 break;
01013                                         }
01014                                         Gdiplus::Brush* xorBrush = graphics.GetGdipBrush(GME_DARKRED_COLOR);
01015                                         gdip.FillRectangle(xorBrush, hotSpot.x - GME_HOTSPOT_VISUAL_RADIUS, hotSpot.y - GME_HOTSPOT_VISUAL_RADIUS, 2 * GME_HOTSPOT_VISUAL_RADIUS, 2 * GME_HOTSPOT_VISUAL_RADIUS);
01016                                         //gdip.FillEllipse(xorBrush, hotSpot.x - GME_HOTSPOT_VISUAL_RADIUS, hotSpot.y - GME_HOTSPOT_VISUAL_RADIUS, 2 * GME_HOTSPOT_VISUAL_RADIUS, 2 * GME_HOTSPOT_VISUAL_RADIUS);
01017                                 }
01018                         }
01019                         if (connTmp) {
01020                                 CRect rect = connTmp->GetLocation();
01021                                 if (connTmpPort) {
01022                                         rect = connTmpPort->GetLocation() + rect.TopLeft();
01023                                 }
01024                                 pDC->DPtoLP(rect);
01025                                 Gdiplus::Pen* xorPen = graphics.GetGdipPen2(&gdip, GME_RED_COLOR, GME_LINE_SOLID, m_zoomVal > ZOOM_NO, GME_CONNSELECT_WIDTH);
01026                                 gdip.DrawRectangle(xorPen, rect.left - .5f, rect.top - .5f, (float) rect.Width(), (float) rect.Height());
01027 
01028                                 if ((connTmpHotSide != GME_CENTER) && (!connTmpPort)) {
01029                                         CPoint hotSpot;
01030                                         switch (connTmpHotSide) {
01031                                         case GME_SOUTH:
01032                                                 hotSpot.x = rect.CenterPoint().x;
01033                                                 hotSpot.y = rect.bottom;
01034                                                 break;
01035                                         case GME_NORTH:
01036                                                 hotSpot.x = rect.CenterPoint().x;
01037                                                 hotSpot.y = rect.top;
01038                                                 break;
01039                                         case GME_WEST:
01040                                                 hotSpot.x = rect.left;
01041                                                 hotSpot.y = rect.CenterPoint().y;
01042                                                 break;
01043                                         case GME_EAST:
01044                                                 hotSpot.x = rect.right;
01045                                                 hotSpot.y = rect.CenterPoint().y;
01046                                                 break;
01047                                         }
01048                                         Gdiplus::Brush* xorBrush = graphics.GetGdipBrush(GME_RED_COLOR);
01049                                         gdip.FillRectangle(xorBrush, hotSpot.x - GME_HOTSPOT_VISUAL_RADIUS, hotSpot.y - GME_HOTSPOT_VISUAL_RADIUS, 2 * GME_HOTSPOT_VISUAL_RADIUS, 2 * GME_HOTSPOT_VISUAL_RADIUS);
01050                                         //gdip.FillEllipse(xorBrush, hotSpot.x - GME_HOTSPOT_VISUAL_RADIUS, hotSpot.y - GME_HOTSPOT_VISUAL_RADIUS, 2 * GME_HOTSPOT_VISUAL_RADIUS, 2 * GME_HOTSPOT_VISUAL_RADIUS);
01051                                 }
01052                         }
01053                 }
01054 
01055                 if (isInConnectionCustomizeOperation) {
01056                         DrawConnectionCustomizationTracker(pDC, &gdip);
01057                 }
01058         }
01059 
01060         if(!onScreen->IsPrinting()  &&  !IsPreview()) {
01061                 CRect r;
01062                 GetClientRect(&r);
01063                 onScreen->DPtoLP(&r);
01064                 CPoint pt = GetScrollPosition();
01065                 // Supposed workaround for Vista black view problem: use StretchBlt instead of BitBlt
01066                 // Problem can arise in multi-monitor systems with NVidia cards (but who knows what other configs)
01067                 if (m_bUseStretchBlt)
01068                         onScreen->StretchBlt(pt.x - 5, pt.y - 5, r.Width() + 10, r.Height() + 10, offScreen, pt.x - 5, pt.y - 5, r.Width() + 10, r.Height() + 10, SRCCOPY);
01069                 else
01070                         onScreen->BitBlt(pt.x - 5, pt.y - 5, r.Width() + 10, r.Height() + 10, offScreen, pt.x - 5, pt.y - 5, SRCCOPY);
01071         }
01072 }
01073 
01074 
01075 void CGMEView::OnInitialUpdate()
01076 {
01077         BeginWaitCursor();
01078         CScrollZoomView::OnInitialUpdate();
01079         frame = (CChildFrame *)(GetParentFrame());
01080         frame->SetView(this);
01081 
01082         dropTarget.Register(this);
01083         EnableToolTips(TRUE);
01084 
01085 //      zoomIdx = GME_ZOOM_LEVEL_MED;
01086         m_zoomVal = ZOOM_NO;
01087         int zv = 0;
01088         int l = _stscanf( (LPCTSTR) theApp.getDefZoomLev(), _T("%d"), &zv);
01089         if( l == 1 && zv && zv >= ZOOM_MIN && zv <= ZOOM_MAX) // do not accept ZOOM_WIDTH,ZOOM_HEIGHT,ZOOM_ALL for now as ZoomValue
01090                 m_zoomVal = zv;
01091         // sets the combo too 
01092         frame->propBar.SetZoomVal(m_zoomVal);
01093         CMainFrame::theInstance->WriteStatusZoom(m_zoomVal); // setZoomPercents[zoomIdx]);
01094 
01095         CDC* pDC = GetDC();
01096         CreateOffScreen(pDC);
01097         ReleaseDC(pDC);
01098         CComPtr<IMgaFCO> centerObj;
01099 
01100         try {
01101                 COMTHROW(theApp.mgaProject->CreateTerritory(driver,&terry, NULL));
01102                 BeginTransaction(TRANSACTION_READ_ONLY);
01103 
01104                 {
01105                    CComPtr<IMgaObject> ob;
01106                    COMTHROW(terry->OpenObj(GetDocument()->nextToView, &ob));
01107                    GetDocument()->ResetNextToView();
01108                    COMTHROW(ob->QueryInterface(&currentModel));
01109                 }
01110 
01111                 COMTHROW(currentModel->Open(OPEN_READ));
01112                 COMTHROW(currentModel->get_Name(PutOut(name)));
01113                 CComPtr<IMgaMetaFCO> meta;
01114                 COMTHROW(currentModel->get_Meta(&meta));
01115                 COMTHROW(meta->get_Name(PutOut(kindName)));
01116                 COMTHROW(meta->get_DisplayedName(PutOut(kindDisplayedName)));
01117 
01118                 CComBSTR modid;
01119                 COMTHROW( currentModel->get_ID( &modid));
01120                 currentModId = modid;
01121 
01122                 metaref_type mt;
01123                 COMTHROW(meta->get_MetaRef(&mt));
01124                 guiMeta = CGuiMetaProject::theInstance->GetGuiMetaModel(mt);
01125                 currentAspect = guiMeta->FindAspect(GetDocument()->nextAspect);
01126                 if(!currentAspect)
01127                         currentAspect = guiMeta->GetFirstAspect();
01128 
01129                 {
01130                         VARIANT_BOOL b;
01131                         COMTHROW(currentModel->get_IsInstance(&b));
01132                         isType = (b == VARIANT_FALSE);
01133                         if(isType) {
01134                                 COMTHROW(currentModel->get_BaseType(&baseType));
01135                         }
01136                         else{
01137                                 COMTHROW(currentModel->get_Type(&baseType));
01138                         }
01139 
01140                         if(isType) {
01141                                 CComPtr<IMgaModel> type;
01142                                 FindDerivedFrom(currentModel,type);
01143                                 isSubType = (type != 0);
01144                         }
01145                 }
01146 
01147                 SetBgColor();
01148                 needsConnConversion = CreateGuiObjects();
01149                 SetProperties();
01150 
01151                 if (GetDocument()->initialCenterObj) {
01152                         COMTHROW(terry->OpenFCO(GetDocument()->initialCenterObj, &centerObj));
01153                         GetDocument()->initialCenterObj = NULL;
01154                 }
01155 
01156                 CommitTransaction();
01157 
01158                 if (needsConnConversion) {
01159                         ConvertNeededConnections();
01160                         needsConnConversion = false;
01161                 }
01162         }
01163         catch(hresult_exception &e) {
01164                 // CrashRpt c51312b4-866b-4a9f-a18d-9928ef9905ef: Close before MessageBox
01165                 frame->SendMessage(WM_CLOSE);
01166                 AbortTransaction(e.hr);
01167                 AfxMessageBox(_T("Unable to open model"),MB_OK | MB_ICONSTOP);
01168                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnInitialUpdate - Unable to open model.\r\n"));
01169                 EndWaitCursor();
01170                 return;
01171         }
01172 
01173         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnInitialUpdate() - opened model: ")+path+name+_T("\r\n"));
01174 
01175         modelGrid.Clear();
01176         FillModelGrid();
01177         AutoRoute();
01178         ClearConnSpecs();
01179         if(guiMeta) {
01180                 theApp.UpdateCompList4CurrentKind( guiMeta->name);
01181                 CMainFrame::theInstance->SetPartBrowserMetaModel(guiMeta);
01182                 CMainFrame::theInstance->SetPartBrowserBg(bgColor);
01183                 CMainFrame::theInstance->ChangePartBrowserAspect(currentAspect->index);
01184         }
01185         SetScroll();
01186         SetCenterObject(centerObj);
01187         initDone = true;
01188         EndWaitCursor();
01189 
01190         SendOpenModelEvent();
01191         DragAcceptFiles(TRUE);
01192 }
01193 
01195 // CGMEView printing
01196 
01197 #define LOGOSIZE                64 // 115
01198 
01199 void CGMEView::PrintMultiLineText(Gdiplus::Graphics* gdip, CDC *pDC, CString txt, int x, int &y, int ry, int xwidth)
01200 {
01201         Gdiplus::Font* font = graphics.GetGdipFont(GME_PORTNAME_FONT);
01202         CPoint pt(x,y);
01203         CSize size = graphics.MeasureText(gdip, txt, pt, font);
01204         if(size.cx < xwidth) {
01205                 graphics.DrawGdipText(gdip, txt, pt, font, GME_BLACK_COLOR, TA_LEFT | TA_BOTTOM);
01206         }
01207         else {
01208                 int incr = 2;
01209                 int lng = txt.GetLength();
01210                 int width = incr;
01211                 for(int start = 0; start < lng; start += width ) {
01212                         for(width = incr; ; width += incr) {
01213                                 bool printIt = false;
01214                                 CString cur = txt.Mid(start,width);
01215                                 if(start + width >= lng)
01216                                         printIt = true;
01217                                 else {
01218                                         CSize size = graphics.MeasureText(gdip, cur, pt, font);
01219                                         if(size.cx > xwidth) {
01220                                                 width -= incr;
01221                                                 cur = txt.Mid(start,width);
01222                                                 printIt = true;
01223                                         }
01224                                 }
01225                                 if(printIt) {
01226                                         graphics.DrawGdipText(gdip, cur, pt, font, GME_BLACK_COLOR, TA_LEFT | TA_BOTTOM);
01227                                         pt.y += (int)(ry / 12);
01228                                         break;
01229                                 }
01230                         }
01231                 }
01232         }
01233 
01234         y = pt.y + (int)(ry / 25);
01235 }
01236 
01237 void CGMEView::PrintHeader(CDC* pDC, CPrintInfo* pInfo)
01238 {
01239         PrintHeaderRect(pDC, pInfo->m_rectDraw);
01240 }
01241 
01242 void CGMEView::PrintHeaderRect(CDC* pDC, CRect &rectDraw)
01243 {
01244         /*const static*/ int logdpi = 140;
01245         int savedID = pDC->SaveDC();
01246 
01247         CString line1;
01248         CString line2;
01249         line1 = name;
01250         line2 = _T("Paradigm: ") + theApp.guiMetaProject->displayedName;
01251         line2 += _T("     Project: ") + theApp.projectName;
01252         line2 += _T("     Model: ") + kindDisplayedName;
01253         line2 += _T("     Aspect: ") + currentAspect->displayedName;
01254         CString tim;
01255         {
01256                 struct tm *newtime;
01257                 TCHAR am_pm[] = _T("AM");
01258                 time_t long_time;
01259                 time( &long_time );                /* Get time as long integer. */
01260                 newtime = localtime( &long_time ); /* Convert to local time. */
01261                 if( newtime->tm_hour > 12 )        /* Set up extension. */
01262                         _tcscpy( am_pm, _T("PM") );
01263                 if( newtime->tm_hour > 12 )        /* Convert from 24-hour */
01264                         newtime->tm_hour -= 12;            /*   to 12-hour clock.  */
01265                 if( newtime->tm_hour == 0 )        /* Set hour to 12 if midnight. */
01266                         newtime->tm_hour = 12;
01267                 tim.Format(_T("%.19s  %s"), asctime( newtime ), am_pm );
01268         }
01269         line2 += _T("     Time: ") + tim;
01270 
01271         // Setup mapping mode to have 50 pixel in 1 inch
01272         pDC->SetMapMode(MM_ISOTROPIC);
01273         double inchX = pDC->GetDeviceCaps(LOGPIXELSX);
01274         double inchY = pDC->GetDeviceCaps(LOGPIXELSY);
01275         pDC->SetWindowExt(logdpi,logdpi);
01276         pDC->SetViewportExt((int)inchX,(int)inchY);
01277 
01278         int gap = (int)(logdpi / 40);                             // 1/40 inch
01279         int txty = gap * 6 ;
01280         int xx = LOGOSIZE/4 + 20;
01281 
01282         Gdiplus::Graphics gdip(pDC->m_hDC);
01283         gdip.SetPageUnit(Gdiplus::UnitPixel);
01284         gdip.SetSmoothingMode(m_eEdgeAntiAlias);
01285         gdip.SetTextRenderingHint(m_eFontAntiAlias);
01286 
01287         PrintMultiLineText(&gdip,pDC,line1,xx,txty,logdpi,rectDraw.Width() - xx);
01288 
01289         txty += 4 * gap;
01290 
01291         CPoint pt = CPoint(LOGOSIZE /4  + 20,txty);
01292 // ??   PrintMultiLineText(&gdip, pDC, line2, LOGOSIZE /4  + 20, txty, logdpi, rectDraw.Width() - xx);
01293         graphics.DrawGdipText(&gdip,line2,pt,graphics.GetGdipFont(GME_PORTNAME_FONT),GME_BLACK_COLOR,TA_LEFT | TA_BOTTOM);
01294 //      pt = CPoint(rectDraw.right-gap * 2,LOGOSIZE + 20);
01295 //      graphics.DrawGdipText(&gdip,tim,pt,graphics.GetGdipFont(GME_PORTNAME_FONT),GME_BLACK_COLOR,TA_RIGHT | TA_BOTTOM);
01296 
01297 
01298         CBitmap logo;
01299         // TODO: Error checking
01300         logo.LoadBitmap(IDB_BITMAP_LOGO);
01301         CDC logoDC;
01302         // TODO: Error checking
01303         logoDC.CreateCompatibleDC(pDC);
01304         logoDC.SetMapMode(MM_TEXT);
01305         CBitmap * bmp = logoDC.SelectObject(&logo);
01306         int bits = pDC->GetDeviceCaps(BITSPIXEL);
01307         if (bits == 1) 
01308                 pDC->SetStretchBltMode(HALFTONE);
01309 //      BOOL ret2 = pDC->StretchBlt(0, txty-LOGOSIZE/4,LOGOSIZE/4,LOGOSIZE/4,&logoDC,0,0,LOGOSIZE, LOGOSIZE, SRCCOPY);
01310         // TODO: Error checking
01311         pDC->StretchBlt(0, txty-LOGOSIZE/2,LOGOSIZE/2,LOGOSIZE/2,&logoDC,0,0,LOGOSIZE, LOGOSIZE, SRCCOPY);
01312         if (bmp)
01313                 bmp = logoDC.SelectObject((CBitmap*)bmp);
01314         logo.DeleteObject();
01315 
01316 
01317         int y = txty;
01318         CPen pen;
01319         CPen *oldpen;
01320         int pw = (int)(logdpi / 48);                              // 1/48 inch
01321         pen.CreatePen(PS_SOLID,pw,RGB(0,0,0));
01322         oldpen = pDC->SelectObject(&pen);
01323         pDC->MoveTo(0,y);
01324         pDC->LineTo(rectDraw.right,y);
01325 
01326         y += 3 * gap;
01327         CPoint offset(0,y);
01328         pDC->LPtoDP(&offset);
01329 
01330         pDC->SelectObject(oldpen);
01331         pen.DeleteObject();
01332         pDC->RestoreDC(savedID);
01333         pDC->DPtoLP(&offset);
01334         rectDraw.top += (offset.y < logdpi/3)? logdpi/3: offset.y; // one third of an inch
01335 }
01336 
01337 BOOL CGMEView::OnPreparePrinting(CPrintInfo* pInfo)
01338 {
01339         // change the PrintDialog to a customized one
01340         CGmePrintDialog *gpd = new CGmePrintDialog(this, guiMeta, FALSE);
01341         if (gpd  &&  pInfo->m_pPD)
01342                 delete pInfo->m_pPD;
01343         if (gpd)
01344         {
01345                 pInfo->m_pPD = gpd;
01346                 pInfo->m_pPD->m_pd.Flags =      PD_ALLPAGES |  // actually the current aspect
01347                                                                         PD_ENABLEPRINTTEMPLATE | PD_NONETWORKBUTTON  | 
01348                                                                         PD_USEDEVMODECOPIES | PD_USEDEVMODECOPIESANDCOLLATE |
01349                                                                         PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK |
01350                                                                         PD_RETURNDC ;
01351                 pInfo->m_pPD->m_pd.nMinPage = 1;      // one based page numbers
01352         pInfo->m_pPD->m_pd.nMaxPage = 0xffff; // how many pages is unknown
01353                 pInfo->m_pPD->m_pd.hInstance = AfxGetInstanceHandle();
01354                 pInfo->m_pPD->m_pd.lpPrintTemplateName = MAKEINTRESOURCE(IDD_PRINT_DIALOG);
01355         }
01356 
01357         if (!CScrollZoomView::DoPreparePrinting(pInfo))
01358                 return FALSE;
01359 
01360         HDC hdc = pInfo->m_pPD->GetPrinterDC();
01361         CDC cdc;
01362         cdc.Attach(hdc);
01363     LPDEVMODE devmode = pInfo->m_pPD->GetDevMode();
01364         devmode->dmOrientation = (gpd->IsPortrait())? (short)DMORIENT_PORTRAIT: (short)DMORIENT_LANDSCAPE;
01365         m_scalePrnPages = (short)gpd->NumOfPages();
01366         pInfo->m_pPD->m_pd.nMinPage = 1;      
01367         m_fullPrnAspNum = gpd->NumOfSelAspects();
01368     pInfo->m_pPD->m_pd.nMaxPage = (short)(m_scalePrnPages * m_scalePrnPages * m_fullPrnAspNum); 
01369         pInfo->m_pPD->m_pd.nToPage = (unsigned short)(0xffff);
01370         cdc.ResetDC(devmode);
01371         cdc.Detach();
01372         m_currPrnNumAsp = 0;
01373         m_prnpos = NULL;
01374         m_lastPrnPage = 0; // hack
01375         return TRUE;
01376 }
01377 
01378 void CGMEView::PrepareAspectPrn(CPrintInfo* pInfo)
01379 {
01380         CGuiMetaAspect *asp = NULL;
01381         CGmePrintDialog* pdlg = (CGmePrintDialog*)(pInfo->m_pPD);
01382         bool changeAsp = false;
01383 
01384         if (m_lastPrnPage == pInfo->m_nCurPage)
01385                 return;
01386 
01387         if (pdlg->IsAllAspect()  ||  pdlg->IsSelAspect())
01388         { // all or some Aspect selected
01389                 if (!m_currPrnNumAsp)
01390                 {  // find the first Aspect
01391                         SaveCurrAsp();
01392                         m_prnpos = guiMeta->aspects.GetHeadPosition();
01393                 }
01394                 if (m_scalePrnPages == 1  ||  
01395                                 pInfo->m_nCurPage % (m_scalePrnPages*m_scalePrnPages) == 1)
01396                 {  // change aspect
01397                         asp = guiMeta->aspects.GetNext(m_prnpos);
01398                         if (pdlg->IsSelAspect()) 
01399                         {
01400                                 while (!pdlg->IsSelectedAspect(asp->name))
01401                                 {
01402                                         if (m_prnpos)
01403                                                 asp = guiMeta->aspects.GetNext(m_prnpos);
01404                                         else
01405                                         {
01406                                                 asp = NULL;
01407                                                 ASSERT(asp);
01408                                                 break;
01409                                         }
01410                                 }
01411                         }
01412                         m_currPrnNumAsp++;
01413                         changeAsp = true;
01414                 }
01415                 if (changeAsp)
01416                 {
01417                         if (ChangePrnAspect(asp->name))
01418                         {
01419                                 if (pdlg->IsAutorotate()) // it doen't work in OnPrint only in OnPrepareDC
01420                                 { // it works only before StartPage
01421                                         HDC hdc = pInfo->m_pPD->GetPrinterDC();
01422                                         CDC cdc;
01423                                         cdc.Attach(hdc);
01424                                         CRect extent, objext, annext;
01425                                         CGuiObject::GetExtent(children,objext);
01426                                         CGuiAnnotator::GetExtent(annotators,annext);
01427                                         extent.UnionRect(&objext, &annext);
01428                                         LPDEVMODE devmode = pInfo->m_pPD->GetDevMode();
01429                                         devmode->dmFields = DM_ORIENTATION;
01430                                         if (extent.Width() > extent.Height()) // rotate it
01431                                                 devmode->dmOrientation = (short)DMORIENT_LANDSCAPE;
01432                                         else
01433                                                 devmode->dmOrientation = (short)DMORIENT_PORTRAIT;
01434                                         // TODO: Error checking
01435                                         cdc.ResetDC(devmode); // done for the AttribDC
01436                                         cdc.Detach();
01437                                 }
01438                         }
01439                 }
01440         }
01441         m_lastPrnPage = pInfo->m_nCurPage;
01442 }
01443 
01444 void CGMEView::OnPrint(CDC* pDC, CPrintInfo* pInfo)
01445 {
01446         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnPrint\r\n"));
01447         CGmePrintDialog* pdlg = (CGmePrintDialog*)(pInfo->m_pPD);
01448         int headerY = 0;
01449 
01450         if (pdlg->HasHeader())
01451         {
01452                 PrintHeader(pDC, pInfo);
01453                 headerY = pInfo->m_rectDraw.top;
01454         }
01455         // setup the DC according to the current page number - multipage
01456         int line = (int)ceil((double)(pInfo->m_nCurPage % (m_scalePrnPages * m_scalePrnPages)) / m_scalePrnPages);
01457         int col = pInfo->m_nCurPage % (m_scalePrnPages * m_scalePrnPages) % m_scalePrnPages;
01458         col = (col)? col: m_scalePrnPages;
01459         line = (line)? line: m_scalePrnPages;
01460         line--; // starts with 0
01461         col--;
01462 
01463         {
01464                 pDC->SetMapMode(MM_ISOTROPIC);
01465                 CRect extent, objext, annext;
01466                 CGuiObject::GetExtent(children,objext);
01467                 CGuiAnnotator::GetExtent(annotators,annext);
01468                 extent.UnionRect(&objext, &annext);
01469                 extent.right = (int)(extent.right*EXTENT_ERROR_CORR); // ??
01470                 extent.bottom = (int)(extent.bottom*EXTENT_ERROR_CORR); // ??
01471                 double wpage, hpage;
01472                 double wmargin = GetDeviceCaps(pDC->m_hDC,PHYSICALOFFSETX);
01473                 double hmargin = GetDeviceCaps(pDC->m_hDC,PHYSICALOFFSETY);
01474                 wpage = GetDeviceCaps(pDC->m_hDC,PHYSICALWIDTH) - 2*wmargin;
01475                 hpage = GetDeviceCaps(pDC->m_hDC,PHYSICALHEIGHT)- 2*hmargin;
01476 
01477                 // headerY was calculated with another scaling
01478                 pDC->SetWindowExt(extent.right, extent.bottom);
01479                 int devheader = (headerY)? (int)(pDC->GetDeviceCaps(LOGPIXELSY)/3): 0; // I know it is 1/3 inch - pfujj
01480 
01481                 pDC->SetViewportExt((int)(m_scalePrnPages*wpage), (int)(m_scalePrnPages*(hpage-devheader)));
01482                 pDC->SetViewportOrg((int)(-wpage*col), (int)(-(hpage-devheader)*line) +devheader);
01483         }
01484 
01485         OnDraw(pDC);
01486 
01487         // restore Aspect
01488         if (pInfo->m_pPD->m_pd.nMaxPage == pInfo->m_nCurPage  && m_currPrnNumAsp == m_fullPrnAspNum)
01489         { 
01490                 CGuiMetaAspect* lastcurr = GetSavedAsp();
01491                 ChangePrnAspect(lastcurr->name);
01492                 Invalidate();
01493         }
01494 }
01495 
01496 void CGMEView::OnDestroy()
01497 {
01498         // Deactivate the item on destruction; this is important
01499         // when a splitter view is being used.
01500         if (timerID) {
01501                 KillTimer(timerID);
01502                 timerID = 0;
01503         }
01504         CMainFrame* main = (CMainFrame*)AfxGetMainWnd();
01505 
01506         CDocument* doc = GetDocument();
01507         POSITION pos = doc->GetFirstViewPosition();
01508         if (pos != NULL  &&  doc->GetNextView(pos)  &&  pos == NULL)
01509         {
01510                 CRect extent(0,0,0,0), target(0,0,0,0); // terge
01511                 main->m_panningWindow.SetBitmapDC(this->m_hWnd, NULL, NULL, extent, target, bgColor);
01512         }
01513 
01514         CScrollZoomView::OnDestroy();
01515 }
01516 
01517 void CGMEView::OnSize(UINT nType, int cx, int cy)
01518 {
01519         m_overlay = nullptr;
01520         CScrollZoomView::OnSize(nType, cx, cy);
01521 }
01522 
01524 // CGMEView diagnostics
01525 
01526 #ifdef _DEBUG
01527 void CGMEView::AssertValid() const
01528 {
01529         CScrollZoomView::AssertValid();
01530 }
01531 
01532 void CGMEView::Dump(CDumpContext& dc) const
01533 {
01534         CScrollZoomView::Dump(dc);
01535 }
01536 
01537 CGMEDoc* CGMEView::GetDocument() // non-debug version is inline
01538 {
01539         ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CGMEDoc)));
01540         return (CGMEDoc*)m_pDocument;
01541 }
01542 
01543 #endif //_DEBUG
01544 
01546 // CGMEView custom operations
01547 
01548 void CGMEView::BeginTransaction(transactiontype_enum mode)
01549 {
01550         VERIFY(inTransaction >= 0);
01551         if(!inEventHandler && ++inTransaction == 1) {
01552                 inRWTransaction = (mode == TRANSACTION_GENERAL);
01553                 COMTHROW(theApp.mgaProject->BeginTransaction(terry,mode));
01554         }
01555 }
01556 
01557 void CGMEView::CommitTransaction()
01558 {
01559         if(inEventHandler)
01560                 return;
01561         VERIFY(inTransaction > 0);
01562         if(inTransaction == 1)
01563                 COMTHROW(theApp.mgaProject->CommitTransaction());
01564         inTransaction--;
01565         inRWTransaction = false;
01566 }
01567 
01568 void CGMEView::__CommitTransaction()
01569 {
01570         if(inEventHandler)
01571                 return;
01572         VERIFY(inTransaction > 0);
01573         if(inTransaction == 1)
01574                 theApp.mgaProject->__CommitTransaction();
01575         inTransaction--;
01576         inRWTransaction = false;
01577 }
01578 
01579 void CGMEView::AbortTransaction(HRESULT hr)
01580 {
01581         if(inEventHandler)
01582                 return;
01583         VERIFY(inTransaction > 0);
01584         if(--inTransaction > 0)
01585                 throw hresult_exception(hr);
01586         else
01587                 theApp.mgaProject->AbortTransaction();
01588 }
01589 
01590 
01591 bool CGMEView::SendOpenModelEvent()
01592 {
01593         bool ok = true;
01594         try {
01595                 BeginTransaction();
01596 
01597                 COMTHROW(currentModel->SendEvent(OBJEVENT_OPENMODEL));
01598 
01599                 __CommitTransaction();
01600         }
01601         catch(hresult_exception &e) {
01602                 AbortTransaction(e.hr);
01603                 ok = false;
01604         }
01605         catch(_com_error& e) {
01606                 AbortTransaction(e.Error());
01607                 ok = false;
01608                 CString error = _T("Notifying Addons of OpenModel failed");
01609                 if (e.Description().length() != 0)
01610                 {
01611                         error += _T(": ");
01612                         error += static_cast<const TCHAR*>(e.Description());
01613                 }
01614                 CGMEEventLogger::LogGMEEvent(error + _T("\r\n"));
01615                 AfxMessageBox(error,MB_ICONSTOP | MB_OK);
01616         }
01617         return ok;
01618 }
01619 
01620 bool CGMEView::SendCloseModelEvent()
01621 {
01622         bool ok = true;
01623         try {
01624                 BeginTransaction();
01625 
01626                 COMTHROW(currentModel->SendEvent(OBJEVENT_CLOSEMODEL));
01627 
01628                 CommitTransaction();
01629         }
01630         catch(hresult_exception &e) {
01631                 try {
01632                         AbortTransaction(e.hr);
01633                 } catch(hresult_exception &e) {
01634                 } // Our transaction count was wrong. What else can we do?
01635                 ok = false;
01636         }
01637         catch(_com_error& e) {
01638                 AbortTransaction(e.Error());
01639                 ok = false;
01640                 CString error = _T("Notifying Addons of CloseModel failed");
01641                 if (e.Description().length() != 0)
01642                 {
01643                         error += _T(": ");
01644                         error += static_cast<const TCHAR*>(e.Description());
01645                 }
01646                 CGMEEventLogger::LogGMEEvent(error + _T("\r\n"));
01647                 AfxMessageBox(error,MB_ICONSTOP | MB_OK);
01648         }
01649         return ok;
01650 }
01651 
01652 bool CGMEView::SendMouseOver4Object( CGuiObject * pObject)
01653 {
01654         bool ok = true;
01655         try {
01656                 BeginTransaction();
01657 
01658                 if( pObject && pObject->mgaFco)
01659                 {
01660                         long oStatus;
01661                         COMTHROW(pObject->mgaFco->get_Status(&oStatus));
01662                         if(oStatus == OBJECT_EXISTS) // make sure it has not been deleted since then
01663                                 COMTHROW( pObject->mgaFco->SendEvent(OBJEVENT_MOUSEOVER));
01664                 }
01665 
01666                 CommitTransaction();
01667         }
01668         catch(hresult_exception &e) {
01669                 AbortTransaction(e.hr);
01670                 ok = false;
01671         }
01672         return ok;
01673 }
01674 
01675 bool CGMEView::SendSelecEvent4Object( CGuiObject* pSelection)
01676 {
01677         bool ok = true;
01678 
01679         std::list<CGuiObject*>::iterator found = std::find( m_lstUnselect.begin(), m_lstUnselect.end(), pSelection);
01680         if( found != m_lstUnselect.end()) // it can't be unsel and sel at the same time
01681         {
01682                 m_lstUnselect.erase( found);
01683         }
01684 
01685         found = std::find( m_lstSelect.begin(), m_lstSelect.end(), pSelection);
01686         if( found != m_lstSelect.end()) // it should not be twice in sel
01687         {
01688                 m_lstSelect.erase( found);
01689         }
01690 
01691         m_lstSelect.push_back( pSelection);
01692         return ok;
01693 }
01694 
01695 bool CGMEView::SendUnselEvent4Object( CGuiObject* pUnselection)
01696 {
01697         bool ok = true;
01698 
01699         std::list<CGuiObject*>::iterator found = std::find( m_lstSelect.begin(), m_lstSelect.end(), pUnselection);
01700         if( found != m_lstSelect.end()) // it can't be unsel and sel at the same time
01701         {
01702                 m_lstSelect.erase( found);
01703         }
01704 
01705         found = std::find( m_lstUnselect.begin(), m_lstUnselect.end(), pUnselection);
01706         if( found != m_lstUnselect.end()) // it should not be twice in unsel
01707         {
01708                 m_lstUnselect.erase( found);
01709         }
01710 
01711         m_lstUnselect.push_back( pUnselection);
01712         return ok;
01713 }
01714 
01715 bool CGMEView::SendSelecEvent4List( CGuiObjectList* pSelection)
01716 {
01717         bool ok = true;
01718         // send select event for each object in list
01719         POSITION pos = pSelection->GetHeadPosition();
01720         CGuiObject *obj;
01721         while(pos) {
01722                 obj = pSelection->GetNext(pos);
01723                 bool ok2 = SendSelecEvent4Object( obj);
01724                 ok = ok && ok2;
01725         }
01726         return ok;
01727 }
01728 
01729 
01730 bool CGMEView::SendUnselEvent4List( CGuiObjectList* pUnselection)
01731 {
01732         bool ok = true;
01733         // send deselect event for each object in list
01734         POSITION pos = pUnselection->GetHeadPosition();
01735         CGuiObject *obj;
01736         while(pos) {
01737                 obj = pUnselection->GetNext(pos);
01738                 bool ok2 = SendUnselEvent4Object( obj);
01739                 ok = ok && ok2;
01740         }
01741         return ok;
01742 }
01743 
01744 bool CGMEView::SendNow(bool onlyDecoratorNotification)
01745 {
01746         if (m_lstSelect.empty() && m_lstUnselect.empty()) {
01747                 return false;
01748         } else {
01749                 if (selectedConnection != NULL) {
01750                         selectedConnection->SetSelect(false);
01751                         selectedConnection = NULL;
01752                 }
01753         }
01754 
01755         bool ok = true;
01756         try {
01757                 if (!onlyDecoratorNotification)
01758                         BeginTransaction();
01759 
01760                 std::list<CGuiObject*>::iterator it;
01761                 for( it = m_lstUnselect.begin(); it != m_lstUnselect.end(); ++it)
01762                 {
01763                         CGuiObject * pUnselection = *it;
01764                         if( pUnselection && pUnselection->mgaFco)
01765                         {
01766                                 long oStatus;
01767                                 COMTHROW(pUnselection->mgaFco->get_Status(&oStatus));
01768                                 if(oStatus == OBJECT_EXISTS) {  // make sure it has not been deleted since then
01769                                         if (!onlyDecoratorNotification)
01770                                                 COMTHROW( pUnselection->mgaFco->SendEvent(OBJEVENT_DESELECT));
01771                                         // Sending decorator events (for efficiency)
01772                                         CGuiAspect* pAspect = pUnselection->GetCurrentAspect();
01773                                         if (pAspect != NULL) {
01774                                                 CComQIPtr<IMgaElementDecorator> newDecorator(pAspect->GetDecorator());
01775                                                 if (newDecorator)
01776                                                         HRESULT retVal = newDecorator->SetSelected(VARIANT_FALSE);
01777                                         }
01778                                 }
01779                         }
01780                 }
01781 
01782                 for( it = m_lstSelect.begin(); it != m_lstSelect.end(); ++it)
01783                 {
01784                         CGuiObject * pSelection = *it;
01785                         if( pSelection && pSelection->mgaFco)
01786                         {
01787                                 long oStatus;
01788                                 COMTHROW(pSelection->mgaFco->get_Status(&oStatus));
01789                                 if (oStatus == OBJECT_EXISTS) {
01790                                         if (!onlyDecoratorNotification)
01791                                                 COMTHROW( pSelection->mgaFco->SendEvent(OBJEVENT_SELECT));
01792                                         // Sending decorator events (for efficiency)
01793                                         CGuiAspect* pAspect = pSelection->GetCurrentAspect();
01794                                         if (pAspect != NULL) {
01795                                                 CComQIPtr<IMgaElementDecorator> newDecorator(pAspect->GetDecorator());
01796                                                 if (newDecorator)
01797                                                         HRESULT retVal = newDecorator->SetSelected(VARIANT_TRUE);
01798                                         }
01799                                 }
01800                         }
01801                 }
01802 
01803                 if (!onlyDecoratorNotification) {
01804                         m_lstSelect.clear();
01805                         m_lstUnselect.clear();
01806 
01807                         CommitTransaction();
01808                 }
01809         }
01810         catch(hresult_exception &e) {
01811                 if (!onlyDecoratorNotification)
01812                         AbortTransaction(e.hr);
01813                 ok = false;
01814         }
01815         return ok;
01816 }
01817 
01818 void CGMEView::AddAnnotationToSelectionHead(CGuiAnnotator* ann)
01819 {
01820         AddAnnotationToSelection(ann, true);
01821 }
01822 
01823 void CGMEView::AddAnnotationToSelectionTail(CGuiAnnotator* ann)
01824 {
01825         AddAnnotationToSelection(ann, false);
01826 }
01827 
01828 void CGMEView::AddAnnotationToSelection(CGuiAnnotator* ann, bool headOrTail)
01829 {
01830         ClearConnectionSelection();
01831         CComPtr<IMgaElementDecorator> decorator = ann->GetDecorator(currentAspect->index);
01832         if (decorator)
01833                 HRESULT retVal = decorator->SetSelected(VARIANT_TRUE);
01834         if (headOrTail)
01835                 selectedAnnotations.AddHead(ann);
01836         else
01837                 selectedAnnotations.AddTail(ann);
01838 }
01839 
01840 void CGMEView::RemoveAllAnnotationFromSelection(void)
01841 {
01842         POSITION pos = selectedAnnotations.GetHeadPosition();
01843         CGuiAnnotator *ann;
01844         while (pos) {
01845                 ann = selectedAnnotations.GetNext(pos);
01846                 CComPtr<IMgaElementDecorator> decorator = ann->GetDecorator(currentAspect->index);
01847                 if (decorator)
01848                         HRESULT retVal = decorator->SetSelected(VARIANT_FALSE);
01849         }
01850         selectedAnnotations.RemoveAll();
01851 }
01852 
01853 void CGMEView::RemoveAnnotationFromSelectionHead(void)
01854 {
01855         CGuiAnnotator* head = selectedAnnotations.GetHead();
01856         CComPtr<IMgaElementDecorator> decorator = head->GetDecorator(currentAspect->index);
01857         if (decorator)
01858                 HRESULT retVal = decorator->SetSelected(VARIANT_FALSE);
01859         selectedAnnotations.RemoveHead();
01860 }
01861 
01862 void CGMEView::RemoveAnnotationFromSelection(POSITION annPos)
01863 {
01864         CGuiAnnotator* ann = selectedAnnotations.GetAt(annPos);
01865         CComPtr<IMgaElementDecorator> decorator = ann->GetDecorator(currentAspect->index);
01866         if (decorator)
01867                 HRESULT retVal = decorator->SetSelected(VARIANT_FALSE);
01868         selectedAnnotations.RemoveAt(annPos);
01869 }
01870 
01871 void CGMEView::ClearConnectionSelection(void)
01872 {
01873         if (selectedConnection != NULL) {
01874                 selectedConnection->SetSelect(false);
01875                 selectedConnection = NULL;
01876         }
01877 }
01878 
01879 void CGMEView::UpdateConnectionSelection(int aspect)
01880 {
01881         if (selectedConnection != NULL) {
01882                 if(!selectedConnection->IsVisible(aspect)) {
01883                         selectedConnection->SetSelect(false);
01884                         selectedConnection = NULL;
01885                 }
01886         }
01887 }
01888 
01889 void CGMEView::ResetParent(bool doInvalidate)
01890 {
01891 #if !defined (ACTIVEXGMEVIEW)
01892         CGMEView *parentView = GetDocument()->FindView(parent);
01893         if(parentView) {
01894                 parentView->Reset(doInvalidate);
01895                 parentView->Invalidate();
01896         }
01897 #endif
01898 }
01899 
01900 CGuiFco* CGMEView::CreateGuiObject(CComPtr<IMgaFCO>& fco, CGuiFcoList* objList, CGuiConnectionList* connList)
01901 {
01902         CComPtr<IMgaMetaRole> role;
01903         COMTHROW(fco->get_MetaRole(&role));
01904         objtype_enum tp;
01905         COMTHROW(fco->get_ObjType(&tp));
01906         CGuiFco* guiFco;
01907         bool isCGuiConnection = false;
01908         if (tp == OBJTYPE_MODEL) {
01909                 guiFco = new CGuiModel(fco, role, this, guiMeta->NumberOfAspects());
01910                 ((CGuiModel *)guiFco)->InitObject(this);
01911                 ((CGuiModel *)guiFco)->SetAspect(currentAspect->index);
01912         } else if(tp == OBJTYPE_REFERENCE) {
01913                 // Immediate referred object
01914                 CComPtr<IMgaFCO> refd;
01915                 CComPtr<IMgaReference> ref;
01916                 COMTHROW(fco.QueryInterface(&ref));
01917                 COMTHROW(ref->get_Referred(&refd));
01918 
01919                 // Final referred (non-reference) object
01920                 CComPtr<IMgaFCO> termRefd;
01921                 CComObjPtr<IMgaFCOs> refChain;
01922                 COMTHROW(refChain.CoCreateInstance(L"Mga.MgaFCOs"));
01923 // This seems to fix the ref-ref problem
01924 // the GetRefereeChain() puts in this fco
01925 //              COMTHROW(refChain->Append(fco));
01926                 GetRefereeChain(refChain,fco);
01927 
01928                 CComPtr<IMgaFCO> lastRef;
01929                 long refChainCnt;
01930                 COMTHROW(refChain->get_Count(&refChainCnt));
01931                 COMTHROW(refChain->get_Item(refChainCnt, &lastRef));
01932 
01933                 ref = NULL;
01934                 COMTHROW(lastRef.QueryInterface(&ref));
01935                 COMTHROW(ref->get_Referred(&termRefd));
01936 
01937                 objtype_enum rtp = OBJTYPE_NULL;
01938                 if (termRefd) {
01939                         COMTHROW(termRefd->get_ObjType(&rtp));
01940                 }
01941 
01942                 if (rtp == OBJTYPE_MODEL) {
01943                         guiFco = new CGuiCompoundReference(fco, role, this, guiMeta->NumberOfAspects(), refd, termRefd);
01944                         ((CGuiCompoundReference *)guiFco)->InitObject(this);
01945                         ((CGuiCompoundReference *)guiFco)->SetAspect(currentAspect->index);
01946                 } else {
01947                         guiFco = new CGuiReference(fco, role, this, guiMeta->NumberOfAspects(), refd, termRefd);
01948                         ((CGuiReference *)guiFco)->InitObject(this);
01949                         ((CGuiReference *)guiFco)->SetAspect(currentAspect->index);
01950                 }       
01951         } else if(tp == OBJTYPE_SET) {
01952                 guiFco = new CGuiSet(fco, role, this, guiMeta->NumberOfAspects());
01953                 ((CGuiSet *)guiFco)->InitObject(this);
01954                 ((CGuiSet *)guiFco)->SetAspect(currentAspect->index);
01955                 if (objList != NULL && !currentSetID.IsEmpty()) {
01956                         CString setID;
01957                         fco->get_ID(PutOut(setID));
01958                         if(setID == currentSetID) {
01959                                 if (guiFco != NULL)
01960                                         currentSet = guiFco->dynamic_cast_CGuiSet();
01961                         }
01962                 }
01963         } else if (tp == OBJTYPE_CONNECTION) {
01964                 guiFco = new CGuiConnection(fco, role, this, guiMeta->NumberOfAspects(), false);
01965                 isCGuiConnection = true;
01966         } else {
01967                 guiFco = new CGuiObject(fco, role, this, guiMeta->NumberOfAspects());
01968                 ((CGuiObject *)guiFco)->InitObject(this);
01969                 ((CGuiObject *)guiFco)->SetAspect(currentAspect->index);
01970         }
01971         guiFco->SetAspect(currentAspect->index);
01972         CComBSTR bstr;
01973         COMTHROW(fco->get_Name(&bstr));
01974         if (!isCGuiConnection) {
01975                 CGuiObject* guiObj = static_cast<CGuiObject*> (guiFco);
01976                 guiObj->ReadAllLocations();
01977                 guiObj->name = bstr;
01978                 if (objList != NULL)
01979                         objList->AddTail(guiObj);
01980         } else {
01981                 CGuiConnection* guiConn = static_cast<CGuiConnection*> (guiFco);
01982                 VERIFY(guiConn);
01983                 guiConn->name = bstr;
01984                 if (objList != NULL)
01985                         objList->AddTail(guiConn);
01986                 if (connList != NULL)
01987                         connList->AddTail(guiConn);
01988         }
01989         return guiFco;
01990 }
01991 
01992 // ??
01993 void CGMEView::CreateGuiObjects(CComPtr<IMgaFCOs>& fcos, CGuiFcoList& objList, CGuiConnectionList& connList)
01994 {
01995         CComPtr<IMgaFCO> fco;
01996         MGACOLL_ITERATE(IMgaFCO,fcos) {
01997                 fco = MGACOLL_ITER;
01998                 CGuiFco* guiFco = CreateGuiObject(fco, &objList, &connList);
01999         }
02000         MGACOLL_ITERATE_END;
02001 }
02002 
02003 // ??
02004 bool CGMEView::CreateGuiObjects()
02005 {
02006         COMTHROW(currentModel->get_Name(PutOut(name)));
02007 
02008         CreateAnnotators();
02009 
02010         CComPtr<IMgaFCOs> fcos;
02011         COMTHROW(currentModel->get_ChildFCOs(&fcos));
02012 
02013         {
02014                 isModelAutoRouted = theApp.useAutoRouting;      // update view's value to the app settings
02015 
02016                 CComBSTR pathBstr = MODELAUTOROUTING;
02017                 CComBSTR bstrVal;
02018                 CString val;
02019                 COMTHROW(currentModel->get_RegistryValue(pathBstr, PutOut(val)));
02020                 if (!val.IsEmpty()) {
02021                         if (val == _T("false"))
02022                                 isModelAutoRouted = false;
02023                         else
02024                                 isModelAutoRouted = true;
02025                 }
02026         }
02027 
02028         CreateGuiObjects(fcos,children,connections);
02029 
02030         InitSets();
02031         if(GetDocument()->GetEditMode() == GME_SET_MODE && currentSet) {
02032                 CGuiFco::GrayOutFcos(children,true);
02033                 CGuiFco::GrayOutFcos(connections,true);
02034                 CGuiAnnotator::GrayOutAnnotations(annotators, true);
02035                 currentSet->GrayOutMembers(false);
02036                 currentSet->GrayOut(false);
02037         }
02038 
02039         CGuiFco::SetAspect(children,currentAspect->index);
02040         CGuiAnnotator::SetAspect(annotators, currentAspect->index);
02041         ResolveConnections();
02042 
02043         CComPtr<IMgaObject> cont;
02044         objtype_enum tp;
02045         COMTHROW(currentModel->GetParent(&cont,&tp));
02046         if(tp == OBJTYPE_MODEL) {
02047                 parent = 0;
02048                 COMTHROW(cont.QueryInterface(&parent));
02049         }
02050 
02051         return IsConnectionConversionNeeded();
02052 }
02053 
02054 void CGMEView::CreateAnnotators(CComPtr<IMgaRegNodes> &regNodes, CGuiAnnotatorList &annList)
02055 {
02056         MGACOLL_ITERATE(IMgaRegNode, regNodes) {
02057                 CComPtr<IMgaRegNode> anNode;
02058                 anNode = MGACOLL_ITER;
02059                 bool arch = !isSubType && isType; // archetype if not subtype and not instance (type)
02060                 if( arch || (!arch && CGuiAnnotator::Showable(anNode, baseType)))
02061                 {
02062                         CGuiAnnotator *annotator = new CGuiAnnotator(currentModel, anNode, this, guiMeta->NumberOfAspects());
02063                         annList.AddTail(annotator);
02064                 }
02065         }
02066         MGACOLL_ITERATE_END;
02067 }
02068 
02069 void CGMEView::CreateAnnotators()
02070 {
02071         try {
02072                 CComPtr<IMgaRegNode> anRoot;
02073                 CComBSTR path(AN_ROOT);
02074                 COMTHROW(currentModel->get_RegistryNode(path, &anRoot));
02075                 if (anRoot != NULL) {
02076                         CComPtr<IMgaRegNodes> anNodes;
02077                         COMTHROW(anRoot->get_SubNodes(VARIANT_TRUE, &anNodes));
02078                         CreateAnnotators(anNodes, annotators);
02079                 }
02080         }
02081         catch (hresult_exception &) {
02082         }
02083 }
02084 
02085 void CGMEView::ResetPartBrowser()
02086 {
02087         guiMeta->ResetParts();
02088         CMainFrame::theInstance->SetPartBrowserMetaModel(guiMeta);
02089         CMainFrame::theInstance->SetPartBrowserBg(bgColor);
02090         CMainFrame::theInstance->RePaintPartBrowser();
02091 }
02092 
02093 
02094 void CGMEView::Reset(bool doInvalidate)
02095 {
02096 //      CGMEView* gmeviewA = (CGMEView*)GetActiveView();
02097 //      if (gmeviewA)
02098         if (m_isActive)
02099         {
02100                 TRACE(_T("CGMEView::Reset GetActiveView\n"));
02101         }
02102         CComPtr<IMgaFCO> selConn;
02103         if (selectedConnection != NULL)
02104                 selConn = selectedConnection->mgaFco;
02105         try {
02106                 BeginTransaction(TRANSACTION_READ_ONLY);
02107                 validGuiObjects = false;
02108 
02109                 BeginWaitCursor();
02110 
02111                 // store the ids of the objects placed into the notifiable objects
02112                 CStringList lstSelBuffIDs;
02113                 CStringList lstUnsBuffIDs;
02114                 CString     cntxSelID;
02115                 CString     cntxAnnID;
02116                 if( contextSelection)
02117                         cntxSelID = contextSelection->id;
02118                 if( contextAnnotation)
02119                         cntxAnnID = contextAnnotation->id;
02120 
02121                 for( std::list<CGuiObject*>::iterator iti = m_lstSelect.begin(); iti != m_lstSelect.end(); ++iti)
02122                         lstSelBuffIDs.AddTail( (*iti)->id);
02123 
02124                 for( std::list<CGuiObject*>::iterator itj = m_lstUnselect.begin(); itj != m_lstUnselect.end(); ++itj)
02125                         lstUnsBuffIDs.AddTail( (*itj)->id);
02126 
02127                 CStringList selIDs;
02128                 CStringList selAnIDs;
02129                 if(newObjectIDs.IsEmpty()) {
02130                         POSITION pos = selected.GetHeadPosition();
02131                         while(pos) {
02132                                 CGuiObject *obj = selected.GetNext(pos);
02133                                 selIDs.AddTail(obj->id);
02134                         }
02135                         pos = selectedAnnotations.GetHeadPosition();
02136                         while(pos) {
02137                                 selAnIDs.AddTail(selectedAnnotations.GetNext(pos)->id);
02138                         }
02139                 }
02140                 else {
02141                         selIDs.AddHead(&newObjectIDs);
02142                         newObjectIDs.RemoveAll();
02143                 }
02144 
02145                 currentSetID.Empty();
02146                 if(currentSet) {
02147                         currentSet->mgaFco->get_ID(PutOut(currentSetID));
02148                         currentSet = 0;
02149                 }
02150 
02151                 ClearConnSpecs();
02152                 tmpConnectMode = false;
02153 
02154                 POSITION pos = children.GetHeadPosition();
02155                 while(pos) {
02156                         CGuiFco* fco = children.GetNext(pos);
02157                         ASSERT(fco != NULL);
02158                         CGuiObject* obj = fco->dynamic_cast_CGuiObject();
02159                         if(obj && obj->IsVisible()) {
02160                                 if(obj->GetRouterBox())                                 // it may be a new object not yet routed
02161                                         // FIXME: so slow. Can't we just create a new router?
02162                                         obj->RemoveFromRouter(router);
02163                         }
02164                         delete obj;
02165                 }
02166 
02167                 RemoveAllAnnotationFromSelection();
02168                 pos = annotators.GetHeadPosition();
02169                 while(pos) {
02170                         delete annotators.GetNext(pos);
02171                 }
02172 
02173                 ClearConnectionSelection();
02174                 pos = connections.GetHeadPosition();
02175                 while(pos) {
02176                         CGuiConnection *conn = connections.GetNext(pos);
02177                         //vt THIS MIGHT BE UNNECESSARY
02178                         conn->RemoveFromRouter(router);
02179                         delete conn;
02180                 }
02181 
02182 
02183                 m_lstSelect.clear(); // clear the contents of these buffers [will be refilled soon] 
02184                 m_lstUnselect.clear();
02185                 contextAnnotation = 0; contextSelection = 0; contextPort = 0;// these will be recalculated also
02186                 children.RemoveAll();
02187                 annotators.RemoveAll();
02188                 connections.RemoveAll();
02189                 selected.RemoveAll(); // we don't call here the this->SendUnselEvent4List( &selected); because it might contain freshly deleted objects, which can't be notified
02190 
02191 
02192                 // Now build up new objectset
02193 
02194                 SetBgColor();
02195                 CreateGuiObjects();
02196                 SetProperties();
02197 
02198                 // Note: Refresh type/subtype/instance property - if it crashes, contact Peter
02199                 {
02200                         baseType = NULL;
02201                         VARIANT_BOOL b;
02202                         COMTHROW(currentModel->get_IsInstance(&b));
02203                         isType = (b == VARIANT_FALSE);
02204                         if(isType) {
02205                                 COMTHROW(currentModel->get_BaseType(&baseType));
02206                         }
02207                         else{
02208                                 COMTHROW(currentModel->get_Type(&baseType));
02209                         }
02210 
02211                         if(isType) {
02212                                 CComPtr<IMgaModel> type;
02213                                 FindDerivedFrom(currentModel,type);
02214                                 isSubType = (type != 0);
02215                         }
02216                 }
02217                 // EndNote
02218 
02219                 if( !(selIDs.IsEmpty() && lstSelBuffIDs.IsEmpty() && lstUnsBuffIDs.IsEmpty() && cntxSelID.IsEmpty()))
02220                 {
02221                         // filling up selected, m_lstSelect and m_lstUnselect lists
02222                         POSITION oPos = children.GetHeadPosition();
02223                         while(oPos) {
02224                                 CGuiFco* fco = children.GetNext(oPos);
02225                                 ASSERT(fco != NULL);
02226                                 CGuiObject* obj = fco->dynamic_cast_CGuiObject();
02227                                 if( obj)
02228                                 {
02229                                         if( !cntxSelID.IsEmpty() && obj->id == cntxSelID)
02230                                                 contextSelection = obj;
02231                                         
02232                                         POSITION sPos = selIDs.GetHeadPosition();
02233                                         while( sPos) {
02234                                                 CString id = selIDs.GetNext( sPos);
02235                                                 if( id == obj->id)
02236                                                 {
02237                                                         selected.AddTail( obj);
02238                                                         sPos = 0;
02239                                                 }
02240                                         }
02241 
02242                                         bool found = false; // will save time because if obj is in lstSelBuffIDs (m_lstSelect), it can't be in lstUnsBuffIDs (m_lstUnselect)
02243                                         sPos = lstSelBuffIDs.GetHeadPosition();
02244                                         while( !found && sPos) {
02245                                                 CString id = lstSelBuffIDs.GetNext( sPos);
02246                                                 if( id == obj->id)
02247                                                 {
02248                                                         m_lstSelect.push_back( obj);
02249                                                         found = true;
02250                                                 }
02251                                         }
02252 
02253                                         sPos = lstUnsBuffIDs.GetHeadPosition();
02254                                         while( !found && sPos) {
02255                                                 CString id = lstUnsBuffIDs.GetNext( sPos);
02256                                                 if( id == obj->id)
02257                                                 {
02258                                                         m_lstUnselect.push_back( obj);
02259                                                         found = true;
02260                                                 }
02261                                         }
02262                                 }
02263                         }
02264                 }
02265 
02266                 // selected was filled up previously like this:
02267                 // now it is done along with m_lstSelect, m_lstUnselect
02268                 //pos = selIDs.GetHeadPosition();
02269                 //while(pos) {
02270                 //      CString id = selIDs.GetNext(pos);
02271                 //      POSITION oPos = children.GetHeadPosition();
02272                 //      while(oPos) {
02273                 //              CGuiFco* fco = children.GetNext(oPos);
02274                 //              ASSERT(fco != NULL);
02275                 //              CGuiObject* obj = fco->dynamic_cast_CGuiObject();
02276                 //              if(obj) {
02277                 //                      if(id == obj->id)
02278                 //                              selected.AddTail(obj); // this->SendSelecEvent4Object( obj); omitted because of a READONLY transaction
02279                 //              }
02280                 //      }
02281                 //}
02282 
02283                 // selectedAnnotations was filled up previously like this:
02284                 //pos = selAnIDs.GetHeadPosition();
02285                 //while(pos) {
02286                 //      CString id = selAnIDs.GetNext(pos);
02287                 //      POSITION oPos = annotators.GetHeadPosition();
02288                 //      while(oPos) {
02289                 //              CGuiAnnotator *ann = annotators.GetNext(oPos);
02290                 //              if (id == ann->id) {
02291                 //                      AddAnnotationToSelectionTail(ann);
02292                 //              }
02293                 //      }
02294                 //}             
02295 
02296                 pos = annotators.GetHeadPosition();
02297                 while(pos) {
02298                         CGuiAnnotator *ann = annotators.GetNext(pos);
02299                         POSITION oPos = selAnIDs.GetHeadPosition();
02300                         while(oPos) {
02301                                 CString id = selAnIDs.GetNext(oPos);
02302                                 if (id == ann->id) {
02303                                         AddAnnotationToSelectionTail(ann);
02304                                 }
02305                         }
02306                         if( !cntxAnnID.IsEmpty() && cntxAnnID == ann->id)
02307                                 contextAnnotation = ann;
02308                 }
02309 
02310                 SendNow(true);
02311 
02312                 try {
02313                         POSITION pos = selected.GetHeadPosition();
02314                         while (pos) {
02315                                 CGuiObject* go = selected.GetNext(pos);
02316                                 if (go && go->mgaFco) {
02317                                         // Sending decorator events (for efficiency)
02318                                         CGuiAspect* pAspect = go->GetCurrentAspect();
02319                                         if (pAspect != NULL) {
02320                                                 CComQIPtr<IMgaElementDecorator> newDecorator(pAspect->GetDecorator());
02321                                                 if (newDecorator)
02322                                                         HRESULT retVal = newDecorator->SetSelected(VARIANT_TRUE); // FIXME: decorators expect a transaction to be open
02323                                         }
02324                                 }
02325                         }
02326                 }
02327                 catch (hresult_exception&) {
02328                         AfxMessageBox(_T("Unable to refresh selected status to decorators"));
02329                         CGMEEventLogger::LogGMEEvent(_T("CGMEView::Reset - Unable to refresh selected status to decorators.\r\n"));
02330                 }
02331 
02332                 if (selConn != NULL) {
02333                         POSITION pos = connections.GetHeadPosition();
02334                         while(pos) {
02335                                 CGuiConnection *conn = connections.GetNext(pos);
02336                                 if (conn->mgaFco == selConn) {
02337                                         selectedConnection = conn;
02338                                         conn->SetSelect(true);
02339                                         break;
02340                                 }
02341                         }
02342                 }
02343                 CommitTransaction();
02344         }
02345         catch (hresult_exception& e) {
02346                 AbortTransaction(e.hr);
02347                 AfxMessageBox(_T("Unable to refresh model"));
02348                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::Reset - Unable to refresh model.\r\n"));
02349                 frame->PostMessage(WM_CLOSE);
02350                 EndWaitCursor();
02351                 return;
02352         }
02353 
02354 
02355         Invalidate(doInvalidate);
02356         AutoRoute();
02357         SetScroll(); // TODO: will this work?
02358         DoPannWinRefresh();
02359 
02360         EndWaitCursor();
02361 }
02362 
02363 void CGMEView::InitSets()
02364 {
02365         POSITION pos = children.GetHeadPosition();
02366         while(pos) {
02367                 CGuiFco* fco = children.GetNext(pos);
02368                 ASSERT(fco != NULL);
02369                 CGuiSet* set = fco->dynamic_cast_CGuiSet();
02370                 if(set)
02371                         set->Init(children,connections);
02372         }
02373 }
02374 
02375 void CGMEView::ChangeAttrPrefObjs(CGuiObjectList &objlist)
02376 {
02377         CComPtr<IMgaObjects> mgaobjs;
02378         COMTHROW(mgaobjs.CoCreateInstance(L"Mga.MgaObjects"));
02379         if (objlist.GetCount() == 0)
02380         {
02381                 COMTHROW(mgaobjs->Append(currentModel));
02382         }
02383         else
02384         {
02385                 POSITION pos = objlist.GetHeadPosition();
02386                 while (pos) {
02387                         CGuiObject *guiObj = objlist.GetNext(pos);
02388                         CComPtr<IMgaObject> mgaobj;
02389                         COMTHROW(guiObj->mgaFco.QueryInterface(&mgaobj));
02390                         COMTHROW(mgaobjs->Append(mgaobj));
02391                 }
02392         }
02393 
02394         CGMEObjectInspector::theInstance->SetObjects(mgaobjs);
02395 }
02396 
02397 void CGMEView::ChangeAttrPrefFco(CGuiFco* guiFco)
02398 {
02399         ASSERT(guiFco != NULL);
02400         CGuiConnection* conn = guiFco->dynamic_cast_CGuiConnection();
02401         if (conn != NULL) {
02402                 if (selectedConnection != conn) {
02403                         if (selectedConnection != NULL)
02404                                 selectedConnection->SetSelect(false);
02405                         conn->SetSelect(true);
02406                         selectedConnection = conn;
02407                         if (isLeftMouseButtonDown)
02408                                 isConnectionJustSelected = true;
02409                 }
02410         } else {
02411                 if (selectedConnection != NULL)
02412                         selectedConnection->SetSelect(false);
02413                 selectedConnection = NULL;
02414         }
02415 
02416         CComPtr<IMgaObjects> mgaobjs;
02417         COMTHROW(mgaobjs.CoCreateInstance(L"Mga.MgaObjects"));
02418         CComPtr<IMgaObject> mgaobj;
02419         COMTHROW(guiFco->mgaFco.QueryInterface(&mgaobj));
02420         COMTHROW(mgaobjs->Append(mgaobj));
02421 
02422         CGMEObjectInspector::theInstance->SetObjects(mgaobjs);
02423 }
02424 
02425 void CGMEView::ChangeAttrPrefFco() // currentModel
02426 {
02427         if (selectedConnection != NULL)
02428                 selectedConnection->SetSelect(false);
02429         selectedConnection = NULL;
02430 
02431         CComPtr<IMgaObjects> mgaobjs;
02432         COMTHROW(mgaobjs.CoCreateInstance(L"Mga.MgaObjects"));
02433         CComPtr<IMgaObject> mgaobj;
02434         COMTHROW(currentModel.QueryInterface(&mgaobj));
02435         COMTHROW(mgaobjs->Append(mgaobj));
02436 
02437         CGMEObjectInspector::theInstance->SetObjects(mgaobjs);
02438 }
02439 
02440 void CGMEView::ShowProperties(CGuiFco* guiFco)
02441 {
02442         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowProperties(")+guiFco->GetName()+_T(" ")+guiFco->GetID()+_T(")\r\n"));
02443     ChangeAttrPrefFco(guiFco);
02444 
02445         CGMEObjectInspector::theInstance->ShowPanel(2);
02446 }
02447 
02448 void CGMEView::ShowProperties()
02449 {
02450         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowProperties()\r\n"));
02451     ChangeAttrPrefFco();
02452 
02453         CGMEObjectInspector::theInstance->ShowPanel(2);
02454 }
02455 
02456 void CGMEView::ShowAttributes(CGuiFco* guiFco)
02457 {
02458         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowAttributes(")+guiFco->GetName()+_T(" ")+guiFco->GetID()+_T(")\r\n"));
02459         ChangeAttrPrefFco(guiFco);
02460 
02461         CGMEObjectInspector::theInstance->ShowPanel(0);
02462 }
02463 
02464 // TODO
02465 void CGMEView::ShowAttributes() // currentModel
02466 {
02467         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowAttributes() on ")+path+name+_T("\r\n"));
02468         ChangeAttrPrefFco();
02469 
02470         CGMEObjectInspector::theInstance->ShowPanel(0);
02471 }
02472 
02473 void CGMEView::ShowPreferences(CGuiFco *guiFco)
02474 {
02475         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowPreferences(")+guiFco->GetName()+_T(" ")+guiFco->GetID()+_T(")\r\n"));
02476         ChangeAttrPrefFco(guiFco);
02477 
02478         CGMEObjectInspector::theInstance->ShowPanel(1);
02479 }
02480 
02481 
02482 // TODO
02483 void CGMEView::ShowPreferences()        // currentModel
02484 {
02485         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowPreferences()\r\n"));
02486         ChangeAttrPrefFco();
02487 
02488         CGMEObjectInspector::theInstance->ShowPanel(1);
02489 }
02490 
02491 void CGMEView::RetrievePath()
02492 {
02493         if ( currentModel ) {
02494                 BeginTransaction(TRANSACTION_READ_ONLY);
02495                 path = _T("");
02496                 CComPtr<IMgaObject> spObject = currentModel.p;
02497                 while ( true ) {
02498                         CComPtr<IMgaObject> spParent;
02499                         if ( SUCCEEDED( spObject->GetParent( &spParent, NULL ) ) && spParent ) {;
02500                                 CComBSTR bstrName;
02501                                 COMTHROW( spParent->get_Name( &bstrName ) );
02502                                 path = CString( bstrName ) + _T("/") + path;
02503                                 spObject = spParent;
02504                         }
02505                         else
02506                                 break;
02507                 }
02508                 path = _T("/") + path;
02509                 CommitTransaction();
02510         }
02511 }
02512 
02513 void CGMEView::SetName()
02514 {
02515         if(currentModel != 0) {
02516                 try {
02517                         BeginTransaction(TRANSACTION_READ_ONLY);
02518                         COMTHROW(currentModel->get_Name(PutOut(name)));
02519                         CommitTransaction();
02520 
02521                         RetrievePath();
02522 
02523                         SetTitles();
02524 
02525                         SetNameProperty();
02526                 }
02527                 catch(hresult_exception &e) {
02528                         AbortTransaction(e.hr);
02529                 }
02530         }
02531 }
02532 
02533 void CGMEView::SetBgColor()
02534 {
02535         if(currentModel != 0) {
02536                 try {
02537                         BeginTransaction(TRANSACTION_READ_ONLY);
02538                         CComBSTR bstr;
02539                         CComBSTR path(MODEL_BACKGROUND_COLOR_PREF);
02540                         COMTHROW(currentModel->get_RegistryValue(path, &bstr));
02541                         CString strVal(bstr);
02542                         unsigned int hexval;
02543                         if (_stscanf(strVal,_T("%x"),&hexval) == 1) {
02544                                 unsigned int r = (hexval & 0xff0000) >> 16;
02545                                 unsigned int g = (hexval & 0xff00) >> 8;
02546                                 unsigned int b = hexval & 0xff;
02547                                 bgColor = RGB(r,g,b);
02548                         }
02549                         else {
02550                                 bgColor = ::GetSysColor(COLOR_WINDOW);
02551                         }
02552                         CMainFrame::theInstance->SetPartBrowserBg(bgColor);
02553                         CMainFrame::theInstance->RePaintPartBrowser();
02554                         CommitTransaction();
02555                 }
02556                 catch(hresult_exception &e) {
02557                         AbortTransaction(e.hr);
02558                 }
02559         }
02560 }
02561 
02562 // prevous zoom value : curzoom
02563 // new zoom value stored in m_zoomVal
02564 // point : win client coordinates - this image point has to be centered
02565 void CGMEView::SetZoomPoint(int curzoom, CPoint point)
02566 {
02567         CRect clientW(0,0,0,0);
02568         GetClientRect(&clientW);
02569         int w = clientW.Width(); 
02570         int h = clientW.Height(); 
02571         CPoint offset = CPoint(w,h);
02572         {
02573                 CWindowDC dc(NULL);
02574                 dc.SetMapMode(MM_ISOTROPIC);
02575                 dc.SetWindowExt(100,100);
02576                 dc.SetViewportExt(curzoom, curzoom);
02577                 dc.DPtoLP((LPPOINT)&point);
02578         }
02579         {
02580                 CWindowDC dc(NULL);
02581                 dc.SetMapMode(MM_ISOTROPIC);
02582                 dc.SetWindowExt(100,100);
02583                 dc.SetViewportExt(m_zoomVal, m_zoomVal);
02584                 dc.DPtoLP((LPPOINT)&offset);
02585         }
02586         offset.x /= 2;
02587         offset.y /= 2;
02588 
02589         CPoint scp = GetScrollPosition();       // upper corner of scrolling
02590         m_zoomP = scp+point-offset;
02591 
02592         m_zoomScroll = true;
02593 }
02594 
02595 void CGMEView::ZoomIn(CPoint point)
02596 {
02597         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ZoomIn() in ")+path+name+_T("\r\n"));
02598 //      zoomIdx = min(GME_ZOOM_LEVEL_NUM-1, zoomIdx+1);
02599         int curzoom = m_zoomVal;
02600         frame->propBar.NextZoomVal(m_zoomVal);
02601 //      CMainFrame::theInstance->WriteStatusZoom(setZoomPercents[zoomIdx]);
02602         CMainFrame::theInstance->WriteStatusZoom(m_zoomVal);
02603         m_zoomP.x = m_zoomP.y = 0;
02604         if (curzoom == m_zoomVal)
02605                 return;
02606 
02607         SetZoomPoint(curzoom, point);
02608 }
02609 
02610 void CGMEView::ZoomOut(CPoint point)
02611 {
02612         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ZoomOut() in ")+path+name+_T("\r\n"));
02613 //      zoomIdx = max(0, zoomIdx-1);
02614         int curzoom = m_zoomVal;
02615         frame->propBar.PrevZoomVal(m_zoomVal);
02616 //      CMainFrame::theInstance->WriteStatusZoom(setZoomPercents[zoomIdx]);
02617         CMainFrame::theInstance->WriteStatusZoom(m_zoomVal);
02618         m_zoomP.x = m_zoomP.y = 0;
02619         if (curzoom == m_zoomVal)
02620                 return;
02621 
02622         SetZoomPoint(curzoom, point);
02623 }
02624 
02625 void CGMEView::ShowHelp(CComPtr<IMgaFCO> fco)
02626 {
02627         try {
02628                 BeginTransaction(TRANSACTION_READ_ONLY);
02629 
02630                 CGMEEventLogger::GMEEventPrintf(_T("CGMEView::ShowHelp(%Z) in ")+path+name+_T("\r\n"),fco,NULL);
02631                 CComObjPtr<IMgaLauncher> launcher;
02632                 COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") );
02633                 COMTHROW( launcher->ShowHelp(fco) );
02634                 CommitTransaction();
02635         }
02636         catch(hresult_exception &e) {
02637                 AbortTransaction(e.hr);
02638                 AfxMessageBox(_T("Unable to access context-specific help information!"),MB_OK | MB_ICONSTOP);
02639                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowHelp - Unable to access context-specific help information.\r\n"));
02640         }
02641 }
02642 
02643 // ??
02644 void CGMEView::ShowModel(CComPtr<IMgaModel> model, const CString& aspect)
02645 {
02646         // FIX for JIRA bug: GME-135
02647         if (!model) return;
02648 #if !defined (ACTIVEXGMEVIEW)
02649         // endFIX
02650         CString newAspect = aspect != _T("") ? aspect : currentAspect->name;
02651         CGMEDoc *doc = GetDocument();
02652         CGMEView *view = doc->FindView(model);
02653         CComPtr<IMgaFCO> fakeObj;
02654         if(!view)
02655                 doc->SetNextToView(model, newAspect, fakeObj);
02656         else
02657                 view->ChangeAspect(newAspect);
02658         CMainFrame::theInstance->CreateNewView(view, model);
02659         if( theApp.isHistoryEnabled())
02660         {
02661                 doc->tellHistorian(model, newAspect);
02662                 doc->clearForwHistory();
02663         }
02664 #endif
02665 }
02666 
02667 void CGMEView::GetModelInContext(CComPtr<IMgaModel> &model)
02668 {
02669         if (contextSelection)
02670                 VERIFY(SUCCEEDED(contextSelection->mgaFco.QueryInterface(&model)));
02671         else
02672                 model = currentModel;
02673         VERIFY(model != 0);
02674 }
02675 
02676 void CGMEView::FindDerivedFrom(CComPtr<IMgaModel> model,CComPtr<IMgaModel> &type)
02677 {
02678         CComPtr<IMgaFCO> der;
02679         try {
02680                 BeginTransaction(TRANSACTION_READ_ONLY);
02681                 CGMEEventLogger::GMEEventPrintf(_T("CGMEView::FindDerivedFrom(model=%Z,type=%z)\r\n"),model,type);
02682                 COMTHROW(model->get_DerivedFrom(&der));
02683                 if(der != 0)
02684                         COMTHROW(der.QueryInterface(&type));
02685                 CommitTransaction();
02686         }
02687         catch(hresult_exception e) {
02688                 AbortTransaction(e.hr);
02689                 AfxMessageBox(_T("Unable to find type model"),MB_ICONSTOP | MB_OK);
02690                 CGMEEventLogger::LogGMEEvent(_T("    Unable to find type model\r\n"));
02691         }
02692 }
02693 
02694 void CGMEView::DrawConnections(HDC pDC, Gdiplus::Graphics* gdip)
02695 {
02696         POSITION pos = connections.GetHeadPosition();
02697         while (pos) {
02698                 CGuiConnection* conn = connections.GetNext(pos);
02699                 if (conn->IsVisible()) {
02700                         conn->Draw(pDC, gdip);
02701                 }
02702         }
02703 }
02704 
02705 void CGMEView::DrawTracker(CDC* pDC, const CRect& trackerRect, CRectTracker::StyleFlags styleFlags)
02706 {
02707         CRectTracker tracker;
02708         OnPrepareDC(pDC);
02709         tracker.m_rect = trackerRect;
02710         tracker.m_nStyle = styleFlags;
02711         pDC->LPtoDP(&tracker.m_rect);
02712         tracker.Draw(pDC);
02713 }
02714 
02715 void CGMEView::DrawConnectionCustomizationTracker(CDC* pDC, Gdiplus::Graphics* gdip)
02716 {
02717         if (customizeConnectionType == SimpleEdgeDisplacement)
02718         {
02719                 if (customizeConnectionPartMoveMethod == HorizontalEdgeMove ||
02720                         customizeConnectionPartMoveMethod == AdjacentEdgeMove)
02721                 {
02722                         CPoint startPoint       = customizeConnectionEdgeStartPoint;
02723                         CPoint endPoint         = customizeConnectionEdgeEndPoint;
02724                         if (customizeConnectionPartMoveMethod == AdjacentEdgeMove && customizeHorizontalOrVerticalEdge) {
02725                                 startPoint      = customizeConnectionEdgeEndPoint;
02726                                 endPoint        = customizeConnectionEdgeThirdPoint;
02727                         }
02728                         CRect trackerRect;
02729                         trackerRect.left        = min(startPoint.x, max(customizeConnectionCurrCursor.x, customizeConnectionEdgeXMinLimit));
02730                         trackerRect.top         = min(startPoint.y, endPoint.y);
02731                         trackerRect.right       = max(startPoint.x, min(customizeConnectionCurrCursor.x, customizeConnectionEdgeXMaxLimit));
02732                         trackerRect.bottom      = max(startPoint.y, endPoint.y);
02733                         //TRACE("Conn Customization Tracker: (%ld,%ld)-(%ld,%ld)\n", trackerRect.left, trackerRect.top,
02734                         //                                                                                                                 trackerRect.right, trackerRect.bottom);
02735                         DrawTracker(pDC, trackerRect, CRectTracker::dottedLine);
02736                 }
02737                 if (customizeConnectionPartMoveMethod == VerticalEdgeMove ||
02738                         customizeConnectionPartMoveMethod == AdjacentEdgeMove)
02739                 {
02740                         CPoint startPoint       = customizeConnectionEdgeStartPoint;
02741                         CPoint endPoint         = customizeConnectionEdgeEndPoint;
02742                         if (customizeConnectionPartMoveMethod == AdjacentEdgeMove && !customizeHorizontalOrVerticalEdge) {
02743                                 startPoint      = customizeConnectionEdgeEndPoint;
02744                                 endPoint        = customizeConnectionEdgeThirdPoint;
02745                         }
02746                         CRect trackerRect;
02747                         trackerRect.left        = min(startPoint.x, endPoint.x);
02748                         trackerRect.top         = min(startPoint.y, max(customizeConnectionCurrCursor.y, customizeConnectionEdgeYMinLimit));
02749                         trackerRect.right       = max(startPoint.x, endPoint.x);
02750                         trackerRect.bottom      = max(startPoint.y, min(customizeConnectionCurrCursor.y, customizeConnectionEdgeYMaxLimit));
02751                         //TRACE("Conn Customization Tracker: (%ld,%ld)-(%ld,%ld)\n", trackerRect.left, trackerRect.top,
02752                         //                                                                                                                 trackerRect.right, trackerRect.bottom);
02753                         DrawTracker(pDC, trackerRect, CRectTracker::dottedLine);
02754                 }
02755         } else if (customizeConnectionType == CustomPointCustomization) {
02756                 Gdiplus::Pen* dashPen = graphics.GetGdipPen2(gdip, GME_BLACK_COLOR, GME_LINE_DASH, m_zoomVal > ZOOM_NO, 1);
02757                 ASSERT(customizeConnectionEdgeStartPoint != emptyPoint);
02758                 if (customizeConnectionEdgeStartPoint != emptyPoint)
02759                         gdip->DrawLine(dashPen, customizeConnectionEdgeStartPoint.x, customizeConnectionEdgeStartPoint.y,
02760                                                    customizeConnectionCurrCursor.x, customizeConnectionCurrCursor.y);
02761                 ASSERT(customizeConnectionEdgeEndPoint != emptyPoint);
02762                 if (customizeConnectionEdgeEndPoint != emptyPoint)
02763                         gdip->DrawLine(dashPen, customizeConnectionCurrCursor.x, customizeConnectionCurrCursor.y,
02764                                                    customizeConnectionEdgeEndPoint.x, customizeConnectionEdgeEndPoint.y);
02765         }
02766 }
02767 
02768 void CGMEView::InsertCustomEdge(CGuiConnection* selectedConn, PathCustomizationType custType,
02769                                                                 int newPosX, int newPosY, int edgeIndex, bool horizontalOrVerticalEdge)
02770 {
02771         CustomPathData pathData;
02772         selectedConn->FillOutCustomPathData(pathData, custType, currentAspect->index, newPosX, newPosY, edgeIndex, -1, horizontalOrVerticalEdge);
02773         selectedConn->InsertCustomPathData(pathData);
02774 }
02775 
02776 void CGMEView::UpdateCustomEdges(CGuiConnection* selectedConn, PathCustomizationType custType,
02777                                                                  int newPosX, int newPosY, int edgeIndex, bool horizontalOrVerticalEdge)
02778 {
02779         CustomPathData pathData;
02780         selectedConn->FillOutCustomPathData(pathData, custType, currentAspect->index, newPosX, newPosY, edgeIndex, -1, horizontalOrVerticalEdge);
02781         selectedConn->UpdateCustomPathData(pathData);
02782 }
02783 
02784 void CGMEView::DeleteCustomEdges(CGuiConnection* selectedConn, PathCustomizationType custType,
02785                                                                  int edgeIndex, bool horizontalOrVerticalEdge)
02786 {
02787         CustomPathData pathData;
02788         selectedConn->FillOutCustomPathData(pathData, custType, currentAspect->index, 0, 0, edgeIndex, -1, horizontalOrVerticalEdge);
02789         selectedConn->DeletePathCustomization(pathData);
02790 }
02791 
02792 void CGMEView::ConvertPathToCustom(CComPtr<IUnknown>& pMgaObject)
02793 {
02794         CComQIPtr<IMgaModel> pMgaModel(pMgaObject);
02795         if (pMgaModel) {
02796                 VARIANT_BOOL isEq = VARIANT_FALSE;
02797                 COMTHROW(currentModel->get_IsEqual(pMgaModel, &isEq));
02798                 if (isEq == VARIANT_FALSE)
02799                         return;
02800         }
02801         CComQIPtr<IMgaConnection> pMgaConn(pMgaObject);
02802 
02803         bool isThereAnyConversion = false;
02804         POSITION pos = connections.GetHeadPosition();
02805         while (pos) {
02806                 CGuiConnection* conn = connections.GetNext(pos);
02807                 bool isThisConnection = false;
02808                 if (pMgaConn != NULL) {
02809                         VARIANT_BOOL isEq = VARIANT_FALSE;
02810                         COMTHROW(conn->mgaFco->get_IsEqual(pMgaConn, &isEq));
02811                         if (isEq == VARIANT_TRUE)
02812                                 isThisConnection = true;
02813                 } else {
02814                         isThisConnection = true;
02815                 }
02816                 if (isThisConnection) {
02817                         conn->ConvertAutoRoutedPathToCustom(currentAspect->index, false);
02818                         if (isThisConnection && pMgaConn != NULL)
02819                                 break;
02820                 }
02821         }
02822 }
02823 
02824 void CGMEView::AutoRoute()
02825 {
02826         BeginWaitCursor();
02827         router.AutoRoute(children, currentAspect->index);  // Must reroute the whole thing, other code depends on it
02828         EndWaitCursor();
02829 }
02830 
02831 void CGMEView::IncrementalAutoRoute()
02832 {
02833         BeginWaitCursor();
02834         router.AutoRoute(currentAspect->index);
02835         EndWaitCursor();
02836 }
02837 
02838 void CGMEView::ModeChange()
02839 {
02840         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ModeChange in ")+path+name+_T("\r\n"));
02841         if (last_Connection)
02842         {
02843                 last_Connection->ToggleHover();
02844                 last_Connection = 0;
02845         }
02846         this->SendUnselEvent4List( &selected);
02847         selected.RemoveAll();
02848         ChangeAttrPrefObjs(selected);
02849         RemoveAllAnnotationFromSelection();
02850         ClearConnectionSelection();
02851         ClearConnSpecs();
02852         CGMEDoc *pDoc = GetDocument();
02853         CGuiAnnotator::GrayOutAnnotations(annotators, pDoc->GetEditMode() == GME_VISUAL_MODE);
02854         CGuiFco::GrayOutFcos(children,pDoc->GetEditMode() == GME_VISUAL_MODE);
02855         CGuiFco::GrayOutFcos(connections,pDoc->GetEditMode() == GME_VISUAL_MODE);
02856         tmpConnectMode = false;
02857         OnSetCursor(NULL, HTCLIENT, 0);
02858         Invalidate();
02859         DoPannWinRefresh();
02860 }
02861 
02862 INT_PTR CGMEView::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const
02863 {
02864         static CGuiObject *oldObject = 0;
02865         static CGuiPort *oldPort = 0;
02866         CGMEView *self = const_cast<CGMEView *>(this);
02867         CoordinateTransfer(point);
02868 
02869 #ifdef _ARDEBUG
02870         SArEdge* edge = router.router->GetListEdgeAt(point, 2);
02871         if( edge )
02872         {
02873                 pTI->hwnd = m_hWnd;
02874                 pTI->rect = CRect(point.x - 3, point.y - 3, point.x + 3, point.y + 3);
02875                 pTI->uId = 1;
02876                 CString str;
02877                 str.Format(_T("%p y=%f (%d,%d,%d,%d) prev=%p next=%p"),
02878                         edge, edge->position_y,
02879                         edge->startpoint->x, edge->startpoint->y,
02880                         edge->endpoint->x, edge->endpoint->y,
02881                         edge->block_prev, edge->block_next);
02882                 pTI->lpszText = _strdup(str);
02883                 return 1;
02884         }
02885         return -1;
02886 #endif
02887         CGuiConnection *conn= router.FindConnection(point);
02888         if(conn)
02889         {
02890                 pTI->hwnd = m_hWnd;
02891                 pTI->rect = CRect(point.x - 8, point.y - 8, point.x + 8, point.y + 8);
02892                 pTI->uId = 1;
02893                 CString str = conn->GetInfoText();
02894                 // FIXME: does this leak?
02895                 pTI->lpszText = _tcsdup(str);
02896                 return 1;
02897         }
02898 
02899         CGuiObject *object = self->FindObject(point);
02900         if(object) {
02901                 CString portinfo;
02902                 CRect rect = object->GetLocation();
02903                 CGuiPort *port = object->FindPort(point);
02904                 if(port && port->IsRealPort()) {
02905                         portinfo = _T(" : ") + port->GetInfoText();
02906                         rect = port->GetLocation() + rect.TopLeft();
02907                 }
02908                 if(object != oldObject || port != oldPort) {
02909                         oldPort = port;
02910                         oldObject = object;
02911                         return -1;
02912                 }
02913 
02914                 CClientDC dc(self);
02915                 self->OnPrepareDC(&dc);
02916                 dc.LPtoDP(rect);
02917                 pTI->hwnd = m_hWnd;
02918                 pTI->rect = rect;
02919                 pTI->uId = 1;
02920                 pTI->lpszText = _tcsdup(object->GetInfoText() + portinfo);
02921                 return 1;
02922         }
02923         oldObject = 0;
02924         return -1;
02925 }
02926 
02927 void CGMEView::CreateOffScreen(CDC *dc)
02928 {
02929         if(offScreenCreated)
02930                 return;
02931         offScreen = new CDC;
02932         BOOL success = offScreen->CreateCompatibleDC(dc);
02933         ASSERT(success);
02934         ASSERT(::GetSystemMetrics(SM_SAMEDISPLAYFORMAT));
02935         // In multi-monitor systems a window can bigger than just one screen, monitor resolutions can be different, etc.
02936         // TODO: Maybe we should calculate with SM_CXMAXTRACK,SM_CYMAXTRACK? A window can be larger than the displays!!!
02937         // TODO: handle run-time resolution changes!
02938         int offScreenWidth = GetSystemMetrics(SM_CXMAXTRACK);
02939         int offScreenHeight = GetSystemMetrics(SM_CYMAXTRACK);
02940 //      int offScreenWidth = GetSystemMetrics(SM_CXVIRTUALSCREEN);
02941 //      int offScreenHeight = GetSystemMetrics(SM_CYVIRTUALSCREEN);
02942         ofsbmp = new CBitmap;
02943         success = ofsbmp->CreateCompatibleBitmap(dc,offScreenWidth,offScreenHeight);
02944         ASSERT(success);
02945         // HACK: what about palettes?
02946     offScreenCreated = SaveDC(*offScreen);
02947     ASSERT(offScreenCreated);
02948     offScreen->SelectObject(ofsbmp);
02949 }
02950 
02951 void CGMEView::SetScroll()
02952 {
02953         CRect objext, annext, extent;
02954         CGuiObject::GetExtent(children, objext);
02955         CGuiAnnotator::GetExtent(annotators, annext);
02956         extent.UnionRect(&objext, &annext);
02957         extent.right = (int)(extent.right*EXTENT_ERROR_CORR); // ??
02958         extent.bottom = (int)(extent.bottom*EXTENT_ERROR_CORR); // ??
02959         CSize s(extent.right, extent.bottom);
02960 //      s.cx = s.cx + END_SCROLL_OFFSET;
02961 //      s.cy = s.cy + END_SCROLL_OFFSET;
02962 
02963 //      if (setZoomPercents[zoomIdx] == 100) {
02964         if (m_zoomVal == ZOOM_NO) {
02965                 SetScrollSizes(MM_TEXT,s, m_zoomVal); // setZoomPercents[zoomIdx]);
02966         }
02967         else {
02968                 SetScrollSizes(MM_ISOTROPIC,s, m_zoomVal); // setZoomPercents[zoomIdx]);
02969         }
02970 }
02971 
02972 void CGMEView::SetCenterObject(CComPtr<IMgaFCO> centerObj)
02973 {
02974         if(centerObj != NULL) {
02975                 CGuiObject* guiObj = NULL;
02976                 try {
02977                         BeginTransaction(TRANSACTION_READ_ONLY);
02978                         guiObj = CGuiFco::FindObject(centerObj, children);
02979                         CommitTransaction();
02980                 }
02981                 catch(hresult_exception e) {
02982                         AbortTransaction(e.hr);
02983                         guiObj = NULL;
02984                 }
02985 
02986                 CGuiConnection* connection = NULL;
02987                 if (guiObj == NULL) {
02988                         try {
02989                                 BeginTransaction(TRANSACTION_READ_ONLY);
02990                                 connection = CGuiFco::FindConnection(centerObj, connections);
02991                                 CommitTransaction();
02992                         }
02993                         catch(hresult_exception e) {
02994                                 AbortTransaction(e.hr);
02995                                 connection = NULL;
02996                         }
02997                 }
02998 
02999                 if (guiObj || connection) {
03000                         if (guiObj)
03001                                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::SetCenterFCO(")+guiObj->GetName()+_T(" ")+guiObj->GetID()+_T(") in ")+path+name+_T("\r\n"));
03002                         else
03003                                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::SetCenterFCO(")+connection->GetName()+_T(" ")+connection->GetID()+_T(") in ")+path+name+_T("\r\n"));
03004                         if (guiObj && !guiObj->IsVisible() ||
03005                                 connection && !connection->IsVisible())
03006                         {
03007                                 int aspNum = guiMeta->aspects.GetCount();
03008                                 for (int aindex = 0; aindex < aspNum; aindex++) {
03009                                         if (guiObj && guiObj->IsVisible(aindex) ||
03010                                                 connection && connection->IsVisible(aindex))
03011                                         {
03012                                                 ChangeAspect(aindex);
03013                                                 CMainFrame::theInstance->ChangePartBrowserAspect(aindex);
03014                                                 break;
03015                                         }
03016                                 }
03017                         }
03018                         if (guiObj && guiObj->IsVisible() ||
03019                                 connection && connection->IsVisible())
03020                         {
03021                                 CDC* pDC = GetDC();
03022                                 OnPrepareDC(pDC);
03023                                 CPoint centerPt;
03024                                 if (guiObj)
03025                                         centerPt = guiObj->GetCenter();
03026                                 else
03027                                         centerPt = connection->GetCenter();
03028                                 CRect wndRect;
03029                                 GetClientRect(&wndRect);
03030                                 pDC->DPtoLP(&wndRect);
03031                                 CSize totalSize = GetTotalSize();
03032                                 CPoint spos;
03033                                 spos.x = centerPt.x - (wndRect.Width()/2);
03034                                 spos.y = centerPt.y - (wndRect.Height()/2);
03035 
03036                                 spos.x = max(spos.x, 0L);
03037                                 spos.x = min(spos.x, totalSize.cx);
03038                                 spos.y = max(spos.y, 0L);
03039                                 spos.y = min(spos.y, totalSize.cy);
03040 
03041                                 this->SendUnselEvent4List( &selected);
03042                                 selected.RemoveAll();
03043                                 RemoveAllAnnotationFromSelection();
03044                                 ClearConnectionSelection();
03045                                 if (guiObj) {
03046                                         this->SendSelecEvent4Object( guiObj);
03047                                         selected.AddTail(guiObj);
03048                                 }
03049                                 ScrollToPosition(spos);
03050                                 if (guiObj)
03051                                         ChangeAttrPrefFco(guiObj);
03052                                 else
03053                                         ChangeAttrPrefFco(connection);  // sets selectedConnection
03054                                 Invalidate();
03055                                 this->SendNow();
03056                                 ReleaseDC(pDC);
03057                         }
03058                 }
03059         }
03060 }
03061 
03062 void CGMEView::Invalidate(bool thorough)
03063 {
03064         if(thorough) {
03065                 modelGrid.Clear();
03066                 FillModelGrid();
03067         }
03068         m_overlay = nullptr;
03069         SetScroll();
03070         CScrollZoomView::Invalidate();
03071 }
03072 
03073 int CGMEView::GetAspectProperty()
03074 {
03075         CComboBox *box;
03076         box = (CComboBox *)(frame->propBar.GetDlgItem(IDC_ASPECT));
03077         ASSERT(box);
03078         return box->GetCurSel();
03079 }
03080 
03081 void CGMEView::SetAspectProperty(int ind)
03082 {
03083         CComboBox *box;
03084         box = (CComboBox *)(frame->propBar.GetDlgItem(IDC_ASPECT));
03085         ASSERT(box);
03086         box->SetCurSel(ind);
03087 }
03088 
03089 void CGMEView::SetNameProperty()
03090 {
03091         CWnd *ctrl;
03092         ctrl = frame->propBar.GetDlgItem(IDC_NAME);
03093         ASSERT(ctrl);
03094         ctrl->SetWindowText( name );
03095         SetTitles();
03096 }
03097 
03098 void CGMEView::SetTitles(void)
03099 {
03100         frame->SetTitle(name);
03101         frame->SetAppTitle(path);
03102         frame->OnUpdateFrameTitle(true);
03103 }
03104 
03105 void CGMEView::GetNameProperty(CString &txt)
03106 {
03107         CWnd *ctrl;
03108         ctrl = frame->propBar.GetDlgItem(IDC_NAME);
03109         ASSERT(ctrl);
03110         ctrl->GetWindowText(txt);
03111 }
03112 
03113 void CGMEView::SetKindNameProperty()
03114 {
03115         CWnd *ctrl;
03116         ctrl = frame->propBar.GetDlgItem(IDC_KINDNAME);
03117         ASSERT(ctrl);
03118         ctrl->SetWindowText(kindDisplayedName);
03119 }
03120 
03121 void CGMEView::SetTypeProperty(bool type)
03122 {
03123         if(type)
03124                 frame->propBar.ShowType();
03125         else
03126                 frame->propBar.ShowInstance();
03127 }
03128 
03129 void CGMEView::SetTypeNameProperty()
03130 {
03131         CWnd *ctrl;
03132         ctrl = frame->propBar.GetDlgItem(IDC_TYPENAME);
03133         ASSERT(ctrl);
03134         CComPtr<IMgaFCO> fco;
03135         CString txt = _T("N/A");
03136         if(baseType != 0) {
03137                 COMTHROW(baseType->get_Name(PutOut(txt)));
03138         }
03139         RetrievePath();
03140         ctrl->SetWindowText(txt);
03141         SetTitles();
03142 }
03143 
03144 void CGMEView::SetProperties()
03145 {
03146         SetTypeProperty(isType);
03147         SetTypeNameProperty();
03148         SetNameProperty();
03149         SetKindNameProperty();
03150 
03151         CComboBox *box = (CComboBox *)(frame->propBar.GetDlgItem(IDC_ASPECT));
03152         ASSERT(box);
03153         if(box->GetCount() <= 0) {
03154                 guiMeta->InitAspectBox(box);
03155                 box->SetCurSel(currentAspect->index);
03156         }
03157 }
03158 
03159 void CGMEView::CoordinateTransfer(CPoint &point) const
03160 {
03161         CClientDC dc(const_cast<CGMEView *>(this));
03162         (const_cast<CGMEView *>(this))->OnPrepareDC(&dc);
03163         dc.DPtoLP(&point);
03164 }
03165 
03166 CGuiObject *CGMEView::FindFirstObject()
03167 {
03168         m_findNextAlreadyAchieved = 0; // reset the currently achieved minimum level to its default
03169 
03170         return HelpMeFindNextObject( false);
03171 }
03172 
03173 CGuiObject *CGMEView::FindNextObject()
03174 {
03175         return HelpMeFindNextObject( true);
03176 }
03177 
03178 CGuiObject *CGMEView::HelpMeFindNextObject( bool p_secondFind)
03179 {
03180         CGuiObject*      first     = 0;
03181         unsigned long    first_abs = 0; // distance square from (0,0)
03182         CPoint           first_pos( 0, 0);
03183 
03184         POSITION pos = children.GetHeadPosition();
03185         while(pos) {
03186                 CGuiFco* fco = children.GetNext(pos);
03187                 ASSERT(fco != NULL);
03188                 CGuiObject* cur = fco->dynamic_cast_CGuiObject();
03189                 if( cur && cur->IsVisible())
03190                 {
03191                         CPoint        cur_pos = cur->GetCenter();
03192                         unsigned long cur_abs = cur_pos.x * cur_pos.x + cur_pos.y * cur_pos.y;
03193 
03194                         // m_findNextAlreadyAchieved is the previously achieved minimum distance
03195                         // and we need to get further now if not invoked from FindFirst
03196                         // we disregard objects closer than m_curAbs
03197                         if( p_secondFind && cur_abs <= m_findNextAlreadyAchieved)
03198                                 continue; // skip if its closer than the allowed/required level
03199 
03200                         if( !first) 
03201                         {
03202                                 first      = cur;
03203                                 first_pos  = cur_pos;
03204                                 first_abs  = cur_abs;
03205                         }
03206                         else
03207                         {
03208                                 if( first_abs > cur_abs) // 'cur' closer to (0, 0) than 'first'?
03209                                 {
03210                                         first     = cur;
03211                                         first_pos = cur_pos;
03212                                         first_abs = cur_abs;
03213                                 }
03214                         }
03215                 }
03216         }
03217 
03218         if( first) // something found
03219                 m_findNextAlreadyAchieved = first_abs;
03220         return first;
03221 }
03222 
03223 CGuiObject* CGMEView::FindObject(CPoint &pt, bool lookNearToo, bool lookForLabel)
03224 {
03225         POSITION pos = children.GetHeadPosition();
03226         while(pos) {
03227                 CGuiFco* fco = children.GetNext(pos);
03228                 ASSERT(fco != NULL);
03229                 CGuiObject* obj = fco->dynamic_cast_CGuiObject();
03230                 if(obj && obj->IsVisible()) {
03231                         if (!lookForLabel) {
03232                                 if (obj->IsInside(pt, lookNearToo))
03233                                         return obj;
03234                         } else {
03235                                 if (obj->IsLabelInside(pt, lookNearToo))
03236                                         return obj;
03237                         }
03238                 }
03239         }
03240         return NULL;
03241 }
03242 
03243 CGuiAnnotator *CGMEView::FindAnnotation(CPoint &pt)
03244 {
03245         POSITION pos = annotators.GetHeadPosition();
03246         while(pos) {
03247                 CGuiAnnotator *ann = annotators.GetNext(pos);
03248                 if (ann->IsVisible() && ann->GetLocation().PtInRect(pt)) {
03249                         return ann;
03250                 }
03251         }
03252         return 0;
03253 }
03254 
03255 bool CGMEView::FindObjects(CRect &rect,CGuiObjectList &objectList)
03256 {
03257         bool ret = false;
03258         CGuiObject* obj;
03259         CRect r, dummy;
03260         POSITION pos = children.GetHeadPosition();
03261         while(pos) {
03262                 CGuiFco* fco = children.GetNext(pos);
03263                 ASSERT(fco != NULL);
03264                 obj = fco->dynamic_cast_CGuiObject();
03265                 if(obj) {
03266                         if(!obj->IsVisible())
03267                                 continue;
03268                         r = obj->GetLocation();
03269                         if(dummy.IntersectRect(&r,&rect)) {
03270                                 objectList.AddTail(obj);
03271                                 ret = true;
03272                         }
03273                 }
03274         }
03275         return ret;
03276 }
03277 
03278 bool CGMEView::FindAnnotations(CRect &rect,CGuiAnnotatorList &annotatorList)
03279 {
03280         bool ret = false;
03281         CRect r,dummy;
03282         POSITION pos = annotators.GetHeadPosition();
03283         while(pos) {
03284                 CGuiAnnotator *ann = annotators.GetNext(pos);
03285                 if(!ann->IsVisible())
03286                         continue;
03287                 r = ann->GetLocation();
03288                 if(dummy.IntersectRect(&r,&rect)) {
03289                         annotatorList.AddTail(ann);
03290                         ret = true;
03291                 }
03292         }
03293         return ret;
03294 }
03295 
03296 bool CGMEView::DisconnectAll(CGuiObject *end,CGuiPort *endPort,bool onlyVisible)
03297 {
03298         if(endPort)
03299                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::DisconnectAll(end=")+end->GetName()+_T(" ")+end->GetID()+_T(" endPort=")+endPort->GetName()+_T(" ")+endPort->GetID()+_T(")\r\n"));
03300         else
03301                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::DisconnectAll(end=")+end->GetName()+_T(" ")+end->GetID()+_T(")\r\n"));
03302         CGuiConnectionList conns;
03303         FindConnections(end,endPort,conns);
03304         POSITION pos = conns.GetHeadPosition();
03305         while(pos) {
03306                 CGuiConnection *guiConn = conns.GetNext(pos);
03307                 if(!onlyVisible || guiConn->IsVisible()) {
03308                         try {
03309                                 BeginTransaction();
03310                                 long status;
03311                                 COMTHROW(guiConn->mgaFco->get_Status(&status));
03312                                 if(status == OBJECT_EXISTS)
03313                                 {
03314                                         bool ok = DeleteConnection(guiConn,false);
03315                                         if (!ok)
03316                                         {
03317                                                 try {
03318                                                 AbortTransaction(E_MGA_MUST_ABORT);
03319                                                 } catch(hresult_exception e) { }
03320                                                 return false;
03321                                         }       
03322                                 }
03323                                 __CommitTransaction();
03324                         }
03325                         catch(hresult_exception e) {
03326                                 AbortTransaction(e.hr);
03327                                 AfxMessageBox(_T("Unable to delete connection"), MB_ICONSTOP | MB_OK);
03328                                 CGMEEventLogger::LogGMEEvent(_T("    Unable to delete connection.\r\n"));
03329                         }
03330                         catch(_com_error& e) {
03331                                 AbortTransaction(e.Error());
03332                                 CString error = _T("Unable to delete connection");
03333                                 if (e.Description().length() != 0)
03334                                 {
03335                                         error += _T(": ");
03336                                         error += static_cast<const TCHAR*>(e.Description());
03337                                 }
03338                                 CGMEEventLogger::LogGMEEvent(error + _T("\r\n"));
03339                                 AfxMessageBox(error,MB_ICONSTOP | MB_OK);
03340                         }
03341                 }
03342         }
03343         return true;
03344 }
03345 
03346 void CGMEView::FindConnections(CGuiObject *end,CGuiPort *endPort,CGuiConnectionList &res)
03347 {
03348         POSITION pos = connections.GetHeadPosition();
03349         while(pos) {
03350                 CGuiConnection *conn = connections.GetNext(pos);
03351                 if(!conn->IsVisible())
03352                         continue;
03353                 if((conn->src == end && conn->srcPort == endPort) ||
03354                                 (conn->dst == end && conn->dstPort == endPort))
03355                         res.AddTail(conn);
03356         }
03357 }
03358 
03359 void CGMEView::FindConnections(CGuiObject *end1,CGuiPort *end1Port,CGuiObject *end2,CGuiPort *end2Port,CGuiConnectionList &res)
03360 {
03361         POSITION pos = connections.GetHeadPosition();
03362         while(pos) {
03363                 CGuiConnection *conn = connections.GetNext(pos);
03364                 if(!conn->IsVisible())
03365                         continue;
03366                 if((conn->src == end1 && end1Port == conn->srcPort && conn->dst == end2 && end2Port == conn->dstPort) ||
03367                                 (conn->src == end2 && end2Port == conn->srcPort &&      conn->dst == end1 && end1Port == conn->dstPort))
03368                         res.AddTail(conn);
03369         }
03370 }
03371 
03372 // returns: false if user answers no
03373 static bool AskDeleteArcheType(IMgaFCOPtr obj)
03374 {
03375         IMgaFCOPtr archetype = obj;
03376         do
03377         {
03378                 archetype = archetype->ArcheType;
03379         } while (archetype->ArcheType);
03380         if (archetype->Status == OBJECT_EXISTS)
03381         {
03382                 int nDerived = CountDeriveds(archetype);
03383                 _bstr_t message = ObjTypeName[obj->Meta->ObjType];
03384                 message += L" '" + (obj->Name.length() ? obj->Name : obj->Meta->Name);
03385                 message += L"' is derived. Children of derived objects cannot be deleted.\n\nDo you want to delete its archetype?";
03386                 if (nDerived > 1)
03387                 {
03388                         wchar_t wDerived[20];
03389                         _itow(nDerived - 1, wDerived, 10);
03390                         message += L" Deleting the archetype will also delete " + _bstr_t(wDerived) + L" other instances/subtypes.";
03391                 }
03392                 if (AfxMessageBox(message, MB_YESNO) == IDYES)
03393                 {
03394                         archetype->__DestroyObject();
03395                         return true;
03396                 }
03397                 else
03398                         return false;
03399         }
03400         return true;
03401 }
03402 
03403 bool CGMEView::DeleteConnection(CGuiConnection *guiConn,bool checkAspect)
03404 {
03405         CGMEEventLogger::LogGMEEvent(_T("CGMEView::DeleteConnection(")+guiConn->GetName()+_T(" ")+guiConn->GetID()+_T(") in ")+path+name+_T("\r\n"));
03406         bool ok = false;
03407         BeginWaitCursor();
03408         try {
03409                 BeginTransaction();
03410                 if (guiConn->mgaFco->ArcheType && guiConn->mgaFco->IsPrimaryDerived == false)
03411                 {
03412                         ok = AskDeleteArcheType(guiConn->mgaFco.p);
03413                 } else if(!checkAspect || guiConn->IsPrimary(guiMeta,currentAspect)) {
03414                         guiConn->mgaFco->__DestroyObject();
03415                         ok = true;
03416                 }
03417                 CommitTransaction();
03418         }
03419         catch(_com_error &e) {
03420                 CString errorstring = L"Unable to delete connection";
03421                 if (e.Description().length() != 0)
03422                 {
03423                         errorstring += _T(": ");
03424                         errorstring += static_cast<const TCHAR*>(e.Description());
03425                 }
03426                 AfxMessageBox(errorstring, MB_ICONSTOP | MB_OK);
03427                 CGMEEventLogger::LogGMEEvent(CString(L"    ") + errorstring + L"\r\n");
03428                 AbortTransaction(e.Error());
03429         }
03430         catch(hresult_exception &e) {
03431                 CComBSTR error;
03432                 CString errorstring = L"Unable to delete connection";
03433                 if (GetErrorInfo(&error))
03434                 {
03435                         errorstring += L": ";
03436                         errorstring += error;
03437                 }
03438                 AfxMessageBox(errorstring, MB_ICONSTOP | MB_OK);
03439                 CGMEEventLogger::LogGMEEvent(CString(L"    ") + errorstring + L"\r\n");
03440                 AbortTransaction(e.hr);
03441         }
03442         this->SetFocus();
03443         return ok;
03444 }
03445 
03446 bool CGMEView::CheckBeforeDeleteObjects(CGuiObjectList &objectList,CString &txt)
03447 {
03448         bool ok = true;
03449         try {
03450                 BeginTransaction(TRANSACTION_READ_ONLY);
03451                 POSITION pos = objectList.GetHeadPosition();
03452                 while(pos) {
03453                         CGuiObject *guiObj = objectList.GetNext(pos);
03454                         if(!guiObj->IsPrimary(guiMeta,currentAspect)) {
03455                                 ok = false;
03456                                 txt += _T("\n   ") + guiObj->name;
03457                         }
03458                 }
03459                 CommitTransaction();
03460         }
03461         catch(hresult_exception e) {
03462                 AbortTransaction(e.hr);
03463         }
03464         return ok;
03465 }
03466 
03467 bool CGMEView::DeleteObjects(CGuiObjectList &objectList)
03468 {
03469         bool brw_refresh_needed = false;
03470         try {
03471                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::DeleteObjects in ")+path+name+_T("\r\n"));
03472                 CString msg;
03473                 if(!CheckBeforeDeleteObjects(objectList,msg)) {
03474                         AfxMessageBox(_T("The following object(s) cannot be deleted: ") + msg);
03475                         CGMEEventLogger::LogGMEEvent(_T("    The following object(s) cannot be deleted: ")+msg+_T("\r\n"));
03476                         return true;
03477                 }
03478                 BeginWaitCursor();
03479                 BeginTransaction();
03480                 GMEEVENTLOG_GUIOBJS(objectList);
03481                 POSITION pos = objectList.GetHeadPosition();
03482                 while(pos) {
03483                         CGuiObject *obj = objectList.GetNext(pos);
03484 
03485                         POSITION pos2 = pendingRequests.GetHeadPosition();
03486                         while (pos2) {
03487                                 POSITION tmp = pos2;
03488                                 CPendingObjectPosRequest *req = dynamic_cast<CPendingObjectPosRequest *> (pendingRequests.GetNext(pos2));
03489                                 if (req) {
03490                                         if ( req->object->mgaFco == obj->mgaFco ) {
03491                                                 pendingRequests.RemoveAt(tmp);
03492                                                 delete req;
03493                                         }
03494                                 }
03495                         }
03496 
03497                         if (obj->IsVisible()) {
03498                                 POSITION pos3 = obj->GetPorts().GetHeadPosition();
03499                                 while(pos3) {
03500                                                 bool ok = DisconnectAll(obj,obj->GetPorts().GetNext(pos3),false);
03501                                                 if (!ok)
03502                                                         throw hresult_exception(E_MGA_MUST_ABORT);
03503                                 }
03504                         }
03505                 }
03506                 pos = objectList.GetHeadPosition();
03507                 while(pos) {
03508                         CGuiObject *obj = objectList.GetNext(pos);
03509                         long oStatus;
03510                         COMTHROW(obj->mgaFco->get_Status(&oStatus));
03511                         // making sure that the fco was not deleted previously in the loop due to a dependency 
03512                         if(oStatus == OBJECT_EXISTS) {
03513                                 // throws E_MGA_MUST_ABORT if user selects CANCEL
03514                                 brw_refresh_needed = AskUserAndDetachIfNeeded(obj->mgaFco); // detach the dependents if needed
03515                                 if (obj->mgaFco->ArcheType && obj->mgaFco->IsPrimaryDerived == false)
03516                                 {
03517                                         if (AskDeleteArcheType(obj->mgaFco.p) == false)
03518                                         {
03519                                                 throw hresult_exception(E_MGA_MUST_ABORT);
03520                                         }
03521                                 }
03522                                 else
03523                                 {
03524                                         obj->mgaFco->__DestroyObject();
03525                                 }
03526                                 COMTHROW(obj->mgaFco->Close());
03527                         }
03528                 }
03529                 CommitTransaction();
03530         }
03531         catch(_com_error &e) {
03532                 AbortTransaction(e.Error());
03533                 CString error = _T("Unable to delete models");
03534                 if (e.Description().length() != 0)
03535                 {
03536                         error += _T(": ");
03537                         error += static_cast<const TCHAR*>(e.Description());
03538                 }
03539                 AfxMessageBox(error,MB_ICONSTOP | MB_OK);
03540                 CGMEEventLogger::LogGMEEvent(error);
03541                 EndWaitCursor();
03542                 return false;
03543         }
03544         catch(hresult_exception &e) {
03545                 AbortTransaction(e.hr);
03546                 if( e.hr == E_MGA_MUST_ABORT)
03547                         CGMEEventLogger::LogGMEEvent(_T("    Archetype delete cancelled by user.\r\n"));
03548                 else
03549                 {
03550                         AfxMessageBox(_T("Unable to delete models"),MB_ICONSTOP | MB_OK);
03551                         CGMEEventLogger::LogGMEEvent(_T("    Unable to delete models.\r\n"));
03552                 }
03553                 EndWaitCursor();
03554                 return false;
03555         }
03556         EndWaitCursor();
03557         ResetParent();
03558         if( brw_refresh_needed) CGMEBrowser::theInstance->RefreshAll();
03559         this->SetFocus();
03560         return true;
03561 }
03562 
03563 void CGMEView::DeleteAnnotations(CGuiAnnotatorList &annotatorList)
03564 {
03565         try {
03566                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::DeleteAnnotations() in ")+path+name+_T("\r\n"));
03567                 GMEEVENTLOG_GUIANNOTATORS(annotatorList);
03568                 BeginWaitCursor();
03569                 BeginTransaction();
03570                 POSITION pos = annotatorList.GetHeadPosition();
03571                 while(pos) {
03572                         CGuiAnnotator *ann = annotatorList.GetNext(pos);
03573                         if( ann->IsSpecial())
03574                                 COMTHROW( CGuiAnnotator::Hide( ann->rootNode));
03575                         else
03576                                 COMTHROW(ann->rootNode->RemoveTree());
03577                 }
03578                 CommitTransaction();
03579         }
03580         catch(hresult_exception &e) {
03581                 AbortTransaction(e.hr);
03582                 AfxMessageBox(_T("Unable to delete annotations"),MB_ICONSTOP | MB_OK);
03583                 CGMEEventLogger::LogGMEEvent(_T("    Unable to delete annotations.\r\n"));
03584                 EndWaitCursor();
03585                 return;
03586         }
03587         EndWaitCursor();
03588         ResetParent();
03589 }
03590 
03591 
03592 bool CGMEView::DoPasteItem(COleDataObject* pDataObject,bool drag,bool move,bool reference,bool derive,bool instance,bool closure,bool merge, CGuiObject *ref,CPoint pt)
03593 {
03594         CGMEEventLogger::LogGMEEvent(_T("CGMEView::DoPasteItem"));
03595         if(drag)
03596                 CGMEEventLogger::LogGMEEvent(_T(" DRAG"));
03597         if(move)
03598                 CGMEEventLogger::LogGMEEvent(_T(" MOVE"));
03599         if(reference)
03600                 CGMEEventLogger::LogGMEEvent(_T(" REFERENCE"));
03601         if(derive)
03602                 CGMEEventLogger::LogGMEEvent(_T(" DERIVE"));
03603         if(instance)
03604                 CGMEEventLogger::LogGMEEvent(_T(" INSTANCE"));
03605         if(closure)
03606                 CGMEEventLogger::LogGMEEvent(_T(" CLOSURE"));
03607         if(merge)
03608                 CGMEEventLogger::LogGMEEvent(_T(" SMART"));
03609         CGMEEventLogger::LogGMEEvent(_T(" in ")+path+name+_T("\r\n"));
03610         if(ref)
03611                 VERIFY(reference);
03612         ASSERT(pDataObject != NULL);
03613         ASSERT_VALID(this);
03614         bool ok = false;
03615 
03616         try
03617         {
03618                 CWaitCursor wait;
03619 
03620                 if (CGMEDataSource::IsGmeNativeDataAvailable(pDataObject,theApp.mgaProject) && !closure)
03621                 {
03622                         ok = DoPasteNative(pDataObject,drag,move,reference,derive,instance,ref,pt);
03623                 }
03624                 else if( CGMEDataSource::IsXMLDataAvailable(pDataObject) )
03625                 {
03626                         if( closure && theApp.mgaConstMgr) theApp.mgaConstMgr->Enable( false); // if closure is inserted disable the constraint manager ...
03627                         ok = CGMEDataSource::ParseXMLData(pDataObject, currentModel, merge);
03628                         if( closure && theApp.mgaConstMgr) theApp.mgaConstMgr->Enable( true); // ... and enable it after done
03629                 }
03630                 else
03631                         AfxThrowNotSupportedException();
03632         }
03633         catch(hresult_exception &)
03634         {
03635                 // general cleanup
03636                 TRACE(_T("failed to embed/link an OLE object\n"));
03637                 return false;
03638         }
03639         this->SetFocus();
03640         return ok;
03641 }
03642 
03643 void CGMEView::MakeSureGUIDIsUniqueForSmartCopy( CComPtr<IMgaFCO>& fco)
03644 {
03645         // this method prevents cloned objects having the same guid
03646         // as their original ones
03647         CComBSTR bstr;
03648         COMTHROW( fco->get_RegistryValue( CComBSTR( L"guid"), &bstr));
03649         if( bstr == 0 || bstr == L"") return; // no guid present, no need to replace it
03650 
03651         GUID t_guid = GUID_NULL;
03652         ::CoCreateGuid(&t_guid);
03653 
03654         if (t_guid != GUID_NULL)
03655         {
03656                 CString str_guid;
03657                 str_guid.Format(_T("{%08lX-%04X-%04x-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
03658                         t_guid.Data1, t_guid.Data2, t_guid.Data3,
03659                         t_guid.Data4[0], t_guid.Data4[1], t_guid.Data4[2], t_guid.Data4[3],
03660                         t_guid.Data4[4], t_guid.Data4[5], t_guid.Data4[6], t_guid.Data4[7]);
03661                 
03662                 // thus replace the old guid with a new one
03663                 COMTHROW( fco->put_RegistryValue( CComBSTR( L"guid"), CComBSTR(str_guid)));
03664         }
03665 
03666         // store the previous guid in prev subnode
03667         COMTHROW( fco->put_RegistryValue( CComBSTR( L"guid/prev"), bstr));
03668 }
03669 
03670 bool CGMEView::DoPasteNative(COleDataObject *pDataObject,bool drag,bool move,bool reference,bool derive,bool instance,CGuiObject *ref,CPoint point)
03671 {
03672         CGMEEventLogger::LogGMEEvent(_T("CGMEView::DoPasteNative"));
03673         if(drag)
03674                 CGMEEventLogger::LogGMEEvent(_T(" DRAG"));
03675         if(move)
03676                 CGMEEventLogger::LogGMEEvent(_T(" MOVE"));
03677         if(reference)
03678                 CGMEEventLogger::LogGMEEvent(_T(" REFERENCE"));
03679         if(derive)
03680                 CGMEEventLogger::LogGMEEvent(_T(" DERIVE"));
03681         if(instance)
03682                 CGMEEventLogger::LogGMEEvent(_T(" INSTANCE"));
03683         CGMEEventLogger::LogGMEEvent(_T(" in ")+path+name+_T("\r\n"));
03684         CComPtr<IDataObject> p = pDataObject->GetIDataObject(FALSE);
03685         CComPtr<IMgaDataSource> pt;
03686         COMTHROW(p.QueryInterface(&pt));
03687 
03688         CGMEDoc *doc = GetDocument();
03689 
03690         CComPtr<IUnknown> unk;
03691 
03692         CComPtr<IMgaRegNodes> regNodes;
03693         COMTHROW(pt->get_RegistryData(&unk));
03694         if (unk != NULL) {
03695                 if (FAILED(unk.QueryInterface(&regNodes))) {
03696                         regNodes = NULL;
03697                 }
03698         }
03699 
03700         unk = NULL;
03701         COMTHROW(pt->get_Data(&unk));
03702         CComPtr<IMgaFCOs> fcos;
03703         CComPtr<IMgaMetaRole> metaRole;
03704 
03705         if(unk && SUCCEEDED(unk.QueryInterface(&fcos))) {                       // not dragging from PartBrowser
03706                 CComPtr<IMgaMetaAspect> aspect;
03707                 currentAspect->GetMetaAspect(aspect);
03708                 try {
03709                         BeginTransaction();
03710 //                      if(currentAspect->CheckFcosBeforeInsertion(fcos) || reference) {
03711                         {
03712                                 // Handle annotations
03713                                 CComPtr<IMgaRegNodes> newRegNodes;
03714                                 COMTHROW(newRegNodes.CoCreateInstance(OLESTR("Mga.MgaRegNodes")));
03715                                 PasteAnnotations(currentModel, regNodes, newRegNodes, (drag && move));
03716 
03717                                 long l;
03718                                 CComPtr<IMgaFCOs> interrfcos;
03719                                 COMTHROW(terry->OpenFCOs( fcos, &interrfcos));
03720                                 COMTHROW( interrfcos->get_Count( &l));
03721 
03722                                 CComPtr<IMgaFCOs> newFcos;
03723                                 if( l > 0)
03724                                 {
03725                                 if ((drag && move) || (!reference && !derive)) {
03726                                         CComPtr<IMgaMetaRoles> newRoles;
03727                                         COMTHROW(newRoles.CoCreateInstance(OLESTR("Mga.MgaMetaRoles")));
03728                                         MGACOLL_ITERATE(IMgaFCO, fcos) {
03729                                                 CComPtr<IMgaFCO> fco;
03730                                                 COMTHROW(terry->OpenFCO(MGACOLL_ITER, &fco));
03731                                                 CComPtr<IMgaMetaRole> role;
03732                                                 COMTHROW(fco->get_MetaRole(&role));
03733                                                 CComPtr<IMgaMetaFCO> kind;
03734                                                 COMTHROW(fco->get_Meta(&kind));
03735                                                 CComPtr<IMgaMetaRole> newRole;
03736 
03737                                                 COMTHROW(doc->resolver->get_RoleByMeta(currentModel,kind,OBJTYPE_NULL,role,aspect,&newRole));
03738                                                 COMTHROW(newRoles->Append(newRole));
03739                                         }
03740                                         MGACOLL_ITERATE_END;
03741 
03742                                         if (drag && move) {
03743                                                 COMTHROW(currentModel->MoveFCOs(fcos,newRoles,&newFcos));
03744                                         }
03745                                         else if(!reference && !derive) {
03746                                                 COMTHROW(currentModel->CopyFCOs(fcos,newRoles,&newFcos));
03747                                         }
03748 
03749                                         if(!reference && !derive) // smart copy subtask:
03750                                         {
03751                                                 MGACOLL_ITERATE(IMgaFCO, newFcos) {
03752                                                         MakeSureGUIDIsUniqueForSmartCopy( CComPtr<IMgaFCO>(MGACOLL_ITER));
03753                                                 }
03754                                                 MGACOLL_ITERATE_END;
03755                                         }
03756 
03757                                         MGACOLL_ITERATE(IMgaFCO, newFcos) {
03758                                                 CComPtr<IMgaFCO> newFco;
03759                                                 newFco = MGACOLL_ITER;
03760                                                 CString newID;
03761                                                 COMTHROW(newFco->get_ID(PutOut(newID)));
03762                                                 newObjectIDs.AddHead(newID);
03763                                         }
03764                                         MGACOLL_ITERATE_END;
03765                                 }
03766                                 else if(derive) {
03767 
03768                                         COMTHROW(newFcos.CoCreateInstance(L"Mga.MgaFCOs"));
03769 
03770                                         /*CComPtr<IMgaMetaFCO> metaFco;
03771                                         COMTHROW(currentModel->get_Meta(&metaFco));
03772                                         CComPtr<IMgaMetaModel> metaModel;
03773                                         COMTHROW(metaFco.QueryInterface(&metaModel));*/ // commented by zolmol, these vars are NOT used
03774                                         bool normalExit = true;
03775                                         HRESULT hr = S_OK;
03776                                         MGACOLL_ITERATE(IMgaFCO,fcos) {
03777                                                 CComPtr<IMgaFCO> fco;
03778                                                 COMTHROW(terry->OpenFCO(MGACOLL_ITER, &fco));
03779                                                 CString fcoName;
03780                                                 COMTHROW(fco->get_Name(PutOut(fcoName)));
03781                                                 // Akos: do not want to derive a connection all by itself. Just skip it. 6/14/2013
03782                                                 CComPtr<IMgaConnection> conn;
03783                                                 HRESULT hr;
03784                                                 if((hr = fco.QueryInterface(&conn)) == S_OK) {
03785                                                         continue;
03786                                                 }
03787                                                 // Akos
03788 /*
03789                                                 CComPtr<IMgaModel> model;
03790                                                 HRESULT hr;
03791                                                 if((hr = fco.QueryInterface(&model)) != S_OK) {
03792                                                         AfxMessageBox(fcoName + " is not a model. Only models can be derived!");
03793                                                         AbortTransaction(hr);
03794                                                         newObjectIDs.RemoveAll();
03795                                                         return false;
03796                                                 }
03797                                                 {
03798                                                         CComPtr<IMgaFCO> base;
03799                                                         COMTHROW(fco->get_DerivedFrom(&base));
03800                                                         if(base != 0) {
03801                                                                 AfxMessageBox(fcoName + " is not a root model type. Only root model types can be derived!");
03802                                                                 AbortTransaction(hr);
03803                                                                 newObjectIDs.RemoveAll();
03804                                                                 return false;
03805                                                         }
03806                                                 }
03807 */
03808                                                 CComPtr<IMgaMetaFCO> kind;
03809                                                 COMTHROW(fco->get_Meta(&kind));
03810                                                 CComPtr<IMgaMetaRole> role;
03811                                                 COMTHROW(fco->get_MetaRole(&role));
03812                                                 CComPtr<IMgaMetaRole> newRole;
03813                                                 COMTHROW(doc->resolver->get_RoleByMeta(currentModel,kind,OBJTYPE_NULL,role,aspect,&newRole));
03814                                                 if(newRole == 0)
03815                                                 {
03816                                                         AfxMessageBox(_T("Cannot insert object derived from ") + fcoName);
03817                                                         CGMEEventLogger::LogGMEEvent(_T("    Cannot insert object derived from ")+fcoName+_T("\r\n"));
03818                                                 }
03819                                                 else {
03820                                                         CComPtr<IMgaFCO> obj;
03821                                                         VARIANT_BOOL inst = instance ? VARIANT_TRUE : VARIANT_FALSE;
03822                                                         if((hr = currentModel->DeriveChildObject(fco,newRole,inst,&obj)) != S_OK) {
03823                                                                 CString msg( (LPCTSTR) fcoName); msg += _T(" cannot be derived! Some of its ancestors or descendants may be already derived!");
03824                                                                 if( hr == E_MGA_NOT_DERIVABLE)
03825                                                                 {
03826                                                                         if( !CGMEConsole::theInstance) AfxMessageBox( msg + _T(" [Error code E_MGA_NOT_DERIVABLE]"));
03827                                                                         else CGMEConsole::theInstance->Message( msg + _T(" [Error code E_MGA_NOT_DERIVABLE]"), MSG_ERROR);
03828                                                                 }
03829                                                                 else
03830                                                                         AfxMessageBox( msg);
03831                                                                 CGMEEventLogger::LogGMEEvent(_T("    ") + msg + _T(" \r\n"));
03832                                                                 normalExit = false;
03833                                                                 break;
03834                                                         }
03835 
03836                                                         newFcos->Append(obj);
03837 
03838                                                         CString newID;
03839                                                         COMTHROW(obj->get_ID(PutOut(newID)));
03840                                                         newObjectIDs.AddHead(newID);
03841                                                 }
03842                                         }
03843                                         MGACOLL_ITERATE_END;
03844                                         if(!normalExit) {
03845                                                 AbortTransaction(hr);
03846                                                 newObjectIDs.RemoveAll();
03847                                                 return false;
03848                                         }
03849                                 }
03850                                 else if(reference) {
03851                                         if(ref) {
03852                                                 CGMEEventLogger::LogGMEEvent(_T("    ref=")+ref->GetName()+_T(" ")+ref->GetID()+_T("\r\n"));
03853                                                 CComPtr<IMgaReference> mgaRef;
03854                                                 COMTHROW(ref->mgaFco.QueryInterface(&mgaRef));
03855                                                 long count;
03856                                                 COMTHROW(fcos->get_Count(&count));
03857                                                 /* if(count != 1) {
03858                                                         AfxMessageBox(_T("Only a single object can be dropped on a reference for redirection!"));
03859                                                         throw hresult_exception(E_FAIL);
03860                                                 } */
03861                                                 if(count < 1) {
03862                                                         AfxMessageBox(_T("Cannot redirect reference to specified object!"));
03863                                                         CGMEEventLogger::LogGMEEvent(_T("    Cannot redirect reference to specified object.\r\n"));
03864                                                         throw hresult_exception(E_FAIL);
03865                                                 }
03866                                                 CComPtr<IMgaFCO> fco;
03867                                                 COMTHROW(fcos->get_Item(1,&fco));
03868                                                 if(!IsEqualObject(fco,mgaRef)) {
03869                                                         try {
03870                                                                 if (mgaRef->UsedByConns->Count > 0)
03871                                                                         MoveReferenceWithRefportConnectionsAndWriteToConsole(fco, mgaRef); // only works if fco.ObjType == model
03872                                                                 else
03873                                                                         COMTHROW(mgaRef->put_Referred(fco));
03874 
03875                                                                 CComBSTR bstr;
03876                                                                 CString newID;
03877                                                                 COMTHROW(mgaRef->get_ID(PutOut(newID)));
03878                                                                 newObjectIDs.AddHead(newID);
03879                                                         }
03880                                                         catch(hresult_exception e) {
03881                                                                 AbortTransaction(e.hr);
03882                                                                 CGMEEventLogger::LogGMEEvent( _T("    Cannot redirect reference to specified object.\r\n"));
03883                                                                 const TCHAR* t1 = _T("Cannot redirect reference to specified object because of active connections!");
03884                                                                 const TCHAR* t2 = _T("Cannot redirect reference to specified object.");
03885                                                                 if( e.hr == E_MGA_REFPORTS_USED)
03886                                                                 {
03887                                                                         if( !CGMEConsole::theInstance) AfxMessageBox( t1);
03888                                                                         else CGMEConsole::theInstance->Message( t1, MSG_ERROR);
03889                                                                 }
03890                                                                 else
03891                                                                         if( CGMEConsole::theInstance) AfxMessageBox( t2);
03892                                                                         else CGMEConsole::theInstance->Message( t2, MSG_ERROR);
03893 
03894                                                                 return false;
03895                                                         }
03896                                                         catch(_com_error &e) {
03897                                                                 AbortTransaction(e.Error());
03898                                                                 CString error = _T("Cannot redirect reference to specified object");
03899                                                                 if (e.Description().length() != 0)
03900                                                                 {
03901                                                                         error += _T(": ");
03902                                                                         error += static_cast<const TCHAR*>(e.Description());
03903                                                                 }
03904                                                                 CGMEEventLogger::LogGMEEvent(error + "\r\n");
03905                                                                 if (CGMEConsole::theInstance)
03906                                                                         CGMEConsole::theInstance->Message(error, MSG_ERROR);
03907 
03908                                                                 return false;
03909                                                         }
03910                                                 }
03911                                         }
03912                                         else {
03913                                                 COMTHROW(newFcos.CoCreateInstance(L"Mga.MgaFCOs"));
03914                                                 /*CComPtr<IMgaMetaFCO> metaFco;
03915                                                 COMTHROW(currentModel->get_Meta(&metaFco));
03916                                                 CComPtr<IMgaMetaModel> metaModel;
03917                                                 COMTHROW(metaFco.QueryInterface(&metaModel));*/ // commented by zolmol, these vars are NOT used
03918                                                 MGACOLL_ITERATE(IMgaFCO,fcos) {
03919                                                         CComPtr<IMgaFCO> fco;
03920                                                         COMTHROW(terry->OpenFCO(MGACOLL_ITER, &fco));
03921                                                         CComPtr<IMgaConnection> conn;
03922                                                         if(fco.QueryInterface(&conn) != S_OK) { // skip connections, they cannot be referenced
03923                                                                 CComPtr<IMgaMetaRole> role;
03924                                                                 COMTHROW(doc->resolver->put_IsStickyEnabled(::GetKeyState(VK_SHIFT) < 0 ? VARIANT_FALSE :VARIANT_TRUE));
03925                                                                 HRESULT hr = doc->resolver->get_RefRoleByMeta(currentModel,aspect,fco,&role);
03926                                                                 if (hr == E_ABORT) {
03927                                                                         AbortTransaction(hr);
03928                                                                         return false;
03929                                                                 } else {
03930                                                                         COMTHROW(hr);
03931                                                                 }
03932                                                                 if(role == 0)
03933                                                                 {
03934                                                                         AfxMessageBox(_T("Cannot create reference"));
03935                                                                         CGMEEventLogger::LogGMEEvent(_T("    Cannot create reference.\r\n"));
03936                                                                 }
03937                                                                 else {
03938                                                                         CComPtr<IMgaFCO> ref;
03939                                                                         COMTHROW(currentModel->CreateReference(role,fco,&ref));
03940                                                                         newFcos->Append(ref);
03941 
03942                                                                         CString newID;
03943                                                                         COMTHROW(ref->get_ID(PutOut(newID)));
03944                                                                         newObjectIDs.AddHead(newID);
03945 
03946                                                                         CComBSTR nmb;
03947                                                                         COMTHROW(fco->get_Name(&nmb));
03948                                                                         // After Larry's wishes
03949                                                                         /* CString nm;
03950                                                                         CopyTo(nmb,nm);
03951                                                                         nm += _T("Ref");
03952                                                                         CopyTo(nm,nmb); */
03953                                                                         COMTHROW(ref->put_Name(nmb));
03954                                                                 }
03955                                                         }
03956                                                 }
03957                                                 MGACOLL_ITERATE_END;
03958                                         }
03959                                 }
03960                                 else
03961                                         VERIFY(false);  // shouldn't be here!
03962                                 } // endif l > 0
03963 
03964                                 if(drag && !ref) {
03965                                         CGuiObjectList newObjs;
03966                                         CGuiFcoList newGuiFcos;
03967                                         CGuiConnectionList newConnections;
03968                                         CGuiAnnotatorList newAnns;
03969                                         if( newFcos) CreateGuiObjects(newFcos,newGuiFcos,newConnections);
03970                                         POSITION fpos = newGuiFcos.GetHeadPosition();
03971                                         while (fpos) {
03972                                                 CGuiFco* fgfco = newGuiFcos.GetNext(fpos);
03973                                                 ASSERT(fgfco != NULL);
03974                                                 CGuiObject* fgobj = fgfco->dynamic_cast_CGuiObject();
03975                                                 if (fgobj) {
03976                                                         newObjs.AddTail(fgobj);
03977                                                 }
03978                                         }
03979                                         CreateAnnotators(newRegNodes, newAnns);
03980 
03981                                         int left = 0, top = 0, leftA = 0, topA = 0;
03982                                         bool valid = false, validA = false;
03983                                         if (newObjs.GetCount() > 0) {
03984                                                 CGuiObject::FindUpperLeft(newObjs, left, top);
03985                                                 valid = true;
03986                                         }
03987                                         if (newAnns.GetCount() > 0) {
03988                                                 CGuiAnnotator::FindUpperLeft(newAnns, leftA, topA);
03989                                                 validA = true;
03990                                         }
03991                                         if (valid && validA) {
03992                                                 left = min(left, leftA);
03993                                                 top = min(top, topA);
03994                                         }
03995                                         else if (validA) {
03996                                                 left = leftA;
03997                                                 top = topA;
03998                                         }
03999                                         else if (!valid) {
04000                                                 ASSERT(("There is no object to move", false));
04001                                         }
04002                                         CPoint diff = point - CPoint(left,top);
04003                                         CGuiObject::ShiftModels(newObjs, diff);
04004                                         CGuiAnnotator::ShiftAnnotations(newAnns,diff);
04005 
04006 
04007                                         // CGuiAnnotatorList newAnns;
04008                                         // CreateGuiAnnotations(newAnns, );
04009                                         CGuiObject::MoveObjects(newObjs,point);
04010 
04011                                         // We don't need this, since reset
04012                                         // children.AddTail(&newGuiFcos);
04013                                         // annotators.AddTail(&newAnns);
04014                                         // Instead:
04015 
04016                                         POSITION dpos = newGuiFcos.GetHeadPosition();
04017                                         while(dpos) {
04018                                                 delete newGuiFcos.GetNext(dpos);
04019                                         }
04020 
04021                                         dpos = newAnns.GetHeadPosition();
04022                                         while(dpos) {
04023                                                 delete newAnns.GetNext(dpos);
04024                                         }
04025 
04026 
04027 
04028                                 }
04029                                 Invalidate(true);
04030                                 AutoRoute();
04031                                 CommitTransaction();
04032                                 ResetParent();
04033                                 ChangeAttrPrefObjs(selected);
04034                                 return true;
04035                         }
04036         /*
04037                         else {
04038                                 CommitTransaction();
04039                                 AfxMessageBox("Objects cannot be inserted!");
04040                         }
04041         */
04042                 }
04043                 catch (hresult_exception& e) {
04044                         AbortTransaction(e.hr);
04045                         if (e.hr == E_MGA_CONSTRAINT_VIOLATION)
04046                                 return false;
04047                         _bstr_t err;
04048                         GetErrorInfo(e.hr, err.GetAddress());
04049                         AfxMessageBox((std::wstring(L"Unable to insert objects: ") + static_cast<const wchar_t*>(err)).c_str(), MB_ICONSTOP | MB_OK); // in most cases there was an error msg already...
04050                         newObjectIDs.RemoveAll();
04051                 }
04052                 return false;
04053         }
04054         else if(unk && SUCCEEDED(unk.QueryInterface(&metaRole))) {                      // dragging from PartBrowser
04055                 try {
04056                         BeginTransaction();
04057                         bool ok = false;
04058                         if(!CGuiFco::IsPrimary(guiMeta,currentAspect,metaRole)) {
04059                                 if(currentAspect->IsPrimaryByRoleName(metaRole)) {
04060                                         CString roleName;
04061                                         COMTHROW(metaRole->get_Name(PutOut(roleName)));
04062                                         metaRole = 0;
04063                                         if(currentAspect->GetRoleByName(roleName,metaRole))
04064                                                 ok = true;
04065                                 }
04066                         }
04067                         else
04068                                 ok = true;
04069                         if(ok) {
04070                                 CComPtr<IMgaFCO> child;
04071                                 COMTHROW(currentModel->CreateChildObject(metaRole,&child));
04072 
04073                                 if (metaRole->Name == metaRole->Kind->Name)
04074                                 {
04075                                         child->Name = metaRole->Kind->DisplayedName;
04076                                 }
04077                                 else
04078                                 {
04079                                         child->Name = metaRole->DisplayedName;
04080                                 }
04081                                 CString newID;
04082                                 COMTHROW(child->get_ID(PutOut(newID)));
04083                                 newObjectIDs.AddHead(newID);
04084 
04085                                 SetObjectLocation(child,metaRole,point);
04086 
04087 //                              Invalidate(true);
04088 //                              AutoRoute();
04089                                 CommitTransaction();
04090                                 ChangeAttrPrefObjs(selected);
04091 //                              ResetParent();
04092                         }
04093                         else {
04094                                 CommitTransaction();
04095                                 AfxMessageBox(_T("Paradigm violation: cannot insert new part!"));
04096                                 CGMEEventLogger::LogGMEEvent(_T("    Paradigm violation: cannot insert new part.\r\n"));
04097                                 return false;
04098                         }
04099                 }
04100                 catch(hresult_exception& e) {
04101                         _bstr_t err;
04102                         GetErrorInfo(e.hr, err.GetAddress());
04103                         AbortTransaction(e.hr);
04104                         if (e.hr == E_MGA_CONSTRAINT_VIOLATION)
04105                                 return false;
04106                         AfxMessageBox((std::wstring(L"Unable to insert objects: ") + static_cast<const wchar_t*>(err)).c_str(), MB_ICONSTOP | MB_OK);
04107                         CGMEEventLogger::LogGMEEvent(_T("    Unable to insert objects.\r\n"));
04108                         newObjectIDs.RemoveAll();
04109             Reset(true); //BGY
04110                         return false;
04111                 }
04112         }
04113         return true;
04114 }
04115 
04116 void CGMEView::PasteAnnotations(CComPtr<IMgaModel> &targetModel, CComPtr<IMgaRegNodes> &regNodes, CComPtr<IMgaRegNodes> &newRegNodes, bool isMove)
04117 {
04118         if (regNodes == NULL) {
04119                 return;
04120         }
04121         MGACOLL_ITERATE(IMgaRegNode,regNodes) {
04122                 CComPtr<IMgaRegNode> regNode;
04123                 regNode = MGACOLL_ITER;
04124 
04125                 CComBSTR nodePath;
04126                 COMTHROW(regNode->get_Path(&nodePath));
04127 
04128                 bool collision = true;
04129                 while (collision) {
04130                         CComPtr<IMgaRegNode> exRegNode;
04131                         COMTHROW(targetModel->get_RegistryNode(nodePath, &exRegNode));
04132                         long status;
04133                         COMTHROW(exRegNode->get_Status(&status));
04134                         if (status == ATTSTATUS_UNDEFINED) {
04135                                 collision = false;
04136                         }
04137                         else {
04138                                 nodePath.Append(_T("Copy"));
04139                         }
04140                 }
04141 
04142                 CComPtr<IMgaRegNode> newNode;
04143                 COMTHROW(targetModel->get_RegistryNode(nodePath, &newNode));
04144                 COMTHROW(newRegNodes->Append(newNode));
04145 
04146                 CopyRegTree(regNode, newNode);
04147 
04148                 if (isMove) {
04149                         COMTHROW(regNode->RemoveTree());
04150                 }
04151 
04152                 // Let's make it visible in all aspects
04153                 CComPtr<IMgaRegNode> newAspRoot;
04154                 CComBSTR aspRootName(AN_ASPECTS);
04155                 COMTHROW(newNode->get_SubNodeByName(aspRootName, &newAspRoot));
04156                 CComPtr<IMgaRegNodes> aspNodes;
04157                 COMTHROW(newAspRoot->get_SubNodes(VARIANT_FALSE, &aspNodes));
04158                 MGACOLL_ITERATE(IMgaRegNode,aspNodes) {
04159                         CComPtr<IMgaRegNode> aspNode;
04160                         aspNode = MGACOLL_ITER;
04161                         COMTHROW(aspNode->RemoveTree());
04162                 }
04163                 MGACOLL_ITERATE_END;
04164 
04165                 CComBSTR defAspName(AN_DEFASPECT);
04166                 CComPtr<IMgaRegNode> defAspNode;
04167                 COMTHROW(newAspRoot->get_SubNodeByName(defAspName, &defAspNode));
04168                 CComBSTR defAspVal(AN_VISIBLE_DEFAULT);
04169                 COMTHROW(defAspNode->put_Value(defAspVal));
04170         }
04171         MGACOLL_ITERATE_END;
04172 }
04173 
04174 void CGMEView::CopyRegTree(CComPtr<IMgaRegNode> &regNode, CComPtr<IMgaRegNode> &newNode)
04175 {
04176         CComBSTR nodeValue;
04177         COMTHROW(regNode->get_Value(&nodeValue));
04178         COMTHROW(newNode->put_Value(nodeValue));
04179 
04180         CComPtr<IMgaRegNodes> subRegNodes;
04181         COMTHROW(regNode->get_SubNodes(VARIANT_FALSE, &subRegNodes));
04182         MGACOLL_ITERATE(IMgaRegNode,subRegNodes) {
04183                 CComPtr<IMgaRegNode> subRegNode;
04184                 subRegNode = MGACOLL_ITER;
04185                 CComBSTR subName;
04186                 COMTHROW(subRegNode->get_Name(&subName));
04187                 CComPtr<IMgaRegNode> newSubNode;
04188                 COMTHROW(newNode->get_SubNodeByName(subName, &newSubNode));
04189                 CopyRegTree(subRegNode, newSubNode);
04190         }
04191         MGACOLL_ITERATE_END;
04192 }
04193 
04194 void CGMEView::FillModelGrid()
04195 {
04196         BeginWaitCursor();
04197         modelGrid.SetSource(this);
04198         CGuiObject* obj;
04199         POSITION pos = children.GetHeadPosition();
04200         bool postPendingRequestEvent = false;
04201         while(pos) {
04202                 CGuiFco* fco = children.GetNext(pos);
04203                 ASSERT(fco != NULL);
04204                 obj = fco->dynamic_cast_CGuiObject();
04205                 if(!obj || !obj->IsVisible())
04206                         continue;
04207                 if(!modelGrid.IsAvailable(obj)) {
04208                         CRect loc = obj->GetLocation();
04209                         if (theApp.labelAvoidance) {
04210                                 CRect name = obj->GetNameLocation();
04211                                 loc.UnionRect(loc, name);
04212                         }
04213                         if(!modelGrid.GetClosestAvailable(obj, loc)) {
04214                                 //AfxMessageBox(_T("Too Many Models! Internal Program Error!"),MB_OK | MB_ICONSTOP);
04215                                 //EndWaitCursor();
04216                                 break;
04217                         }
04218                         // ASSERT(modelGrid.IsAvailable(loc));
04219                         if (!executingPendingRequests && !IsInstance()) {
04220                                 CPendingObjectPosRequest *req = new CPendingObjectPosRequest(obj, loc, obj->GetParentAspect());
04221                                 pendingRequests.AddHead(req);
04222                                 postPendingRequestEvent = true;
04223                         }
04224 
04225                         obj->SetObjectLocation(loc, -1, false);
04226                 }
04227                 modelGrid.Set(obj);
04228         }
04229         if (postPendingRequestEvent)
04230                 PostMessage(WM_USER_EXECUTEPENDINGREQUESTS);
04231         EndWaitCursor();
04232 }
04233 
04234 void CGMEView::SetObjectLocation(CComPtr<IMgaFCO> &child,CComPtr<IMgaMetaRole> &mmRole,CPoint pt)
04235 {
04236         // We temporarily create a GuiObject in order to have a decorator and be able to access real size data
04237         CGuiFco* guiFco = CreateGuiObject(child, NULL, NULL);
04238         ASSERT(guiFco != NULL);
04239         CGuiObject* guiObject = guiFco->dynamic_cast_CGuiObject();
04240         ASSERT(guiObject != NULL);
04241         CRect loc = guiObject->GetLocation();
04242         ::SetLocation(loc,pt);
04243 
04244         // CPoint npt = loc.CenterPoint();
04245         // if(!modelGrid.IsAvailable(loc)) {
04246         //      if(!modelGrid.GetClosestAvailable(loc.Size(),npt)) {
04247         //              AfxMessageBox(_T("Too Many Models! Internal Program Error!"),MB_OK | MB_ICONSTOP);
04248         //              EndWaitCursor();
04249         //              return;
04250         //      }
04251         // }
04252 
04253         try {
04254                 CComPtr<IMgaMetaParts> mmParts;
04255                 CComPtr<IMgaMetaPart> mmPart;
04256                 COMTHROW(mmRole->get_Parts(&mmParts));
04257                 MGACOLL_ITERATE(IMgaMetaPart,mmParts) {
04258                         mmPart = MGACOLL_ITER;
04259                         CComPtr<IMgaMetaAspect> mmAspect;
04260                         COMTHROW(mmPart->get_ParentAspect(&mmAspect));
04261                         CComPtr<IMgaPart> part;
04262                         COMTHROW(child->get_Part(mmAspect,&part));
04263                         COMTHROW(part->SetGmeAttrs(0,loc.TopLeft().x,loc.TopLeft().y));
04264                         // COMTHROW(part->SetGmeAttrs(0,npt.x,npt.y));
04265                 }
04266                 MGACOLL_ITERATE_END;
04267         }
04268         catch(hresult_exception &e) {
04269                 throw hresult_exception(e.hr);
04270         }
04271 
04272         delete guiFco;
04273 }
04274 
04275 void CGMEView::GetRefereeChain(IMgaFCOs* visitedRefs, IMgaFCO* fco)
04276 {
04277         CComQIPtr<IMgaReference> spReference(fco);
04278         CComPtr<IMgaFCO> spReferenced;
04279         if (spReference) {
04280                 while (spReference) {
04281                         spReferenced = NULL;
04282 
04283                         // Avoid circular references
04284                         long res;
04285                         if ((visitedRefs->Find(spReference, 1L, &res)) == E_NOTFOUND) {
04286                                 COMTHROW(visitedRefs->Append(spReference));
04287                                 COMTHROW(spReference->get_Referred(&spReferenced));
04288                         }
04289 
04290                         spReference = spReferenced;
04291                 }
04292         }
04293 }
04294 
04295 bool CGMEView::Connect(CGuiObject *src,CGuiPort *srcPort, int srcHotSide, CGuiObject *dst,CGuiPort *dstPort, int dstHotSide, bool nosticky)
04296 {
04297         CGMEEventLogger::LogGMEEvent(_T("CGMEView::Connect src=")+src->GetName()+_T(" ")+src->GetID()+_T(",dst=")+dst->GetName()+_T(" ")+dst->GetID()+_T(" in ")+path+name+_T("\r\n"));
04298         bool ret = false;
04299         CGMEDoc *doc = GetDocument();
04300         try {
04301                 BeginTransaction();
04302 
04303                 CComPtr<IMgaMetaRole> role;
04304                 CComPtr<IMgaMetaAspect> aspect;
04305                 currentAspect->GetMetaAspect(aspect);
04306 
04307                 if (srcPort) {
04308                         srcPort = srcPort->IsRealPort() ? srcPort : NULL;
04309                         if (srcPort) CGMEEventLogger::LogGMEEvent(_T("    srcPort=")+srcPort->GetName()+_T(" ")+srcPort->GetID()+_T("\r\n"));
04310                 }
04311                 if (dstPort) {
04312                         dstPort = dstPort->IsRealPort() ? dstPort : NULL;
04313                         if (dstPort) CGMEEventLogger::LogGMEEvent(_T("    dstPort=")+dstPort->GetName()+_T(" ")+dstPort->GetID()+_T("\r\n"));
04314                 }
04315                 COMTHROW(doc->resolver->put_IsStickyEnabled(nosticky ? VARIANT_FALSE :VARIANT_TRUE));
04316                 role = doc->resolver->ConnRoleByMeta[currentModel,
04317                                                                                                         aspect,
04318                                                                                                         src->mgaFco,
04319                                                                                                         srcPort ? srcPort->mgaFco : NULL,
04320                                                                                                         dst->mgaFco,
04321                                                                                                         dstPort ? dstPort->mgaFco : NULL];
04322                 CComPtr<IMgaFCO> conn;
04323                 if(role != 0) {
04324                         CComObjPtr<IMgaFCOs> srcRefs, dstRefs;
04325                         COMTHROW(srcRefs.CoCreateInstance(L"Mga.MgaFCOs"));
04326                         COMTHROW(dstRefs.CoCreateInstance(L"Mga.MgaFCOs"));
04327 
04328 // Bakay hack: avoid setting up refchains for atomrefs.
04329                         if(srcPort) GetRefereeChain(srcRefs,src->mgaFco);
04330 //                      GetRefereeChain(srcRefs,src->mgaFco);
04331                         if(dstPort) GetRefereeChain(dstRefs,dst->mgaFco);
04332 //                      GetRefereeChain(dstRefs,dst->mgaFco);
04333 
04334 /*
04335 // Bakay hack
04336 // Atom references must pass the referenced atom as src and dst
04337                         CComQIPtr<IMgaReference> refp;
04338                         while((refp = src->mgaFco) != NULL) {
04339                                 src->mgaFco = NULL;
04340                                 COMTHROW(refp->get_Referred(&src->mgaFco));
04341                         }
04342                         while((refp = dst->mgaFco) != NULL) {
04343                                 dst->mgaFco = NULL;
04344                                 COMTHROW(refp->get_Referred(&dst->mgaFco));
04345                         }
04346 // Bakay hack ends
04347 */
04348                         conn = currentModel->__CreateSimpleConn(
04349                                 role,
04350                                 srcPort ? srcPort->mgaFco : src->mgaFco,
04351                                 dstPort ? dstPort->mgaFco : dst->mgaFco,
04352                                 srcRefs,
04353                                 dstRefs);
04354                         CComBSTR nm;
04355                         COMTHROW(role->get_DisplayedName(&nm));
04356                         COMTHROW(conn->put_Name(nm));
04357 
04358                         // Setup autorouter prefs
04359                         CString routerPrefStr;
04360                         switch (srcHotSide) {
04361                         case GME_NORTH:
04362                                 routerPrefStr = _T("N");
04363                                 break;
04364                         case GME_SOUTH:
04365                                 routerPrefStr = _T("S");
04366                                 break;
04367                         case GME_WEST:
04368                                 routerPrefStr = _T("W");
04369                                 break;
04370                         case GME_EAST:
04371                                 routerPrefStr = _T("E");
04372                                 break;
04373                         }
04374                         switch (dstHotSide) {
04375                         case GME_NORTH:
04376                                 routerPrefStr += _T("n");
04377                                 break;
04378                         case GME_SOUTH:
04379                                 routerPrefStr += _T("s");
04380                                 break;
04381                         case GME_WEST:
04382                                 routerPrefStr += _T("w");
04383                                 break;
04384                         case GME_EAST:
04385                                 routerPrefStr += _T("e");
04386                                 break;
04387                         }
04388                         if (!routerPrefStr.IsEmpty()) {
04389                                 CComBSTR        bstrPath(AUTOROUTER_PREF);
04390                                 CComBSTR        bstrVal(routerPrefStr);
04391                                 COMTHROW(conn->put_RegistryValue(bstrPath,bstrVal));
04392                         }
04393 
04394                         ret = true;
04395                         CommitTransaction();
04396                 }
04397                 else {
04398                         CommitTransaction();
04399                         CGMEEventLogger::LogGMEEvent(_T("    Paradigm violation: cannot connect selected objects!\r\n"));
04400                         AfxMessageBox(_T("Paradigm violation: cannot connect selected objects!"),MB_ICONSTOP | MB_OK);
04401                 }
04402         }
04403         catch(hresult_exception &e) {
04404                 CGMEEventLogger::LogGMEEvent(_T("    Cannot Connect, hresult_exception in CGMEView::Connect\r\n"));
04405                 AbortTransaction(e.hr);
04406 //              AfxMessageBox(_T("Unable to connect specified parts!"),MB_ICONSTOP | MB_OK);
04407         Reset(true); // BGY: something similar needed, otherwise the created conenction not 
04408         // deleted form the gui if the committransaction failed
04409                 ret = false;
04410         }
04411         catch(_com_error &e) {
04412                 AbortTransaction(e.Error());
04413                 CString error = _T("Cannot create connection");
04414                 if (e.Description().length() != 0)
04415                 {
04416                         error += _T(": ");
04417                         error += static_cast<const TCHAR*>(e.Description());
04418                 }
04419                 CGMEEventLogger::LogGMEEvent(error + _T("\r\n"));
04420                 if (e.Error() != E_ABORT) // "Operation canceled by user"
04421                         AfxMessageBox(error,MB_ICONSTOP | MB_OK);
04422 
04423         Reset(true); // BGY: something similar needed, otherwise the created conenction not 
04424         // deleted form the gui if the committransaction failed
04425                 ret = false;
04426         }
04427         // error messages output to the console window
04428         // or simple refreshing of ActiveBrowser might leave
04429         // the focus set to another window, thus making the
04430         // connectmode cursor switch back to the normal one
04431         this->SetFocus();
04432         return ret;
04433 }
04434 
04435 void CGMEView::ResolveConnections()
04436 {
04437         POSITION pos = connections.GetHeadPosition();
04438         while(pos)
04439                 connections.GetNext(pos)->Resolve();
04440 }
04441 
04442 bool CGMEView::IsConnectionConversionNeeded(void)
04443 {
04444         if (isModelAutoRouted)
04445                 return false;
04446 
04447         POSITION pos = connections.GetHeadPosition();
04448         while(pos) {
04449                 if (connections.GetNext(pos)->NeedsRouterPathConversion(false))
04450                         return true;
04451         }
04452 
04453         return false;
04454 }
04455 
04456 void CGMEView::ConvertNeededConnections(void)
04457 {
04458         BeginTransaction();
04459         POSITION pos = connections.GetHeadPosition();
04460         while (pos) {
04461                 CGuiConnection* conn = connections.GetNext(pos);
04462                 conn->ConvertAutoRoutedPathToCustom(currentAspect->index, false, false);
04463         }
04464         CommitTransaction();
04465 }
04466 
04467 void CGMEView::InsertNewPart(const CString& roleName, const CPoint& pt)
04468 {
04469         CGMEEventLogger::LogGMEEvent(_T("CGMEView::InsertNewPart(")+roleName+_T(") in ")+path+name+_T("\r\n"));
04470         CComPtr<IMgaFCO> child;
04471         CComPtr<IMgaMetaRole> role;
04472         try {
04473                 BeginTransaction();
04474                 if(!currentAspect->GetRoleByName(roleName, role, true)) {
04475                         AfxMessageBox(_T("Internal Program Error in CGMEView::InsertNewPart"));
04476                         CGMEEventLogger::LogGMEEvent(_T("    Internal Program Error in CGMEView::InsertNewPart.\r\n"));
04477                         AbortTransaction(E_FAIL);
04478                         return;
04479                 }
04480                 COMTHROW(currentModel->CreateChildObject(role,&child));
04481                 CComBSTR realRoleName;
04482                 CComPtr<IMgaMetaFCO> childMeta;
04483                 COMTHROW(child->get_Meta(&childMeta));
04484                 CComBSTR kindName;
04485                 COMTHROW(childMeta->get_Name(&kindName));
04486                 CComBSTR bstrRoleName;
04487                 COMTHROW(role->get_DisplayedName(&bstrRoleName));
04488                 if (kindName == bstrRoleName) {
04489                         CComBSTR kindDisplayName;
04490                         COMTHROW(childMeta->get_DisplayedName(&kindDisplayName));
04491                         COMTHROW(child->put_Name(kindDisplayName));
04492                 } else {
04493                         COMTHROW(child->put_Name(bstrRoleName));
04494                 }
04495 
04496                 CString newID;
04497                 COMTHROW(child->get_ID(PutOut(newID)));
04498                 newObjectIDs.AddHead(newID);
04499 
04500                 SetObjectLocation(child, role, pt);
04501                 __CommitTransaction();
04502         }
04503         catch(hresult_exception &e) {
04504                 AbortTransaction(e.hr);
04505                 newObjectIDs.RemoveAll();
04506                 AfxMessageBox(_T("Unable to insert new part"),MB_ICONSTOP | MB_OK);
04507                 CGMEEventLogger::LogGMEEvent(_T("    Unable to insert new part.\r\n"));
04508                 return;
04509         }
04510         catch(_com_error& e) {                
04511                 AbortTransaction(e.Error());
04512                 newObjectIDs.RemoveAll();
04513                 CString error = _T("Unable to insert new part");
04514                 if (e.Description().length() != 0)
04515                 {
04516                         error += _T(": ");
04517                         error += static_cast<const TCHAR*>(e.Description());
04518                 }
04519                 CGMEEventLogger::LogGMEEvent(error + _T("\r\n"));
04520                 AfxMessageBox(error,MB_ICONSTOP | MB_OK);
04521                 return;
04522         }
04523         ChangeAttrPrefObjs(selected);
04524         try {
04525                 BeginTransaction(TRANSACTION_READ_ONLY);
04526                 if(currentAspect->IsLinkedRole(role) && parent != 0)
04527                         ResetParent();
04528                 CommitTransaction();
04529         }
04530         catch(hresult_exception &e) {
04531                 AbortTransaction(e.hr);
04532                 AfxMessageBox(_T("Unable to update parent"),MB_ICONSTOP | MB_OK);
04533                 CGMEEventLogger::LogGMEEvent(_T("    Unable to update parent.\r\n"));
04534         }
04535         Invalidate(true);
04536 }
04537 
04538 void CGMEView::ChangeAspect(CString aspName, bool p_eraseStack /*=true*/)
04539 {
04540         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ChangeAspect(")+aspName+_T(") in ")+path+name+_T("\r\n"));
04541         if(currentAspect->name != aspName) {
04542                 CGuiMetaAspect *newAsp = guiMeta->FindAspect(aspName);
04543                 if(newAsp) {
04544                         currentAspect = newAsp;
04545                         SetAspectProperty(currentAspect->index);
04546                         CGuiAnnotator::SetAspect(annotators, currentAspect->index);
04547 
04548                         if( theApp.isHistoryEnabled())
04549                         {
04550                                 if( m_isActive) // only the active view's changeaspect event is recorded
04551                                 {
04552                                         GetDocument()->tellHistorian( currentModel, currentAspect?currentAspect->name:_T(""));
04553                                 }
04554 
04555                                 if( p_eraseStack)
04556                                 {
04557                                         GetDocument()->clearForwHistory();
04558                                 }
04559                         }
04560                         CGuiFco::SetAspect(children,currentAspect->index);
04561                         ResolveConnections();
04562 
04563                         currentSet = 0;
04564                         if(GetDocument()->GetEditMode() == GME_SET_MODE) {
04565                                 CGuiAnnotator::GrayOutAnnotations(annotators,false);
04566                                 CGuiFco::GrayOutFcos(children,false);
04567                                 CGuiFco::GrayOutFcos(connections,false);
04568                         }
04569 
04570                         modelGrid.Clear();
04571                         FillModelGrid();
04572                         AutoRoute(); // HACK we may have size change here, reroute the whole thing for now
04573                         this->SendUnselEvent4List( &selected);
04574 
04575                         // Keep selection active if it is still visible in the new aspect
04576                         POSITION pos = selected.GetHeadPosition();
04577                         while( pos != NULL ) {
04578                                 POSITION oldPos = pos;
04579                                 CGuiFco *gfco = selected.GetNext(pos);
04580                                 if(!gfco->IsVisible(currentAspect->index))
04581                                         selected.RemoveAt(oldPos);
04582                         }
04583                         UpdateConnectionSelection(currentAspect->index);
04584 
04585                         RemoveAllAnnotationFromSelection();
04586 
04587                         ChangeAttrPrefObjs(selected);
04588 
04589 
04590 //                      CGMEView* gmeviewA = (CGMEView*)GetActiveView();
04591 //                      if (gmeviewA)
04592                         if (m_isActive)
04593                         {
04594                                 TRACE(_T("CGMEView::ChangeAspect activeView\n"));
04595                                 DoPannWinRefresh();
04596                         }
04597                         Invalidate();
04598                 }
04599         }
04600 }
04601 
04602 void CGMEView::ChangeAspect(int ind)
04603 {
04604         CGuiMetaAspect *am = guiMeta->FindAspect(ind);
04605         VERIFY(am);
04606         ChangeAspect(am->name);
04607 }
04608 
04609 CString& CGMEView::GetAspectName(int ind)
04610 {
04611         CGuiMetaAspect *am = guiMeta->FindAspect(ind);
04612         VERIFY(am);
04613         return am->name;
04614 }
04615 
04616 CString& CGMEView::GetCurrentAspectName(void)
04617 {
04618         return GetAspectName(currentAspect->index);
04619 }
04620 
04621 CGMEView *CGMEView::GetActiveView()
04622 {
04623         CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetApp()->m_pMainWnd;
04624 //      CMDIFrameWnd *pFrame = (CMDIFrameWnd*)AfxGetMainWnd( );
04625         if (!pFrame)
04626         {
04627                 return NULL;
04628         }
04629         CMDIChildWnd *pChild = (CMDIChildWnd *) pFrame->GetActiveFrame();
04630 //      BOOL ismax = FALSE;
04631 //      CMDIChildWnd *pChild = pFrame->MDIGetActive(&ismax);
04632         if (!pChild)
04633         {
04634                 return NULL;
04635         }
04636         return ((CGMEView *)(pChild->GetActiveView()));
04637 }
04638 
04640 // CGMEView message handlers
04641 
04642 BOOL CGMEView::OnEraseBkgnd(CDC* pDC)
04643 {
04644         if (!pDC->IsPrinting() && !IsPreview()) {
04645                 OnPrepareDC(offScreen);
04646                 CRect r;
04647                 GetClientRect(&r);
04648                 offScreen->DPtoLP(&r);
04649                 r.InflateRect(5, 5);
04650                 offScreen->FillSolidRect(&r,bgColor);
04651         }
04652 
04653         return TRUE;
04654 
04655 //      return CScrollZoomView::OnEraseBkgnd(pDC);
04656 }
04657 
04658 BOOL CGMEView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
04659 {
04660         if (IsCursorChangedByDecorator() || isCursorChangedByEdgeCustomize)
04661                 return TRUE;
04662 
04663         if (nHitTest != HTCLIENT) {
04664                 SetCursor(editCursor);  // JIRA GME-222
04665                 return FALSE;
04666         }
04667 
04668         if( GetFocus() != this )
04669                 SetCursor(editCursor);
04670         else {
04671                 CGMEDoc *pDoc = GetDocument();
04672                 switch(pDoc->GetEditMode()) {
04673                 case GME_AUTOCONNECT_MODE:
04674                 case GME_SHORTAUTOCONNECT_MODE:
04675                         SetCursor(connSrc ? autoconnect2Cursor : autoconnectCursor);
04676                         break;
04677                 case GME_DISCONNECT_MODE:
04678                 case GME_SHORTDISCONNECT_MODE:
04679                         SetCursor(connSrc ? disconnect2Cursor : disconnectCursor);
04680                         break;
04681                 case GME_SET_MODE:
04682                         SetCursor(currentSet ? set2Cursor : setCursor);
04683                         break;
04684                 case GME_ZOOM_MODE:
04685                         SetCursor(zoomCursor);
04686                         break;
04687                 case GME_VISUAL_MODE:
04688                         SetCursor(visualCursor);
04689                         break;
04690                 default:
04691                         SetCursor(tmpConnectMode ? autoconnect2Cursor : editCursor);
04692                         break;
04693                 }
04694         }
04695 
04696         ShowCursor(TRUE);
04697         return TRUE;
04698 }
04699 
04700 void CGMEView::OnDropFiles(HDROP p_hDropInfo)
04701 {
04702         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDropFiles in ") + path + name + _T("\r\n"));
04703         if (GetDocument()->GetEditMode() == GME_EDIT_MODE) {
04704                 CPoint point;
04705                 DragQueryPoint(p_hDropInfo, &point);
04706                 CoordinateTransfer(point);
04707 
04708                 CGMEView* self = const_cast<CGMEView*> (this);
04709                 CGuiObject*     object  = self ? self->FindObject(point, true, true) : 0;
04710                 if (object == NULL)     // not label of the object but can be some port label inside the object
04711                         object = self ? self->FindObject(point, true, false) : 0;
04712 
04713                 HRESULT retVal = S_OK;
04714                 if (object != NULL) {
04715                         CGuiAspect* pAspect = object->GetCurrentAspect();
04716                         if (pAspect != NULL) {
04717                                 CComQIPtr<IMgaElementDecorator> newDecorator(pAspect->GetDecorator());
04718                                 if (newDecorator) {
04719                                         CClientDC transformDC(this);
04720                                         OnPrepareDC(&transformDC);
04721                                         retVal = newDecorator->DropFile((ULONGLONG)p_hDropInfo, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
04722                                         if (retVal == S_DECORATOR_EVENT_HANDLED) {
04723                                                 if (IsInOpenedDecoratorTransaction()) {
04724                                                         if (ShouldCommitOperation()) {
04725                                                                 try {
04726                                                                         CommitTransaction();
04727                                                                 } catch (hresult_exception& e) {
04728                                                                         // GME-292: the commit may fail
04729                                                                         AbortTransaction(e.hr);
04730                                                                         if (e.hr != E_MGA_CONSTRAINT_VIOLATION) {
04731                                                                                 CGMEEventLogger::LogGMEEvent(_T("    Couldn't commit transaction.\r\n"));
04732                                                                                 AfxMessageBox(_T("Couldn't commit transaction."),MB_ICONSTOP | MB_OK);
04733                                                                         }
04734                                                                 }
04735                                                                 SetShouldCommitOperation(false);
04736                                                                 SetObjectInDecoratorOperation(NULL);
04737                                                                 SetAnnotatorInDecoratorOperation(NULL);
04738                                                                 SetInOpenedDecoratorTransaction(false);
04739                                                                 SetIsContextInitiatedOperation(false);
04740                                                                 SetInElementDecoratorOperation(false);
04741                                                                 return;
04742                                                         } else if (!IsInElementDecoratorOperation()) {
04743                                                                 AbortTransaction(S_OK);
04744                                                                 SetInOpenedDecoratorTransaction(false);
04745                                                                 SetIsContextInitiatedOperation(false);
04746                                                                 SetInElementDecoratorOperation(false);
04747                                                                 return;
04748                                                         }
04749                                                         // Note: DecoratorLib in-place edit currently not use SetCapture,
04750                                                         // but ReleaseCapture can be handy if some decorator issues SetCapture
04751                                                         if (::GetCapture() != NULL)
04752                                                                 ::ReleaseCapture();
04753                                                         SetInOpenedDecoratorTransaction(false);
04754                                                         SetIsContextInitiatedOperation(false);
04755                                                 } else {
04756                                                         if (IsInElementDecoratorOperation()) {
04757                                                                 if (IsDecoratorOrAnnotator())
04758                                                                         SetObjectInDecoratorOperation(object);
04759                                                                 else
04760                                                                         ASSERT(false);
04761                                                         }
04762                                                         return;
04763                                                 }
04764                                         } else if (retVal != S_OK &&
04765                                                            retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
04766                                                            retVal != E_DECORATOR_NOT_IMPLEMENTED)
04767                                         {
04768                                                 CancelDecoratorOperation();
04769                                                 // FIXME: how to handle this error?
04770                                                 // COMTHROW(retVal);
04771                                                 return;
04772                                         }
04773                                         if (IsInElementDecoratorOperation()) {
04774                                                 if (IsDecoratorOrAnnotator())
04775                                                         SetObjectInDecoratorOperation(object);
04776                                                 else
04777                                                         ASSERT(false);
04778                                         }
04779                                 }
04780                         }
04781                 }
04782                 if (IsInElementDecoratorOperation())
04783                         return;
04784                 if (retVal == S_DECORATOR_EVENT_HANDLED)
04785                         return;
04786         }
04787 
04788         CMainFrame::theInstance->OnDropFiles(p_hDropInfo);
04789 }
04790 
04791 void CGMEView::OnKillfocusNameProp()
04792 {
04793         if(!initDone)
04794                 return;
04795         CString txt;
04796         GetNameProperty(txt);
04797         if(txt != name) {
04798                 if(currentModel != 0) {
04799                         try {
04800                                 BeginTransaction();
04801                                 COMTHROW(currentModel->put_Name(_bstr_t(txt)));
04802                                 CommitTransaction();
04803                                 RetrievePath();
04804                                 name = txt;
04805                                 SetTitles();
04806                         }
04807                         catch(hresult_exception &e) {
04808                                 AbortTransaction(e.hr);
04809                                 AfxMessageBox(_T("Unable to set model name"));
04810                                 SetNameProperty();
04811                         }
04812                 }
04813         }
04814 }
04815 
04816 void CGMEView::OnSelChangeAspectProp()
04817 {
04818         int ind = GetAspectProperty();
04819         CGuiMetaAspect *am = guiMeta->FindAspect(ind);
04820         VERIFY(am);
04821         CString aspName = am->name;
04822         if(currentAspect->name != aspName) 
04823         {
04824                 currentAspect = guiMeta->FindAspect(aspName);
04825                 CMainFrame::theInstance->ChangePartBrowserAspect(currentAspect->index);
04826                 CGuiAnnotator::SetAspect(annotators, currentAspect->index);
04827                 CGuiFco::SetAspect(children,currentAspect->index);
04828                 ResolveConnections();
04829                 if( theApp.isHistoryEnabled())
04830                 {
04831                         GetDocument()->tellHistorian( currentModel, currentAspect?currentAspect->name:_T(""));
04832                         GetDocument()->clearForwHistory();
04833                 }
04834 
04835                 currentSet = 0;
04836                 if(GetDocument()->GetEditMode() == GME_SET_MODE) {
04837                         CGuiAnnotator::GrayOutAnnotations(annotators,false);
04838                         CGuiFco::GrayOutFcos(children,false);
04839                         CGuiFco::GrayOutFcos(connections,false);
04840                 }
04841 
04842                 modelGrid.Clear();
04843                 FillModelGrid();
04844                 AutoRoute(); // HACK we may have size change here, reroute the whole thing for now
04845                 this->SendUnselEvent4List( &selected);
04846                 selected.RemoveAll();
04847                 RemoveAllAnnotationFromSelection();
04848                 ClearConnectionSelection();
04849                 if (m_isActive)
04850                 {
04851                         DoPannWinRefresh();
04852                 }
04853 
04854                 TRACE(_T("CGMEView::OnSelChangeAspectProp\n"));
04855                 Invalidate();
04856         }
04857 }
04858 
04859 bool CGMEView::ChangePrnAspect(CString aspName)
04860 {
04861         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ChangePrnAspect(")+aspName+_T(") in ")+path+name+_T("\r\n"));
04862         if(currentAspect->name == aspName)
04863                 return true;
04864         CGuiMetaAspect *newAsp = guiMeta->FindAspect(aspName);
04865         if(!newAsp) 
04866                 return false;
04867         currentAspect = newAsp;
04868         SetAspectProperty(currentAspect->index);
04869         CGuiAnnotator::SetAspect(annotators, currentAspect->index);
04870         CGuiFco::SetAspect(children,currentAspect->index);
04871         ResolveConnections();
04872 
04873         modelGrid.Clear();
04874         FillModelGrid();
04875         AutoRoute(); // HACK we may have size change here, reroute the whole thing for now
04876         this->SendUnselEvent4List( &selected);
04877         selected.RemoveAll();
04878         RemoveAllAnnotationFromSelection();
04879         ClearConnectionSelection();
04880         return true;
04881 }
04882 
04883 void CGMEView::OnLButtonUp(UINT nFlags, CPoint point)
04884 {
04885         isLeftMouseButtonDown = false;
04886         isConnectionJustSelected = false;
04887         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnLButtonUp in ") + path + name + _T("\r\n"));
04888 
04889         CPoint ppoint = point;
04890         if (!tmpConnectMode) {
04891                 CPoint trackPoint = point;
04892                 CoordinateTransfer(point);
04893 
04894                 CGMEDoc* doc = GetDocument();
04895                 switch(doc->GetEditMode()) {
04896                 case GME_EDIT_MODE:
04897                         {
04898                                 CGMEEventLogger::LogGMEEvent(_T("    mode=GME_EDIT_MODE\r\n"));
04899 
04900                                 CGMEView* self = const_cast<CGMEView*> (this);
04901                                 CGuiObject*     object  = self          ? self->FindObject(point, true) : 0;
04902 //                              CGuiPort*       port    = object        ? object->FindPort(point, true) : 0;
04903                                 if (object == NULL)
04904                                         object = self ? self->FindObject(point, true, true) : 0;
04905 
04906                                 if (IsInElementDecoratorOperation()) {
04907                                         CComPtr<IMgaElementDecorator> newDecorator;
04908                                         if (IsDecoratorOrAnnotator()) {
04909                                                 CGuiObject* objInOp = GetObjectInDecoratorOperation();
04910                                                 if (objInOp != NULL) {
04911                                                         CGuiAspect* pAspect = objInOp->GetCurrentAspect();
04912                                                         if (pAspect != NULL) {
04913                                                                 CComQIPtr<IMgaElementDecorator> newDecorator2(pAspect->GetDecorator());
04914                                                                 newDecorator = newDecorator2;
04915                                                         }
04916                                                 }
04917                                         } else {
04918                                                 CGuiAnnotator* annInOp = GetAnnotatorInDecoratorOperation();
04919                                                 if (annInOp != NULL)
04920                                                         newDecorator = annInOp->GetDecorator(currentAspect->index);
04921                                         }
04922                                         if (newDecorator) {
04923                                                 CClientDC transformDC(this);
04924                                                 OnPrepareDC(&transformDC);
04925                                                 HRESULT retVal = newDecorator->MouseLeftButtonUp(nFlags, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
04926                                                 if (retVal == S_DECORATOR_EVENT_HANDLED) {
04927                                                         if (IsInOpenedDecoratorTransaction()) {
04928                                                                 if (ShouldCommitOperation()) {
04929                                                                         try {
04930                                                                                 CommitTransaction();
04931                                                                         } catch (hresult_exception& e) {
04932                                                                                 // GME-292: the commit may fail
04933                                                                                 AbortTransaction(e.hr);
04934                                                                                 if (e.hr != E_MGA_CONSTRAINT_VIOLATION) {
04935                                                                                         CGMEEventLogger::LogGMEEvent(_T("    Couldn't commit transaction.\r\n"));
04936                                                                                         AfxMessageBox(_T("Couldn't commit transaction."),MB_ICONSTOP | MB_OK);
04937                                                                                 }
04938                                                                         }
04939                                                                         SetShouldCommitOperation(false);
04940                                                                         SetObjectInDecoratorOperation(NULL);
04941                                                                         SetAnnotatorInDecoratorOperation(NULL);
04942                                                                 } else {
04943                                                                         AbortTransaction(S_OK);
04944                                                                 }
04945                                                                 SetInOpenedDecoratorTransaction(false);
04946                                                                 SetIsContextInitiatedOperation(false);
04947                                                         }
04948                                                         break;
04949                                                 } else if (retVal != S_OK &&
04950                                                                    retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
04951                                                                    retVal != E_DECORATOR_NOT_IMPLEMENTED)
04952                                                 {
04953                                                         CancelDecoratorOperation();
04954                                                         // FIXME: how to handle this error?
04955                                                         // COMTHROW(retVal);
04956                                                         return;
04957                                                 }
04958                                         }
04959                                 } else if (isInConnectionCustomizeOperation) {
04960                                         isInConnectionCustomizeOperation = false;
04961                                         ::SetCursor(customizeConnectionCursorBackup);
04962                                         isCursorChangedByEdgeCustomize = false;
04963                                         bool trySnap = false;
04964                                         if (customizeConnectionType == SimpleEdgeDisplacement) {
04965                                                 int newPos = 0;
04966                                                 if (customizeConnectionPartMoveMethod == HorizontalEdgeMove ||
04967                                                         customizeConnectionPartMoveMethod == AdjacentEdgeMove)
04968                                                 {
04969                                                         newPos = min(max(point.x, customizeConnectionEdgeXMinLimit),
04970                                                                                                           customizeConnectionEdgeXMaxLimit);
04971                                                         int edgeIndex = customizeConnectionEdgeIndex;
04972                                                         if (customizeConnectionPartMoveMethod == AdjacentEdgeMove && customizeHorizontalOrVerticalEdge)
04973                                                                 edgeIndex++;
04974                                                         UpdateCustomEdges(selectedConnection, SimpleEdgeDisplacement, newPos, 0, edgeIndex, false);
04975                                                 }
04976                                                 if (customizeConnectionPartMoveMethod == VerticalEdgeMove ||
04977                                                         customizeConnectionPartMoveMethod == AdjacentEdgeMove)
04978                                                 {
04979                                                         newPos = min(max(point.y, customizeConnectionEdgeYMinLimit),
04980                                                                                                           customizeConnectionEdgeYMaxLimit);
04981                                                         int edgeIndex = customizeConnectionEdgeIndex;
04982                                                         if (customizeConnectionPartMoveMethod == AdjacentEdgeMove && !customizeHorizontalOrVerticalEdge)
04983                                                                 edgeIndex++;
04984                                                         UpdateCustomEdges(selectedConnection, SimpleEdgeDisplacement, 0, newPos, edgeIndex, true);
04985                                                 }
04986                                         } else if (customizeConnectionType == CustomPointCustomization) {
04987                                                 if (customizeConnectionPartMoveMethod == InsertNewCustomPoint) {
04988                                                         InsertCustomEdge(selectedConnection, CustomPointCustomization, point.x, point.y, customizeConnectionEdgeIndex, true);
04989                                                         trySnap = true;
04990                                                 } else if (customizeConnectionPartMoveMethod == ModifyExistingCustomPoint) {
04991                                                         long edgeIndex = selectedConnection->IsPointOnSectionAndDeletable(customizeConnectionEdgeIndex, point);
04992                                                         if (edgeIndex >= 0) {
04993                                                                 DeleteCustomEdges(selectedConnection, CustomPointCustomization, edgeIndex);
04994                                                         } else {
04995                                                                 UpdateCustomEdges(selectedConnection, CustomPointCustomization, point.x, point.y, customizeConnectionEdgeIndex, true);
04996                                                                 trySnap = true;
04997                                                         }
04998                                                 }
04999                                         }
05000                                         if (trySnap && !(nFlags & MK_CONTROL))  // Control button disables snapping
05001                                                 selectedConnection->VerticalAndHorizontalSnappingOfConnectionLineSegments(currentAspect->index, customizeConnectionEdgeIndex);
05002                                         selectedConnection->WriteCustomPathData();
05003                                 } else {
05004                                         CGuiAnnotator* annotation = NULL;
05005                                         CComPtr<IMgaElementDecorator> newDecorator;
05006                                         if (object != NULL) {
05007                                                 CGuiAspect* pAspect = object->GetCurrentAspect();
05008                                                 if (pAspect != NULL) {
05009                                                         CComQIPtr<IMgaElementDecorator> newDecorator2(pAspect->GetDecorator());
05010                                                         newDecorator = newDecorator2;
05011                                                 }
05012                                         } else {
05013                                                 annotation = FindAnnotation(point);
05014                                                 if (annotation)
05015                                                         newDecorator = annotation->GetDecorator(currentAspect->index);
05016                                         }
05017                                         if (newDecorator) {
05018                                                 CClientDC transformDC(this);
05019                                                 OnPrepareDC(&transformDC);
05020                                                 HRESULT retVal = newDecorator->MouseLeftButtonUp(nFlags, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
05021                                                 if (retVal == S_DECORATOR_EVENT_HANDLED) {
05022                                                         doNotDeselectAfterInPlaceEdit = true;
05023 
05024                                                         if (IsInOpenedDecoratorTransaction()) {
05025                                                                 if (ShouldCommitOperation()) {
05026                                                                         try {
05027                                                                                 CommitTransaction();
05028                                                                         } catch (hresult_exception& e) {
05029                                                                                 // GME-292: the commit may fail
05030                                                                                 AbortTransaction(e.hr);
05031                                                                                 if (e.hr != E_MGA_CONSTRAINT_VIOLATION) {
05032                                                                                         CGMEEventLogger::LogGMEEvent(_T("    Couldn't commit transaction.\r\n"));
05033                                                                                         AfxMessageBox(_T("Couldn't commit transaction."),MB_ICONSTOP | MB_OK);
05034                                                                                 }
05035                                                                         }
05036                                                                         SetShouldCommitOperation(false);
05037                                                                         SetObjectInDecoratorOperation(NULL);
05038                                                                         SetAnnotatorInDecoratorOperation(NULL);
05039                                                                         SetInOpenedDecoratorTransaction(false);
05040                                                                         SetIsContextInitiatedOperation(false);
05041                                                                 } else if (!IsInElementDecoratorOperation()) {
05042                                                                         AbortTransaction(S_OK);
05043                                                                         SetInOpenedDecoratorTransaction(false);
05044                                                                         SetIsContextInitiatedOperation(false);
05045                                                                 } else {
05046                                                                         // Note: DecoratorLib in-place edit currently not use SetCapture,
05047                                                                         // but ReleaseCapture can be handy if some decorator issues SetCapture
05048                                                                         if (::GetCapture() != NULL)
05049                                                                                 ::ReleaseCapture();
05050                                                                 }
05051                                                                 SetInElementDecoratorOperation(false);
05052                                                                 SetInOpenedDecoratorTransaction(false);
05053                                                                 SetIsContextInitiatedOperation(false);
05054                                                         }
05055                                                 }
05056                                                 if (retVal != S_OK &&
05057                                                         retVal != S_DECORATOR_EVENT_HANDLED &&
05058                                                         retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
05059                                                         retVal != E_DECORATOR_NOT_IMPLEMENTED)
05060                                                 {
05061                                                         CancelDecoratorOperation();
05062                                                         // FIXME: how to handle this error?
05063                                                         // COMTHROW(retVal);
05064                                                         return;
05065                                                 }
05066                                                 if (IsInElementDecoratorOperation()) {
05067                                                         if (IsDecoratorOrAnnotator())
05068                                                                 SetObjectInDecoratorOperation(object);
05069                                                         else
05070                                                                 SetAnnotatorInDecoratorOperation(annotation);
05071                                                 }
05072                                         } else {
05073                                                 SetConnectionCustomizeCursor(point);
05074                                         }
05075                                 }
05076                         }       //case
05077                 }       // switch
05078         }       // if (!tmpConnectMode)
05079         CScrollZoomView::OnLButtonUp(nFlags, ppoint);
05080 }
05081 
05082 void CGMEView::OnLButtonDown(UINT nFlags, CPoint point)
05083 {
05084         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnLButtonDown in ")+path+name+_T("\r\n"));
05085         isLeftMouseButtonDown = true;
05086         if (!(nFlags & MK_LBUTTON)) {
05087                 // PETER: this was needed to discard "got focus" situations: eg.: add-on dialog appears during attribute editing
05088                 return;
05089         }
05090 
05091         CPoint trackPoint = point;
05092         CPoint ppoint = point;
05093         CoordinateTransfer(point);
05094 
05095         if(tmpConnectMode) {
05096                 if(connTmp && (connSrc != 0)) {
05097                         Connect(connSrc, connSrcPort, connSrcHotSide, connTmp, connTmpPort, connTmpHotSide, 0 != (nFlags & MK_SHIFT));
05098                 }
05099                 tmpConnectMode = false;
05100                 ClearConnSpecs();
05101                 SetCursor(editCursor);
05102                 ShowCursor(TRUE);
05103                 Invalidate();
05104         }
05105         else {
05106                 CGMEDoc *doc = GetDocument();
05107                 switch(doc->GetEditMode()) {
05108                 case GME_EDIT_MODE:
05109                         {
05110                                 CGMEEventLogger::LogGMEEvent(_T("    mode=GME_EDIT_MODE\r\n"));
05111 
05112                                 CGMEView* self = const_cast<CGMEView*> (this);
05113                                 CGuiObject*     object  = self          ? self->FindObject(point, true) : 0;
05114 //                              CGuiPort*       port    = object        ? object->FindPort(point, true) : 0;
05115                                 if (object == NULL)
05116                                         object = self ? self->FindObject(point, true, true) : 0;
05117 
05118                                 if (IsInElementDecoratorOperation()) {
05119                                         CComPtr<IMgaElementDecorator> newDecorator;
05120                                         if (IsDecoratorOrAnnotator()) {
05121                                                 CGuiObject* objInOp = GetObjectInDecoratorOperation();
05122                                                 if (objInOp != NULL) {
05123                                                         CGuiAspect* pAspect = objInOp->GetCurrentAspect();
05124                                                         if (pAspect != NULL) {
05125                                                                 CComQIPtr<IMgaElementDecorator> newDecorator2(pAspect->GetDecorator());
05126                                                                 newDecorator = newDecorator2;
05127                                                         }
05128                                                 }
05129                                         } else {
05130                                                 CGuiAnnotator* annInOp = GetAnnotatorInDecoratorOperation();
05131                                                 if (annInOp != NULL)
05132                                                         newDecorator = annInOp->GetDecorator(currentAspect->index);
05133                                         }
05134                                         if (newDecorator) {
05135                                                 CClientDC transformDC(this);
05136                                                 OnPrepareDC(&transformDC);
05137                                                 HRESULT retVal = newDecorator->MouseLeftButtonDown(nFlags, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
05138                                                 if (retVal == S_DECORATOR_EVENT_HANDLED) {
05139                                                         if (IsInOpenedDecoratorTransaction()) {
05140                                                                 if (ShouldCommitOperation()) {
05141                                                                         try {
05142                                                                                 CommitTransaction();
05143                                                                         } catch (hresult_exception& e) {
05144                                                                                 // GME-292: the commit may fail
05145                                                                                 AbortTransaction(e.hr);
05146                                                                                 if (e.hr != E_MGA_CONSTRAINT_VIOLATION) {
05147                                                                                         CGMEEventLogger::LogGMEEvent(_T("    Couldn't commit transaction.\r\n"));
05148                                                                                         AfxMessageBox(_T("Couldn't commit transaction."),MB_ICONSTOP | MB_OK);
05149                                                                                 }
05150                                                                         }
05151                                                                         SetShouldCommitOperation(false);
05152                                                                         SetObjectInDecoratorOperation(NULL);
05153                                                                         SetAnnotatorInDecoratorOperation(NULL);
05154                                                                 } else {
05155                                                                         AbortTransaction(S_OK);
05156                                                                 }
05157                                                                 SetInElementDecoratorOperation(false);
05158                                                                 SetInOpenedDecoratorTransaction(false);
05159                                                                 SetIsContextInitiatedOperation(false);
05160                                                         }
05161                                                 } else if (retVal != S_OK &&
05162                                                                    retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
05163                                                                    retVal != E_DECORATOR_NOT_IMPLEMENTED)
05164                                                 {
05165                                                         CancelDecoratorOperation();
05166                                                         // FIXME: how to handle this error?
05167                                                         // COMTHROW(retVal);
05168                                                         return;
05169                                                 }
05170                                                 CScrollZoomView::OnLButtonDown(nFlags, ppoint);
05171                                                 return;
05172                                         }
05173                                 } else {
05174                                         CGuiAnnotator* annotation = NULL;
05175                                         CComPtr<IMgaElementDecorator> newDecorator;
05176                                         if (object != NULL) {
05177                                                 CGuiAspect* pAspect = object->GetCurrentAspect();
05178                                                 if (pAspect != NULL) {
05179                                                         CComQIPtr<IMgaElementDecorator> newDecorator2(pAspect->GetDecorator());
05180                                                         newDecorator = newDecorator2;
05181                                                 }
05182                                         } else {
05183                                                 annotation = FindAnnotation(point);
05184                                                 if (annotation)
05185                                                         newDecorator = annotation->GetDecorator(currentAspect->index);
05186                                         }
05187                                         if (selectedConnection != NULL && !IsInstance()) {      // customization not allowed in instances
05188                                                 // Start edge moving operation if needed
05189                                                 bool isPartFixed = false;
05190                                                 customizeConnectionEdgeIndex = selectedConnection->GetEdgeIndex(
05191                                                                                                                                                 point,
05192                                                                                                                                                 customizeConnectionEdgeStartPoint,
05193                                                                                                                                                 customizeConnectionEdgeEndPoint,
05194                                                                                                                                                 customizeConnectionEdgeThirdPoint,
05195                                                                                                                                                 customizeConnectionPartMoveMethod,
05196                                                                                                                                                 customizeHorizontalOrVerticalEdge,
05197                                                                                                                                                 isPartFixed,
05198                                                                                                                                                 customizeConnectionEdgeXMinLimit,
05199                                                                                                                                                 customizeConnectionEdgeXMaxLimit,
05200                                                                                                                                                 customizeConnectionEdgeYMinLimit,
05201                                                                                                                                                 customizeConnectionEdgeYMaxLimit);
05202                                                 if (customizeConnectionEdgeIndex >= 0 && !isPartFixed) {
05203                                                         TRACE(_T("Starting edge customize operation of %ld.: (%ld, %ld)-(%ld, %ld)-(%ld, %ld) min/max: X(%ld, %ld) Y(%ld, %ld) h/v: %d\n"),
05204                                                                         customizeConnectionEdgeIndex,
05205                                                                         customizeConnectionEdgeStartPoint.x, customizeConnectionEdgeStartPoint.y,
05206                                                                         customizeConnectionEdgeEndPoint.x, customizeConnectionEdgeEndPoint.y,
05207                                                                         customizeConnectionEdgeThirdPoint.x, customizeConnectionEdgeThirdPoint.y,
05208                                                                         customizeConnectionEdgeXMinLimit, customizeConnectionEdgeXMaxLimit,
05209                                                                         customizeConnectionEdgeYMinLimit, customizeConnectionEdgeYMaxLimit,
05210                                                                         customizeConnectionPartMoveMethod);
05211                                                         if (selectedConnection->IsAutoRouted()) {
05212                                                                 customizeConnectionType = SimpleEdgeDisplacement;
05213                                                         } else {
05214                                                                 customizeConnectionType = CustomPointCustomization;
05215                                                         }
05216                                                         isInConnectionCustomizeOperation = true;
05217                                                         customizeConnectionOrigCursor = point;
05218                                                         customizeConnectionCurrCursor = point;
05219                                                         Invalidate();
05220                                                 }
05221                                         } else if (newDecorator && !isInConnectionCustomizeOperation) {
05222                                                 CClientDC transformDC(this);
05223                                                 OnPrepareDC(&transformDC);
05224                                                 HRESULT retVal = newDecorator->MouseLeftButtonDown(nFlags, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
05225                                                 if (retVal == S_DECORATOR_EVENT_HANDLED) {
05226                                                         if (IsInOpenedDecoratorTransaction()) {
05227                                                                 if (ShouldCommitOperation()) {
05228                                                                         try {
05229                                                                                 CommitTransaction();
05230                                                                         } catch (hresult_exception& e) {
05231                                                                                 // GME-292: the commit may fail
05232                                                                                 AbortTransaction(e.hr);
05233                                                                                 if (e.hr != E_MGA_CONSTRAINT_VIOLATION) {
05234                                                                                         CGMEEventLogger::LogGMEEvent(_T("    Couldn't commit transaction.\r\n"));
05235                                                                                         AfxMessageBox(_T("Couldn't commit transaction."),MB_ICONSTOP | MB_OK);
05236                                                                                 }
05237                                                                         }
05238                                                                         SetShouldCommitOperation(false);
05239                                                                         SetObjectInDecoratorOperation(NULL);
05240                                                                         SetAnnotatorInDecoratorOperation(NULL);
05241                                                                         SetInOpenedDecoratorTransaction(false);
05242                                                                         SetIsContextInitiatedOperation(false);
05243                                                                         SetInElementDecoratorOperation(false);
05244                                                                         CScrollZoomView::OnLButtonDown(nFlags, ppoint);
05245                                                                         return;
05246                                                                 } else if (!IsInElementDecoratorOperation()) {
05247                                                                         AbortTransaction(S_OK);
05248                                                                         SetInOpenedDecoratorTransaction(false);
05249                                                                         SetIsContextInitiatedOperation(false);
05250                                                                         SetInElementDecoratorOperation(false);
05251                                                                         CScrollZoomView::OnLButtonDown(nFlags, ppoint);
05252                                                                         return;
05253                                                                 }
05254                                                                 // Note: DecoratorLib in-place edit currently not use SetCapture,
05255                                                                 // but ReleaseCapture can be handy if some decorator issues SetCapture
05256                                                                 if (::GetCapture() != NULL)
05257                                                                         ::ReleaseCapture();
05258                                                                 SetInElementDecoratorOperation(false);
05259                                                         } else {
05260                                                                 if (IsInElementDecoratorOperation()) {
05261                                                                         if (IsDecoratorOrAnnotator())
05262                                                                                 SetObjectInDecoratorOperation(object);
05263                                                                         else
05264                                                                                 SetAnnotatorInDecoratorOperation(annotation);
05265                                                                 }
05266                                                                 CScrollZoomView::OnLButtonDown(nFlags, ppoint);
05267                                                                 return;
05268                                                         }
05269                                                 } else if (retVal != S_OK &&
05270                                                                    retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
05271                                                                    retVal != E_DECORATOR_NOT_IMPLEMENTED)
05272                                                 {
05273                                                         CancelDecoratorOperation();
05274                                                         // FIXME: how to handle this error?
05275                                                         // COMTHROW(retVal);
05276                                                         return;
05277                                                 }
05278                                                 if (IsInElementDecoratorOperation()) {
05279                                                         if (IsDecoratorOrAnnotator())
05280                                                                 SetObjectInDecoratorOperation(object);
05281                                                         else
05282                                                                 SetAnnotatorInDecoratorOperation(annotation);
05283                                                 }
05284                                         }
05285                                 }
05286                                 if (IsInElementDecoratorOperation() || isInConnectionCustomizeOperation) {
05287                                         CScrollZoomView::OnLButtonDown(nFlags, ppoint);
05288                                         return;
05289                                 }
05290 
05291                                 CGuiObject* selection = FindObject(point);
05292                                 if (selection == NULL)  // select with label
05293                                         selection = FindObject(point, false, true);
05294 
05295                                 CGuiAnnotator* annotation = selection ? NULL : FindAnnotation(point);
05296                                 CGuiConnection* connection = router.FindConnection(point);
05297 
05298                                 POSITION alreadySelected = 0;
05299                                 if((selection != 0) || (annotation != 0)) {
05300                                         if (selection) {
05301                                                 CGMEEventLogger::LogGMEEvent(_T("    LButton over ")+selection->GetName()+_T(" ")+selection->GetID()+_T("\r\n")); 
05302                                                 alreadySelected = selected.Find(selection);
05303                                                 if(alreadySelected)
05304                                                 {
05305                                                         this->SendUnselEvent4Object( selected.GetAt( alreadySelected));
05306                                                         selected.RemoveAt(alreadySelected);
05307                                                 }
05308                                                 else if(!(nFlags & MK_CONTROL)) {
05309                                                         RemoveAllAnnotationFromSelection();
05310                                                         this->SendUnselEvent4List( &selected);
05311                                                         selected.RemoveAll();
05312                                                         ClearConnectionSelection();
05313                                                 }
05314 
05315                                                 this->SendSelecEvent4Object( selection);
05316                                                 selected.AddHead(selection);
05317                                         }
05318                                         if (annotation) {
05319                                                 CGMEEventLogger::LogGMEEvent(_T("    LButton over ")+annotation->GetName()+_T("\r\n")); 
05320                                                 alreadySelected = selectedAnnotations.Find(annotation);
05321                                                 if (alreadySelected) {
05322                                                         RemoveAnnotationFromSelection(alreadySelected);
05323                                                 } else if (!(nFlags & MK_CONTROL)) {
05324                                                         this->SendUnselEvent4List( &selected);
05325                                                         selected.RemoveAll();
05326                                                         RemoveAllAnnotationFromSelection();
05327                                                 }
05328                                                 AddAnnotationToSelectionHead(annotation);
05329                                         }
05330 
05331                                         inDrag = true;
05332                                         CRect selRect(0,0,0,0);
05333                                         CRect selAnnRect(0,0,0,0);
05334                                         CGuiObject::GetExtent(selected,selRect);
05335                                         CGuiAnnotator::GetExtent(selectedAnnotations, selAnnRect);
05336                                         dragRect.UnionRect(selRect, selAnnRect);
05337 
05338                                         CPoint ptClickOffset(point.x - dragRect.left,
05339                                                                                         point.y - dragRect.top);
05340                                         CRect rectAwake = CRect(trackPoint.x,trackPoint.y,trackPoint.x + 1,trackPoint.y + 1);
05341                                         rectAwake.InflateRect(3,3);
05342                                         ClientToScreen(&dragRect);
05343                                         ClientToScreen(&rectAwake);
05344 
05345                                         CRectList rects;
05346                                         CRectList annRects;
05347                                         CGuiObject::GetRectList(selected,rects);
05348                                         CGuiAnnotator::GetRectList(selectedAnnotations,annRects);
05349                                         CGMEDataDescriptor desc(rects,annRects,point,ptClickOffset);
05350                                         CGMEDataDescriptor::destructList( rects);
05351                                         CGMEDataDescriptor::destructList( annRects);
05352 
05353                                         validGuiObjects = true;
05354                                         dragSource = (selected.GetCount() > 0) ? selected.GetHead() : NULL;
05355                                         DROPEFFECT dropEffect = CGMEDoc::DoDragDrop(&selected, &selectedAnnotations, &desc,
05356                                                 DROPEFFECT_MOVE | DROPEFFECT_COPY | DROPEFFECT_LINK, &rectAwake,this);
05357 
05358                                         if (validGuiObjects && dropEffect == DROPEFFECT_NONE) {
05359                                                 if (inDrag && alreadySelected != NULL && (selection || annotation)) {
05360                                                         OnLButtonUp(nFlags, ppoint);
05361                                                 }
05362                                                 if (nFlags & MK_CONTROL) {
05363                                                         if (selection) {
05364                                                                 if (alreadySelected) {
05365                                                                         this->SendUnselEvent4Object( selected.GetHead());
05366                                                                         selected.RemoveHead();
05367                                                                         selection = selected.GetCount() ? selected.GetHead() : 0;
05368                                                                 }
05369                                                                 ChangeAttrPrefObjs(selected);
05370                                                         }
05371                                                         if (annotation) {
05372                                                                 if (alreadySelected) {
05373                                                                         RemoveAnnotationFromSelectionHead();
05374                                                                         annotation = selectedAnnotations.GetCount() ? selectedAnnotations.GetHead() : 0;
05375                                                                         /*
05376                                                                         if(annotation)
05377                                                                                 ChangeAttrPrefFco(annotation);
05378                                                                         */
05379                                                                 }
05380                                                                 else
05381                                                                         /*
05382                                                                         ChangeAttrPrefFco(annotation);
05383                                                                         */ ;
05384                                                         }
05385                                                 }
05386                                                 else if (!doNotDeselectAfterInPlaceEdit) {
05387                                                         this->SendUnselEvent4List( &selected);
05388                                                         selected.RemoveAll();
05389                                                         RemoveAllAnnotationFromSelection();
05390                                                         ClearConnectionSelection();
05391                                                         if (selection) {
05392                                                                 if(!alreadySelected) {
05393                                                                         this->SendSelecEvent4Object( selection);
05394                                                                         selected.AddHead(selection);
05395                                                                         ChangeAttrPrefObjs(selected);
05396                                                                 }
05397                                                         }
05398                                                         if (annotation) {
05399                                                                 if(!alreadySelected) {
05400                                                                         AddAnnotationToSelectionHead(annotation);
05401                                                                          /* ChangeAttrPrefFco(selectedAnnotations.GetTail()); */
05402                                                                 }
05403                                                         }
05404                                                 }
05405                                                 doNotDeselectAfterInPlaceEdit = false;
05406                                         }
05407                                         else {
05408                                                 ChangeAttrPrefObjs(selected);
05409                                         }
05410                                         Invalidate();
05411                                         if(inDrag && dropEffect == DROPEFFECT_MOVE) {
05412 /* HACK
05413                                                 int num;
05414                                                 if((num = currentModel->CheckForReferences(selected)) > 0) {
05415                                                         char txt[128];
05416                                                         sprintf(txt,_T("Selected model(s) cannot be deleted due to %ld reference(s)"),num);
05417                                                         AfxMessageBox(txt,MB_OK | MB_ICONSTOP);
05418                                                 }
05419                                                 else if((num = currentModel->CheckForInherited(selected)) > 0) {
05420                                                         char txt[128];
05421                                                         sprintf(txt,_T("Selected model(s) cannot be deleted due to %ld inherited part(s)"),num);
05422                                                         AfxMessageBox(txt,MB_OK | MB_ICONSTOP);
05423                                                 }
05424                                                 else {
05425                                                         MoveToTrash(selected);
05426                                                         CGMEDoc *doc = GetDocument();
05427                                                         doc->SetModifiedFlag(TRUE);
05428                                                         selected.RemoveAll();
05429                                                         selection = 0;
05430                                                 }
05431 */
05432                                         }
05433                                         inDrag = false;
05434                                 }
05435                                 else {
05436                                         this->SendUnselEvent4List( &selected);
05437                                         selected.RemoveAll();
05438                                         RemoveAllAnnotationFromSelection();
05439                                         ClearConnectionSelection();
05440                                         selection = 0;
05441                                         annotation = 0;
05442 
05443                                         if (connection) {
05444                                                 ChangeAttrPrefFco(connection);
05445                                         }
05446                                         else {
05447                                                 CRectTracker tracker;
05448                                                 CClientDC dc(this);
05449                                                 OnPrepareDC(&dc);
05450                                                 if(tracker.TrackRubberBand(this, trackPoint,TRUE)) {
05451                                                         tracker.m_rect.NormalizeRect();
05452                                                         dc.DPtoLP(tracker.m_rect);
05453                                                         FindObjects(tracker.m_rect,selected);
05454                                                         this->SendSelecEvent4List( &selected);
05455                                                         FindAnnotations(tracker.m_rect,selectedAnnotations);
05456                                                         if(selected.GetCount() > 0) {
05457                                                                 selection = selected.GetHead();
05458                                                         }
05459                                                         else if (selectedAnnotations.GetCount() > 0 ){
05460                                                                 annotation = selectedAnnotations.GetHead();
05461                                                                 // ANNTODO: ChangeAttrPrefFco...
05462                                                         }
05463                                                 }
05464                                                 ChangeAttrPrefObjs(selected);
05465                                         }
05466                                 }
05467                                 bool succ = this->SendNow();
05468                                 Invalidate( succ);
05469                         }
05470                         break;
05471                 case GME_AUTOCONNECT_MODE:
05472                 case GME_SHORTAUTOCONNECT_MODE:
05473                         {
05474                                 CGMEEventLogger::LogGMEEvent(_T("    mode=GME_AUTOCONNECT_MODE\r\n"));
05475                                 if(connTmp) {
05476                                         if(connSrc == 0) {
05477                                                 connSrc = connTmp;
05478                                                 connSrcPort = connTmpPort;
05479                                                 connSrcHotSide = connTmpHotSide;
05480                                         }
05481                                         else {
05482                                                 Connect(connSrc, connSrcPort, connSrcHotSide, connTmp, connTmpPort, connTmpHotSide, 0 != (nFlags & MK_SHIFT));
05483                                                 ClearConnSpecs();
05484                                                 if( doc->GetEditMode() == GME_SHORTAUTOCONNECT_MODE)
05485                                                         GetDocument()->SetMode(0); // switch back to GME_EDIT_MODE
05486                                         }
05487 
05488                                 }
05489                         }
05490                         Invalidate();
05491                         break;
05492                 case GME_DISCONNECT_MODE:
05493                 case GME_SHORTDISCONNECT_MODE:
05494                         {
05495                                 CGMEEventLogger::LogGMEEvent(_T("    mode=GME_DISCONNECT_MODE\r\n"));
05496                                 CGuiObject *selection = FindObject(point);
05497                                 if(selection) {
05498                                         CGuiPort *port = 0;
05499                                         port = selection->FindPort(point);
05500                                         if(connSrc == 0) {
05501                                                 if (port != 0) {
05502                                                         connSrc = port->parent->GetParent();
05503                                                         connSrcPort = port;
05504                                                         CGuiConnectionList conns;
05505                                                         FindConnections(connSrc,connSrcPort,conns);
05506                                                         if(conns.GetCount() < 2) {
05507                                                                 if(conns.GetCount() == 1) {
05508                                                                         if(!DeleteConnection(conns.GetHead())) {
05509                                                                                 AfxMessageBox(_T("Connection cannot be deleted!"));
05510                                                                         }
05511                                                                 }
05512                                                                 else if(conns.GetCount() == 0) {
05513                                                                         AfxMessageBox(_T("Selected object is not connected!"));
05514                                                                 }
05515                                                                 ClearConnSpecs();
05516                                                                 if( doc->GetEditMode() == GME_SHORTDISCONNECT_MODE)
05517                                                                         GetDocument()->SetMode(0); // switch back to GME_EDIT_MODE
05518                                                         }
05519                                                 } else {
05520                                                         AfxMessageBox(_T("Cannot find port to connection!"));
05521                                                 }
05522                                         }
05523                                         else {
05524                                                 CGuiConnectionList conns;
05525                                                 FindConnections(connSrc,connSrcPort,selection,port,conns);
05526                                                 if(conns.GetCount()) {
05527                                                         if(!DeleteConnection(conns.GetHead()))
05528                                                                 AfxMessageBox(_T("Connection cannot be deleted!"));
05529                                                 }
05530                                                 else
05531                                                         AfxMessageBox(_T("Selected objects are not connected!"));
05532                                                 ClearConnSpecs();
05533                                                 if( doc->GetEditMode() == GME_SHORTDISCONNECT_MODE)
05534                                                         GetDocument()->SetMode(0); // switch back to GME_EDIT_MODE
05535                                         }
05536                                 }
05537                                 if(!selection) {
05538                                         CGuiConnection *conn = router.FindConnection(point);
05539                                         if(conn) {
05540                                                 if(!DeleteConnection(conn))
05541                                                         AfxMessageBox(_T("Connection cannot be deleted!"));
05542                                                 ClearConnSpecs();
05543                                                 if( doc->GetEditMode() == GME_SHORTDISCONNECT_MODE)
05544                                                         GetDocument()->SetMode(0); // switch back to GME_EDIT_MODE
05545                                         }
05546                                 }
05547                         }
05548                         Invalidate();
05549                         break;
05550                 case GME_SET_MODE:
05551                         {
05552                                 CGMEEventLogger::LogGMEEvent(_T("    mode=GME_SET_MODE\r\n"));
05553                                 if(!currentSet)
05554                                         break;
05555                                 CGuiFco *fco = 0;
05556                                 try {
05557                                         BeginTransaction(TRANSACTION_READ_ONLY);
05558                                         CGuiObject *object = FindObject(point);
05559                                         if(object) {
05560                                                 CGMEEventLogger::LogGMEEvent(_T("    LButton over ")+object->GetName()+_T(" ")+object->GetID()+_T("\r\n"));
05561                                                 if(currentSet->CheckMember(object))
05562                                                         fco = object;
05563                                         }
05564                                         else {
05565                                                 CGuiConnection *conn = router.FindConnection(point);
05566                                                 if(conn && currentSet->CheckMember(conn))
05567                                                         fco = conn;
05568                                         }
05569                                         CommitTransaction();
05570                                 }
05571                                 catch(hresult_exception &e) {
05572                                         AbortTransaction(e.hr);
05573                                         break;
05574                                 }
05575                                 if(fco) {
05576                                         try {
05577                                                 BeginTransaction();
05578                                                 currentSet->ToggleMember(fco);  // nothing else needs to be done: events will be generated!
05579                                                 CommitTransaction();
05580                                         }
05581                                         catch(hresult_exception &e) {
05582                                                 AbortTransaction(e.hr);
05583                                                 break;
05584                                         }
05585                                 }
05586                         }
05587                         break;
05588                 case GME_ZOOM_MODE:
05589                         {
05590                                 CGMEEventLogger::LogGMEEvent(_T("    mode=GME_ZOOM_MODE\r\n"));
05591                 CRectTracker tracker;
05592                                 tracker.m_rect = CRect(0,0,0,0);
05593                 if(tracker.TrackRubberBand(this, trackPoint,TRUE)) 
05594                                 {
05595                                         CRect truerect(0,0,0,0);
05596                                         tracker.GetTrueRect(&truerect);
05597                                         truerect.NormalizeRect();
05598                                         if (truerect.Height() <= MIN_ZOOM_RECT && truerect.Width() <= MIN_ZOOM_RECT)
05599                                                 ZoomIn(ppoint); 
05600                                         else
05601                                                 ZoomRect(truerect);
05602                 }
05603                                 else
05604                                         ZoomIn(ppoint); 
05605                                 Invalidate();
05606                         }
05607                         break;
05608                 case GME_VISUAL_MODE:
05609                         {
05610                                 CGMEEventLogger::LogGMEEvent(_T("    mode=GME_VISUAL_MODE\r\n"));
05611                                 CGuiObject *obj = FindObject(point);
05612                                 if(obj) {
05613                                         CGMEEventLogger::LogGMEEvent(_T("    LButton over ")+obj->GetName()+_T(" ")+obj->GetID()+_T("\r\n"));
05614                                         obj->ToggleGrayOut();
05615                                         CGuiFco::GrayOutNonInternalConnections(connections);
05616                                         Invalidate();
05617                                 }
05618                                 else {
05619                                         CGuiConnection *conn = router.FindConnection(point);
05620                                         if(conn) {
05621                                                 CGMEEventLogger::LogGMEEvent(_T("    LButton over ")+conn->GetName()+_T(" ")+conn->GetID()+_T("\r\n"));
05622                                                 conn->ToggleGrayOut();
05623                                                 conn->GrayOutEndPoints();
05624                                                 Invalidate();
05625                                         }
05626                                         else {
05627                                                 CGuiAnnotator *ann = FindAnnotation(point);
05628                                                 if (ann) {
05629                                                         CGMEEventLogger::LogGMEEvent(_T("    LButton over ")+ann->GetName()+_T("\r\n"));
05630                                                         ann->ToggleGrayOut();
05631                                                         Invalidate();
05632                                                 }
05633                                         }
05634                                 }
05635                         }
05636                         break;
05637                 default:
05638                         break;
05639                 }
05640         }
05641         dragSource = 0;
05642         CScrollZoomView::OnLButtonDown(nFlags, ppoint);
05643 }
05644 
05645 void CGMEView::OnLButtonDblClk(UINT nFlags, CPoint point)
05646 {
05647         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnLButtonDblClk in ") + path + name + _T("\r\n"));
05648         CPoint ppoint = point;
05649         if (GetDocument()->GetEditMode() == GME_EDIT_MODE) {
05650                 CoordinateTransfer(point);      // DPtoLP
05651 
05652                 CGMEView* self = const_cast<CGMEView*> (this);
05653                 CGuiObject*     object  = self ? self->FindObject(point, true, true) : 0;
05654                 if (object == NULL)     // not label of the object but can be some port label inside the object
05655                         object = self ? self->FindObject(point, true, false) : 0;
05656                 CGuiAnnotator *annotation = FindAnnotation(point);
05657 
05658                 if (object || annotation) {
05659                         CComPtr<IMgaElementDecorator> newDecorator;
05660                         if (object != NULL) {
05661                                 CGuiAspect* pAspect = object->GetCurrentAspect();
05662                                 if (pAspect != NULL) {
05663                                         CComQIPtr<IMgaElementDecorator> newDecorator2(pAspect->GetDecorator());
05664                                         newDecorator = newDecorator2;
05665                                 }
05666                         } else {
05667                                 annotation = FindAnnotation(point);
05668                                 if (annotation)
05669                                         newDecorator = annotation->GetDecorator(currentAspect->index);
05670                         }
05671 
05672                         if (newDecorator) {
05673                                 CClientDC transformDC(this);
05674                                 OnPrepareDC(&transformDC);
05675                                 HRESULT retVal = newDecorator->MouseLeftButtonDoubleClick(nFlags, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
05676                                 if (retVal == S_DECORATOR_EVENT_HANDLED) {
05677                                         if (IsInOpenedDecoratorTransaction()) {
05678                                                 if (ShouldCommitOperation()) {
05679                                                         try {
05680                                                                 CommitTransaction();
05681                                                         } catch (hresult_exception& e) {
05682                                                                 // GME-292: the commit may fail
05683                                                                 AbortTransaction(e.hr);
05684                                                                 if (e.hr != E_MGA_CONSTRAINT_VIOLATION) {
05685                                                                         CGMEEventLogger::LogGMEEvent(_T("    Couldn't commit transaction.\r\n"));
05686                                                                         AfxMessageBox(_T("Couldn't commit transaction."),MB_ICONSTOP | MB_OK);
05687                                                                 }
05688                                                         }
05689                                                         SetShouldCommitOperation(false);
05690                                                         SetObjectInDecoratorOperation(NULL);
05691                                                         SetAnnotatorInDecoratorOperation(NULL);
05692                                                         SetInOpenedDecoratorTransaction(false);
05693                                                         SetIsContextInitiatedOperation(false);
05694                                                         SetInElementDecoratorOperation(false);
05695                                                         CScrollZoomView::OnLButtonDblClk(nFlags, ppoint);
05696                                                         return;
05697                                                 } else if (!IsInElementDecoratorOperation()) {
05698                                                         AbortTransaction(S_OK);
05699                                                         SetInOpenedDecoratorTransaction(false);
05700                                                         SetIsContextInitiatedOperation(false);
05701                                                         SetInElementDecoratorOperation(false);
05702                                                         CScrollZoomView::OnLButtonDblClk(nFlags, ppoint);
05703                                                         return;
05704                                                 }
05705                                                 // Note: DecoratorLib in-place edit currently not use SetCapture,
05706                                                 // but ReleaseCapture can be handy if some decorator issues SetCapture
05707                                                 if (::GetCapture() != NULL)
05708                                                         ::ReleaseCapture();
05709                                                 SetInElementDecoratorOperation(false);
05710                                                 SetInOpenedDecoratorTransaction(false);
05711                                                 SetIsContextInitiatedOperation(false);
05712                                         } else {
05713                                                 if (IsInElementDecoratorOperation()) {
05714                                                         if (IsDecoratorOrAnnotator())
05715                                                                 SetObjectInDecoratorOperation(object);
05716                                                         else
05717                                                                 SetAnnotatorInDecoratorOperation(annotation);
05718                                                 }
05719                                                 CScrollZoomView::OnLButtonDown(nFlags, ppoint);
05720                                                 return;
05721                                         }
05722                                 } else if (retVal != S_OK &&
05723                                                    retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
05724                                                    retVal != E_DECORATOR_NOT_IMPLEMENTED)
05725                                 {
05726                                         CancelDecoratorOperation();
05727                                         // FIXME: how to handle this error?
05728                                         // COMTHROW(retVal);
05729                                         return;
05730                                 }
05731                                 if (IsInElementDecoratorOperation()) {
05732                                         if (IsDecoratorOrAnnotator())
05733                                                 SetObjectInDecoratorOperation(object);
05734                                         else
05735                                                 SetAnnotatorInDecoratorOperation(annotation);
05736                                 }
05737                         }
05738                 }
05739                 if (IsInElementDecoratorOperation()) {
05740                         CScrollZoomView::OnLButtonDown(nFlags, ppoint);
05741                         return;
05742                 }
05743 
05744                 CGuiObject *selection = FindObject(point);
05745 
05746                 if(selection) {
05747                         CGMEEventLogger::LogGMEEvent(    _T("LButton double clicked on ")+selection->GetName()+_T(" ")+selection->GetID()+_T("\r\n"));
05748                         CString aspectName = currentAspect->name;
05749                         CComPtr<IMgaFCO> mgaFco = selection->mgaFco;
05750                         CComPtr<IMgaModel> model;
05751                         CComPtr<IMgaReference> ref;
05752                         CComPtr<IMgaFCO> referred;
05753                         CComBSTR         referred_id;
05754                         if(FAILED(mgaFco.QueryInterface(&model))) {             // it is not a model
05755                                 if(SUCCEEDED(mgaFco.QueryInterface(&ref))) {            // it is a reference
05756                                         CComPtr<IMgaObject> obj;
05757                                         try {
05758                                                 BeginTransaction(TRANSACTION_READ_ONLY);
05759                                                 COMTHROW(ref->get_Referred(&referred));
05760                                                 if(referred)
05761                                                 {
05762                                                         COMTHROW(referred->GetParent(&obj, NULL));
05763                                                         COMTHROW(referred->get_ID( &referred_id));
05764                                                 }
05765                                                 CommitTransaction();
05766                                         }
05767                                         catch(hresult_exception e) {
05768                                                 AbortTransaction(e.hr);
05769                                                 CScrollZoomView::OnLButtonDblClk(nFlags, ppoint);
05770                                         }
05771                                         if(referred) {
05772                                                 if(FAILED(obj.QueryInterface(&model))) {                // it is a root
05773                                                         if (SUCCEEDED(referred.QueryInterface(&model))) {
05774                                                                 int aspi = selection->MapAspect(selection->GetParentAspect());
05775                                                                 if(aspi >= 0) {
05776                                                                         try {
05777                                                                                 BeginTransaction(TRANSACTION_READ_ONLY);
05778                                                                                 ASSERT(selection != NULL);
05779                                                                                 CGuiCompoundReference* compref = selection->dynamic_cast_CGuiCompoundReference();
05780                                                                                 VERIFY(compref);
05781                                                                                 CComPtr<IMgaMetaFCO> metaFco;
05782                                                                                 COMTHROW(compref->GetTerminalReferee()->get_Meta(&metaFco));
05783                                                                                 metaref_type metaRef;
05784                                                                                 VERIFY(metaFco);
05785                                                                                 COMTHROW(metaFco->get_MetaRef(&metaRef));
05786                                                                                 CGuiMetaModel *guiMetaModel = CGuiMetaProject::theInstance->GetGuiMetaModel(metaRef);
05787                                                                                 VERIFY(guiMetaModel);
05788                                                                                 CGuiMetaAspect *asp = guiMetaModel->FindAspect(aspi);
05789                                                                                 if(asp) {
05790                                                                                         aspectName = asp->name;
05791                                                                                 }
05792                                                                                 CommitTransaction();
05793                                                                         }
05794                                                                         catch (hresult_exception &e) {
05795                                                                                 AbortTransaction(e.hr);
05796                                                                         }
05797                                                                 }
05798                                                         }
05799 //                                                      AfxMessageBox(_T("Referenced model is a root model. Opening model.")); // instead show target selected
05800                                                         else // obj is not a model, referred is also not a model
05801                                                         {
05802                                                                 CGMEConsole::theInstance->Message( _T("Reference target is child of a folder, thus it is shown in the TreeBrowser only."), MSG_INFO);
05803                                                                 CGMEBrowser::theInstance->FocusItem( referred_id);//CComBSTR( mgaObjectId));//FireLocateMgaObject( (LPCTSTR) (CString) referred_id);
05804                                                                 //CGMEBrowser::theInstance->FocusItem( CComBSTR( (LPCTSTR) CString( referred_id)));
05805                                                                 CScrollZoomView::OnLButtonDblClk(nFlags, ppoint);
05806                                                                 return;
05807                                                         }
05808                                                 } else {
05809                                                         try {
05810                                                                 BeginTransaction(TRANSACTION_READ_ONLY);
05811 
05812                                                                 // Get the first aspect of the referenced element's parent model
05813                                                                 CComPtr<IMgaMetaFCO> spMetaFCO;
05814                                                                 COMTHROW(model->get_Meta(&spMetaFCO));
05815                                                                 CComQIPtr<IMgaMetaModel> spMetaModel = spMetaFCO;
05816 
05817                                                                 CComPtr<IMgaMetaAspects> spAspects;
05818                                                                 COMTHROW(spMetaModel->get_Aspects(&spAspects));
05819                                                                 ASSERT(spAspects);
05820                                                                 long nAspects = 0;
05821                                                                 COMTHROW(spAspects->get_Count(&nAspects));
05822                                                                 CComPtr<IMgaMetaAspect> spAspect;
05823                                                                 if (nAspects > 0) {
05824                                                                         COMTHROW(spAspects->get_Item(1, &spAspect));
05825                                                                 }
05826                                                                 CComBSTR nm;
05827                                                                 COMTHROW(spAspect->get_Name(&nm));
05828                                                                 aspectName = nm;
05829 
05830                                                                 CommitTransaction();
05831                                                         }
05832                                                         catch (hresult_exception &e) {
05833                                                                 AbortTransaction(e.hr);
05834                                                         }
05835                                                 }
05836                                         }
05837                                         else
05838                                         {
05839                                                 AfxMessageBox(_T("Unable to show referred object of null reference."));
05840                                                 CGMEEventLogger::LogGMEEvent(_T("    Unable to show referred object of null reference.\r\n"));
05841                                         }
05842                                 }
05843                         }
05844                         else {
05845                                 int aspi = selection->MapAspect(selection->GetParentAspect());
05846                                 if(aspi >= 0) {
05847                                         ASSERT(selection != NULL);
05848                                         CGuiCompound* comp = selection->dynamic_cast_CGuiCompound();
05849                                         VERIFY(comp);
05850                                         CGuiMetaModel* guiMetaModel = dynamic_cast<CGuiMetaModel*>(comp->guiMeta);
05851                                         VERIFY(guiMetaModel);
05852                                         CGuiMetaAspect* asp = guiMetaModel->FindAspect(aspi);
05853                                         if(asp)
05854                                                 aspectName = asp->name;
05855                                 }
05856                         }
05857                         auto guiport = selection->FindPort(point);
05858                         CComPtr<IMgaFCO> port;
05859                         if (guiport)
05860                                 port = guiport->mgaFco; // n.b. get the MgaFCO here, or double-clicking on refport fails (guiport is deleted?)
05861                         if(model != 0) {
05862                                 ShowModel(model, aspectName);
05863 #if !defined (ACTIVEXGMEVIEW)
05864                                 CGMEView *view = CGMEDoc::theInstance->FindView(model);
05865                                 if (view)
05866                                 {
05867                                         if (port)
05868                                                 view->SetCenterObject(port); // this may change the aspect. (does it matter?)
05869                                         else
05870                                                 view->SetCenterObject(referred);
05871                                 }
05872 #endif
05873                         }
05874                 }
05875                 else if (annotation) {
05876                         CGMEEventLogger::LogGMEEvent(    _T("LButton double clicked on ")+annotation->GetName()+_T("\r\n"));
05877                         CComPtr<IMgaFCO> fcoToShow;
05878                         currentModel.QueryInterface(&fcoToShow);
05879                         ShowAnnotationBrowser(fcoToShow, annotation->rootNode);
05880                 }
05881                 else {
05882 //#ifdef _DEBUG
05883 /*                      // Auto Router stress test
05884                         struct _timeb measuerementStartTime;
05885                         _ftime(&measuerementStartTime);
05886                         CString structSizeStr;
05887                         structSizeStr.Format(_T("sizeof(CAutoRouterEdge) = %ld\n"), sizeof(CAutoRouterEdge));
05888                         OutputDebugString(structSizeStr);
05889                         for (long i = 0; i < 10; i++)
05890                                 AutoRoute();
05891                         struct _timeb measuerementEndTime;
05892                         _ftime(&measuerementEndTime);
05893                         unsigned long elapsedSeconds = (unsigned long)(measuerementEndTime.time - measuerementStartTime.time);
05894                         long elapsedMilliSeconds = ((long)measuerementEndTime.millitm - measuerementStartTime.millitm);
05895                         CString elapsedTimeStr;
05896                         elapsedTimeStr.Format(_T("Ellapsed: %lu s + %d ms\n"), elapsedSeconds, elapsedMilliSeconds);
05897                         OutputDebugString(elapsedTimeStr);
05898                         Reset();*/
05899                         // XML dump test
05900 //                      HRESULT hr = DumpModelGeometryXML(_T("C:\\XMLDump.xml"));
05901 //#else
05902                         OnViewParent(); // double click on model background brings up the parent model
05903                                                         // user requested standard behavior
05904 
05905 //#endif
05906                 }
05907         }
05908         CScrollZoomView::OnLButtonDblClk(nFlags, ppoint);
05909 }
05910 
05911 void CGMEView::OnRButtonDown(UINT nFlags, CPoint point)
05912 {
05913         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnRButtonDown in ")+path+name+_T("\r\n"));
05914 
05915         CPoint trackPoint = point;
05916         CPoint ppoint = point;
05917         CoordinateTransfer(point);
05918 
05919         if(!tmpConnectMode) {
05920                 CGMEDoc *doc = GetDocument();
05921                 if(doc->GetEditMode() == GME_EDIT_MODE)
05922                 {
05923                         CGuiObject* selection = FindObject(point);
05924                         POSITION alreadySelected = 0;
05925                         if (selection) {
05926                                 CGMEEventLogger::LogGMEEvent(_T("    RButton over ")+selection->GetName()+_T(" ")+selection->GetID()+_T("\r\n")); 
05927                                 ClearConnectionSelection();
05928                                 RemoveAllAnnotationFromSelection();
05929                                 alreadySelected = selected.Find(selection);
05930                                 if(!alreadySelected)
05931                                 {
05932                                         if(!(nFlags & MK_CONTROL)) {
05933                                                 this->SendUnselEvent4List( &selected);
05934                                                 selected.RemoveAll();
05935                                         }
05936                                         this->SendSelecEvent4Object( selection);
05937                                         selected.AddHead(selection);
05938                                 }
05939                                 inDrag = true;
05940                                 CGuiObject::GetExtent(selected,dragRect);
05941                                 CPoint ptClickOffset(point.x - dragRect.left,
05942                                                                                 point.y - dragRect.top);
05943                                 CRect rectAwake = CRect(trackPoint.x,trackPoint.y,trackPoint.x + 1,trackPoint.y + 1);
05944                                 rectAwake.InflateRect(3,3);
05945                                 ClientToScreen(&dragRect);
05946                                 ClientToScreen(&rectAwake);
05947 
05948                                 CRectList rects,annRects;
05949                                 CGuiObject::GetRectList(selected,rects);
05950                                 CGuiAnnotator::GetRectList(selectedAnnotations,annRects);
05951                                 CGMEDataDescriptor desc(rects,annRects,point,ptClickOffset);
05952                                 CGMEDataDescriptor::destructList( rects);
05953                                 CGMEDataDescriptor::destructList( annRects);
05954 
05955                                 dragSource = (selected.GetCount() > 0) ? selected.GetHead() : NULL;
05956                                 validGuiObjects = true;
05957                                 DROPEFFECT dropEffect = CGMEDoc::DoDragDrop(&selected, &selectedAnnotations, &desc,
05958                                                                                                         DROPEFFECT_MOVE | DROPEFFECT_COPY | DROPEFFECT_LINK, &rectAwake,this);
05959                                 if (validGuiObjects && dropEffect == DROPEFFECT_NONE) {
05960                                         OnRButtonUp(nFlags, trackPoint);
05961                                 }
05962                                 inDrag = false;
05963                         }
05964                 }
05965         }
05966 
05967         CScrollZoomView::OnRButtonDown(nFlags, ppoint);
05968 }
05969 
05970 void CGMEView::OnRButtonUp(UINT nFlags, CPoint point)
05971 {
05972         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnRButtonUp in ")+path+name+_T("\r\n"));
05973         CPoint local = point;
05974         CPoint ppoint = point;
05975         CoordinateTransfer(local);      // DPtoLP
05976         contextMenuLocation = local;
05977 
05978         CGMEDoc* doc = GetDocument();
05979         contextPort = 0;
05980         contextSelection = FindObject(local);
05981         if (contextSelection == NULL && doc->GetEditMode() == GME_EDIT_MODE)
05982                 contextSelection = FindObject(local, false, true);
05983         CGuiObject* cgobj = NULL;
05984         if (contextSelection != NULL)
05985                 cgobj = contextSelection->dynamic_cast_CGuiObject();
05986         if (cgobj) {
05987                 CGuiPort *port = cgobj->FindPort( local);
05988                 if (port && port->IsRealPort()) {
05989                         contextPort = port;
05990                 }
05991         }
05992 
05993         if (contextSelection == 0)
05994                 contextSelection = router.FindConnection(local);
05995         if (!contextSelection) {
05996                 contextAnnotation = FindAnnotation(local);
05997         }
05998         else {
05999                 contextAnnotation = NULL;
06000         }
06001         if (contextSelection)
06002                 CGMEEventLogger::LogGMEEvent(_T("    RButton over ")+contextSelection->GetName()+_T(" ")+contextSelection->GetID()+_T("\r\n"));
06003         else if (contextAnnotation)
06004                 CGMEEventLogger::LogGMEEvent(_T("    RButton over ")+contextAnnotation->GetName()+_T("\r\n"));
06005 
06006         switch(doc->GetEditMode()) {
06007         case GME_SET_MODE:
06008                 {
06009                         CGMEEventLogger::LogGMEEvent(_T("    mode=GME_SET_MODE\r\n"));
06010                         selected.RemoveAll();
06011                         RemoveAllAnnotationFromSelection();
06012                         ClearConnectionSelection();
06013                         CGuiSet* set = NULL;
06014                         if (contextSelection)
06015                                 set = contextSelection->dynamic_cast_CGuiSet();
06016                         if(set) {
06017                                 if(set == currentSet)
06018                                         currentSet = 0;
06019                                 else {
06020                                         currentSet = set;
06021                                         selected.AddHead(set);
06022                                         ChangeAttrPrefFco(set);
06023                                 }
06024                         }
06025                         else
06026                                 currentSet = 0;
06027                         if(currentSet) {
06028                                 CGuiAnnotator::GrayOutAnnotations(annotators,true);
06029                                 CGuiFco::GrayOutFcos(children,true);
06030                                 CGuiFco::GrayOutFcos(connections,true);
06031                                 currentSet->GrayOutMembers(false);
06032                                 currentSet->GrayOut(false);
06033                         }
06034                         else {
06035                                 CGuiAnnotator::GrayOutAnnotations(annotators,false);
06036                                 CGuiFco::GrayOutFcos(children,false);
06037                                 CGuiFco::GrayOutFcos(connections,false);
06038                         }
06039                         Invalidate();
06040                         DoPannWinRefresh();
06041                 }
06042                 break;
06043         case GME_ZOOM_MODE:
06044                 {
06045                         CGMEEventLogger::LogGMEEvent(_T("    mode=GME_ZOOM_MODE\r\n"));
06046                         ZoomOut(ppoint);
06047                         Invalidate();
06048                 }
06049                 break;
06050         case GME_VISUAL_MODE:
06051                 {
06052                         CGMEEventLogger::LogGMEEvent(_T("    mode=GME_VISUAL_MODE\r\n"));
06053                         CGuiObject* obj = NULL;
06054                         if (contextSelection)
06055                                 obj = contextSelection->dynamic_cast_CGuiObject();
06056                         if(obj) {
06057                                 obj->ToggleGrayOut();
06058                                 obj->GrayOutNeighbors();
06059                                 CGuiFco::GrayOutNonInternalConnections(connections);
06060                                 Invalidate();
06061                         }
06062                         else {
06063                                 CGuiConnection* conn = NULL;
06064                                 if (contextSelection)
06065                                         conn = contextSelection->dynamic_cast_CGuiConnection();
06066                                 if (conn) {
06067                                         conn->ToggleGrayOut();
06068                                         conn->GrayOutEndPoints();
06069                                         CGuiFco::GrayOutNonInternalConnections(connections);
06070                                         Invalidate();
06071                                 }
06072                         }
06073                         if (contextAnnotation) {
06074                                 contextAnnotation->ToggleGrayOut();
06075                                 Invalidate();
06076                         }
06077                 }
06078                 break;
06079         case GME_EDIT_MODE:
06080                 {
06081                         CGMEEventLogger::LogGMEEvent(_T("    mode=GME_EDIT_MODE\r\n"));
06082                         CPoint global = point;
06083                         ClientToScreen(&global);
06084 
06085                         // new selection logic 8/2/00
06086                         CGuiObject* selection = FindObject(local);
06087                         if (selection == NULL)  // select with label
06088                                 selection = FindObject(local, false, true);
06089 
06090                         {
06091                                 CGuiAnnotator *annotation = selection ? NULL : FindAnnotation(local);
06092 
06093                                 POSITION alreadySelected = 0;
06094                                 if(selection != 0) {
06095                                         alreadySelected = selected.Find(selection);
06096                                         if(!(nFlags & MK_CONTROL)) {
06097                                                 this->SendUnselEvent4List( &selected);
06098                                                 selected.RemoveAll();
06099                                                 RemoveAllAnnotationFromSelection();
06100                                                 ClearConnectionSelection();
06101                                         }
06102                                         else if(alreadySelected) {
06103                                                 this->SendUnselEvent4Object( selected.GetAt( alreadySelected));
06104                                                 selected.RemoveAt(alreadySelected);
06105                                         }
06106                                         this->SendSelecEvent4Object( selection);
06107                                         selected.AddHead(selection);
06108                                         ChangeAttrPrefObjs(selected);
06109                                 } else {
06110                                         if (annotation != 0) {
06111                                                 alreadySelected = selectedAnnotations.Find(annotation);
06112                                                 if (!(nFlags & MK_CONTROL)) {
06113                                                         this->SendUnselEvent4List( &selected);
06114                                                         selected.RemoveAll();
06115                                                         RemoveAllAnnotationFromSelection();
06116                                                 } else if (alreadySelected) {
06117                                                         RemoveAnnotationFromSelection(alreadySelected);
06118                                                 }
06119                                                 AddAnnotationToSelectionHead(annotation);
06120                                                 // ANNTODO: ChangeAttrPref....
06121                                         }
06122                                 }
06123 
06124                                 Invalidate();
06125                         }
06126 
06127                         if (contextPort != NULL) {
06128                                 CString itemname = CString( _T("[")) + (contextSelection?(contextSelection->GetInfoText() + CString(_T(" : "))): CString(_T(""))) + contextPort->GetInfoText() + CString( _T("]"));
06129 
06130                                 CMenu menu;
06131                                 menu.LoadMenu(IDR_PORTCONTEXT_MENU);
06132 
06133                                 CMenu *sm = menu.GetSubMenu(0); ASSERT( sm);
06134                                 if( sm) {
06135                                         sm->InsertMenu( 0, MF_BYPOSITION|MF_SEPARATOR); 
06136                                         sm->InsertMenu( 0, MF_BYPOSITION|MFS_DEFAULT, ID_CNTX_SHOWPORTINPARENT, itemname);
06137                                         sm->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, global.x,global.y,GetParent());
06138                                 }
06139                         } else if (contextSelection != NULL) {
06140                                 selectedContextConnection = contextSelection->dynamic_cast_CGuiConnection();
06141                                 if (selectedContextConnection) {
06142                                         bool isPartFixed = false;
06143                                         contextConnectionEdgeIndex = selectedContextConnection->IsPathAt(local,
06144                                                 contextConnectionPartMoveMethod, customizeHorizontalOrVerticalEdge, isPartFixed);
06145                                         contextConnectionCustomizationType = selectedContextConnection->IsAutoRouted() ? SimpleEdgeDisplacement : CustomPointCustomization;
06146                                 }
06147 
06148                                 HMENU decoratorAdditionalMenu = ::CreatePopupMenu();
06149                                 if (selection != NULL) {
06150                                         CGuiAspect* pAspect = selection->GetCurrentAspect();
06151                                         if (pAspect != NULL) {
06152                                                 CComQIPtr<IMgaElementDecorator> newDecorator(pAspect->GetDecorator());
06153                                                 HRESULT retVal = S_OK;
06154                                                 if (newDecorator) {
06155                                                         CClientDC transformDC(this);
06156                                                         OnPrepareDC(&transformDC);
06157                                                         retVal = newDecorator->MouseRightButtonDown((ULONGLONG)decoratorAdditionalMenu, nFlags, local.x, local.y, (ULONGLONG)transformDC.m_hDC);
06158                                                 }
06159                                         }
06160                                 }
06161                                 CMenu menu;
06162                                 menu.LoadMenu(selectedContextConnection != NULL ? IDR_CONNCONTEXT_MENU : IDR_CONTEXT_MENU);
06163                                 CMenu* subMenu = menu.GetSubMenu(0);
06164                                 if (::GetMenuItemCount(decoratorAdditionalMenu) > 0) {
06165                                         subMenu->InsertMenu(0, MF_BYPOSITION | MF_SEPARATOR, 0, _T(""));
06166                                         subMenu->InsertMenu(0, MF_BYPOSITION | MF_POPUP | MF_ENABLED, (UINT_PTR)(decoratorAdditionalMenu), _T("Decorator Edit"));
06167                                 }
06168                                 UINT cmdId = (UINT)subMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
06169                                                                                                                         global.x,global.y,GetParent());
06170                                 // Save state for possible later use, see OnCmdMsg
06171                                 ctxClkSt.nFlags = nFlags;
06172                                 ctxClkSt.lpoint = local;
06173                                 ctxClkSt.dpoint = ppoint;
06174                                 selectedObjectOfContext = selection;
06175                                 selectedAnnotationOfContext = NULL;
06176                                 ::DestroyMenu(decoratorAdditionalMenu);
06177                         } else if (contextAnnotation != NULL) {
06178                                 HMENU decoratorAdditionalMenu = ::CreatePopupMenu();
06179                                 CComPtr<IMgaElementDecorator> decorator = contextAnnotation->GetDecorator(currentAspect->index);
06180                                 HRESULT retVal = S_OK;
06181                                 if (decorator) {
06182                                         CClientDC transformDC(this);
06183                                         OnPrepareDC(&transformDC);
06184                                         retVal = decorator->MouseRightButtonDown((ULONGLONG)decoratorAdditionalMenu, nFlags, local.x, local.y, (ULONGLONG)transformDC.m_hDC);
06185                                 }
06186                                 CMenu menu;
06187                                 menu.LoadMenu(IDR_ANNCONTEXT_MENU);
06188                                 CMenu* subMenu = menu.GetSubMenu(0);
06189                                 if (::GetMenuItemCount(decoratorAdditionalMenu) > 0) {
06190                                         subMenu->InsertMenu(0, MF_BYPOSITION | MF_SEPARATOR, 0, _T(""));
06191                                         subMenu->InsertMenu(0, MF_BYPOSITION | MF_POPUP | MF_ENABLED, (UINT_PTR)(decoratorAdditionalMenu), _T("Decorator Edit"));
06192                                 }
06193                                 UINT cmdId = (UINT)subMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
06194                                                                                                                         global.x,global.y,GetParent());
06195                                 // Save state for possible later use, see OnCmdMsg
06196                                 ctxClkSt.nFlags = nFlags;
06197                                 ctxClkSt.lpoint = local;
06198                                 ctxClkSt.dpoint = ppoint;
06199                                 selectedAnnotationOfContext = contextAnnotation;
06200                                 selectedObjectOfContext = NULL;
06201                                 ::DestroyMenu(decoratorAdditionalMenu);
06202                         } else {
06203                                 CMenu menu;
06204                                 menu.LoadMenu(IDR_SELFCONTEXT_MENU);
06205                                 CMenu *submenu = menu.GetSubMenu(0);
06206                                 currentAspect->InitContextMenu(submenu);
06207 #if defined(ADDCRASHTESTMENU)
06208                                 CMenu crashTestMenu;
06209                                 crashTestMenu.LoadMenu(IDR_CRASH_TEST_MENU);
06210                                 submenu->AppendMenu(MF_POPUP, (UINT_PTR)((HMENU)crashTestMenu), _T("Debug"));
06211 #endif
06212                                 submenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
06213                                                                                                 global.x,global.y,GetParent());
06214                                 currentAspect->ResetContextMenu(submenu);
06215                         }
06216                 }
06217                 break;
06218 
06219         case GME_AUTOCONNECT_MODE:
06220         case GME_SHORTAUTOCONNECT_MODE:
06221                 CGMEEventLogger::LogGMEEvent(_T("    mode=GME_AUTOCONNECT_MODE\r\n"));
06222         case GME_DISCONNECT_MODE:
06223         case GME_SHORTDISCONNECT_MODE:
06224                 {
06225                         CGMEEventLogger::LogGMEEvent(_T("    mode=GME_DISCONNECT_MODE\r\n"));
06226                         CPoint global = point;
06227                         ClientToScreen(&global);
06228                         if (contextSelection) {
06229                                 CMenu menu;
06230                                 menu.LoadMenu(contextSelection->dynamic_cast_CGuiConnection() ? IDR_CONNCONTEXT_MENU : IDR_CONTEXT_MENU);
06231                                 menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
06232                                                                                                         global.x,global.y,GetParent());
06233                         }
06234                         else if (contextAnnotation) {
06235                                 CMenu menu;
06236                                 menu.LoadMenu(IDR_ANNCONTEXT_MENU);
06237                                 menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
06238                                                                                                         global.x,global.y,GetParent());
06239                         }
06240                         else {
06241                                 CMenu menu;
06242                                 menu.LoadMenu(IDR_SELFCONTEXT_MENU);
06243                                 CMenu *submenu = menu.GetSubMenu(0);
06244                                 currentAspect->InitContextMenu(submenu);
06245                                 submenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
06246                                                                                                 global.x,global.y,GetParent());
06247                                 currentAspect->ResetContextMenu(submenu);
06248                         }
06249                 }
06250                 break;
06251         }
06252         CScrollZoomView::OnRButtonUp(nFlags, ppoint);
06253         this->SendNow();
06254 }
06255 
06256 BOOL CGMEView::OnMouseWheel(UINT fFlags, short zDelta, CPoint point)
06257 {
06258         // handle zoom in/out
06259         if (fFlags & MK_CONTROL) {
06260                 UINT uWheelScrollLines = GetMouseScrollLines();
06261                 int nToScroll = ::MulDiv(zDelta, uWheelScrollLines, WHEEL_DELTA);
06262 
06263                 int scale = m_zoomVal;
06264                 float zoom = pow((float)1 + (float)abs(nToScroll)/8, nToScroll > 0 ? 1 : -1);
06265                 int newScale = scale * zoom; // + 0.49999997f;
06266                 newScale = max(ZOOM_MIN, min(ZOOM_MAX, newScale));
06267                 if (abs((float)newScale - 100) < 8) // TODO: implement fixup for more values?
06268                 {
06269                         newScale = 100;
06270                         zoom = (float) newScale / scale;
06271                 }
06272                 if (scale != newScale)
06273                 {
06274                         // goal: zoom in and move scrollbars such that the mouse is over the same spot in the grid (logical coords)
06275                         //  (sometimes this cannot be acheived due to scrollbar limits, especially at low zooms)
06276                         this->ScreenToClient(&point);
06277                         CPoint scp = GetScrollPosition(); // upper corner of scrolling (logical coords)
06278 
06279                         CPoint scaledPoint = point;
06280                         //  scaledPoint /= scale / 100.0f;
06281                         scaledPoint.x = ::MulDiv(scaledPoint.x, 100, scale);
06282                         scaledPoint.y = ::MulDiv(scaledPoint.y, 100, scale);
06283                         // now scp + scaledPoint == mouse coords (logical). Translate using new zoom back to mouse coords
06284                         //  scaledPoint -= point / (zoom * (scale / 100.0f));
06285                         scaledPoint.x -= ::MulDiv(point.x, 100, newScale);
06286                         scaledPoint.y -= ::MulDiv(point.y, 100, newScale);
06287 
06288                         SetRedraw(FALSE); // Reduce flicker: OnZoom sets scrollbar position, and Windows redraws it before we can ScrollToPosition
06289                         OnZoom(0, newScale);
06290                         ScrollToPosition(scp + scaledPoint);
06291 
06292                         frame->propBar.SetZoomVal(m_zoomVal);
06293                         CMainFrame::theInstance->WriteStatusZoom(m_zoomVal);
06294 
06295                         SetRedraw(TRUE);
06296                         Invalidate();
06297                 }
06298                 return TRUE;
06299         }
06300 
06301         return CScrollZoomView::OnMouseWheel(fFlags, zDelta, point);
06302 }
06303 
06304 void CGMEView::OnAppCommand(CWnd* pWnd, UINT nCmd, UINT nDevice, UINT nKey)
06305 {
06306         bool handled = true;
06307         switch (nCmd) {
06308                 case APPCOMMAND_BROWSER_BACKWARD:
06309                         {
06310                                 CGMEDoc* pDoc = GetDocument();
06311                                 ASSERT_VALID(pDoc);
06312                                 pDoc->back();
06313                         }
06314                         break;
06315                 case APPCOMMAND_BROWSER_FORWARD:
06316                         {
06317                                 CGMEDoc* pDoc = GetDocument();
06318                                 ASSERT_VALID(pDoc);
06319                                 pDoc->forw();
06320                         }
06321                         break;
06322                 case APPCOMMAND_BROWSER_HOME:
06323                         {
06324                                 CGMEDoc* pDoc = GetDocument();
06325                                 ASSERT_VALID(pDoc);
06326                                 pDoc->home();
06327                         }
06328                         break;
06329                 case APPCOMMAND_BROWSER_REFRESH:
06330                         {
06331                                 CGMEDoc* pDoc = GetDocument();
06332                                 ASSERT_VALID(pDoc);
06333                                 pDoc->DoOnViewRefresh();
06334                         }
06335                         break;
06336                 case APPCOMMAND_BROWSER_SEARCH:
06337                         {
06338                                 if (CMainFrame::theInstance != NULL)
06339                                         CMainFrame::theInstance->ShowFindDlg();
06340                         }
06341                         break;
06342                 default:
06343                         handled = false;
06344                         break;
06345         }
06346         if (!handled)
06347                 CScrollZoomView::OnAppCommand(pWnd, nCmd, nDevice, nKey);
06348 }
06349 
06350 DROPEFFECT CGMEView::OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
06351 {
06352         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDragEnter in ")+path+name+_T("\r\n"));
06353         ASSERT(prevDropEffect == DROPEFFECT_NONE);
06354 
06355         m_dropRightClick = GetKeyState(VK_RBUTTON) & 0x8000;
06356 
06357         if(isType && CGMEDataSource::IsGmeNativeDataAvailable(pDataObject,theApp.mgaProject)) {
06358 //      if(pDataObject->IsDataAvailable(CGMEDataSource::cfGMEDesc)) {
06359 
06360                 if(dragDesc.Load(pDataObject)) {
06361                         dragOffset = dragDesc.offset;
06362                         dragPoint = point - CSize(1,1);
06363                         return OnDragOver(pDataObject,dwKeyState,point);
06364                 }
06365         }
06366         else if( isType && CGMEDataSource::IsXMLDataAvailable(pDataObject) )
06367                 return DROPEFFECT_COPY;
06368 
06369         CoordinateTransfer(point);
06370         DROPEFFECT dropEffect = DROPEFFECT_NONE;
06371         HRESULT retVal = S_OK;
06372         CGuiObject* selection = FindObject(point);
06373         if (selection != NULL) {
06374                 CGuiAspect* pAspect = selection->GetCurrentAspect();
06375                 if (pAspect != NULL) {
06376                         CComQIPtr<IMgaElementDecorator> newDecorator(pAspect->GetDecorator());
06377                         if (newDecorator) {
06378                                 CClientDC transformDC(this);
06379                                 OnPrepareDC(&transformDC);
06380                                 retVal = newDecorator->DragEnter(&dropEffect, (ULONGLONG)pDataObject, dwKeyState, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
06381                         }
06382                 }
06383         }
06384         if (dropEffect != DROPEFFECT_NONE) {
06385                 dragPoint = point;
06386                 return dropEffect;
06387         }
06388 
06389         CGuiAnnotator* annotation = FindAnnotation(point);
06390         if (annotation != NULL) {
06391                 CComPtr<IMgaElementDecorator> decorator = annotation->GetDecorator(currentAspect->index);
06392                 if (decorator) {
06393                         CClientDC transformDC(this);
06394                         OnPrepareDC(&transformDC);
06395                         retVal = decorator->DragEnter(&dropEffect, (ULONGLONG)pDataObject, dwKeyState, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
06396                 }
06397         }
06398         if (dropEffect != DROPEFFECT_NONE) {
06399                 dragPoint = point;
06400                 return dropEffect;
06401         }
06402 
06403         return DROPEFFECT_NONE;
06404 }
06405 
06406 void CGMEView::OnDragLeave()
06407 {
06408         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDragLeave from ")+path+name+_T("\r\n"));
06409         CClientDC dc(this);
06410         OnPrepareDC(&dc);
06411         if(prevDropEffect != DROPEFFECT_NONE) {
06412                 dragDesc.Draw(&dc,dragPoint);
06413                 prevDropEffect = DROPEFFECT_NONE;
06414         }
06415         dragDesc.Clean();
06416 }
06417 
06418 DROPEFFECT CGMEView::OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point)
06419 {
06420         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDragOver in ")+path+name+_T("\r\n"));
06421 
06422         //this event happens too much, logfile size could explode...
06423         if(!CGMEDataSource::IsGmeNativeDataAvailable(pDataObject,theApp.mgaProject))
06424 //      if(!pDataObject->IsDataAvailable(CGMEDataSource::cfGMEDesc))
06425         {
06426                 if(isType && CGMEDataSource::IsXMLDataAvailable(pDataObject))
06427                         return DROPEFFECT_COPY;
06428 
06429                 return DROPEFFECT_NONE;
06430         }
06431 
06432         CoordinateTransfer(point);
06433         CGuiObject *obj = FindObject(point);
06434         HRESULT retVal = S_OK;
06435         DROPEFFECT dropEffect = DROPEFFECT_NONE;
06436         if(obj) {
06437                 CGMEEventLogger::LogGMEEvent(_T("    Dragging over: ")+obj->GetName()+_T(" ")+obj->GetID()+_T(" in ")+path+name+_T("\r\n"));//better this way, not logging dragging over empty space
06438 
06439                 CGuiAspect* pAspect = obj->GetCurrentAspect();
06440                 if (pAspect != NULL) {
06441                         CComQIPtr<IMgaElementDecorator> newDecorator(pAspect->GetDecorator());
06442                         if (newDecorator) {
06443                                 CClientDC transformDC(this);
06444                                 OnPrepareDC(&transformDC);
06445                                 retVal = newDecorator->DragOver(&dropEffect, (ULONGLONG)pDataObject, dwKeyState, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
06446                         }
06447                 }
06448                 if (dropEffect != DROPEFFECT_NONE)
06449                         return dropEffect;
06450         }
06451 
06452         CGuiAnnotator* annotation = FindAnnotation(point);
06453         if (annotation != NULL) {
06454                 CComPtr<IMgaElementDecorator> decorator = annotation->GetDecorator(currentAspect->index);
06455                 if (decorator) {
06456                         CClientDC transformDC(this);
06457                         OnPrepareDC(&transformDC);
06458                         retVal = decorator->DragOver(&dropEffect, (ULONGLONG)pDataObject, dwKeyState, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
06459                 }
06460         }
06461         if (dropEffect != DROPEFFECT_NONE)
06462                 return dropEffect;
06463 
06464         CGuiObject* ref = NULL;
06465         if (obj)
06466                 ref = obj->dynamic_cast_CGuiReference();
06467         if (obj && !ref)
06468                 ref = obj->dynamic_cast_CGuiCompoundReference();
06469 
06470         if (ref && obj != dragSource && dragDesc.GetCount() <= 1)
06471                 return DROPEFFECT_LINK;
06472         else if(!isType)
06473                 return DROPEFFECT_NONE;
06474 
06475         DROPEFFECT de = DROPEFFECT_MOVE;
06476         if((dwKeyState & MK_CONTROL) != 0)
06477                 de = (((dwKeyState & MK_SHIFT) == 0) ? DROPEFFECT_COPY : DROPEFFECT_LINK);
06478 
06479         if((dwKeyState & MK_ALT) != 0) {
06480                 de = DROPEFFECT_COPY | DROPEFFECT_LINK;
06481                 derivedDrop = true;
06482                 instanceDrop = ((dwKeyState & MK_SHIFT) == 0);
06483         }
06484         else {
06485                 derivedDrop = false;
06486                 instanceDrop = false;
06487         }
06488 
06489         if(point == dragPoint)
06490                 return de;
06491 
06492         CClientDC dc(this);
06493         OnPrepareDC(&dc);
06494         if(prevDropEffect != DROPEFFECT_NONE) {
06495                 dragDesc.Draw(&dc,dragPoint);
06496         }
06497         prevDropEffect = de;
06498         if(prevDropEffect != DROPEFFECT_NONE) {
06499                 dragPoint = point;
06500                 dragDesc.Draw(&dc,point);
06501         }
06502         return de;
06503 }
06504 
06505 BOOL CGMEView::OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point)
06506 {
06507         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDrop in ")+path+name+_T("\r\n"));
06508         if(dropEffect & DROPEFFECT_MOVE)
06509                 CGMEEventLogger::LogGMEEvent(_T("    DROPEFFECT_MOVE\r\n"));
06510         if(dropEffect & DROPEFFECT_LINK)
06511                 CGMEEventLogger::LogGMEEvent(_T("    DROPEFFECT_LINK\r\n"));
06512         if(dropEffect & DROPEFFECT_COPY)
06513                 CGMEEventLogger::LogGMEEvent(_T("    DROPEFFECT_COPY\r\n"));
06514         if(dropEffect == DROPEFFECT_NONE) //DROPEFFECT_NONE==0
06515                 CGMEEventLogger::LogGMEEvent(_T("    DROPEFFECT_NONE\r\n"));
06516         ASSERT_VALID(this);
06517         CGMEDoc* pDoc = GetDocument();
06518         ASSERT_VALID(pDoc);
06519         CSize size;
06520         CPoint orig = point;
06521         CPoint testPoint = point;
06522 
06523         CPoint screen = point;
06524         ClientToScreen(&screen);
06525 
06526         CoordinateTransfer(point);
06527         CoordinateTransfer(testPoint);
06528 
06529         point.x = (long)(point.x - dragOffset.x);
06530         point.y = (long)(point.y - dragOffset.y);
06531 
06532         OnDragLeave();
06533         if (m_dropRightClick)
06534         {
06535                 CMenu menu;
06536                 if (menu.CreatePopupMenu())
06537                 {
06538                         enum actions { MOVE= 1000, COPY, REF, INSTANCE, SUBTYPE, CANCEL };
06539                         menu.AppendMenu(MF_STRING, MOVE, L"Move");
06540                         menu.AppendMenu(MF_STRING, COPY, L"Copy");
06541                         menu.AppendMenu(MF_STRING, REF, L"Create reference");
06542                         menu.AppendMenu(MF_STRING, SUBTYPE, L"Create subtype");
06543                         menu.AppendMenu(MF_STRING, INSTANCE, L"Create instance");
06544                         menu.AppendMenu(MF_STRING, CANCEL, L"Cancel");
06545 
06546                         UINT nItemID = menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD, screen.x, screen.y, this);
06547 
06548                         switch (nItemID)
06549                         {
06550                         case MOVE:
06551                                 DoPasteItem(pDataObject, true, true, false, false, false, false, false, 0, point);
06552                                 break;
06553                         case COPY:
06554                                 DoPasteItem(pDataObject, true, false, false, false, false, false, false, 0, point);
06555                                 break;
06556                         case REF:
06557                                 DoPasteItem(pDataObject, true, false, true, false, false, false, false, 0, point);
06558                                 break;
06559                         case SUBTYPE:
06560                                 DoPasteItem(pDataObject, true, false, false, true, false, false, false, 0, point);
06561                                 break;
06562                         case INSTANCE:
06563                                 DoPasteItem(pDataObject, true, false, false, true, true, false, false, 0, point);
06564                                 break;
06565                         }
06566                 }
06567                 return TRUE;
06568         }
06569 
06570         if(isType) {
06571                 if ((dropEffect & DROPEFFECT_MOVE) && inDrag)
06572                 {
06573                         ASSERT((selected.GetCount() + selectedAnnotations.GetCount()) > 0);
06574                         CGMEEventLogger::LogGMEEvent(_T("    Dropping:\r\n"));
06575                         GMEEVENTLOG_GUIOBJS(selected);
06576                         GMEEVENTLOG_GUIANNOTATORS(selectedAnnotations);
06577                         Invalidate();
06578 
06579                         try {
06580                                 BeginTransaction();
06581                                 int left = 0, top = 0, leftA = 0, topA = 0;
06582                                 bool valid = false, validA = false;
06583                                 if (selected.GetCount() > 0) {
06584                                         CGuiObject::FindUpperLeft(selected, left, top);
06585                                         valid = true;
06586                                 }
06587                                 if (selectedAnnotations.GetCount() > 0) {
06588                                         CGuiAnnotator::FindUpperLeft(selectedAnnotations, leftA, topA);
06589                                         validA = true;
06590                                 }
06591                                 if (valid && validA) {
06592                                         left = min(left, leftA);
06593                                         top = min(top, topA);
06594                                 }
06595                                 else if (validA) {
06596                                         left = leftA;
06597                                         top = topA;
06598                                 }
06599                                 else if (!valid) {
06600                                         ASSERT(("There is no object to move",false));
06601                                 }
06602                                 CPoint diff = point - CPoint(left,top);
06603                                 CGuiObject::ShiftModels(selected, diff);
06604                                 CGuiAnnotator::ShiftAnnotations(selectedAnnotations,diff);
06605                                 ResetParent();
06606                                 __CommitTransaction();
06607                         }
06608                         catch(hresult_exception e) {                
06609                                 AbortTransaction(e.hr);
06610                                 CGMEEventLogger::LogGMEEvent(_T("    Unable to complete drop operation.\r\n"));
06611                                 AfxMessageBox(_T("Unable to complete drop operation"),MB_ICONSTOP | MB_OK);
06612                                 Reset(true);
06613                                 return FALSE;
06614                         }
06615                         catch(_com_error& e) {                
06616                                 AbortTransaction(e.Error());
06617                                 CString error = _T("Unable to complete drop operation");
06618                                 if (e.Description().length() != 0)
06619                                 {
06620                                         error += _T(": ");
06621                                         error += static_cast<const TCHAR*>(e.Description());
06622                                 }
06623                                 CGMEEventLogger::LogGMEEvent(error + _T("\r\n"));
06624                                 AfxMessageBox(error,MB_ICONSTOP | MB_OK);
06625                                 Reset(true);
06626                                 return FALSE;
06627                         }
06628                         AutoRoute(); // HACK reroute the whole thing for now!
06629                         Invalidate(true);
06630                         inDrag = false;
06631                         return TRUE;
06632                 }
06633         }
06634         CGuiObject *target = FindObject(testPoint);
06635         HRESULT retVal = S_OK;
06636         if (target != NULL) {
06637                 CGuiAspect* pAspect = target->GetCurrentAspect();
06638                 if (pAspect != NULL) {
06639                         CComQIPtr<IMgaElementDecorator> newDecorator(pAspect->GetDecorator());
06640                         if (newDecorator) {
06641                                 CClientDC transformDC(this);
06642                                 OnPrepareDC(&transformDC);
06643                                 retVal = newDecorator->Drop((ULONGLONG)pDataObject, dropEffect, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
06644                         }
06645                 }
06646         }
06647         if (retVal == S_DECORATOR_EVENT_HANDLED)
06648                 return TRUE;
06649 
06650         CGuiAnnotator* annotation = FindAnnotation(point);
06651         if (annotation != NULL) {
06652                 CComPtr<IMgaElementDecorator> decorator = annotation->GetDecorator(currentAspect->index);
06653                 if (decorator) {
06654                         CClientDC transformDC(this);
06655                         OnPrepareDC(&transformDC);
06656                         retVal = decorator->Drop((ULONGLONG)pDataObject, dropEffect, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
06657                 }
06658         }
06659         if (retVal == S_DECORATOR_EVENT_HANDLED)
06660                 return TRUE;
06661 
06662         CGuiReference* guiRef = NULL;
06663         CGuiCompoundReference* compRef = NULL;
06664         if (target != NULL) {
06665                 guiRef = target->dynamic_cast_CGuiReference();
06666                 compRef = target->dynamic_cast_CGuiCompoundReference();
06667         }
06668         bool sameTarget = (target == dragSource);
06669         if(isType || guiRef || compRef) {
06670                 DoPasteItem(pDataObject,
06671                                         true,
06672                                         ((dropEffect & DROPEFFECT_MOVE) != 0) && !(guiRef || compRef),
06673                                         (dropEffect & DROPEFFECT_LINK) != 0 || guiRef || compRef,
06674                                         derivedDrop,
06675                                         instanceDrop,
06676                                         false,
06677                                         false,
06678                                         ((guiRef || compRef) && !sameTarget) ? target : 0,
06679                                         point);
06680                 derivedDrop = instanceDrop = false;
06681 //              GetDocument()->InvalidateAllViews(true);
06682                 return TRUE;
06683         }
06684         CGMEEventLogger::LogGMEEvent(_T("    Nothing Dropped\r\n"));
06685         return FALSE;
06686 }
06687 
06688 void CGMEView::OnViewParent()
06689 {
06690         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnViewParent from ")+path+name+_T("\r\n"));
06691         ShowModel(parent);
06692 }
06693 
06694 void CGMEView::OnUpdateViewParent(CCmdUI* pCmdUI)
06695 {
06696         pCmdUI->Enable(parent != 0);
06697 }
06698 
06699 void CGMEView::ShowGrid(bool show)
06700 {
06701         drawGrid = show;
06702         Invalidate();
06703 }
06704 
06705 void CGMEView::OnViewGrid()
06706 {
06707         drawGrid = !drawGrid;
06708         Invalidate();
06709 }
06710 
06711 void CGMEView::OnUpdateViewGrid(CCmdUI* pCmdUI)
06712 {
06713 //      pCmdUI->Enable(zoomIdx >= GME_ZOOM_LEVEL_MED);
06714         pCmdUI->Enable(m_zoomVal >= ZOOM_NO);
06715         pCmdUI->SetCheck(drawGrid);
06716 }
06717 
06718 void CGMEView::OnEditNudgedown()
06719 {
06720         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditNudgedown in ")+path+name+_T("\r\n"));
06721 
06722         try {
06723                 BeginTransaction();
06724                 CGuiAnnotator::NudgeAnnotations(selectedAnnotations, 0, 1);
06725                 if(isType && CGuiObject::NudgeObjects(selected, 0, 1))
06726                         router.NudgeObjects(selected, 0, 1, currentAspect->index);
06727                 Invalidate();
06728 
06729                 CommitTransaction();
06730         }
06731         catch(hresult_exception e) {
06732                 AbortTransaction(e.hr);
06733                 AfxMessageBox(_T("Unable to nudge objects"),MB_ICONSTOP | MB_OK);
06734                 CGMEEventLogger::LogGMEEvent(_T("    Unable to nudge objects.\r\n"));
06735                 return;
06736         }
06737         ResetParent();
06738 //  Workaround fixes sticky objects
06739         Invalidate(true);
06740 }
06741 
06742 void CGMEView::OnEditNudgeleft()
06743 {
06744         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditNudgeleft in ")+path+name+_T("\r\n"));
06745 
06746         try {
06747                 BeginTransaction();
06748                 CGuiAnnotator::NudgeAnnotations(selectedAnnotations, -1, 0);
06749                 if(isType && CGuiObject::NudgeObjects(selected, -1, 0))
06750                         router.NudgeObjects(selected, -1, 0, currentAspect->index);
06751                 Invalidate();
06752                 CommitTransaction();
06753         }
06754         catch(hresult_exception e) {
06755                 AbortTransaction(e.hr);
06756                 AfxMessageBox(_T("Unable to nudge objects"),MB_ICONSTOP | MB_OK);
06757                 CGMEEventLogger::LogGMEEvent(_T("    Unable to nudge objects.\r\n"));
06758                 return;
06759         }
06760         ResetParent();
06761 //  Workaround fixes sticky objects
06762         Invalidate(true);
06763 }
06764 
06765 void CGMEView::OnEditNudgeright()
06766 {
06767         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditNudgeright in ")+path+name+_T("\r\n"));
06768 
06769         try {
06770                 BeginTransaction();
06771                 CGuiAnnotator::NudgeAnnotations(selectedAnnotations, 1, 0);
06772                 if(isType && CGuiObject::NudgeObjects(selected, 1, 0))
06773                         router.NudgeObjects(selected, 1, 0, currentAspect->index);
06774                 Invalidate();
06775                 CommitTransaction();
06776         }
06777         catch(hresult_exception e) {
06778                 AbortTransaction(e.hr);
06779                 AfxMessageBox(_T("Unable to nudge objects"),MB_ICONSTOP | MB_OK);
06780                 CGMEEventLogger::LogGMEEvent(_T("    Unable to nudge objects.\r\n"));
06781                 return;
06782         }
06783         ResetParent();
06784 //  Workaround fixes sticky objects
06785         Invalidate(true);
06786 }
06787 
06788 void CGMEView::OnEditNudgeup()
06789 {
06790         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditNudgeup in ")+path+name+_T("\r\n"));
06791 
06792         try {
06793                 BeginTransaction();
06794                 CGuiAnnotator::NudgeAnnotations(selectedAnnotations, 0, -1);
06795                 if(isType && CGuiObject::NudgeObjects(selected, 0, -1))
06796                         router.NudgeObjects(selected, 0, -1, currentAspect->index);
06797                 Invalidate();
06798                 CommitTransaction();
06799         }
06800         catch(hresult_exception e) {
06801                 AbortTransaction(e.hr);
06802                 AfxMessageBox(_T("Unable to nudge objects"),MB_ICONSTOP | MB_OK);
06803                 CGMEEventLogger::LogGMEEvent(_T("    Unable to nudge objects.\r\n"));
06804                 return;
06805         }
06806         ResetParent();
06807 //  Workaround fixes sticky objects
06808         Invalidate(true);
06809 }
06810 
06811 BOOL CGMEView::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
06812 {
06813         if (nID == ID_EDIT_CANCEL) {    // capture ESC for decorator or connection customization operation cancel
06814                 if (IsInElementDecoratorOperation())
06815                         CancelDecoratorOperation();
06816                 if (isInConnectionCustomizeOperation) {
06817                         isInConnectionCustomizeOperation = false;
06818                         ::SetCursor(customizeConnectionCursorBackup);
06819                         isCursorChangedByEdgeCustomize = false;
06820                 }
06821                 if (tmpConnectMode) {
06822                         tmpConnectMode = false;
06823                         ClearConnSpecs();
06824                         SetCursor(editCursor);
06825                         ShowCursor(TRUE);
06826                         Invalidate();
06827                 }
06828         }
06829 
06830         if(CGuiMetaProject::theInstance->CmdIDInRange(nID))     {
06831                 if(nCode == CN_COMMAND && pHandlerInfo == NULL) {
06832                         CString label;
06833                         switch (CGuiMetaProject::theInstance->CmdType(nID, label)) {
06834                         case GME_CMD_CONTEXT:
06835                                 if (isType && currentAspect->FindCommand(nID, label))
06836                                         InsertNewPart(label, contextMenuLocation);
06837                                 break;
06838                         default:
06839                                 ASSERT(FALSE);
06840                                 break;
06841                         }
06842                         return true;
06843                 }
06844                 else if(nCode == CN_UPDATE_COMMAND_UI && pExtra != NULL) {
06845                         CCmdUI *pUI = (CCmdUI *)pExtra;
06846                         pUI->Enable(isType);
06847                         return true;
06848                 }
06849         } else if (nID >= DECORATOR_CTX_MENU_MINID && nID < DECORATOR_CTX_MENU_MAXID && CGuiMetaProject::theInstance->maxMenuCmdID < DECORATOR_CTX_MENU_MINID) {
06850                 if (nCode == CN_UPDATE_COMMAND_UI && pExtra != NULL) {
06851                         CCmdUI* pUI = (CCmdUI*) pExtra;
06852                         pUI->Enable(isType);
06853                         return true;
06854                 } else if (nCode == CN_COMMAND) {
06855                         if (selectedObjectOfContext != NULL || selectedAnnotationOfContext != NULL) {
06856                                 // Send command using saved state
06857                                 CComPtr<IMgaElementDecorator> newDecorator;
06858                                 if (selectedObjectOfContext != NULL) {
06859                                         CGuiAspect* pAspect = selectedObjectOfContext->GetCurrentAspect();
06860                                         if (pAspect != NULL) {
06861                                                 CComQIPtr<IMgaElementDecorator> newDecorator2(pAspect->GetDecorator());
06862                                                 newDecorator = newDecorator2;
06863                                         }
06864                                 } else {
06865                                         newDecorator = selectedAnnotationOfContext->GetDecorator(currentAspect->index);
06866                                 }
06867                                 if (newDecorator) {
06868                                         SetIsContextInitiatedOperation(true);
06869                                         if (selectedObjectOfContext != NULL)
06870                                                 SetObjectInDecoratorOperation(selectedObjectOfContext);
06871                                         else
06872                                                 SetAnnotatorInDecoratorOperation(selectedAnnotationOfContext);
06873                                         CClientDC transformDC(this);
06874                                         OnPrepareDC(&transformDC);
06875                                         HRESULT retVal = newDecorator->MenuItemSelected(nID, ctxClkSt.nFlags, ctxClkSt.lpoint.x, ctxClkSt.lpoint.y,
06876                                                                                                                                         (ULONGLONG)transformDC.m_hDC);
06877                                         if (retVal == S_DECORATOR_EVENT_HANDLED) {
06878                                                 if (IsInOpenedDecoratorTransaction()) {
06879                                                         if (ShouldCommitOperation()) {
06880                                                                 try {
06881                                                                         CommitTransaction();
06882                                                                 } catch (hresult_exception& e) {
06883                                                                         // GME-292: the commit may fail
06884                                                                         AbortTransaction(e.hr);
06885                                                                         if (e.hr != E_MGA_CONSTRAINT_VIOLATION) {
06886                                                                                 CGMEEventLogger::LogGMEEvent(_T("    Couldn't commit transaction.\r\n"));
06887                                                                                 AfxMessageBox(_T("Couldn't commit transaction."),MB_ICONSTOP | MB_OK);
06888                                                                         }
06889                                                                 }
06890                                                                 SetShouldCommitOperation(false);
06891                                                                 SetObjectInDecoratorOperation(NULL);
06892                                                                 SetAnnotatorInDecoratorOperation(NULL);
06893                                                         } else {
06894                                                                 AbortTransaction(S_OK);
06895                                                         }
06896                                                         SetInOpenedDecoratorTransaction(false);
06897                                                         SetIsContextInitiatedOperation(false);
06898                                                         SetInElementDecoratorOperation(false);
06899                                                 }
06900                                         } else if (retVal != S_OK &&
06901                                                                 retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
06902                                                                 retVal != E_DECORATOR_NOT_IMPLEMENTED)
06903                                         {
06904                                                 CancelDecoratorOperation();
06905                                                 // FIXME: how to handle this error?
06906                                                 // COMTHROW(retVal);
06907                                                 return TRUE;
06908                                         }
06909                                 }
06910                         }
06911                 }
06912         }
06913         return CScrollZoomView::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
06914 }
06915 
06916 void CGMEView::OnEditDelete()
06917 {
06918         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditDelete in ")+path+name+_T("\r\n"));
06919 
06920         if (selectedConnection && selected.IsEmpty() && selectedAnnotations.IsEmpty()) {
06921                 bool ok = DeleteConnection(selectedConnection);
06922                 // user already got a MessageBox, no need for another
06923         } else {
06924                 GMEEVENTLOG_GUIANNOTATORS(selectedAnnotations);
06925                 DeleteAnnotations(selectedAnnotations);
06926                 RemoveAllAnnotationFromSelection();
06927                 ClearConnectionSelection();
06928 
06929                 GMEEVENTLOG_GUIOBJS(selected);
06930                 this->SendUnselEvent4List( &selected);
06931                 if(DeleteObjects( selected))
06932                         selected.RemoveAll();
06933         }
06934 }
06935 
06936 void CGMEView::OnUpdateEditDelete(CCmdUI* pCmdUI)
06937 {
06938         if( !selected.IsEmpty())
06939                 pCmdUI->Enable(true);
06940         else
06941                 pCmdUI->Enable(!selectedAnnotations.IsEmpty() || selectedConnection);
06942 }
06943 
06944 void CGMEView::OnContextProperties()
06945 {
06946         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnContextProperties in ")+path+name+_T("\r\n"));
06947     if (contextSelection) {
06948                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
06949                 if (guiObj)
06950                         ShowProperties(guiObj);
06951                 else {
06952                         CGuiConnection* guiConn = contextSelection->dynamic_cast_CGuiConnection();
06953                         if (guiConn)
06954                                 ShowProperties(guiConn);
06955                 }
06956         }
06957         else
06958                 ShowProperties();
06959         contextSelection = 0;
06960         contextPort = 0;
06961 }
06962 
06963 void CGMEView::AttributepanelPage(long page)
06964 {
06965         switch (page)
06966         {
06967         case 0:
06968                 ShowAttributes();
06969                 break;
06970         case 1:
06971                 ShowPreferences();
06972                 break;
06973         case 2:
06974                 ShowProperties();
06975                 break;
06976         }
06977 }
06978 
06979 void CGMEView::OnCntxPreferences()
06980 {
06981         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxPreferences in ")+path+name+_T("\r\n"));
06982         if (contextSelection) {
06983                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
06984                 if(guiObj)
06985                         ShowPreferences(guiObj);
06986                 else {
06987                         CGuiConnection* guiConn = contextSelection->dynamic_cast_CGuiConnection();
06988                         if (guiConn)
06989                                 ShowPreferences(guiConn);
06990                 }
06991         }
06992         else {
06993                 ShowPreferences();
06994         }
06995 
06996         contextSelection = 0;
06997         contextAnnotation = 0;
06998         contextPort = 0;
06999 }
07000 
07001 void CGMEView::OnCntxDisconnectall()
07002 {
07003         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxDisconnectall in ")+path+name+_T("\r\n"));
07004         if (!isType)
07005                 return;
07006         if (contextSelection) {
07007                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
07008                 if (guiObj && guiObj->IsVisible()) {
07009                         try {
07010                                 BeginTransaction();
07011                                 POSITION pos = guiObj->GetPorts().GetHeadPosition();
07012                                 while(pos) {
07013                                                 DisconnectAll(guiObj,guiObj->GetPorts().GetNext(pos));
07014                                 }
07015                                 contextSelection = 0;
07016                                 contextPort = 0;
07017                                 __CommitTransaction();
07018                         }
07019                         catch(hresult_exception e) {
07020                                 AbortTransaction(e.hr);
07021                                 AfxMessageBox(_T("Could not complete disconnect operation"),MB_OK | MB_ICONSTOP);
07022                                 CGMEEventLogger::LogGMEEvent(_T("    Could not complete disconnect operation.\r\n"));
07023                         }
07024                         catch(_com_error& e) {                
07025                                 AbortTransaction(e.Error());
07026                                 CString error = _T("Could not complete disconnect operation");
07027                                 if (e.Description().length() != 0)
07028                                 {
07029                                         error += _T(": ");
07030                                         error += static_cast<const TCHAR*>(e.Description());
07031                                 }
07032                                 CGMEEventLogger::LogGMEEvent(error + _T("\r\n"));
07033                                 AfxMessageBox(error,MB_ICONSTOP | MB_OK);
07034                         }
07035                 }
07036         }
07037 }
07038 
07039 void CGMEView::OnUpdateCntxDisconnectall(CCmdUI* pCmdUI)
07040 {
07041         // HACK
07042         pCmdUI->Enable(isType);
07043 }
07044 
07045 void CGMEView::OnCntxAttributes()
07046 {
07047         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxAttributes in ")+path+name+_T("\r\n"));
07048         if (contextSelection) {
07049                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
07050                 if (guiObj)
07051                         ShowAttributes(guiObj);
07052                 else {
07053                         CGuiConnection* guiConn = contextSelection->dynamic_cast_CGuiConnection();
07054                         if (guiConn)
07055                                 ShowAttributes(guiConn);
07056                 }
07057         }
07058         else
07059                 ShowAttributes();
07060         contextSelection = 0;
07061         contextPort = 0;
07062 }
07063 
07064 void CGMEView::OnUpdateCntxAttributes(CCmdUI* pCmdUI)
07065 {
07066         bool enable = false;
07067         CGuiMetaAttributeList *metaAttrs = 0;
07068         try {
07069                 BeginTransaction(TRANSACTION_READ_ONLY);
07070                 metaAttrs = contextSelection ? contextSelection->GetMetaAttributes() : &currentAspect->attrs;
07071                 if(metaAttrs->GetCount() > 0)
07072                         enable = true;
07073                 CommitTransaction();
07074         }
07075         catch(hresult_exception &e) {
07076                 AbortTransaction(e.hr);
07077                 AfxMessageBox(_T("Unable to get model attributes"),MB_OK | MB_ICONSTOP);
07078                 CGMEEventLogger::LogGMEEvent(_T("    Unable to get model attributes.\r\n"));
07079         }
07080         pCmdUI->Enable(enable);
07081 }
07082 
07083 void CGMEView::OnEditUndo() 
07084 {
07085         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditUndo\r\n"));
07086         if (IsInElementDecoratorOperation())
07087                 return;
07088         theApp.mgaProject->Undo();
07089         // Don't lose TreeBrowser focus
07090         //this->SetFocus();
07091 }
07092 
07093 void CGMEView::OnEditRedo() 
07094 {
07095         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditRedo\r\n"));
07096         if (IsInElementDecoratorOperation())
07097                 return;
07098         theApp.mgaProject->Redo();
07099         // Don't lose TreeBrowser focus
07100         //this->SetFocus();
07101 }
07102 
07103 void CGMEView::OnEditCopy()
07104 {
07105         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditCopy in ")+path+name+_T("\r\n"));
07106         if(selected.GetCount() + selectedAnnotations.GetCount() > 0) {
07107                 GMEEVENTLOG_GUIOBJS(selected);
07108                 GMEEVENTLOG_GUIANNOTATORS(selectedAnnotations);
07109                 CPoint pt = CPoint(0,0);
07110                 CRectList rects, annRects;
07111                 CGuiObject::GetRectList(selected,rects);
07112                 CGuiAnnotator::GetRectList(selectedAnnotations,annRects);
07113                 CGMEDataDescriptor desc(rects,annRects,pt,pt);
07114                 CGMEDataDescriptor::destructList( rects);
07115                 CGMEDataDescriptor::destructList( annRects);
07116                 GetDocument()->CopyToClipboard(&selected,&selectedAnnotations,&desc,this);
07117         }
07118 }
07119 
07120 void CGMEView::OnEditCopyClosure()
07121 {
07122         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditCopyClosure in ")+path+name+_T("\r\n"));
07123         if(selected.GetCount() > 0) {
07124                 GMEEVENTLOG_GUIOBJS(selected);
07125                 GMEEVENTLOG_GUIANNOTATORS(selectedAnnotations);
07126                 CPoint pt = CPoint(0,0);
07127                 CRectList rects, annRects;
07128                 CGuiObject::GetRectList(selected,rects);
07129                 CGuiAnnotator::GetRectList(selectedAnnotations,annRects);
07130                 CGMEDataDescriptor desc(rects,annRects,pt,pt);
07131                 CGMEDataDescriptor::destructList( rects);
07132                 CGMEDataDescriptor::destructList( annRects);
07133                 GetDocument()->CopyClosureToClipboard( &selected, &selectedAnnotations, &desc, this);
07134         }
07135 }
07136 
07137 void CGMEView::OnEditCopySmart()
07138 {
07139         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditCopySmart in ")+path+name+_T("\r\n"));
07140         if(selected.GetCount() > 0) {
07141                 GMEEVENTLOG_GUIOBJS(selected);
07142                 GMEEVENTLOG_GUIANNOTATORS(selectedAnnotations);
07143                 CPoint pt = CPoint(0,0);
07144                 CRectList rects, annRects;
07145                 CGuiObject::GetRectList(selected,rects);
07146                 CGuiAnnotator::GetRectList(selectedAnnotations,annRects);
07147                 CGMEDataDescriptor desc(rects,annRects,pt,pt);
07148                 CGMEDataDescriptor::destructList( rects);
07149                 CGMEDataDescriptor::destructList( annRects);
07150                 CGuiFcoList fcoList;// copy selected->selectedFco
07151                 POSITION pos = selected.GetHeadPosition();
07152                 while( pos != NULL ) fcoList.AddTail( selected.GetNext( pos ));
07153 
07154                 GetDocument()->CopySmartToClipboard( &fcoList, &selectedAnnotations, &desc, this);
07155         }
07156 }
07157 
07158 void CGMEView::OnUpdateEditCopy(CCmdUI* pCmdUI)
07159 {
07160         pCmdUI->Enable(selected.GetCount() + selectedAnnotations.GetCount() > 0);
07161 }
07162 
07163 void CGMEView::OnUpdateEditCopyClosure(CCmdUI* pCmdUI)
07164 {
07165         pCmdUI->Enable(selected.GetCount() > 0);
07166 }
07167 
07168 void CGMEView::OnUpdateEditCopySmart(CCmdUI* pCmdUI)
07169 {
07170         pCmdUI->Enable(selected.GetCount() > 0);
07171 }
07172 
07173 void CGMEView::OnEditCut()
07174 {
07175         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditCut in ")+path+name+_T("\r\n"));
07176         if(selected.GetCount() + selectedAnnotations.GetCount() > 0) {
07177                 if(isType) GMEEVENTLOG_GUIOBJS(selected);
07178                 GMEEVENTLOG_GUIANNOTATORS(selectedAnnotations);
07179                 CPoint pt = CPoint(0,0);
07180                 CRectList rects,annRects;
07181                 if(isType) CGuiObject::GetRectList(selected,rects);
07182                 CGuiAnnotator::GetRectList(selectedAnnotations,annRects);
07183                 CGMEDataDescriptor desc(rects,annRects,pt,pt);
07184                 CGMEDataDescriptor::destructList( rects);
07185                 CGMEDataDescriptor::destructList( annRects);
07186                 GetDocument()->CopyToClipboard(&selected,&selectedAnnotations,&desc,this);
07187                 if(isType) DeleteObjects(selected);
07188                 DeleteAnnotations(selectedAnnotations);
07189                 if(isType) selected.RemoveAll();
07190                 RemoveAllAnnotationFromSelection();
07191                 ClearConnectionSelection();
07192         }
07193 }
07194 
07195 void CGMEView::OnUpdateEditCut(CCmdUI* pCmdUI)
07196 {
07197         if( !selectedAnnotations.IsEmpty() && selected.IsEmpty())
07198                 pCmdUI->Enable( TRUE); // allow if annotations are selected only
07199         else
07200                 pCmdUI->Enable(isType && selected.GetCount() + selectedAnnotations.GetCount() > 0);
07201 }
07202 
07203 void CGMEView::OnEditPaste()
07204 {
07205         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditPaste in ")+path+name+_T("\r\n"));
07206         if(isType) {
07207                 COleDataObject clipboardData;
07208                 clipboardData.AttachClipboard();
07209                 derivedDrop = instanceDrop = false;
07210                 DoPasteItem(&clipboardData);
07211         }
07212 }
07213 
07214 void CGMEView::OnUpdateEditPaste(CCmdUI* pCmdUI)
07215 {
07216         COleDataObject dataObj;
07217         BOOL bEnable = isType && dataObj.AttachClipboard() &&
07218                 ((CGMEDataSource::IsGmeNativeDataAvailable(&dataObj,theApp.mgaProject)) ||
07219                 (CGMEDataSource::IsXMLDataAvailable(&dataObj))
07220                 );
07221 
07222         pCmdUI->Enable(bEnable);
07223 }
07224 
07225 void CGMEView::OnCntxCopy()
07226 {
07227         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxCopy in ")+path+name+_T("\r\n"));
07228         if (contextSelection) {
07229                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
07230                 if(guiObj) {
07231                         CGMEEventLogger::LogGMEEvent(_T("    ")+guiObj->GetName()+_T(" ")+guiObj->GetID()+_T("\r\n"));
07232                         CGuiObjectList list;
07233                         CGuiAnnotatorList dummyList;
07234                         list.AddTail(guiObj);
07235                         CPoint pt = CPoint(0,0);
07236                         CRectList rects;
07237                         CGuiObject::GetRectList(list,rects);
07238                         CRectList dummyAnnList;
07239                         CGMEDataDescriptor desc(rects,dummyAnnList,pt,pt);
07240                         CGMEDataDescriptor::destructList( rects);
07241                         GetDocument()->CopyToClipboard(&list,&dummyList,&desc,this);
07242                 }
07243                 contextSelection = 0;
07244                 contextPort = 0;
07245         }
07246         else if (contextAnnotation) {
07247                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextAnnotation->GetName()+_T("/r/n"));
07248                 CGuiObjectList dummyList;
07249                 CGuiAnnotatorList list;
07250                 list.AddTail(contextAnnotation);
07251                 CPoint pt = CPoint(0,0);
07252                 CRectList rects;
07253                 CGuiAnnotator::GetRectList(list,rects);
07254                 CRectList dummyObjList;
07255                 CGMEDataDescriptor desc(dummyObjList,rects,pt,pt);
07256                 CGMEDataDescriptor::destructList( rects);
07257                 GetDocument()->CopyToClipboard(&dummyList,&list,&desc,this);
07258                 contextAnnotation = 0;
07259         }
07260 }
07261 
07262 void CGMEView::OnCntxCopyClosure()
07263 {
07264         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxCopyClosure in ")+path+name+_T("\r\n"));
07265         if (contextSelection) {
07266                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
07267                 if (guiObj) {
07268                         CGMEEventLogger::LogGMEEvent(_T("    ")+guiObj->GetName()+_T(" ")+guiObj->GetID()+_T("\r\n"));
07269                         CGuiObjectList list;
07270                         CGuiAnnotatorList dummyList;
07271                         list.AddTail(guiObj);
07272                         CPoint pt = CPoint(0,0);
07273                         CRectList rects;
07274                         CGuiObject::GetRectList(list,rects);
07275                         CRectList dummyAnnList;
07276                         CGMEDataDescriptor desc(rects,dummyAnnList,pt,pt);
07277                         CGMEDataDescriptor::destructList( rects);
07278                         GetDocument()->CopyClosureToClipboard( &list, &dummyList, &desc, this);
07279                 }
07280                 contextSelection = 0;
07281                 contextPort = 0;
07282         }
07283         else if (contextAnnotation) {
07284                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextAnnotation->GetName()+_T("/r/n"));
07285                 CGuiObjectList dummyList;
07286                 CGuiAnnotatorList list;
07287                 list.AddTail(contextAnnotation);
07288                 CPoint pt = CPoint(0,0);
07289                 CRectList rects;
07290                 CGuiAnnotator::GetRectList(list,rects);
07291                 CRectList dummyObjList;
07292                 CGMEDataDescriptor desc(dummyObjList,rects,pt,pt);
07293                 CGMEDataDescriptor::destructList( rects);
07294                 GetDocument()->CopyClosureToClipboard(&dummyList,&list,&desc,this);
07295                 contextAnnotation = 0;
07296         }
07297 }
07298 
07299 void CGMEView::OnCntxCopySmart()
07300 {
07301         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxCopySmart in ")+path+name+_T("\r\n"));
07302         if (contextSelection) {
07303                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
07304                 if (guiObj) {
07305                         CGMEEventLogger::LogGMEEvent(_T("    ")+guiObj->GetName()+_T(" ")+guiObj->GetID()+_T("\r\n"));
07306                         CGuiObjectList list;
07307                         CGuiAnnotatorList dummyList;
07308                         list.AddTail(guiObj);
07309                         CPoint pt = CPoint(0,0);
07310                         CRectList rects;
07311                         CGuiObject::GetRectList(list,rects);
07312                         CRectList dummyAnnList;
07313                         CGMEDataDescriptor desc(rects,dummyAnnList,pt,pt);
07314                         CGMEDataDescriptor::destructList( rects);
07315 
07316                         CGuiFcoList fcoList;
07317                         POSITION pos = list.GetHeadPosition();// copy list->fcoList
07318                         while( pos != NULL ) fcoList.AddTail( list.GetNext( pos ));
07319 
07320                         GetDocument()->CopySmartToClipboard( &fcoList, &dummyList, &desc, this);
07321                 }
07322                 else 
07323                 {
07324                         CGuiConnection* guiConn = contextSelection->dynamic_cast_CGuiConnection();
07325                         if( guiConn) // a valid connection
07326                         {
07327                                 CGMEEventLogger::LogGMEEvent(_T("    ")+guiConn->GetName()+_T(" ")+guiConn->GetID()+_T("\r\n"));
07328                                 CGuiFcoList list;
07329                                 CGuiAnnotatorList dummyList;
07330                                 list.AddTail(guiConn);
07331                                 CPoint pt = CPoint(0,0);
07332                                 CRectList dummyRects;
07333                                 CRectList dummyAnnList;
07334                                 CGMEDataDescriptor desc(dummyRects,dummyAnnList,pt,pt);
07335                                 GetDocument()->CopySmartToClipboard( &list, &dummyList, &desc, this);
07336                         }
07337                 }
07338                 contextSelection = 0;
07339                 contextPort = 0;
07340         }
07341         else if (contextAnnotation) {
07342                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextAnnotation->GetName()+_T("/r/n"));
07343                 CGuiFcoList dummyList;
07344                 CGuiAnnotatorList list;
07345                 list.AddTail(contextAnnotation);
07346                 CPoint pt = CPoint(0,0);
07347                 CRectList rects;
07348                 CGuiAnnotator::GetRectList(list,rects);
07349                 CRectList dummyObjList;
07350                 CGMEDataDescriptor desc(dummyObjList,rects,pt,pt);
07351                 CGMEDataDescriptor::destructList( rects);
07352                 GetDocument()->CopySmartToClipboard(&dummyList,&list,&desc,this);
07353                 contextAnnotation = 0;
07354         }
07355 }
07356 
07357 
07358 void CGMEView::OnCntxCut()
07359 {
07360         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxCut in ")+path+name+_T("\r\n"));
07361         if(isType && contextSelection) {
07362                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
07363                 if(guiObj) {
07364                         CGMEEventLogger::LogGMEEvent(_T("    ")+guiObj->GetName()+_T(" ")+guiObj->GetID()+_T("\r\n"));
07365                         CGuiObjectList list;
07366                         CGuiAnnotatorList dummyList;
07367                         list.AddTail(guiObj);
07368                         CPoint pt = CPoint(0,0);
07369                         CRectList rects;
07370                         CGuiObject::GetRectList(list,rects);
07371                         CRectList dummyAnnList;
07372                         CGMEDataDescriptor desc(rects,dummyAnnList,pt,pt);
07373                         CGMEDataDescriptor::destructList( rects);
07374                         GetDocument()->CopyToClipboard(&list,&dummyList,&desc,this);
07375                         DeleteObjects(list);
07376                 }
07377                 contextSelection = 0;
07378                 contextPort = 0;
07379         }
07380         else if (contextAnnotation) {
07381                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextAnnotation->GetName()+_T("/r/n"));
07382                 CGuiObjectList dummyList;
07383                 CGuiAnnotatorList list;
07384                 list.AddTail(contextAnnotation);
07385                 CPoint pt = CPoint(0,0);
07386                 CRectList rects;
07387                 CGuiAnnotator::GetRectList(list,rects);
07388                 CRectList dummyObjList;
07389                 CGMEDataDescriptor desc(dummyObjList,rects,pt,pt);
07390                 CGMEDataDescriptor::destructList( rects);
07391                 GetDocument()->CopyToClipboard(&dummyList,&list,&desc,this);
07392                 DeleteAnnotations(list);
07393                 contextAnnotation = 0;
07394         }
07395 }
07396 
07397 void CGMEView::OnUpdateCntxCut(CCmdUI* pCmdUI)
07398 {
07399         if( contextAnnotation)
07400                 pCmdUI->Enable( TRUE);
07401         else
07402                 pCmdUI->Enable(isType);
07403 }
07404 
07405 void CGMEView::OnCntxDelete()
07406 {
07407         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxDelete in ")+path+name+_T("\r\n"));
07408         if(isType && contextSelection) {
07409                 CGuiObject* guiObj = contextSelection->dynamic_cast_CGuiObject();
07410                 if(guiObj) {
07411                         CGMEEventLogger::LogGMEEvent(_T("    ")+guiObj->GetName()+_T(" ")+guiObj->GetID()+_T("\r\n"));
07412                         CGuiObjectList list;
07413                         list.AddTail(guiObj);
07414                         DeleteObjects(list);
07415                 }
07416                 contextSelection = 0;
07417                 contextPort = 0;
07418         }
07419         if( contextAnnotation) {
07420                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextAnnotation->GetName()+_T("/r/n"));
07421                 CGuiAnnotatorList list;
07422                 list.AddTail(contextAnnotation);
07423                 DeleteAnnotations(list);
07424                 contextAnnotation = 0;
07425         }
07426 }
07427 
07428 void CGMEView::OnUpdateCntxDelete(CCmdUI* pCmdUI)
07429 {
07430         if( contextAnnotation && !contextSelection)
07431                 pCmdUI->Enable(TRUE);
07432         else
07433                 pCmdUI->Enable(isType);
07434 }
07435 
07436 void CGMEView::OnSelfcntxCopy()
07437 {
07438         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnSelfcntxCopy in ")+path+name+_T("\r\n"));
07439         OnEditCopy();
07440 }
07441 
07442 void CGMEView::OnUpdateSelfcntxCopy(CCmdUI* pCmdUI)
07443 {
07444         OnUpdateEditCopy(pCmdUI);
07445 }
07446 
07447 void CGMEView::OnSelfcntxCopyClosure()
07448 {
07449         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnSelfcntxCopyClosure in ")+path+name+_T("\r\n"));
07450         OnEditCopyClosure();
07451 }
07452 
07453 void CGMEView::OnSelfcntxCopySmart()
07454 {
07455         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnSelfcntxCopySmart in ")+path+name+_T("\r\n"));
07456         OnEditCopySmart();
07457 }
07458 
07459 void CGMEView::OnUpdateSelfcntxCopyClosure(CCmdUI* pCmdUI)
07460 {
07461         OnUpdateEditCopyClosure(pCmdUI);
07462 }
07463 
07464 void CGMEView::OnUpdateSelfcntxCopySmart(CCmdUI* pCmdUI)
07465 {
07466         OnUpdateEditCopySmart(pCmdUI);
07467 }
07468 
07469 void CGMEView::OnSelfcntxCut()
07470 {
07471         OnEditCut();
07472 }
07473 
07474 void CGMEView::OnUpdateSelfcntxCut(CCmdUI* pCmdUI)
07475 {
07476         OnUpdateEditCut(pCmdUI);
07477 }
07478 
07479 void CGMEView::OnSelfcntxDelete()
07480 {
07481         OnEditDelete();
07482 }
07483 
07484 void CGMEView::OnUpdateSelfcntxDelete(CCmdUI* pCmdUI)
07485 {
07486         OnUpdateEditDelete(pCmdUI);
07487 }
07488 
07489 void CGMEView::OnSelfcntxPaste()
07490 {
07491         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnSelfcntxPaste in ")+path+name+_T("\r\n"));
07492         if(isType) {
07493                 COleDataObject clipboardData;
07494                 clipboardData.AttachClipboard();
07495                 derivedDrop = instanceDrop = false;
07496                 DoPasteItem(&clipboardData,true,false,false,false,false,false,false,0,contextMenuLocation);
07497         }
07498 }
07499 
07500 void CGMEView::OnUpdateSelfcntxPaste(CCmdUI* pCmdUI)
07501 {
07502         OnUpdateEditPaste(pCmdUI);
07503 }
07504 
07505 void CGMEView::OnActivateFrame( UINT nState, CFrameWnd* pFrameWnd )
07506 {
07507 
07508 //      CGMEView* gmeviewA = (CGMEView*)GetActiveView();
07509 //      if (gmeviewA)
07510         if (m_isActive)
07511         {
07512                 TRACE(_T("CGMEView::OnActivateFrame\n"));
07513         }
07514         CScrollZoomView::OnActivateFrame(nState, pFrameWnd);
07515 }
07516 
07517 void CGMEView::OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView)
07518 {
07519         CString s = bActivate ? _T("ACTIVATE "):_T("DEACTIVATE ");
07520         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnActivateView ")+s+path+name+_T("\r\n"));
07521         //I tried logging pActivateView and pDeactiveView, but they always seemed to be "this"
07522         //anyways, OnActivateView is called on both views, so you would know if going from
07523         //one to another by the ACTIVATE/DEACTIVATE - Brian
07524         m_overlay = nullptr;
07525 
07526         if (bActivate && (!initDone || needsReset)) {
07527                 if( theApp.isHistoryEnabled())
07528                 {
07529                         GetDocument()->tellHistorian( currentModId, currentAspect?currentAspect->name:_T(""));
07530                 }
07531 
07532                 modelGrid.Clear();
07533                 FillModelGrid();
07534                 AutoRoute();
07535                 ClearConnSpecs();
07536                 if(guiMeta) {
07537                         theApp.UpdateCompList4CurrentKind( guiMeta->name);
07538                         CMainFrame::theInstance->SetPartBrowserMetaModel(guiMeta);
07539                         CMainFrame::theInstance->SetPartBrowserBg(bgColor);
07540                         CMainFrame::theInstance->ChangePartBrowserAspect(currentAspect->index);
07541                 }
07542                 needsReset = false;
07543         }
07544         else if(tmpConnectMode) {
07545                 tmpConnectMode = false;
07546                 ClearConnSpecs();
07547         }
07548         //comm'd by zolmol
07549         //CMainFrame::theInstance->UpdateTitle(theApp.projectName);
07550 
07551 //      CGMEView * gmeviewA = (CGMEView *)pActivateView;
07552 //      CGMEView * gmeviewI = (CGMEView *)pDeactiveView;
07553         m_isActive = bActivate;
07554         TRACE(_T("CGMEView::OnActivateView final false\n"));
07555         if (bActivate)
07556                 theApp.UpdateMainTitle();
07557         CScrollZoomView::OnActivateView(bActivate, pActivateView, pDeactiveView);
07558 }
07559 
07560 
07561 void CGMEView::OnEditCancel()
07562 {
07563         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditCancel in ")+path+name+_T("\r\n"));
07564         if(tmpConnectMode) {
07565                 tmpConnectMode = false;
07566                 ClearConnSpecs();
07567                 SetCursor(editCursor);
07568                 ShowCursor(TRUE);
07569                 Invalidate();
07570         }
07571         else {
07572                 CGMEDoc *doc = GetDocument();
07573                 if(doc->GetEditMode() == GME_AUTOCONNECT_MODE
07574                 || doc->GetEditMode() == GME_SHORTAUTOCONNECT_MODE) {
07575                         ClearConnSpecs();
07576                         SetCursor(autoconnectCursor);
07577                         Invalidate();
07578                 }
07579                 else if(doc->GetEditMode() == GME_DISCONNECT_MODE
07580                         || doc->GetEditMode() == GME_SHORTDISCONNECT_MODE) {
07581                         ClearConnSpecs();
07582                         SetCursor(disconnectCursor);
07583                         Invalidate();
07584                 }
07585         }
07586 }
07587 
07588 void CGMEView::OnUpdateEditCancel(CCmdUI* pCmdUI)
07589 {
07590         CGMEDoc *doc = GetDocument();
07591         pCmdUI->Enable(((doc->GetEditMode() == GME_AUTOCONNECT_MODE || doc->GetEditMode() == GME_SHORTAUTOCONNECT_MODE) && connSrc) ||
07592                                         ((doc->GetEditMode() == GME_DISCONNECT_MODE || doc->GetEditMode() == GME_SHORTDISCONNECT_MODE) && connSrc));
07593 
07594 }
07595 
07596 BOOL CGMEView::PreTranslateMessage(MSG* pMsg)
07597 {
07598         ASSERT( m_hWnd != NULL && theApp.m_GMEView_hAccel != NULL && pMsg != NULL );
07599         if( TranslateAccelerator(m_hWnd, theApp.m_GMEView_hAccel, pMsg) )
07600                 return TRUE;
07601 
07602         return CScrollZoomView::PreTranslateMessage(pMsg);
07603 }
07604 
07605 void CGMEView::OnFileClose()
07606 {
07607         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnFileClose() in ")+path+name+_T("\r\n"));
07608         frame->SetSendEvent(true);
07609         frame->PostMessage(WM_CLOSE);
07610 }
07611 
07612 void CGMEView::OnFileInterpret()
07613 {
07614         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnFileInterpret in ")+path+name+_T("\r\n"));
07615         RunComponent(_T(""));
07616 }
07617 
07618 void CGMEView::RunComponent(CString compname)
07619 {
07620         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnRunComponent ")+compname+_T(" in ")+path+name+_T("\r\n"));
07621         CGMEEventLogger::LogGMEEvent(_T("    Selected FCOs:"));
07622         GMEEVENTLOG_GUIFCOS(selected);
07623         MSGTRY
07624         {
07625                 IMgaLauncherPtr launcher;
07626                 COMTHROW( launcher.CreateInstance(L"Mga.MgaLauncher") );
07627                 if(!launcher) {
07628                         AfxMessageBox(_T("Cannot start up component launcher"));
07629                         CGMEEventLogger::LogGMEEvent(_T("    Cannot start up component launcher.\r\n"));
07630                 }
07631                 else {
07632                         CComPtr<IMgaFCO> focus;
07633                         CComPtr<IMgaFCOs> selfcos;
07634                         COMTHROW(selfcos.CoCreateInstance(OLESTR("Mga.MgaFCOs")));
07635                         COMTHROW(currentModel.QueryInterface(&focus));
07636                         POSITION pos = selected.GetHeadPosition();
07637                         while (pos) {
07638                                 CGuiFco *gfco = selected.GetNext(pos);
07639                                 COMTHROW(selfcos->Append(gfco->mgaFco));
07640                         }
07641 
07642                         if(theApp.bNoProtect) COMTHROW( launcher->put_Parameter(CComVariant(true)));
07643                         // Disable the DCOM wait dialogs: if interpreters want them, they can do it themselves; but if they don't want them, they need to link to GME's mfc1xxu.dll
07644                         COleMessageFilter* messageFilter = AfxOleGetMessageFilter();
07645                         messageFilter->EnableBusyDialog(FALSE);
07646                         messageFilter->EnableNotRespondingDialog(FALSE);
07647                         std::shared_ptr<COleMessageFilter> busyRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableBusyDialog(TRUE); } );
07648                         std::shared_ptr<COleMessageFilter> notRespondingRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableNotRespondingDialog(TRUE); } );
07649                         launcher->__RunComponent(_bstr_t(compname), theApp.mgaProject, focus, selfcos, GME_MAIN_START);
07650                 }
07651         }
07652         MSGCATCH(_T("Error while trying to run the interpreter"),;)
07653 }
07654 
07655 void CGMEView::SetEditCursor(void)
07656 {
07657         SetCursor(editCursor);
07658         SetIsCursorChangedByDecorator(false);
07659 }
07660 
07661 void CGMEView::StartDecoratorOperation(void)
07662 {
07663 }
07664 
07665 void CGMEView::EndDecoratorOperation(void)
07666 {
07667 }                                               
07668 
07669 void CGMEView::CancelDecoratorOperation(bool notify)
07670 {
07671         if (IsInElementDecoratorOperation()) {
07672                 // Note: DecoratorLib in-place edit currently not use SetCapture,
07673                 // but ReleaseCapture can be handy if some decorator issues SetCapture
07674                 if (::GetCapture() != NULL)
07675                         ::ReleaseCapture();
07676                 EndDecoratorOperation();
07677                 SetShouldCommitOperation(false);
07678                 if (GetOriginalRect().IsRectEmpty() == FALSE) {
07679                         if (IsDecoratorOrAnnotator())
07680                                 GetObjectInDecoratorOperation()->ResizeObject(GetOriginalRect());
07681 //                      else
07682 //                              GetAnnotatorInDecoratorOperation()->ResizeObject(GetOriginalRect());
07683                         Invalidate();
07684                         SetOriginalRectEmpty();
07685                 }
07686                 SetInElementDecoratorOperation(false);
07687                 if (IsCursorChangedByDecorator())
07688                         SetEditCursor();
07689                 if (notify) {
07690                         CComPtr<IMgaElementDecorator> newDecorator;
07691                         if (GetObjectInDecoratorOperation() != NULL) {
07692                                 CGuiAspect* pAspect = GetObjectInDecoratorOperation()->GetCurrentAspect();
07693                                 if (pAspect != NULL)
07694                                         newDecorator = pAspect->GetNewDecorator();
07695                         } else if (GetAnnotatorInDecoratorOperation() != NULL) {
07696                                 newDecorator = GetAnnotatorInDecoratorOperation()->GetDecorator(currentAspect->index);
07697                         }
07698                         if (newDecorator)
07699                                 HRESULT retVal = newDecorator->OperationCanceled();
07700                 }
07701                 SetObjectInDecoratorOperation(NULL);
07702                 SetAnnotatorInDecoratorOperation(NULL);
07703                 SetIsContextInitiatedOperation(false);
07704         }
07705         if (IsInOpenedDecoratorTransaction()) {
07706                 AbortTransaction(S_OK);
07707                 SetInOpenedDecoratorTransaction(false);
07708         }
07709 }
07710 
07711 
07712 bool CGMEView::IsCursorChangedByDecorator(void) const
07713 {
07714         return isCursorChangedByDecorator;
07715 }
07716 
07717 void CGMEView::SetIsCursorChangedByDecorator(bool isCurChanged)
07718 {
07719         isCursorChangedByDecorator = isCurChanged;
07720 }
07721 
07722 CRect CGMEView::GetOriginalRect(void) const
07723 {
07724         return originalRect;
07725 }
07726 
07727 void CGMEView::SetOriginalRect(const CRect& rect)
07728 {
07729         originalRect = rect;
07730 }
07731 
07732 void CGMEView::SetOriginalRectEmpty(void)
07733 {
07734         originalRect.SetRectEmpty();
07735 }
07736 
07737 bool CGMEView::IsInElementDecoratorOperation(void) const
07738 {
07739         return inElementDecoratorOperation;
07740 }
07741 
07742 void CGMEView::SetInElementDecoratorOperation(bool isIn)
07743 {
07744         inElementDecoratorOperation = isIn;
07745 }
07746 
07747 bool CGMEView::IsInOpenedDecoratorTransaction(void) const
07748 {
07749         return inOpenedDecoratorTransaction;
07750 }
07751 
07752 void CGMEView::SetInOpenedDecoratorTransaction(bool inOpenedTr)
07753 {
07754         inOpenedDecoratorTransaction = inOpenedTr;
07755 }
07756 
07757 bool CGMEView::IsContextInitiatedOperation(void) const
07758 {
07759         return isContextInitiatedOperation;
07760 }
07761 
07762 void CGMEView::SetIsContextInitiatedOperation(bool isCtxInit)
07763 {
07764         isContextInitiatedOperation = isCtxInit;
07765 }
07766 
07767 bool CGMEView::ShouldCommitOperation(void) const
07768 {
07769         return shouldCommitOperation;
07770 }
07771 
07772 void CGMEView::SetShouldCommitOperation(bool shouldCommitOp)
07773 {
07774         shouldCommitOperation = shouldCommitOp;
07775 }
07776 
07777 bool CGMEView::IsDecoratorOrAnnotator(void) const
07778 {
07779         return decoratorOrAnnotator;
07780 }
07781 
07782 void CGMEView::SetDecoratorOrAnnotator(bool decorOrAnnot)
07783 {
07784         decoratorOrAnnotator = decorOrAnnot;
07785 }
07786 
07787 CGuiObject* CGMEView::GetObjectInDecoratorOperation(void) const
07788 {
07789         return objectInDecoratorOperation;
07790 }
07791 
07792 void CGMEView::SetObjectInDecoratorOperation(CGuiObject* obj)
07793 {
07794         objectInDecoratorOperation = obj;
07795 }
07796 
07797 CGuiAnnotator*CGMEView::GetAnnotatorInDecoratorOperation(void) const
07798 {
07799         return annotatorInDecoratorOperation;
07800 }
07801 
07802 void CGMEView::SetAnnotatorInDecoratorOperation(CGuiAnnotator* ann)
07803 {
07804         annotatorInDecoratorOperation = ann;
07805 }
07806 
07807 XERCES_CPP_NAMESPACE_USE
07808 
07809 // ---------------------------------------------------------------------------
07810 //  This is a simple class that lets us do easy (though not terribly efficient)
07811 //  trancoding of char* data to XMLCh data.
07812 // ---------------------------------------------------------------------------
07813 class XStr
07814 {
07815 public :
07816         // -----------------------------------------------------------------------
07817         //  Constructors and Destructor
07818         // -----------------------------------------------------------------------
07819         XStr(const char* const toTranscode)
07820         {
07821                 // Call the private transcoding method
07822                 fUnicodeForm = XMLString::transcode(toTranscode);
07823         }
07824 
07825         XStr(const wchar_t* const toTranscode)
07826         {
07827                 fUnicodeForm = XMLString::replicate(toTranscode);
07828         }
07829         ~XStr()
07830         {
07831                 XMLString::release(&fUnicodeForm);
07832         }
07833 
07834 
07835         // -----------------------------------------------------------------------
07836         //  Getter methods
07837         // -----------------------------------------------------------------------
07838         const XMLCh* unicodeForm() const
07839         {
07840                 return fUnicodeForm;
07841         }
07842 
07843 private :
07844         // -----------------------------------------------------------------------
07845         //  Private data members
07846         //
07847         //  fUnicodeForm
07848         //      This is the Unicode XMLCh format of the string.
07849         // -----------------------------------------------------------------------
07850         XMLCh*   fUnicodeForm;
07851 };
07852 
07853 #define X(str) XStr(str).unicodeForm()
07854 
07855 
07856 HRESULT CGMEView::DumpModelGeometryXML(LPCTSTR filePath)
07857 {
07858         HRESULT hr = S_OK;
07859         try {
07860                 XMLPlatformUtils::Initialize();
07861 
07862                 DOMImplementation* impl =  DOMImplementationRegistry::getDOMImplementation(X("Core"));
07863                 if (impl != NULL)
07864                 {
07865                         try
07866                         {
07867                                 xercesc::DOMDocument* doc = impl->createDocument(
07868                                                         0,                                      // root element namespace URI.
07869                                                         X("model"),                     // root element name
07870                                                         0);                                     // document type object (DTD).
07871 
07872                                 DOMElement* rootElem = doc->getDocumentElement();
07873                                 rootElem->setAttribute(X("name"), X(name));
07874                                 rootElem->setAttribute(X("id"), X(currentModId));
07875 
07876                                 DOMElement* aspectsElem = doc->createElement(X("aspects"));
07877                                 rootElem->appendChild(aspectsElem);
07878                                 // save current aspect
07879                                 SaveCurrAsp();
07880                                 POSITION aspPos = guiMeta->aspects.GetHeadPosition();
07881                                 // rotate through all aspects
07882                                 while (aspPos) {
07883                                         CGuiMetaAspect* asp = guiMeta->aspects.GetNext(aspPos);
07884                                         ChangePrnAspect(asp->name);
07885                                         DOMElement* aspectElem = doc->createElement(X("aspect"));
07886                                         aspectsElem->appendChild(aspectElem);
07887                                         CString intValStr;
07888                                         intValStr.Format(_T("%ld"), asp->index);
07889                                         aspectElem->setAttribute(X("index"), X(intValStr));                                     
07890                                         aspectElem->setAttribute(X("name"), X(asp->name));
07891 
07892                                         // List the contained elements (objects, connections)
07893                                         DOMElement* objsElem = doc->createElement(X("objects"));
07894                                         aspectElem->appendChild(objsElem);
07895                                         DOMElement* connsElem = doc->createElement(X("connections"));
07896                                         aspectElem->appendChild(connsElem);
07897 
07898                                         POSITION pos = children.GetHeadPosition();
07899                                         while (pos) {
07900                                                 CGuiFco* fco = children.GetNext(pos);
07901                                                 ASSERT(fco != NULL);
07902                                                 if (fco->IsVisible()) {
07903                                                         CGuiObject* obj = fco->dynamic_cast_CGuiObject();
07904                                                         if (obj) {
07905                                                                 DOMElement* objElem = doc->createElement(X("object"));
07906                                                                 objsElem->appendChild(objElem);
07907                                                                 objElem->setAttribute(X("name"), X(obj->GetName()));
07908                                                                 objElem->setAttribute(X("id"), X(obj->GetID()));
07909 
07910                                                                 CString intValStr;
07911                                                                 CRect loc = obj->GetLocation();
07912                                                                 DOMElement* locElem = doc->createElement(X("location"));
07913                                                                 objElem->appendChild(locElem);
07914                                                                 intValStr.Format(_T("%ld"), loc.left);
07915                                                                 locElem->setAttribute(X("left"), X(intValStr));
07916                                                                 intValStr.Format(_T("%ld"), loc.top);
07917                                                                 locElem->setAttribute(X("top"), X(intValStr));
07918                                                                 intValStr.Format(_T("%ld"), loc.right);
07919                                                                 locElem->setAttribute(X("right"), X(intValStr));
07920                                                                 intValStr.Format(_T("%ld"), loc.bottom);
07921                                                                 locElem->setAttribute(X("bottom"), X(intValStr));
07922 
07923                                                                 CRect nameLoc = obj->GetNameLocation();
07924                                                                 DOMElement* nameLocElem = doc->createElement(X("namelocation"));
07925                                                                 objElem->appendChild(nameLocElem);
07926                                                                 intValStr.Format(_T("%ld"), nameLoc.left);
07927                                                                 nameLocElem->setAttribute(X("left"), X(intValStr));
07928                                                                 intValStr.Format(_T("%ld"), nameLoc.top);
07929                                                                 nameLocElem->setAttribute(X("top"), X(intValStr));
07930                                                                 intValStr.Format(_T("%ld"), nameLoc.right);
07931                                                                 nameLocElem->setAttribute(X("right"), X(intValStr));
07932                                                                 intValStr.Format(_T("%ld"), nameLoc.bottom);
07933                                                                 nameLocElem->setAttribute(X("bottom"), X(intValStr));
07934                                                         }
07935                                                         CGuiConnection* conn = fco->dynamic_cast_CGuiConnection();
07936                                                         if (conn) {
07937                                                                 DOMElement* connElem = doc->createElement(X("connection"));
07938                                                                 connsElem->appendChild(connElem);
07939                                                                 connElem->setAttribute(X("name"), X(conn->GetName()));
07940                                                                 connElem->setAttribute(X("id"), X(conn->GetID()));
07941 
07942                                                                 CString intValStr;
07943                                                                 CPointList points;
07944                                                                 conn->GetPointList(points);
07945                                                                 DOMElement* pointsElem = doc->createElement(X("points"));
07946                                                                 connElem->appendChild(pointsElem);
07947 
07948                                                                 POSITION pos = points.GetHeadPosition();
07949                                                                 while (pos) {
07950                                                                         CPoint pt = points.GetNext(pos);
07951                                                                         DOMElement* ptElem = doc->createElement(X("pt"));
07952                                                                         pointsElem->appendChild(ptElem);
07953                                                                         intValStr.Format(_T("%ld"), pt.x);
07954                                                                         ptElem->setAttribute(X("x"), X(intValStr));
07955                                                                         intValStr.Format(_T("%ld"), pt.y);
07956                                                                         ptElem->setAttribute(X("y"), X(intValStr));
07957                                                                 }
07958 
07959                                                                 DOMElement* labelsElem = doc->createElement(X("labels"));
07960                                                                 connElem->appendChild(labelsElem);
07961                                                                 for(int i = 0; i < GME_CONN_LABEL_NUM; i++)
07962                                                                 {
07963                                                                         CGuiConnectionLabelSet& labelset = conn->GetLabelSet();
07964                                                                         CString label = labelset.GetLabel(i);
07965                                                                         if (label.GetLength() > 0) {
07966                                                                                 DOMElement* labelElem = NULL;
07967                                                                                 switch(i) {
07968                                                                                         case GME_CONN_SRC_LABEL1: labelElem = doc->createElement(X("srcLabel1")); break;
07969                                                                                         case GME_CONN_SRC_LABEL2: labelElem = doc->createElement(X("srcLabel2")); break;
07970                                                                                         case GME_CONN_DST_LABEL1: labelElem = doc->createElement(X("dstLabel1")); break;
07971                                                                                         case GME_CONN_DST_LABEL2: labelElem = doc->createElement(X("dstLabel2")); break;
07972                                                                                         case GME_CONN_MAIN_LABEL: labelElem = doc->createElement(X("mainLabel")); break;
07973                                                                                 }
07974                                                                                 labelsElem->appendChild(labelElem);
07975                                                                                 CPoint pt = labelset.GetLocation(i);
07976                                                                                 intValStr.Format(_T("%ld"), pt.x);
07977                                                                                 labelElem->setAttribute(X("x"), X(intValStr));
07978                                                                                 intValStr.Format(_T("%ld"), pt.y);
07979                                                                                 labelElem->setAttribute(X("y"), X(intValStr));
07980                                                                                 intValStr.Format(_T("%ld"), labelset.GetAlignment(i));
07981                                                                                 labelElem->setAttribute(X("alignment"), X(intValStr));
07982                                                                                 labelElem->setAttribute(X("label"), X(label));
07983                                                                         }
07984                                                                 }
07985                                                         }
07986                                                 }
07987                                         }
07988                                 }
07989                                 // restore Aspect
07990                                 CGuiMetaAspect* lastcurr = GetSavedAsp();
07991                                 ChangePrnAspect(lastcurr->name);
07992                                 Invalidate();
07993 
07994                                 //
07995                                 // Now serialize the DOM tree with pretty print format.
07996                                 //
07997 
07998                                 DOMLSSerializer* theSerializer = impl->createLSSerializer();
07999                                 theSerializer->setNewLine(X("\n\r"));
08000                                 theSerializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
08001 
08002                                 XMLFormatTarget* myFormatTarget = new LocalFileFormatTarget(filePath);
08003                                 DOMLSOutput* theOutput = impl->createLSOutput();
08004                                 theOutput->setByteStream(myFormatTarget);
08005                                 theSerializer->write( doc, theOutput );
08006                                 
08007                                 // Free up stuff
08008 
08009                                 delete myFormatTarget;
08010                                 theSerializer->release();
08011                                 theOutput->release();
08012 
08013                                 doc->release();
08014                         }
08015                         catch (const OutOfMemoryException&)
08016                         {
08017                                 XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl;
08018                                 SetStandardOrGMEErrorInfo(E_OUTOFMEMORY);
08019                                 hr = E_OUTOFMEMORY;
08020                         }
08021                         catch (const DOMException& e)
08022                         {
08023                                 XERCES_STD_QUALIFIER cerr << "DOMException code is:  " << e.code << XERCES_STD_QUALIFIER endl;
08024                                 SetErrorInfo(E_FAIL, L"DOMException");
08025                                 hr = E_FAIL;
08026                         }
08027                         catch (const IOException& e)
08028                         {
08029                                 SetErrorInfo(E_FAIL, (wchar_t*)e.getMessage());
08030                                 hr = E_FAIL;
08031                         }
08032                         catch (...)
08033                         {
08034                                 XERCES_STD_QUALIFIER cerr << "An error occurred creating the document" << XERCES_STD_QUALIFIER endl;
08035                                 SetStandardOrGMEErrorInfo(E_FAIL);
08036                                 hr = E_FAIL;
08037                         }
08038                 } // (inpl != NULL)
08039                 else
08040                 {
08041                         XERCES_STD_QUALIFIER cerr << "Requested implementation is not supported" << XERCES_STD_QUALIFIER endl;
08042                         SetStandardOrGMEErrorInfo(E_FAIL);
08043                         hr = E_FAIL;
08044                 }
08045 
08046                 XMLPlatformUtils::Terminate();
08047         }
08048         catch(const XMLException& toCatch)
08049         {
08050                 // FIXME does this leak XMLPlatformUtils::Terminate();
08051                 std::basic_stringstream<wchar_t> err;
08052                 err << L"Error during Xerces-c Initialization.\n"
08053                          << L"  Exception message:"
08054                          << (wchar_t*)toCatch.getMessage();
08055                 SetErrorInfo(err.str().c_str());
08056         }
08057 
08058         return hr;
08059 }
08060 
08061 void CGMEView::SetConnectionCustomizeCursor(const CPoint& point)
08062 {
08063         if (selectedConnection != NULL) {
08064                 ConnectionPartMoveType connectionPartMoveType;
08065                 bool horizontalOrVerticalEdge = false;
08066                 bool isPartFixed;
08067                 int edgeIndex = selectedConnection->IsPathAt(point, connectionPartMoveType, horizontalOrVerticalEdge, isPartFixed);
08068                 if (edgeIndex >= 0 && !isPartFixed && !IsInstance()) {  // customization not allowed in instances
08069                         HCURSOR wantedCursor;
08070                         if (connectionPartMoveType == HorizontalEdgeMove) {
08071                                 wantedCursor = LoadCursor(NULL, IDC_SIZEWE);
08072                         } else if (connectionPartMoveType == VerticalEdgeMove) {
08073                                 wantedCursor = LoadCursor(NULL, IDC_SIZENS);
08074                         } else if (connectionPartMoveType == AdjacentEdgeMove) {
08075                                 wantedCursor = LoadCursor(NULL, IDC_SIZEALL);
08076                         } else if (connectionPartMoveType == InsertNewCustomPoint) {
08077                                 wantedCursor = LoadCursor(NULL, IDC_HAND);
08078                         } else if (connectionPartMoveType == ModifyExistingCustomPoint) {
08079                                 wantedCursor = LoadCursor(NULL, IDC_CROSS);
08080                         } else {
08081                                 ASSERT(false);
08082                         }
08083                         HCURSOR cursorBackup = ::SetCursor(wantedCursor);
08084                         if (!isCursorChangedByEdgeCustomize)
08085                                 customizeConnectionCursorBackup = cursorBackup;
08086                         isCursorChangedByEdgeCustomize = true;
08087                 } else {
08088                         if (isCursorChangedByEdgeCustomize) {
08089                                 ::SetCursor(customizeConnectionCursorBackup);
08090                                 isCursorChangedByEdgeCustomize = false;
08091                         }
08092                 }
08093         }
08094 }
08095 
08096 bool CGMEView::IsInstance(void) const
08097 {
08098         return !isType && isSubType;
08099 }
08100 
08101 void CGMEView::TryToExecutePendingRequests(void)
08102 {
08103         if (!inEventHandler && inTransaction > 0 && inRWTransaction) {
08104                 while (!pendingRequests.IsEmpty()) {
08105                         CPendingRequest* req = pendingRequests.RemoveHead();
08106                         if( CGMEDoc::theInstance && !CGMEDoc::theInstance->m_isClosing)
08107                                 req->Execute(this);
08108                         delete req;
08109                 }
08110         }
08111 }
08112 
08113 void CGMEView::OnConncntxProperties()
08114 {
08115         OnContextProperties(); // We now use the Launcher COM interface.
08116 }
08117 
08118 static bool CanReverseConnection(CString& srcKind, CString& dstKind, IMgaMetaConnectionPtr& meta)
08119 {
08120         for (int i = 1; i <= meta->Joints->Count; i++)
08121         {
08122                 IMgaMetaConnJointPtr joint = meta->Joints->GetItem(i);
08123                 bool srcFound = false;
08124                 bool dstFound = false;
08125                 for (int j = 1; j <= joint->PointerSpecs->Count; j++)
08126                 {
08127                         IMgaMetaPointerSpecPtr spec = joint->PointerSpecs->GetItem(j);
08128                         _bstr_t specName = spec->Name;
08129                         for (int k = 1; k <= spec->Items->Count; k++)
08130                         {
08131                                 IMgaMetaPointerItemPtr item = spec->Items->GetItem(k);
08132                                 if (wcscmp(specName.GetBSTR(), L"src") == 0)
08133                                 {
08134                                         if (wcscmp(dstKind, item->Desc) == 0)
08135                                         {
08136                                                 srcFound = true;
08137                                         }
08138                                 }
08139                                 else if (wcscmp(specName.GetBSTR(), L"dst") == 0)
08140                                 {
08141                                         if (wcscmp(srcKind, item->Desc) == 0)
08142                                         {
08143                                                 dstFound = true;
08144                                         }
08145                                 }
08146                         }
08147                 }
08148                 if (srcFound && dstFound)
08149                         return true;
08150         }
08151         return false;
08152 }
08153 
08154 void CGMEView::OnConncntxReverse()
08155 {
08156         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnConncntxReverse in ")+path+name+_T("\r\n"));
08157         if (isType) {
08158                 CGuiConnection* conn = NULL;
08159                 if (contextSelection)
08160                         conn = contextSelection->dynamic_cast_CGuiConnection();
08161                 else
08162                 {
08163                         ASSERT(false); // should only get here thru connection context menu
08164                         return;
08165                 }
08166                 MSGTRY
08167                 {
08168                         //CString srcKind = conn->srcPort ? static_cast<const TCHAR*>(conn->srcPort->metaFco->Name) : conn->src->kindName;
08169                         //CString dstKind = conn->dstPort ? static_cast<const TCHAR*>(conn->dstPort->metaFco->Name) : conn->dst->kindName;
08170                         //IMgaMetaConnectionPtr meta = conn->metaFco.p;
08171                         //CanReverseConnection(srcKind, dstKind, meta) ? TRUE : FALSE;
08172                         BeginTransaction();
08173                         IMgaSimpleConnectionPtr connection = conn->mgaFco.p;
08174                         IMgaFCOPtr src = connection->Src;
08175                         IMgaFCOPtr dst = connection->Dst;
08176                         IMgaFCOsPtr srcRefs = connection->SrcReferences;
08177                         IMgaFCOsPtr dstRefs = connection->DstReferences;
08178 
08179                         long oldprefs = connection->Project->Preferences;
08180                         try {
08181                                 connection->Project->Preferences = connection->Project->Preferences | MGAPREF_IGNORECONNCHECKS;
08182                                 // n.b. need to disconnect first, as self-connection is often illegal
08183                                 connection->__SetSrc(NULL, NULL);
08184                                 connection->__SetDst(NULL, NULL);
08185                         } catch (...) {
08186                                 connection->Project->Preferences = oldprefs;
08187                                 throw;
08188                         }
08189                         connection->__SetSrc(dstRefs, dst);
08190                         connection->__SetDst(srcRefs, src);
08191                         _bstr_t autoroutePrefKey = _bstr_t(L"autorouterPref");
08192                         _bstr_t autoroutePref = connection->RegistryValue[autoroutePrefKey];
08193                         if (autoroutePref.length())
08194                         {
08195                                 wchar_t* dir = autoroutePref.GetBSTR();
08196                                 while (*dir)
08197                                 {
08198                                         if (isupper(*dir))
08199                                         {
08200                                                 *dir = tolower(*dir);
08201                                         }
08202                                         else if (islower(*dir))
08203                                         {
08204                                                 *dir = toupper(*dir);
08205                                         }
08206                                         dir++;
08207                                 }
08208                                 connection->RegistryValue[autoroutePrefKey] = autoroutePref;
08209                         }
08210                         __CommitTransaction();
08211                 } MSGCATCH(L"Could not reverse connection direction", --inTransaction; theApp.mgaProject->AbortTransaction();)
08212                 contextSelection = 0;
08213                 contextPort = 0;
08214         }
08215 }
08216 
08217 void CGMEView::OnUpdateConncntxReverse(CCmdUI* pCmdUI)
08218 {
08219         BOOL enable = FALSE;
08220         if (isType && contextSelection) {
08221                 CGuiConnection* conn = contextSelection->dynamic_cast_CGuiConnection();
08222                 CString srcKind = conn->srcPort ? static_cast<const TCHAR*>(conn->srcPort->metaFco->Name) : conn->src->kindName;
08223                 CString dstKind = conn->dstPort ? static_cast<const TCHAR*>(conn->dstPort->metaFco->Name) : conn->dst->kindName;
08224                 if (conn) {
08225                         IMgaMetaConnectionPtr meta = conn->metaFco.p;
08226                         enable = CanReverseConnection(srcKind, dstKind, meta) ? TRUE : FALSE;
08227                         enable = TRUE;
08228                 }
08229         }
08230         pCmdUI->Enable(enable);
08231 }
08232 
08233 void CGMEView::OnConncntxDelete()
08234 {
08235         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnConncntxDelete in ")+path+name+_T("\r\n"));
08236         if(isType) {
08237                 CGuiConnection* conn = NULL;
08238                 if (contextSelection)
08239                         conn = contextSelection->dynamic_cast_CGuiConnection();
08240                 if(!conn || !DeleteConnection(conn))
08241                         AfxMessageBox(_T("Connection cannot be deleted!"));
08242                 contextSelection = 0;
08243                 contextPort = 0;
08244         }
08245 }
08246 
08247 void CGMEView::OnUpdateConncntxDelete(CCmdUI* pCmdUI)
08248 {
08249         pCmdUI->Enable(isType);
08250 }
08251 
08252 void CGMEView::OnShowContextMenu() // called from Accelerators like SHIFT+F10 or Property (VK_APPS)
08253 {
08254         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnShowContextMenu in ")+path+name+_T("\r\n"));
08255 
08256         CGMEDoc *doc = GetDocument();
08257         if( doc && doc->GetEditMode() == GME_EDIT_MODE)
08258         {
08259                 CRect cr;// GetWindowRect( &cr);
08260                 GetClientRect( &cr);
08261                 ClientToScreen( &cr);
08262                 CPoint global( cr.TopLeft() + CPoint( 10, 10));
08263                 if( selected.GetCount() > 0)
08264                 {
08265                         CGuiObject* head = selected.GetHead();
08266                         CPoint local = !head? CPoint( 0, 0): head->GetLocation().TopLeft();//GetCenter()); // overwrite the menu's topleft placement
08267 
08268                         // reverse CoordinateTransfer
08269                         CClientDC fernst(this);
08270                         (const_cast<CGMEView *>(this))->OnPrepareDC(&fernst);
08271                         fernst.LPtoDP( &local);
08272 
08273                         global.Offset( local);
08274                         CMenu menu;
08275                         menu.LoadMenu( dynamic_cast< CGuiConnection *>( head)? IDR_CONNCONTEXT_MENU: IDR_CONTEXT_MENU);
08276                         menu.GetSubMenu( 0)->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, global.x, global.y, GetParent());
08277                 }
08278                 else if( selectedAnnotations.GetCount() > 0)
08279                 {
08280                         CGuiAnnotator* head = selectedAnnotations.GetHead();
08281                         CPoint local = !head? CPoint( 0, 0): head->GetLocation().TopLeft();
08282 
08283                         // reverse CoordinateTransfer
08284                         CClientDC fernst(this);
08285                         (const_cast<CGMEView *>(this))->OnPrepareDC(&fernst);
08286                         fernst.LPtoDP( &local);
08287 
08288                         global.Offset( local); // overwrite the menu's topleft placement
08289                         CMenu menu;
08290                         menu.LoadMenu( IDR_ANNCONTEXT_MENU);
08291                         menu.GetSubMenu( 0)->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, global.x, global.y, GetParent());
08292                 }
08293                 else
08294                 {
08295                         CMenu menu;
08296                         menu.LoadMenu( IDR_SELFCONTEXT_MENU);
08297                         CMenu *submenu = menu.GetSubMenu( 0);
08298                         currentAspect->InitContextMenu( submenu);
08299                         submenu->TrackPopupMenu( TPM_LEFTALIGN | TPM_RIGHTBUTTON, global.x, global.y, GetParent());
08300                         currentAspect->ResetContextMenu( submenu);
08301                 }
08302         }
08303 }
08304 
08305 void CGMEView::OnJumpToFirstObject()
08306 {
08307         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnJumpToFirstObject in ")+path+name+_T("\r\n"));
08308 
08309         CGuiObject* first = FindFirstObject();
08310 
08311         if( first && first->mgaFco && CGMEDoc::theInstance)
08312         {
08313                 CGMEDoc::theInstance->ShowObject( CComPtr<IUnknown>( first->mgaFco), TRUE);
08314         }
08315 }
08316 
08317 void CGMEView::OnJumpToNextObject()
08318 {
08319         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnJumpToNextObject in ")+path+name+_T("\r\n"));
08320 
08321         CGuiObject* next = FindNextObject();
08322 
08323         if( next && next->mgaFco && CGMEDoc::theInstance)
08324         {
08325                 CGMEDoc::theInstance->ShowObject( CComPtr<IUnknown>( next->mgaFco), TRUE);
08326         }
08327 }
08328 
08329 void CGMEView::OnConnCntxFollow() // 'Go to Dst' context command of a connection 
08330 {
08331         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnConnCntxFollow in ")+path+name+_T("\r\n"));
08332         if (contextSelection) {
08333                 CGuiConnection* conn = contextSelection->dynamic_cast_CGuiConnection();
08334                 FollowLine( conn, false, ::GetKeyState( VK_CONTROL) < 0);
08335                 contextSelection = 0;
08336                 contextPort = 0;
08337         }
08338 }
08339 
08340 void CGMEView::OnConnCntxRevfollow() // 'Go to Src' context command of a connection
08341 {
08342         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnConnCntxRevfollow in ")+path+name+_T("\r\n"));
08343         if (contextSelection) {
08344                 CGuiConnection* conn = contextSelection->dynamic_cast_CGuiConnection();
08345                 FollowLine( conn, true, ::GetKeyState( VK_CONTROL) < 0);
08346                 contextSelection = 0;
08347                 contextPort = 0;
08348         }
08349 }
08350 
08351 void CGMEView::OnPortCntxFollowConnection() // 'Follow Connection' context command of a port
08352 {
08353         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnPortCntxFollowConnection in ")+path+name+_T("\r\n"));
08354         if( contextPort)
08355         {
08356                 FollowLine( contextPort, false, ::GetKeyState( VK_CONTROL) < 0);
08357                 contextSelection = 0;
08358                 contextPort = 0;
08359         }
08360 }
08361 
08362 void CGMEView::OnCntxPortDelete()
08363 {
08364         try {
08365                 if (contextPort) {
08366                         CGMEEventLogger::LogGMEEvent(_T("OnCntxPortDelete  ") + contextPort->GetName() + _T(" ") + contextPort->GetID() + _T("\r\n"));
08367                         BeginTransaction();
08368                         COMTHROW(contextPort->mgaFco->__DestroyObject());
08369                         CommitTransaction();
08370                 }
08371         }
08372         catch (const _com_error& e) {
08373                 _bstr_t errorMessage = _bstr_t(L"Cannot delete port: ") + e.Description();
08374                 AbortTransaction(e.Error());
08375                 if (!CGMEConsole::theInstance)
08376                         AfxMessageBox(errorMessage);
08377                 else
08378                         CGMEConsole::theInstance->Message(static_cast<const TCHAR *>(errorMessage), MSG_ERROR);
08379         }
08380 
08381 }
08382 
08383 void CGMEView::OnPortCntxRevfollowConnection() // 'Follow Reverse Connection' context command of a port
08384 {
08385         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxRevfollowConnection in ")+path+name+_T("\r\n"));
08386         if( contextPort)
08387         {
08388                 FollowLine( contextPort, true, ::GetKeyState( VK_CONTROL) < 0);
08389                 contextSelection = 0;
08390                 contextPort = 0;
08391         }
08392 }
08393 
08394 void CGMEView::OnCntxFollowConnection() // 'Follow Connection' context command of an fco
08395 {
08396         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxFollowConnection in ")+path+name+_T("\r\n"));
08397         if( selected.GetCount() > 0)
08398                 FollowLine( selected.GetHead(), false, ::GetKeyState( VK_CONTROL) < 0);
08399 }
08400 
08401 void CGMEView::OnCntxRevfollowConnection() // 'Follow Reverse Connection' context command of an fco
08402 {
08403         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxRevfollowConnection in ")+path+name+_T("\r\n"));
08404         if( selected.GetCount() > 0)
08405                 FollowLine( selected.GetHead(), true, ::GetKeyState( VK_CONTROL) < 0);
08406 }
08407 
08408 void CGMEView::OnCntxPortShowInParent() // 'Show Port in Parent' context command of a PORT
08409 {
08410         if( !contextPort) return;
08411         
08412         CGMEDoc::theInstance->ShowObject( CComPtr<IUnknown>( contextPort->mgaFco), TRUE);
08413         contextPort = 0;
08414 }
08415 
08416 void CGMEView::OnCntxPortLocateInBrw() // 'Locate Port in Browser' context command of a PORT
08417 {
08418         if( !contextPort) return;
08419 
08420         CGMEBrowser::theInstance->FocusItem( CComBSTR( contextPort->id));
08421         contextPort = 0;
08422 }
08423 
08424 void CGMEView::OnJumpAlongConnection() // 'Jump Along Conn' command on the Navigation toolbar
08425 {
08426         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnJumpAlongConnection in ")+path+name+_T("\r\n"));
08427         if( selected.GetCount() > 0)
08428                 FollowLine( selected.GetHead(), false, ::GetKeyState( VK_CONTROL) < 0);
08429 }
08430 
08431 void CGMEView::OnBackAlongConnection() // 'Jump back Along Conn' on Navigation toolbar
08432 {
08433         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnBackAlongConnection in ")+path+name+_T("\r\n"));
08434         if( selected.GetCount() > 0)
08435                 FollowLine( selected.GetHead(), true, ::GetKeyState( VK_CONTROL) < 0);
08436 }
08437 
08438 void CGMEView::OnTryToSnapHorzVertPath()
08439 {
08440         selectedContextConnection->VerticalAndHorizontalSnappingOfConnectionLineSegments(currentAspect->index, -1);
08441         selectedConnection->WriteCustomPathData();
08442 }
08443 
08444 void CGMEView::OnDeleteConnEdgeCustomData()
08445 {
08446         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDeleteConnEdgeCustomData in ")+path+name+_T("\r\n"));
08447         if (selectedContextConnection != NULL && contextConnectionEdgeIndex >= 0) {
08448                 if (contextConnectionCustomizationType == SimpleEdgeDisplacement) {
08449                         if (contextConnectionPartMoveMethod == HorizontalEdgeMove ||
08450                                 contextConnectionPartMoveMethod == AdjacentEdgeMove)
08451                         {
08452                                 int edgeIndex = contextConnectionEdgeIndex;
08453                                 if (contextConnectionPartMoveMethod == AdjacentEdgeMove && customizeHorizontalOrVerticalEdge)
08454                                         edgeIndex++;
08455                                 DeleteCustomEdges(selectedContextConnection, SimpleEdgeDisplacement, edgeIndex, false);
08456                         }
08457                         if (contextConnectionPartMoveMethod == VerticalEdgeMove ||
08458                                 contextConnectionPartMoveMethod == AdjacentEdgeMove)
08459                         {
08460                                 int edgeIndex = contextConnectionEdgeIndex;
08461                                 if (contextConnectionPartMoveMethod == AdjacentEdgeMove && !customizeHorizontalOrVerticalEdge)
08462                                         edgeIndex++;
08463                                 DeleteCustomEdges(selectedContextConnection, SimpleEdgeDisplacement, edgeIndex, true);
08464                         }
08465                 } else if (contextConnectionCustomizationType == CustomPointCustomization) {
08466                         DeleteCustomEdges(selectedContextConnection, CustomPointCustomization, contextConnectionEdgeIndex);
08467                 }
08468                 selectedContextConnection->WriteCustomPathData();
08469         }
08470         selectedContextConnection = NULL;
08471 }
08472 
08473 void CGMEView::OnDeleteConnPointCustomData()
08474 {
08475         OnDeleteConnEdgeCustomData();
08476 }
08477 
08478 void CGMEView::OnDeleteConnRouteCustomDataThisAspect()
08479 {
08480         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDeleteConnRouteCustomDataThisAspect in ")+path+name+_T("\r\n"));
08481         if (selectedContextConnection != NULL) {
08482                 selectedContextConnection->DeleteAllPathCustomizationsForCurrentAspect();
08483                 selectedContextConnection->WriteCustomPathData();
08484         }
08485         selectedContextConnection = NULL;
08486 }
08487 
08488 void CGMEView::OnDeleteConnRouteCustomDataAllAspects()
08489 {
08490         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDeleteConnRouteCustomDataAllAspects in ")+path+name+_T("\r\n"));
08491         if (selectedContextConnection != NULL) {
08492                 selectedContextConnection->DeleteAllPathCustomizationsForAllAspects();
08493                 selectedContextConnection->WriteCustomPathData();
08494         }
08495         selectedContextConnection = NULL;
08496 }
08497 
08498 void CGMEView::OnKillFocus(CWnd* pNewWnd)
08499 {
08500         bool destroyOverlay = true;
08501         CString name;
08502         if (pNewWnd)
08503         {
08504                 CWnd* parent = pNewWnd->GetParent();
08505                 CWnd* wnd = pNewWnd;
08506                 while (wnd)
08507                 {
08508                         if (wnd == parent)
08509                         {
08510                                 destroyOverlay = false;
08511                                 break;
08512                         }
08513                         wnd = wnd->GetParent();
08514                 }
08515         }
08516         if (destroyOverlay)
08517         {
08518                 //overlay = nullptr;
08519         }
08520 }
08521 
08522 void CGMEView::HighlightConnection(CGuiConnection* connection)
08523 {
08524         m_overlay = std::unique_ptr<GMEViewOverlay>(new GMEViewOverlay());
08525         CRect rect;
08526         GetWindowRect(&rect);
08527         if (this->GetStyle() & WS_VSCROLL)
08528         {
08529                 rect.right -= GetSystemMetrics(SM_CXVSCROLL);
08530         }
08531         if (this->GetStyle() & WS_HSCROLL)
08532         {
08533                 rect.bottom -= GetSystemMetrics(SM_CYHSCROLL);
08534         }
08535         rect.top++;
08536         rect.left++;
08537         rect.right--;
08538         rect.bottom--;
08539         LPCTSTR pszClassName = _T("GMEViewOverlay");
08540         WNDCLASS wndcls = {0};
08541     if (!::GetClassInfo(AfxGetInstanceHandle(), pszClassName, &wndcls))
08542     {
08543                 wndcls.style = CS_VREDRAW | CS_HREDRAW;
08544         wndcls.lpszClassName = pszClassName;
08545                 wndcls.lpfnWndProc = AfxWndProc;
08546                 wndcls.hInstance = AfxGetInstanceHandle();
08547         VERIFY(::RegisterClass(&wndcls));
08548     }
08549 
08550         if (m_overlay->CreateEx(0 /* GMEViewOverlay::style*/, L"GMEViewOverlay", NULL, GMEViewOverlay::exstyle, rect, 0, 0, 0) == FALSE)
08551         {
08552                 ASSERT(false);
08553                 return;
08554         }
08555         
08556         bool selected = connection->IsSelected();
08557         connection->SetSelect(true);
08558         
08559         m_overlay->Init1();
08560         if (1) {
08561                 OnPrepareDC(m_overlay->m_memcdc, NULL);
08562                 CPoint point = m_overlay->m_memcdc->GetViewportOrg();
08563                 {
08564                         Gdiplus::Graphics gdip(*m_overlay->m_memcdc);
08565                         //gdip.Clear(Gdiplus::Color(0));
08566                         //gdip.SetTransform(
08567                         gdip.SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
08568                         gdip.SetTextRenderingHint(Gdiplus::TextRenderingHintAntiAlias);
08569                         connection->Draw(*m_overlay->m_memcdc, &gdip);
08570                 }
08571                 m_overlay->m_memcdc->SetViewportOrg(0, 0);
08572         }
08573         m_overlay->Init2();
08574 
08575         connection->SetSelect(selected);
08576 
08577         AfxGetApp()->OnIdle(0); // update button status immediately (ON_UPDATE_COMMAND_UI)
08578 }
08579 
08580 bool CGMEView::jumpToSelectedEnd( CGuiConnectionList& p_collOfConns, bool p_reverse, bool p_tryPort)
08581 {
08582         int hmany = p_collOfConns.GetCount();
08583 
08584         if( hmany > 0)
08585         {
08586                 CGuiConnection*     a_conn       = p_collOfConns.GetHead();
08587                 CGuiFco*            a_neighbor   = a_conn? p_reverse? a_conn->src: a_conn->dst: 0;
08588                 CGuiPort*           a_port       = a_conn? p_reverse? a_conn->srcPort: a_conn->dstPort: 0;
08589 
08590                 if( hmany > 1)
08591                 {
08592                         CConnityDlg dlg( p_reverse);
08593                         dlg.setList( p_collOfConns);
08594                         if( IDOK != dlg.DoModal())
08595                                 return false;
08596 
08597                         a_conn     = dlg.getSelectedC(); // owerwrite with the selected one (if > 1)
08598                         a_neighbor = a_conn? p_reverse? a_conn->src: a_conn->dst: 0;
08599                         a_port     = a_conn? p_reverse? a_conn->srcPort: a_conn->dstPort: 0;
08600                 }
08601                         
08602                 if( a_neighbor)
08603                 {
08604                         if( p_tryPort && a_port && a_port->IsRealPort())
08605                                 CGMEDoc::theInstance->ShowObject( CComPtr<IUnknown>( a_port->mgaFco), TRUE);
08606                         else
08607                                 CGMEDoc::theInstance->ShowObject( CComPtr<IUnknown>( a_neighbor->mgaFco), TRUE);
08608                         HighlightConnection(a_conn);
08609                         return true;
08610                 }
08611         }
08612         return false;
08613 }
08614 
08615 bool CGMEView::FollowLine( CGuiConnection *p_guiConn, bool p_reverse, bool p_tryPort)
08616 {
08617         if( !p_guiConn) 
08618                 return false;
08619 
08620         CGuiConnectionList curr_conns;
08621         curr_conns.AddTail( p_guiConn);
08622 
08623         return jumpToSelectedEnd( curr_conns, p_reverse, p_tryPort);
08624 }
08625 
08626 bool CGMEView::FollowLine( CGuiPort* p_guiPort, bool p_reverse, bool p_tryPort)
08627 {
08628         if( !p_guiPort)
08629                 return false;
08630 
08631         CGuiConnectionList& curr_conns = p_reverse? p_guiPort->inConns: p_guiPort->outConns;
08632         return jumpToSelectedEnd( curr_conns, p_reverse, p_tryPort);
08633 }
08634 
08635 bool CGMEView::FollowLine( CGuiObject* p_guiObj, bool p_reverse, bool p_tryPort)
08636 {
08637         if( !p_guiObj)
08638                 return false;
08639 
08640         CGuiConnectionList curr_conns;
08641         p_guiObj->GetRelationsInOut( curr_conns, p_reverse);
08642         return jumpToSelectedEnd( curr_conns, p_reverse, p_tryPort);
08643 }
08644 
08645 bool areConnsForSels( CGuiObjectList& p_sels, bool p_inOrOut)
08646 {
08647         CGuiConnectionList conn_list;
08648         if( p_sels.GetCount() == 1)
08649         {
08650                 CGuiObject* head = p_sels.GetHead();
08651                 if( head) head->GetRelationsInOut( conn_list, p_inOrOut);
08652         }
08653         return conn_list.GetCount() > 0;
08654 }
08655 
08656 bool areConnsForPort( CGuiPort* p_contextPort, bool p_inOrOut)
08657 {
08658         return p_contextPort && (p_inOrOut? p_contextPort->inConns: p_contextPort->outConns).GetCount() > 0;
08659 }
08660 
08661 void CGMEView::OnUpdatePortCntxFollowConnection( CCmdUI* pCmdUI)
08662 {
08663         pCmdUI->Enable( areConnsForPort( contextPort, false));
08664 }
08665 
08666 void CGMEView::OnUpdatePortCntxRevfollowConnection( CCmdUI* pCmdUI)
08667 {
08668         pCmdUI->Enable( areConnsForPort( contextPort, true));
08669 }
08670 
08671 void CGMEView::OnUpdateCntxFollowConnection( CCmdUI* pCmdUI)
08672 {
08673         pCmdUI->Enable( areConnsForSels( selected, false));
08674 }
08675 
08676 void CGMEView::OnUpdateCntxRevfollowConnection( CCmdUI* pCmdUI)
08677 {
08678         pCmdUI->Enable( areConnsForSels( selected, true));
08679 }
08680 
08681 void CGMEView::OnUpdateJumpAlongConnection(CCmdUI* pCmdUI)
08682 {
08683         pCmdUI->Enable( areConnsForSels( selected, false));
08684 }
08685 
08686 void CGMEView::OnUpdateBackAlongConnection(CCmdUI* pCmdUI)
08687 {
08688         pCmdUI->Enable( areConnsForSels( selected, true));
08689 }
08690 
08691 void CGMEView::OnUpdateTryToSnapHorzVertPath(CCmdUI* pCmdUI)
08692 {
08693         pCmdUI->Enable(selectedContextConnection != NULL &&
08694                                    !selectedContextConnection->IsAutoRouted());
08695 }
08696 
08697 void CGMEView::OnUpdateDeleteConnEdgeCustomData(CCmdUI* pCmdUI)
08698 {
08699         pCmdUI->Enable(selectedContextConnection != NULL && selectedContextConnection->IsAutoRouted() &&
08700                                    selectedContextConnection->HasPathCustomizationForTypeAndCurrentAspect(SimpleEdgeDisplacement, contextConnectionEdgeIndex));
08701 }
08702 
08703 void CGMEView::OnUpdateDeleteConnPointCustomData(CCmdUI* pCmdUI)
08704 {
08705         pCmdUI->Enable(selectedContextConnection != NULL && !selectedContextConnection->IsAutoRouted() &&
08706                                    contextConnectionPartMoveMethod == ModifyExistingCustomPoint &&
08707                                    selectedContextConnection->HasPathCustomizationForTypeAndCurrentAspect(CustomPointCustomization, contextConnectionEdgeIndex));
08708 }
08709 
08710 void CGMEView::OnUpdateDeleteConnRouteCustomDataThisAspect(CCmdUI* pCmdUI)
08711 {
08712         pCmdUI->Enable(selectedContextConnection != NULL &&
08713                                    selectedContextConnection->HasPathCustomizationForCurrentAspect());
08714 }
08715 
08716 void CGMEView::OnUpdateDeleteConnRouteCustomDataAllAspects(CCmdUI* pCmdUI)
08717 {
08718         pCmdUI->Enable(selectedContextConnection != NULL &&
08719                                    selectedContextConnection->HasPathCustomization());
08720 }
08721 
08722 #if defined(ADDCRASHTESTMENU)
08723 void CGMEView::OnCrashTestIllegalWrite(void)
08724 {
08725         CrashTest::IllegalWrite();
08726 }
08727 
08728 void CGMEView::OnCrashTestIllegalRead(void)
08729 {
08730         CrashTest::IllegalRead();
08731 }
08732 
08733 void CGMEView::OnCrashTestIllegalReadInCRuntime(void)
08734 {
08735         CrashTest::IllegalReadInCRuntime();
08736 }
08737 
08738 void CGMEView::OnCrashTestIllegalCodeRead(void)
08739 {
08740         CrashTest::IllegalCodeRead();
08741 }
08742 
08743 void CGMEView::OnCrashTestDivideByZero(void)
08744 {
08745         CrashTest::DivideByZero();
08746 }
08747 
08748 void CGMEView::OnCrashTestAbort()
08749 {
08750         CrashTest::Abort();
08751 }
08752 
08753 void CGMEView::OnCrashTestTerminate()
08754 {
08755         CrashTest::Terminate();
08756 }
08757 
08758 void CGMEView::OnUpdateCrashTestMenu(CCmdUI* pCmdUI)
08759 {
08760         pCmdUI->Enable();
08761 }
08762 
08763 void CGMEView::OnUpdateCrashTestIllegalWrite(CCmdUI* pCmdUI)
08764 {
08765         pCmdUI->Enable();
08766 }
08767 
08768 void CGMEView::OnUpdateCrashTestIllegalRead(CCmdUI* pCmdUI)
08769 {
08770         pCmdUI->Enable();
08771 }
08772 
08773 void CGMEView::OnUpdateCrashTestIllegalReadInCRuntime(CCmdUI* pCmdUI)
08774 {
08775         pCmdUI->Enable();
08776 }
08777 
08778 void CGMEView::OnUpdateCrashTestIllegalCodeRead(CCmdUI* pCmdUI)
08779 {
08780         pCmdUI->Enable();
08781 }
08782 
08783 void CGMEView::OnUpdateCrashTestDivideByZero(CCmdUI* pCmdUI)
08784 {
08785         pCmdUI->Enable();
08786 }
08787 
08788 void CGMEView::OnUpdateCrashTestAbort(CCmdUI* pCmdUI)
08789 {
08790         pCmdUI->Enable();
08791 }
08792 
08793 void CGMEView::OnUpdateCrashTestTerminate(CCmdUI* pCmdUI)
08794 {
08795         pCmdUI->Enable();
08796 }
08797 #endif
08798 
08799 void CGMEView::OnCntxClear()    // set refs to null, delete all members from set
08800 {
08801         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxClear in ")+path+name+_T("\r\n"));
08802         if (!isType)
08803                 return;
08804         CGuiObject* obj = NULL;
08805         if (contextSelection)
08806                 obj = contextSelection->dynamic_cast_CGuiReference();
08807         if (contextSelection && !obj)
08808                 obj = contextSelection->dynamic_cast_CGuiCompoundReference();
08809         if (obj) {
08810                 try {
08811                         CGMEEventLogger::LogGMEEvent(_T("    ")+obj->GetName()+_T(" ")+obj->GetID()+_T("\r\n"));
08812                         BeginTransaction();
08813                         CComPtr<IMgaReference> mgaRef;
08814                         COMTHROW(obj->mgaFco.QueryInterface(&mgaRef));
08815                         CComPtr<IMgaFCO> nullFco;
08816                         COMTHROW(mgaRef->put_Referred(nullFco));
08817                         CommitTransaction();
08818                 }
08819                 catch(hresult_exception e) {
08820                         AbortTransaction(e.hr);
08821                         const TCHAR* t1 = _T("Cannot clear reference because of active connections!");
08822                         const TCHAR* t2 = _T("Cannot clear reference.");
08823                         if( e.hr == E_MGA_REFPORTS_USED)
08824                         {
08825                                 if( !CGMEConsole::theInstance) AfxMessageBox( t1);
08826                                 else CGMEConsole::theInstance->Message( t1, MSG_ERROR);
08827                         }
08828                         else
08829                                 if( !CGMEConsole::theInstance) AfxMessageBox( t2);
08830                                 else CGMEConsole::theInstance->Message( t2, MSG_ERROR);
08831                 }
08832         }
08833         else {
08834                 CGuiSet* set = NULL;
08835                 if (contextSelection)
08836                         set = contextSelection->dynamic_cast_CGuiSet();
08837                 if (set) {
08838                         try {
08839                                 CGMEEventLogger::LogGMEEvent(_T("    ")+set->GetName()+_T(" ")+set->GetID()+_T("\r\n"));
08840                                 BeginTransaction();
08841                                 CComPtr<IMgaSet> mgaSet;
08842                                 COMTHROW(set->mgaFco.QueryInterface(&mgaSet));
08843                                 COMTHROW(mgaSet->RemoveAll());
08844                                 CommitTransaction();
08845                         }
08846                         catch(hresult_exception e) {
08847                                 AbortTransaction(e.hr);
08848                         }
08849                 }
08850         }
08851 }
08852 
08853 void CGMEView::OnUpdateCntxClear(CCmdUI* pCmdUI)
08854 {
08855         CGuiObject* obj = NULL;
08856         if (contextSelection)
08857                 obj = contextSelection->dynamic_cast_CGuiReference();
08858         if (contextSelection && !obj)
08859                 obj = contextSelection->dynamic_cast_CGuiCompoundReference();
08860         if (contextSelection && !obj)
08861                 obj = contextSelection->dynamic_cast_CGuiSet();
08862         pCmdUI->Enable(isType && obj != 0);
08863 }
08864 
08865 void CGMEView::OnCntxReset()    // revert to base i.e. reestablish dependency chain for refs and sets
08866 {
08867         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxReset in ")+path+name+_T("\r\n"));
08868         CGuiObject* obj = NULL;
08869         if (contextSelection)
08870                 obj = contextSelection->dynamic_cast_CGuiReference();
08871         if (contextSelection && !obj)
08872                 obj = contextSelection->dynamic_cast_CGuiCompoundReference();
08873         if (obj) {
08874                 try {
08875                         CGMEEventLogger::LogGMEEvent(_T("    ")+obj->GetName()+_T(" ")+obj->GetID()+_T("\r\n"));
08876                         BeginTransaction();
08877                         CComPtr<IMgaReference> mgaRef;
08878                         COMTHROW(obj->mgaFco.QueryInterface(&mgaRef));
08879                         COMTHROW(mgaRef->RevertToBase());
08880                         CommitTransaction();
08881                 }
08882                 catch(hresult_exception e) {
08883                         AbortTransaction(e.hr);
08884                 }
08885         }
08886         else {
08887                 CGuiSet* set = NULL;
08888                 if (contextSelection)
08889                         set = contextSelection->dynamic_cast_CGuiSet();
08890                 if (set) {
08891                         try {
08892                                 CGMEEventLogger::LogGMEEvent(_T("    ")+set->GetName()+_T(" ")+set->GetID()+_T("\r\n"));
08893                                 BeginTransaction();
08894                                 CComPtr<IMgaSet> mgaSet;
08895                                 COMTHROW(set->mgaFco.QueryInterface(&mgaSet));
08896                                 COMTHROW(mgaSet->RevertToBase());
08897                                 CommitTransaction();
08898                         }
08899                         catch(hresult_exception e) {
08900                                 AbortTransaction(e.hr);
08901                         }
08902                 }
08903         }
08904 }
08905 
08906 void CGMEView::OnUpdateCntxReset(CCmdUI* pCmdUI)
08907 {
08908         CGuiObject* obj = NULL;
08909         if (contextSelection)
08910                 obj = contextSelection->dynamic_cast_CGuiReference();
08911         if (contextSelection && !obj)
08912                 obj = contextSelection->dynamic_cast_CGuiCompoundReference();
08913         if (contextSelection && !obj)
08914                 obj = contextSelection->dynamic_cast_CGuiSet();
08915         pCmdUI->Enable(baseType != 0 && obj != 0);
08916 }
08917 
08918 void CGMEView::OnEditPreferences()
08919 {
08920         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditPreferences in ")+path+name+_T("\r\n"));
08921         ShowPreferences();
08922 }
08923 
08924 void CGMEView::OnHelpHelp()
08925 {
08926         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnHelpHelp in ")+path+name+_T("\r\n"));
08927         CComPtr<IMgaFCO> fco;
08928         POSITION pos = selected.GetHeadPosition();
08929         if( pos) // if any object selected
08930         {
08931                 CGuiObject *obj = selected.GetAt( pos);
08932                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnHelpHelp for selected: ")+obj->GetID()+_T("\r\n"));
08933                 fco = obj->mgaFco;
08934         }
08935         else
08936                 COMTHROW(currentModel.QueryInterface(&fco));
08937 
08938         ShowHelp(fco);
08939 }
08940 
08941 void CGMEView::OnCntxHelp()
08942 {
08943         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxHelp in ")+path+name+_T("\r\n"));
08944         CComPtr<IMgaFCO> fco;
08945         if (contextSelection)
08946         {
08947                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextSelection->GetName()+_T(" ")+contextSelection->GetID()+_T("\r\n"));
08948                 fco = contextSelection->mgaFco;
08949         }
08950         else
08951                 currentModel.QueryInterface(&fco);
08952 
08953         ShowHelp(fco);
08954 
08955         contextSelection = 0;
08956         contextPort = 0;
08957 }
08958 
08959 
08960 
08961 void CGMEView::OnEditShowtype()
08962 {
08963         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditShowtype in ")+path+name+_T("\r\n"));
08964         contextSelection = 0;   // just to be on the safe side
08965         contextPort = 0;
08966         CComPtr<IMgaModel> type;
08967         FindDerivedFrom(currentModel,type);
08968         ShowModel(type);
08969         contextSelection = 0;
08970 }
08971 
08972 void CGMEView::OnUpdateEditShowtype(CCmdUI* pCmdUI)
08973 {
08974         pCmdUI->Enable(!isType);
08975 }
08976 
08977 void CGMEView::OnEditShowbasetype()
08978 {
08979         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnShowbasetype in ")+path+name+_T("\r\n"));
08980         CComPtr<IMgaModel> type;
08981         FindDerivedFrom(currentModel,type);
08982         ShowModel(type);
08983         contextSelection = 0;
08984         contextPort = 0;
08985 }
08986 
08987 void CGMEView::OnUpdateEditShowbasetype(CCmdUI* pCmdUI)
08988 {
08989         pCmdUI->Enable(isSubType);
08990 }
08991 
08992 void CGMEView::OnCntxShowtype()
08993 {
08994         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxShowtype in ")+path+name+_T("\r\n"));
08995         CComPtr<IMgaModel> model;
08996         GetModelInContext(model);
08997         CComPtr<IMgaModel> type;
08998         FindDerivedFrom(model,type);
08999         ShowModel(type);
09000         contextSelection = 0;
09001         contextPort = 0;
09002 }
09003 
09004 void CGMEView::OnUpdateCntxShowtype(CCmdUI* pCmdUI)
09005 {
09006         bool type = (contextSelection ? contextSelection->IsType() : isType);
09007         bool model = (contextSelection ? (contextSelection->dynamic_cast_CGuiModel() != NULL) : true);
09008         pCmdUI->Enable(model && !type);
09009 }
09010 
09011 void CGMEView::OnCntxShowbasetype()
09012 {
09013         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxShowbasetype in ")+path+name+_T("\r\n"));
09014         CComPtr<IMgaModel> model;
09015         GetModelInContext(model);
09016         CComPtr<IMgaModel> type;
09017         FindDerivedFrom(model,type);
09018         ShowModel(type);
09019         contextSelection = 0;
09020         contextPort = 0;
09021 }
09022 
09023 void CGMEView::OnUpdateCntxShowbasetype(CCmdUI* pCmdUI)
09024 {
09025         bool ok = false;
09026         bool type = contextSelection ? contextSelection->IsType() : isType;
09027         bool model = (contextSelection ? (contextSelection->dynamic_cast_CGuiModel() != NULL) : true);
09028         if(type && model) {
09029                 CComPtr<IMgaModel> model;
09030                 GetModelInContext(model);
09031                 CComPtr<IMgaModel> type;
09032                 FindDerivedFrom(model,type);
09033                 ok = (type != 0);
09034         }
09035         pCmdUI->Enable(ok);
09036 }
09037 
09038 
09039 void CGMEView::OnUpdateFileCheck(CCmdUI* pCmdUI)
09040 {
09041         pCmdUI->Enable(theApp.mgaConstMgr != NULL);
09042 }
09043 
09044 void CGMEView::OnUpdateFileCheckSelected(CCmdUI* pCmdUI)
09045 {
09046         pCmdUI->Enable(theApp.mgaConstMgr != NULL && selected.GetCount());
09047 }
09048 
09049 void CGMEView::OnFileCheck()
09050 {
09051         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnFileCheck in ")+path+name+_T("\r\n"));
09052         ASSERT(theApp.mgaConstMgr);
09053         if (!theApp.mgaConstMgr)
09054                 return;
09055         if(currentModel)
09056         {
09057                 // message boxes displayed from constraint manager if in interactive mode
09058                 theApp.mgaConstMgr->ObjectsInvokeEx(theApp.mgaProject, currentModel, NULL, NULL);
09059         }
09060         else
09061                 AfxMessageBox(_T("No context selection for CM."));
09062 }
09063 
09064 
09065 void CGMEView::OnFileCheckSelected()
09066 {
09067         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnFileCheckSelected in ")+path+name+_T("\r\n"));
09068         ASSERT(theApp.mgaConstMgr);
09069         if (!theApp.mgaConstMgr)
09070                 return;
09071         GMEEVENTLOG_GUIOBJS(selected);
09072         POSITION pos = selected.GetHeadPosition();
09073         if(pos)
09074         {
09075 
09076 #if(0)   // while we cannot add connections
09077                 while(pos) {
09078                         theApp.mgaConstMgr->ObjectsInvokeEx(
09079                                         theApp.mgaProject,
09080                                         selected.GetNext(pos)->mgaFco,
09081                                         NULL, NULL);
09082                 }
09083 #else
09084                 CComPtr<IMgaFCOs> fcos;
09085                 if(CGMEDoc::CreateFcoList(&selected,fcos,this)) {
09086                         MGACOLL_ITERATE(IMgaFCO, fcos) {
09087                                 theApp.mgaConstMgr->ObjectsInvokeEx(
09088                                                 theApp.mgaProject,
09089                                                 MGACOLL_ITER,
09090                                                 NULL, NULL);
09091                         } MGACOLL_ITERATE_END;
09092                 }
09093 #endif
09094         }
09095         else
09096                 AfxMessageBox(_T("No context selection for CM."));
09097 }
09098 
09099 void CGMEView::OnCntxCheck()
09100 {
09101         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxCheck\r\n"));
09102         CGMEEventLogger::LogGMEEvent(_T("    Selected FCOs:"));
09103         GMEEVENTLOG_GUIFCOS(selected);
09104 
09105         ASSERT(theApp.mgaConstMgr);
09106         if (!theApp.mgaConstMgr)
09107                 return;
09108 
09109         MSGTRY
09110         {
09111                 CComPtr<IMgaFCO> selfco;
09112 
09113                 if (selected.IsEmpty())
09114                         selfco = currentModel;
09115                 else
09116                 {
09117                         POSITION pos = selected.GetHeadPosition();
09118                         selfco = selected.GetNext(pos)->mgaFco;
09119                 }
09120                 theApp.mgaConstMgr->ObjectsInvokeEx(theApp.mgaProject, selfco, NULL, NULL);
09121         }
09122         MSGCATCH(_T("Error while trying to check the selected or current model"),;)
09123 }
09124 
09125 void CGMEView::OnCntxInterpret()
09126 {
09127         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxInterpret in ")+path+name+_T("\r\n"));
09128         CGMEEventLogger::LogGMEEvent(_T("    Selected FCOs:"));
09129         GMEEVENTLOG_GUIFCOS(selected);
09130         MSGTRY
09131         {
09132                 IMgaLauncherPtr launcher;
09133                 COMTHROW( launcher.CreateInstance(L"Mga.MgaLauncher") );
09134                 if(!launcher) {
09135                         AfxMessageBox(_T("Cannot start up component launcher"));
09136                 }
09137                 else {
09138                         CComPtr<IMgaFCO> focus;
09139                         CComPtr<IMgaFCOs> selfcos;
09140                         COMTHROW(selfcos.CoCreateInstance(OLESTR("Mga.MgaFCOs")));
09141                         COMTHROW(currentModel.QueryInterface(&focus));
09142                         if (!selected.IsEmpty()) {
09143                                 POSITION pos = selected.GetHeadPosition();
09144                                 while (pos) {
09145                                         CGuiFco *gfco = selected.GetNext(pos);
09146                                         COMTHROW(selfcos->Append(gfco->mgaFco));
09147                                 }
09148                         } else {
09149                                 COMTHROW(selfcos->Append(currentModel));
09150                         }
09151 
09152                         if(theApp.bNoProtect) COMTHROW( launcher->put_Parameter(CComVariant(true)));
09153                         // Disable the DCOM wait dialogs: if interpreters want them, they can do it themselves; but if they don't want them, they need to link to GME's mfc1xxu.dll
09154                         COleMessageFilter* messageFilter = AfxOleGetMessageFilter();
09155                         messageFilter->EnableBusyDialog(FALSE);
09156                         messageFilter->EnableNotRespondingDialog(FALSE);
09157                         std::shared_ptr<COleMessageFilter> busyRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableBusyDialog(TRUE); } );
09158                         std::shared_ptr<COleMessageFilter> notRespondingRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableNotRespondingDialog(TRUE); } );
09159 
09160                         MSGTRY {
09161                         launcher->__RunComponent(_bstr_t(), theApp.mgaProject, focus, selfcos, contextSelection ? GME_CONTEXT_START :  GME_BGCONTEXT_START);
09162                         } MSGCATCH(L"Component execution failed",;)
09163                 }
09164         }
09165         MSGCATCH(_T("Error while trying to run the interpreter"),;)
09166 }
09167 
09168 void CGMEView::OnCntxLocate()
09169 {
09170         // ?? 
09171         // position the Object Browser to the selected or current object
09172         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxLocate\r\n"));
09173         CGMEEventLogger::LogGMEEvent(_T("    Selected FCO:"));
09174         GMEEVENTLOG_GUIFCOS(selected);
09175 
09176         MSGTRY
09177         {
09178                 CComPtr<IMgaFCO> selfco;
09179 
09180                 if (selected.IsEmpty())
09181                         selfco = currentModel;
09182                 else
09183                 {
09184                         POSITION pos = selected.GetHeadPosition();
09185                         selfco = selected.GetNext(pos)->mgaFco;
09186                 }
09187                 BeginTransaction(TRANSACTION_READ_ONLY);
09188                 _bstr_t IDObj;
09189                 selfco->get_ID(IDObj.GetAddress());
09190                 CommitTransaction();
09191                 CGMEBrowser::theInstance->FocusItem(IDObj);
09192         }
09193         MSGCATCH(_T("Error while trying to check the selected or current model"),;)
09194 }
09195 
09196 void CGMEView::OnUpdateCntxCheck(CCmdUI* pCmdUI)
09197 {
09198         pCmdUI->Enable(!selected.IsEmpty()  ||  currentModel != NULL); 
09199 }
09200 
09201 void CGMEView::OnUpdateCntxInterpret(CCmdUI* pCmdUI)
09202 {
09203         pCmdUI->Enable(TRUE);   // selected.IsEmpty() means we'll activete the interpeter for the current model (currentModel)
09204 }
09205 
09206 void CGMEView::OnUpdateCntxLocate(CCmdUI* pCmdUI)
09207 {
09208         pCmdUI->Enable(!selected.IsEmpty()  ||  currentModel != NULL); 
09209 }
09210 
09211 void CGMEView::OnCntxRegistry()
09212 {
09213         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxRegistry in ")+path+name+_T("\r\n"));
09214         CComPtr<IMgaFCO> fco;
09215         if (contextSelection)
09216         {
09217                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextSelection->GetName()+_T(" ")+contextSelection->GetID()+_T("\r\n"));
09218                 fco = contextSelection->mgaFco;
09219         }
09220         else
09221                 currentModel.QueryInterface(&fco);
09222 
09223         ShowRegistryBrowser(fco);
09224 
09225         contextSelection = 0;
09226         contextPort = 0;
09227 
09228 }
09229 
09230 void CGMEView::OnEditRegistry()
09231 {
09232         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditRegistry in ")+path+name+_T("\r\n"));
09233         CComPtr<IMgaFCO> fco;
09234         COMTHROW(currentModel.QueryInterface(&fco));
09235         ShowRegistryBrowser(fco);
09236 }
09237 
09238 void CGMEView::OnEditAnnotations()
09239 {
09240         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditAnnotations in ")+path+name+_T("\r\n"));
09241         CComPtr<IMgaFCO> fco;
09242         COMTHROW(currentModel.QueryInterface(&fco));
09243         ShowAnnotationBrowser(fco, NULL);
09244 }
09245 
09246 
09247 void CGMEView::ShowRegistryBrowser(CComPtr<IMgaFCO> fco)
09248 {
09249         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowRegistryBrowser in ")+path+name+_T("\r\n"));
09250         try {
09251                 BeginTransaction();
09252 
09253                 CComObjPtr<IMgaLauncher> launcher;
09254                 COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") );
09255                 COMTHROW( launcher->RegistryBrowser(fco) );
09256                 CommitTransaction();
09257         }
09258         catch(hresult_exception &e) {
09259                 AbortTransaction(e.hr);
09260                 AfxMessageBox(_T("Unable to access object registry"),MB_OK | MB_ICONSTOP);
09261                 CGMEEventLogger::LogGMEEvent(_T("    Unable to access object registry.\r\n"));
09262         }
09263 }
09264 
09265 bool CGMEView::ShowAnnotationBrowser(CComPtr<IMgaFCO> fco, CComPtr<IMgaRegNode> focus)
09266 {
09267         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ShowAnnotationBrowser in ")+path+name+_T("\r\n"));
09268         bool success = true;
09269         try {
09270                 BeginTransaction();
09271                 CComObjPtr<IMgaLauncher> launcher;
09272                 COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") );
09273                 HRESULT hr = launcher->AnnotationBrowser(fco, focus);
09274                 if (hr == E_MGA_MUST_ABORT) {   // JIRA GME-236 special ret code, indicating that the dialog was cancelled
09275                         throw hresult_exception(S_OK);
09276                 } if (FAILED(hr)) {
09277                         ASSERT((_T("COMTHROW: Throwing HRESULT exception. Press IGNORE"), false));
09278                         throw hresult_exception(hr);
09279                 } else {
09280                         CommitTransaction();
09281                 }
09282         }
09283         catch(hresult_exception &e) {
09284                 success = false;
09285                 AbortTransaction(e.hr);
09286                 if (e.hr != S_OK) {
09287                         AfxMessageBox(_T("Unable to access annotations"),MB_OK | MB_ICONSTOP);
09288                         CGMEEventLogger::LogGMEEvent(_T("    Unable to access annotations.\r\n"));
09289                 }
09290         }
09291         return success;
09292 }
09293 
09294 void CGMEView::OnEditSync()
09295 {
09296         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditSync in ")+path+name+_T("\r\n"));
09297         CAspectSyncDlg dlg;
09298         VARIANT_BOOL isInstance = VARIANT_TRUE;
09299         BeginTransaction();
09300         HRESULT hr = currentModel->get_IsInstance(&isInstance);
09301         AbortTransaction(E_FAIL);
09302         ASSERT(SUCCEEDED(hr));
09303         if (isInstance != VARIANT_FALSE) {
09304                 AfxMessageBox(L"Cannot synchronize aspects for instances", MB_ICONEXCLAMATION);
09305                 return;
09306         }
09307         dlg.m_srcAspect = currentAspect;
09308         POSITION apos = guiMeta->aspects.GetHeadPosition();
09309         while (apos) {
09310                 CGuiMetaAspect *metaAspect = guiMeta->aspects.GetNext(apos);
09311                 dlg.m_allAspects.AddTail(metaAspect);
09312 
09313                 if (currentAspect == metaAspect) {
09314                         dlg.m_dstAspects.AddTail(metaAspect);
09315                 }
09316         }
09317 
09318         POSITION opos = children.GetHeadPosition();
09319         while (opos) {
09320                 CGuiFco* ofco = children.GetNext(opos);
09321                 ASSERT(ofco != NULL);
09322                 CGuiObject* obj = ofco->dynamic_cast_CGuiObject();
09323 
09324                 if (!obj) {
09325                         // It is a connection
09326                         continue;
09327                 }
09328 
09329                 bool isMoving;
09330                 if (selected.GetCount() > 0)
09331                         isMoving = (selected.Find(obj) != NULL);
09332                 else
09333                         isMoving = obj->IsVisible();
09334 
09335                 dlg.m_allObjects.AddTail(obj);
09336                 if (isMoving)
09337                         dlg.m_movingObjects.AddTail(obj);
09338         }
09339 
09340 
09341         if (dlg.DoModal() == IDOK) {
09342                 CGuiMetaAspectList dstAspects;
09343                 CGuiMetaAspect*    srcAspect;
09344                 CGuiObjectList     movingObjects;
09345                 CGuiObjectList     sedentaryObjects;
09346 
09347                 dstAspects.AddTail(&dlg.m_dstAspects);
09348                 srcAspect = dlg.m_srcAspect;
09349                 movingObjects.AddTail(&dlg.m_movingObjects);
09350 
09351 
09352                 POSITION opos = dlg.m_allObjects.GetHeadPosition();
09353                 while (opos) {
09354                         CGuiObject* obj = (CGuiObject*)dlg.m_allObjects.GetNext(opos);
09355                         if (!dlg.m_movingObjects.Find(obj))
09356                                 sedentaryObjects.AddTail(obj);
09357                 }
09358                 SyncAspects(srcAspect, dstAspects, movingObjects, sedentaryObjects, dlg.m_priorityForSrcVisible == TRUE, dlg.m_priorityForSelected == TRUE);
09359         }
09360 }
09361 
09362 void CGMEView::OnUpdateEditSync(CCmdUI* pCmdUI)
09363 {
09364         pCmdUI->Enable((guiMeta->aspects.GetCount()>1));
09365 }
09366 
09367 
09368 void CGMEView::SyncAspects(CGuiMetaAspect *srcAspect, CGuiMetaAspectList &dstAspects, CGuiObjectList &movingObjects, CGuiObjectList &sedentaryObjects,  bool priorityForSrcVisible, bool priorityForSelected)
09369 {
09370         CGMEEventLogger::LogGMEEvent(_T("CGMEView::SyncAspects in ")+path+name+_T("\r\n"));
09371         if(srcAspect)
09372                 CGMEEventLogger::LogGMEEvent(_T("    srcAspect=")+srcAspect->name+_T("\r\n"));
09373         CGMEEventLogger::LogGMEEvent(_T("    moving objects:"));
09374         GMEEVENTLOG_GUIOBJS(movingObjects);
09375         CGMEEventLogger::LogGMEEvent(_T("    sedentary objects:"));
09376         GMEEVENTLOG_GUIOBJS(sedentaryObjects);
09377         CGMEEventLogger::LogGMEEvent(_T("    dstAspects:\r\n"));
09378         try {
09379                 BeginTransaction(TRANSACTION_GENERAL);
09380                 BeginWaitCursor();
09381 
09382                 modelGrid.SetSource(this);
09383 
09384                 POSITION apos = dstAspects.GetHeadPosition();
09385                 while (apos) {
09386                         CGuiMetaAspect *dstAspect = dstAspects.GetNext(apos);
09387                         if (dstAspect == srcAspect)
09388                                 continue;
09389                         CGMEEventLogger::LogGMEEvent(_T("    ")+dstAspect->name+_T("\r\n"));
09390 
09391                         modelGrid.Clear();
09392 
09393                         POSITION pos;
09394 
09395                         if (!priorityForSelected) {
09396                                 pos = sedentaryObjects.GetHeadPosition();
09397                                 while (pos) {
09398                                         CGuiObject *obj = sedentaryObjects.GetNext(pos);
09399                                         if (obj->IsVisible(dstAspect->index)) {
09400                                                 SyncOnGrid(obj, dstAspect->index, dstAspect->index);
09401                                         }
09402                                 }
09403                         }
09404 
09405                         CGuiObjectList  lowPriorityObjects;
09406                         pos = movingObjects.GetHeadPosition();
09407                         while (pos) {
09408                                 CGuiObject *obj = movingObjects.GetNext(pos);
09409                                 if (obj->IsVisible(dstAspect->index)) {
09410                                         if (priorityForSrcVisible) {
09411                                                 if (obj->IsVisible(srcAspect->index)) {
09412                                                         SyncOnGrid(obj, srcAspect->index, dstAspect->index);
09413                                                 }
09414                                                 else {
09415                                                         lowPriorityObjects.AddTail(obj);
09416                                                 }
09417 
09418                                         }
09419                                         else {
09420                                                 if (obj->IsVisible(srcAspect->index)) {
09421                                                         lowPriorityObjects.AddTail(obj);
09422                                                 }
09423                                                 else {
09424                                                         SyncOnGrid(obj, dstAspect->index, dstAspect->index);
09425                                                 }
09426                                         }
09427                                 }
09428                         }
09429 
09430                         pos = lowPriorityObjects.GetHeadPosition();
09431                         while (pos) {
09432                                 CGuiObject *obj = lowPriorityObjects.GetNext(pos);
09433                                 if (priorityForSrcVisible) {
09434                                         SyncOnGrid(obj, dstAspect->index, dstAspect->index);
09435                                 }
09436                                 else {
09437                                         SyncOnGrid(obj, srcAspect->index, dstAspect->index);
09438                                 }
09439                         }
09440 
09441                         if (priorityForSelected) {
09442                                 pos = sedentaryObjects.GetHeadPosition();
09443                                 while (pos) {
09444                                         CGuiObject *obj = sedentaryObjects.GetNext(pos);
09445                                         if (obj->IsVisible(dstAspect->index)) {
09446                                                 SyncOnGrid(obj, dstAspect->index, dstAspect->index);
09447                                         }
09448                                 }
09449                         }
09450                 }
09451 
09452                 needsReset = true;
09453                 EndWaitCursor();
09454                 __CommitTransaction();
09455         }
09456         catch(hresult_exception &e) {
09457                 AbortTransaction(e.hr);
09458                 AfxMessageBox(_T("Unable to synchronize aspects"),MB_OK | MB_ICONSTOP);
09459                 CGMEEventLogger::LogGMEEvent(_T("    Unable to synchronize aspects.\r\n"));
09460                 EndWaitCursor();
09461                 return;
09462         }
09463         catch(_com_error& e) {                
09464                 AbortTransaction(e.Error());
09465                 CString error = _T("Unable to synchronize aspects");
09466                 if (e.Description().length() != 0)
09467                 {
09468                         error += _T(": ");
09469                         error += static_cast<const TCHAR*>(e.Description());
09470                 }
09471                 CGMEEventLogger::LogGMEEvent(error + _T("\r\n"));
09472                 AfxMessageBox(error, MB_ICONSTOP | MB_OK);
09473                 EndWaitCursor();
09474         }
09475 
09476 }
09477 
09478 void CGMEView::SyncOnGrid(CGuiObject *obj, int aspectIndexFrom, int aspectIndexTo)
09479 {
09480         // aspectIndexTo might be equal with aspectIndexFrom
09481         CRect loc = obj->GetLocation(aspectIndexFrom);//take the pos from the aspFrom (source) aspect
09482 
09483         if (!modelGrid.IsAvailable(obj, aspectIndexFrom)) {//is enough space to occupy the pos taken from the aspFrom aspect?
09484                 if (!modelGrid.GetClosestAvailable(obj, loc, aspectIndexTo)) { // if cannot get any position close to the position got above
09485                         //AfxMessageBox(_T("Too Many Models! Internal Program Error!"),MB_OK | MB_ICONSTOP);
09486                         //throw hresult_exception();
09487                 }
09488         }
09489         obj->SetLocation(loc, aspectIndexTo);
09490         modelGrid.Set(obj, FALSE, aspectIndexTo);
09491 }
09492 
09493 
09494 void CGMEView::OnEditSelectall()
09495 {
09496         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditSelectall in ")+path+name+_T("\r\n"));
09497         if (IsInElementDecoratorOperation())
09498                 return;
09499         this->SendUnselEvent4List( &selected);
09500         selected.RemoveAll();
09501         RemoveAllAnnotationFromSelection();
09502         ClearConnectionSelection();
09503         POSITION pos = children.GetHeadPosition();
09504         while(pos) {
09505                 CGuiFco* ofco = children.GetNext(pos);
09506                 ASSERT(ofco != NULL);
09507                 CGuiObject* obj = ofco->dynamic_cast_CGuiObject();
09508                 if(obj && obj->IsVisible()) {
09509                         this->SendSelecEvent4Object( obj);
09510                         selected.AddTail(obj);
09511                 }
09512         }
09513 
09514         GMEEVENTLOG_GUIOBJS(selected);
09515 
09516         pos = annotators.GetHeadPosition();
09517         while(pos) {
09518                 CGuiAnnotator *ann = annotators.GetNext(pos);
09519                 if (ann->IsVisible()) {
09520                         AddAnnotationToSelectionTail(ann);
09521                 }
09522         }
09523 
09524         GMEEVENTLOG_GUIANNOTATORS(selectedAnnotations);
09525         Invalidate();
09526         ChangeAttrPrefObjs(selected);
09527         this->SendNow();
09528 }
09529 
09530 
09531 void CGMEView::OnUpdateFileSettings(CCmdUI* pCmdUI)
09532 {
09533         // This is an update message for Tools/Options menu
09534         // This triggers the refresh of plugins/interpreters menus
09535         theApp.UpdateDynMenus(pCmdUI->m_pMenu);
09536 }
09537 
09538 void CGMEView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
09539 {
09540         CScrollZoomView::OnPrepareDC(pDC, pInfo);
09541 
09542         if (pDC->IsPrinting()) 
09543         {
09544                 PrepareAspectPrn(pInfo);
09545 /*
09546                 pDC->SetMapMode(MM_ISOTROPIC);
09547                 CRect extent, objext, annext;
09548                 CGuiObject::GetExtent(children,objext);
09549                 CGuiAnnotator::GetExtent(annotators,annext);
09550                 extent.UnionRect(&objext, &annext);
09551                 pDC->SetWindowExt(extent.right, extent.bottom);
09552                 double w, h;
09553                 w = GetDeviceCaps(pDC->m_hDC,PHYSICALWIDTH) - 4*GetDeviceCaps(pDC->m_hDC,PHYSICALOFFSETX);
09554                 h = GetDeviceCaps(pDC->m_hDC,PHYSICALHEIGHT)- 4*GetDeviceCaps(pDC->m_hDC,PHYSICALOFFSETY);
09555                 pDC->SetViewportExt((int)w, (int)h);
09556 */
09557         }
09558 }
09559 
09560 void CGMEView::OnEditPastespecialAssubtype()
09561 {
09562         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditPastespecialAssubtype in ")+path+name+_T("\r\n"));
09563         if(isType) {
09564                 COleDataObject clipboardData;
09565                 clipboardData.AttachClipboard();
09566                 derivedDrop = instanceDrop = false;
09567                 DoPasteItem(&clipboardData,false,false,false,true,false);
09568         }
09569 }
09570 
09571 void CGMEView::OnEditPastespecialAsinstance()
09572 {
09573         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditPastespecialAsinstance in ")+path+name+_T("\r\n"));
09574         if(isType) {
09575                 COleDataObject clipboardData;
09576                 clipboardData.AttachClipboard();
09577                 derivedDrop = instanceDrop = false;
09578                 DoPasteItem(&clipboardData,false,false,false,true,true);
09579         }
09580 }
09581 
09582 void CGMEView::OnEditPastespecialAsreference()
09583 {
09584         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditPastespecialAsreference in ")+path+name+_T("\r\n"));
09585         if(isType) {
09586                 COleDataObject clipboardData;
09587                 clipboardData.AttachClipboard();
09588                 derivedDrop = instanceDrop = false;
09589                 DoPasteItem(&clipboardData,false,false,true);
09590         }
09591 }
09592 
09593 void CGMEView::OnEditPastespecialAsclosure()
09594 {
09595         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditPastespecialAsclosure in ")+path+name+_T("\r\n"));
09596         if(isType) {
09597                 COleDataObject clipboardData;
09598                 clipboardData.AttachClipboard();
09599                 derivedDrop = instanceDrop = false;
09600                 DoPasteItem(&clipboardData,false,false,false,false,false,true, false);
09601         }
09602 }
09603 
09604 void CGMEView::OnEditPastespecialAdditive()
09605 {
09606         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditPastespecialAdditive in ")+path+name+_T("\r\n"));
09607         if(isType) {
09608                 COleDataObject clipboardData;
09609                 clipboardData.AttachClipboard();
09610                 derivedDrop = instanceDrop = false;
09611                 DoPasteItem(&clipboardData,false,false,false,false,false,true, false);
09612         }
09613 }
09614 
09615 void CGMEView::OnEditPastespecialMerge()
09616 {
09617         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnEditPastespecialMerge in ")+path+name+_T("\r\n"));
09618         if(isType) {
09619                 COleDataObject clipboardData;
09620                 clipboardData.AttachClipboard();
09621                 derivedDrop = instanceDrop = false;
09622                 DoPasteItem(&clipboardData,false,false,false,false,false,true, true);
09623         }
09624 }
09625 
09626 void CGMEView::OnUpdateEditPastespecialAsinstance(CCmdUI* pCmdUI)
09627 {
09628         OnUpdateEditPaste(pCmdUI);
09629 }
09630 
09631 void CGMEView::OnUpdateEditPastespecialAsreference(CCmdUI* pCmdUI)
09632 {
09633         OnUpdateEditPaste(pCmdUI);
09634 }
09635 
09636 void CGMEView::OnUpdateEditPastespecialAssubtype(CCmdUI* pCmdUI)
09637 {
09638         OnUpdateEditPaste(pCmdUI);
09639 }
09640 
09641 void CGMEView::OnUpdateEditPastespecialAsclosure(CCmdUI* pCmdUI)
09642 {
09643         OnUpdateEditPaste(pCmdUI);
09644 }
09645 
09646 void CGMEView::OnUpdateEditPastespecialAdditive(CCmdUI* pCmdUI)
09647 {
09648         OnUpdateEditPaste(pCmdUI);
09649 }
09650 
09651 void CGMEView::OnUpdateEditPastespecialMerge(CCmdUI* pCmdUI)
09652 {
09653         OnUpdateEditPaste(pCmdUI);
09654 }
09655 
09656 void CGMEView::OnCntxPastespecialAsinstance()
09657 {
09658         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxPastespecialAsinstance in ")+path+name+_T("\r\n"));
09659         if(isType) {
09660                 COleDataObject clipboardData;
09661                 clipboardData.AttachClipboard();
09662                 derivedDrop = instanceDrop = true;
09663                 DoPasteItem(&clipboardData,true,false,false,true,true,false,false,0,contextMenuLocation);
09664         }
09665 }
09666 
09667 void CGMEView::OnUpdateCntxPastespecialAsinstance(CCmdUI* pCmdUI)
09668 {
09669         OnUpdateEditPaste(pCmdUI);
09670 }
09671 
09672 void CGMEView::OnCntxPastespecialAsreference()
09673 {
09674         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxPastespecialAsreference in ")+path+name+_T("\r\n"));
09675         if(isType) {
09676                 COleDataObject clipboardData;
09677                 clipboardData.AttachClipboard();
09678                 derivedDrop = instanceDrop = false;
09679                 DoPasteItem(&clipboardData,true,false,true,false,false,false,false,0,contextMenuLocation);
09680         }
09681 }
09682 
09683 void CGMEView::OnUpdateCntxPastespecialAsreference(CCmdUI* pCmdUI)
09684 {
09685         OnUpdateEditPaste(pCmdUI);
09686 }
09687 
09688 void CGMEView::OnCntxPastespecialAssubtype()
09689 {
09690         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxPastespecialAssubtype in ")+path+name+_T("\r\n"));
09691         if(isType) {
09692                 COleDataObject clipboardData;
09693                 clipboardData.AttachClipboard();
09694                 derivedDrop = true;
09695                 instanceDrop = false;
09696                 DoPasteItem(&clipboardData,true,false,false,true,false,false,false,0,contextMenuLocation);
09697         }
09698 }
09699 
09700 void CGMEView::OnUpdateCntxPastespecialAssubtype(CCmdUI* pCmdUI)
09701 {
09702         OnUpdateEditPaste(pCmdUI);
09703 }
09704 
09705 void CGMEView::OnCntxPastespecialAsclosure()
09706 {
09707         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxPastespecialAsclosure in ")+path+name+_T("\r\n"));
09708         if(isType) {
09709                 COleDataObject clipboardData;
09710                 clipboardData.AttachClipboard();
09711                 derivedDrop = true;
09712                 instanceDrop = false;
09713                 DoPasteItem(&clipboardData,false,false,false,false,false,true,false,0,contextMenuLocation);
09714         }
09715 }
09716 
09717 void CGMEView::OnUpdateCntxPastespecialAsclosure(CCmdUI* pCmdUI)
09718 {
09719         OnUpdateEditPaste(pCmdUI);
09720 }
09721 
09722 void CGMEView::OnCntxPastespecialAdditive()
09723 {
09724         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxPastespecialAdditive in ")+path+name+_T("\r\n"));
09725         if(isType) {
09726                 COleDataObject clipboardData;
09727                 clipboardData.AttachClipboard();
09728                 derivedDrop = true;
09729                 instanceDrop = false;
09730                 DoPasteItem(&clipboardData,false,false,false,false,false,true,false,0,contextMenuLocation);
09731         }
09732 }
09733 
09734 void CGMEView::OnUpdateCntxPastespecialAdditive(CCmdUI* pCmdUI)
09735 {
09736         OnUpdateEditPaste(pCmdUI);
09737 }
09738 
09739 void CGMEView::OnCntxPastespecialMerge()
09740 {
09741         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxPastespecialMerge in ")+path+name+_T("\r\n"));
09742         if(isType) {
09743                 COleDataObject clipboardData;
09744                 clipboardData.AttachClipboard();
09745                 derivedDrop = true;
09746                 instanceDrop = false;
09747                 DoPasteItem(&clipboardData,false,false,false,false,false,true,true,0,contextMenuLocation);
09748         }
09749 }
09750 
09751 void CGMEView::OnUpdateCntxPastespecialMerge(CCmdUI* pCmdUI)
09752 {
09753         OnUpdateEditPaste(pCmdUI);
09754 }
09755 
09756 void CGMEView::OnCntxRedirectionpaste()
09757 {
09758         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxRedirectionpaste in ")+path+name+_T("\r\n"));
09759         if(isType && contextSelection) {
09760                 CGuiObject* ref = contextSelection->dynamic_cast_CGuiReference();
09761                 if (!ref)
09762                         ref = contextSelection->dynamic_cast_CGuiCompoundReference();
09763                 if (ref) {
09764                         COleDataObject clipboardData;
09765                         clipboardData.AttachClipboard();
09766                         derivedDrop = instanceDrop = false;
09767                         DoPasteItem(&clipboardData,true,false,true,false,false,false,false,ref,contextMenuLocation);
09768                 }
09769         }
09770 }
09771 
09772 void CGMEView::OnUpdateCntxRedirectionpaste(CCmdUI* pCmdUI)
09773 {
09774         BOOL bEnable = (contextSelection != 0);
09775         CGuiObject* ref = NULL;
09776         if (contextSelection != NULL)
09777                 ref = contextSelection->dynamic_cast_CGuiReference();
09778         if (contextSelection && !ref)
09779                 ref = contextSelection->dynamic_cast_CGuiCompoundReference();
09780         bEnable = bEnable && (ref != 0);
09781         COleDataObject dataObj;
09782         bEnable = bEnable && dataObj.AttachClipboard() &&
09783                 (CGMEDataSource::IsGmeNativeDataAvailable(&dataObj,theApp.mgaProject));
09784 
09785         pCmdUI->Enable(bEnable);
09786 }
09787 
09788 void CGMEView::OnCntxConnect()
09789 {
09790         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxConnect in ")+path+name+_T("\r\n"));
09791         if (contextSelection) {
09792                 CGuiObject* obj = contextSelection->dynamic_cast_CGuiObject();
09793                 if (obj) {
09794                         CGuiPort* port = obj->FindPort(contextMenuLocation);
09795                         if (connSrc == 0) {
09796                                 connSrc = obj;
09797                                 connSrcPort = port;
09798                                 connSrcHotSide = GME_CENTER;
09799                                 tmpConnectMode = true;
09800                                 SetCursor(autoconnect2Cursor);
09801                         }
09802                         else {
09803                                 Connect(connSrc,connSrcPort,connSrcHotSide,obj,port, GME_CENTER, ::GetKeyState(VK_SHIFT) < 0);
09804                                 ClearConnSpecs();
09805                                 tmpConnectMode = false;
09806                                 SetCursor(editCursor);
09807                         }
09808                         ShowCursor(TRUE);
09809                         Invalidate();
09810                 }
09811         }
09812 }
09813 
09814 void CGMEView::OnUpdateCntxConnect(CCmdUI* pCmdUI)
09815 {
09816         pCmdUI->Enable(GetDocument()->GetEditMode() == GME_EDIT_MODE && isType);
09817 }
09818 
09819 void CGMEView::OnResetSticky()
09820 {
09821         CGMEDoc *doc = GetDocument();
09822         if(doc && doc->resolver) {
09823                 COMTHROW(doc->resolver->Clear());
09824         }
09825 }
09826 
09827 void CGMEView::OnNcMouseMove(UINT nHitTest, CPoint point)
09828 {
09829         if (nHitTest != HTCLIENT && !IsInElementDecoratorOperation() && IsCursorChangedByDecorator())
09830                 SetEditCursor();
09831         else
09832                 CScrollZoomView::OnNcMouseMove(nHitTest, point);
09833 }
09834 
09835 bool CGMEView::IsLegalConnectionEnd(CGuiObject *connEnd, CGuiPort *port)
09836 {
09837         IMgaMetaModelPtr metaModel = guiMeta->mgaMeta.p;
09838         IMgaMetaRolePtr srcMeta = connSrc->dynamic_cast_CGuiObject()->metaRole.p;
09839         IMgaMetaRolePtr srcPortMeta = connSrcPort ? connSrcPort->metaRole.p : NULL;
09840         IMgaMetaRolePtr dstMeta = connEnd->dynamic_cast_CGuiObject()->metaRole.p;
09841         IMgaMetaRolePtr dstPortMeta = port ? port->metaRole.p : NULL;
09842 
09843         wchar_t srcPath[100];
09844         if (srcPortMeta)
09845                 swprintf_s(srcPath, L"src %d %d, ", srcMeta->MetaRef, srcPortMeta->MetaRef);
09846         else
09847                 swprintf_s(srcPath, L"src %d, ", srcMeta->MetaRef);
09848 
09849         wchar_t dstPath[100];
09850         if (dstPortMeta)
09851                 swprintf_s(dstPath, L"dst %d %d", dstMeta->MetaRef, dstPortMeta->MetaRef);
09852         else
09853                 swprintf_s(dstPath, L"dst %d", dstMeta->MetaRef);
09854 
09855         _bstr_t path = srcPath;
09856         path += dstPath;
09857 
09858         IMgaMetaRolesPtr roles = metaModel->__LegalConnectionRoles(path);
09859 
09860         // TODO: check for primary aspect
09861 
09862         return roles->Count > 0;
09863 }
09864 
09865 void CGMEView::OnMouseMove(UINT nFlags, CPoint screenpoint)
09866 {
09867         if (!isLeftMouseButtonDown || (GetKeyState(VK_LBUTTON) & 0x8000) == 0) {
09868                 isConnectionJustSelected = false;
09869                 isLeftMouseButtonDown = false;
09870         }
09871 
09872         CGMEView *self = const_cast<CGMEView *>(this);
09873         CPoint point(screenpoint);
09874         CoordinateTransfer(point);
09875 
09876         {
09877                 CGuiObject *object = self ? self->FindObject(point) : 0;
09878                 CGuiPort   *port   = object? object->FindPort(point) : 0;
09879                 if(object && object != lastObject && theApp.isMouseOverNotifyEnabled()/* && GetDocument()->GetEditMode() == GME_EDIT_MODE*/) {
09880                         this->SendMouseOver4Object(object);
09881                 }
09882                 lastObject = object;
09883                 lastPort = port;
09884         }
09885 
09886         if (GetDocument()->GetEditMode() == GME_EDIT_MODE) { // new decorator notification logic
09887                 //static CGuiObject* lastObject = 0;
09888                 CGuiObject*     object  = self          ? self->FindObject(point, true) : 0;
09889                 CGuiPort*       port    = object        ? object->FindPort(point, true) : 0;
09890                 if (object == NULL)
09891                         object = self ? self->FindObject(point, true, true) : 0;
09892                 CGuiAnnotator* annotation = FindAnnotation(point);
09893 
09894                 if (IsInElementDecoratorOperation()) {
09895                         CComPtr<IMgaElementDecorator> newDecorator;
09896                         if (IsDecoratorOrAnnotator()) {
09897                                 CGuiObject* objInOp = GetObjectInDecoratorOperation();
09898                                 // It can be NULL: if we start a label edit operation and we double click on another label
09899                                 // then in-spite of the modal behavior of the in-place dialog GMEView gets MouseMoves
09900                                 if (objInOp != NULL) {
09901                                         CGuiAspect* pAspect = objInOp->GetCurrentAspect();
09902                                         if (pAspect != NULL) {
09903                                                 CComQIPtr<IMgaElementDecorator> newDecorator2(pAspect->GetDecorator());
09904                                                 newDecorator = newDecorator2;
09905                                         }
09906                                 }
09907                         } else {
09908                                 CGuiAnnotator* annInOp = GetAnnotatorInDecoratorOperation();
09909                                 if (annInOp != NULL)
09910                                         newDecorator = annInOp->GetDecorator(currentAspect->index);
09911                         }
09912                         if (newDecorator) {
09913                                 CClientDC transformDC(this);
09914                                 OnPrepareDC(&transformDC);
09915                                 HRESULT retVal = newDecorator->MouseMoved(nFlags, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
09916                                 if (retVal == S_DECORATOR_EVENT_HANDLED) {
09917                                         CScrollZoomView::OnMouseMove(nFlags, screenpoint);
09918                                         return;
09919                                 } else if (retVal != S_OK &&
09920                                                    retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
09921                                                    retVal != E_DECORATOR_NOT_IMPLEMENTED)
09922                                 {
09923                                         CancelDecoratorOperation();
09924                                         // FIXME: how to handle this error?
09925                                         // COMTHROW(retVal);
09926                                         return;
09927                                 }
09928                         }
09929                 } else if (isInConnectionCustomizeOperation) {
09930                         // Update Connection Customization Tracker
09931                         customizeConnectionCurrCursor = point;
09932                         Invalidate();
09933                 } else if (object != NULL || annotation != NULL) {
09934                         CComPtr<IMgaElementDecorator> newDecorator;
09935                         if (object != NULL) {
09936                                 CGuiAspect* pAspect = object->GetCurrentAspect();
09937                                 if (pAspect != NULL) {
09938                                         CComQIPtr<IMgaElementDecorator> newDecorator2(pAspect->GetDecorator());
09939                                         newDecorator = newDecorator2;
09940                                 }
09941                         } else {
09942                                 ASSERT(annotation != NULL);
09943                                 newDecorator = annotation->GetDecorator(currentAspect->index);
09944                         }
09945                         if (newDecorator) {
09946                                 CClientDC transformDC(this);
09947                                 OnPrepareDC(&transformDC);
09948                                 HRESULT retVal = newDecorator->MouseMoved(nFlags, point.x, point.y, (ULONGLONG)transformDC.m_hDC);
09949                                 if (retVal == S_DECORATOR_EVENT_HANDLED) {
09950                                         CScrollZoomView::OnMouseMove(nFlags, screenpoint);
09951                                         return;
09952                                 } else if (retVal != S_OK &&
09953                                                    retVal != S_DECORATOR_EVENT_NOT_HANDLED &&
09954                                                    retVal != E_DECORATOR_NOT_IMPLEMENTED)
09955                                 {
09956                                         CancelDecoratorOperation();
09957                                         // FIXME: how to handle this error?
09958                                         // COMTHROW(retVal);
09959                                         return;
09960                                 }
09961                         }
09962                 } else {
09963                         if (selectedConnection != NULL && !isConnectionJustSelected) {
09964                                 SetConnectionCustomizeCursor(point);
09965                         } else {
09966                                 if (isCursorChangedByEdgeCustomize) {
09967                                         ::SetCursor(customizeConnectionCursorBackup);
09968                                         isCursorChangedByEdgeCustomize = false;
09969                                 }
09970                         }
09971                         if (IsCursorChangedByDecorator())
09972                                 SetEditCursor();
09973                 }
09974         }
09975 
09976         if (GetDocument()->GetEditMode() == GME_VISUAL_MODE)
09977         {
09978                 CGuiObject *object = self? self->FindObject(point): 0;
09979                 // if object found, curr_Connection will be 0
09980                 CGuiConnection        *curr_Connection = object? 0: router.FindConnection( point);
09981                 if( last_Connection != curr_Connection) // state change for at most two connections
09982                 {
09983                         if( last_Connection) last_Connection->ToggleHover(); // if a previous was selected, now it will become unselected
09984                         if( curr_Connection) curr_Connection->ToggleHover(); // toggle the new one
09985                         last_Connection = curr_Connection;
09986                         Invalidate();
09987                 } 
09988         }
09989         if ((GetDocument()->GetEditMode() == GME_AUTOCONNECT_MODE || GetDocument()->GetEditMode() == GME_SHORTAUTOCONNECT_MODE || (tmpConnectMode))) {
09990                 CGuiObject *object = self->FindObject(point);
09991                 CGuiPort *port = object ? object->FindPort(point) : NULL;
09992                 if (object && (connSrc == NULL || IsLegalConnectionEnd(object, port))) {
09993                         CRect rect = object->GetLocation();
09994                         int hotSide = GME_CENTER;
09995                         if(port && port->IsRealPort()) {
09996                                 rect = port->GetLocation() + rect.TopLeft();
09997                         }
09998                         else {
09999                                 port = NULL;
10000 
10001                                 if (object->IsHotspotEnabled()) {
10002                                         int mx = rect.CenterPoint().x;
10003                                         int my = rect.CenterPoint().y;
10004                                         int hsRadx = GME_HOTSPOT_RADIUS;
10005                                         int hsRady = GME_HOTSPOT_RADIUS;
10006                                         if (rect.Width() < (GME_HOTSPOT_RADIUS * 3)) {
10007                                                 hsRadx = rect.Width()/3;
10008                                         }
10009                                         if (rect.Height() < (GME_HOTSPOT_RADIUS * 3)) {
10010                                                 hsRady = rect.Height()/3;
10011                                         }
10012                                         if ( abs(point.x - mx) < hsRadx) {
10013                                                 if ( abs(point.y - rect.top) < hsRady ) {
10014                                                         hotSide = GME_NORTH;
10015                                                 }
10016                                                 if ( abs(point.y - rect.bottom) < hsRady ) {
10017                                                         hotSide = GME_SOUTH;
10018                                                 }
10019                                         }
10020                                         else if ( abs(point.y - my) < hsRady) {
10021                                                 if ( abs(point.x - rect.left) < hsRadx ) {
10022                                                         hotSide = GME_WEST;
10023                                                 }
10024                                                 if ( abs(point.x - rect.right) < hsRadx ) {
10025                                                         hotSide = GME_EAST;
10026                                                 }
10027                                         }
10028                                 }
10029                         }
10030 
10031                         if((object != connTmp) || (port != connTmpPort) || (hotSide != connTmpHotSide)) {
10032                                         connTmp = object;
10033                                         connTmpPort = port;
10034                                         connTmpHotSide = hotSide;
10035                                         Invalidate();
10036                         }
10037                 }
10038                 else {
10039                         connTmp = NULL;
10040                         connTmpPort = NULL;
10041                         connTmpHotSide = GME_CENTER;
10042                         Invalidate();
10043                 }
10044         }
10045 
10046         CScrollZoomView::OnMouseMove(nFlags, screenpoint);
10047 }
10048 
10049 void CGMEView::ClearConnSpecs()
10050 {
10051         connSrc = NULL;
10052         connSrcPort = NULL;
10053         connSrcHotSide = GME_CENTER;
10054         connTmp = NULL;
10055         connTmpPort = NULL;
10056         connTmpHotSide = GME_CENTER;
10057 }
10058 
10059 void CGMEView::OnTimer(UINT_PTR nIDEvent)
10060 {
10061         if (nIDEvent == GME_ANIM_EVENT_ID) {
10062                 Invalidate();
10063         }
10064         CScrollZoomView::OnTimer(nIDEvent);
10065 }
10066 
10067 void CGMEView::OnUpdateCntxInsertannotation(CCmdUI* pCmdUI)
10068 {
10069         pCmdUI->Enable(TRUE);
10070 }
10071 
10072 void CGMEView::OnCntxInsertannotation()
10073 {
10074         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxInsertannotation in ")+path+name+_T("\r\n"));
10075         CComPtr<IMgaRegNode> rootReg;
10076         try {
10077                 BeginTransaction();
10078                 int annID = 0;
10079                 bool found = false;
10080 
10081                 while (!found) {
10082                         rootReg = NULL;
10083                         CString path;
10084                         path.Format(_T("%s/%s%d"), AN_ROOT, AN_DEFANNOTATION_NAME, annID++);
10085                         CComBSTR bstr(path);
10086                         COMTHROW(currentModel->get_RegistryNode(bstr, &rootReg));
10087                         long status;
10088                         COMTHROW(rootReg->get_Status(&status));
10089                         if (status == ATTSTATUS_UNDEFINED) {
10090                                 found = true;
10091                         }
10092                 }
10093 
10094                 CComBSTR value(AN_DEFAULTANNOTATION_TXT);
10095                 COMTHROW(rootReg->put_Value(value));
10096 
10097                 CComPtr<IMgaRegNode> aspRoot;
10098                 CComBSTR aspName(AN_ASPECTS);
10099                 COMTHROW(rootReg->get_SubNodeByName(aspName, &aspRoot));
10100                 CString pos;
10101                 pos.Format(_T("%d,%d"), contextMenuLocation.x, contextMenuLocation.y);
10102                 CComBSTR posval(pos);
10103                 COMTHROW(aspRoot->put_Value(posval));
10104 
10105                 CComPtr<IMgaRegNode> defAspNode;
10106                 CComBSTR defAspName(AN_DEFASPECT);
10107                 COMTHROW(aspRoot->get_SubNodeByName(defAspName, &defAspNode));
10108                 CComBSTR bstrVis(AN_VISIBLE_DEFAULT);
10109                 COMTHROW(defAspNode->put_Value(bstrVis));
10110 
10111                 CComPtr<IMgaFCO> fcoToShow;
10112                 currentModel.QueryInterface(&fcoToShow);
10113 
10114                 if (ShowAnnotationBrowser(fcoToShow, rootReg)) {
10115                         // ANNTODO: new object id list
10116                         CommitTransaction();
10117                 } else {
10118                         throw hresult_exception(S_OK);  // the dialog was cancelled
10119                 }
10120         }
10121         catch(hresult_exception &e) {
10122                 AbortTransaction(e.hr);
10123                 if (e.hr != S_OK) {
10124                         AfxMessageBox(_T("Unable to insert annotation"),MB_ICONSTOP | MB_OK);
10125                         CGMEEventLogger::LogGMEEvent(_T("    Unable to insert annotation.\r\n"));
10126                         return;
10127                 }
10128         }
10129         Invalidate(true);
10130 }
10131 
10132 void CGMEView::OnCntxAnnotations()
10133 {
10134         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxAnnotations in ")+path+name+_T("\r\n"));
10135         CComPtr<IMgaFCO> fco;
10136         currentModel.QueryInterface(&fco);
10137         ShowAnnotationBrowser(fco, contextAnnotation ? contextAnnotation->rootNode : NULL);
10138         contextAnnotation = NULL;
10139         contextSelection = NULL;
10140 }
10141 
10142 void CGMEView::OnUpdateCntxAutoRouters( CCmdUI* pCmdUI )
10143 {
10144         pCmdUI->Enable();
10145         if ( contextSelection ) {
10146                 CComPtr<IMgaFCO> spFCO = contextSelection->mgaFco;
10147                 if ( spFCO ) {
10148                         BeginTransaction(TRANSACTION_READ_ONLY);
10149                         CComBSTR bstrPref;
10150                         COMTHROW( spFCO->get_RegistryValue( CComBSTR( AUTOROUTER_PREF ), &bstrPref ) );
10151                         CommitTransaction();
10152                         CString strPref( bstrPref );
10153                         switch ( pCmdUI->m_nID ) {
10154                                 case ID_CNTX_SRCAR_NORTH :      pCmdUI->SetCheck( ( strPref.Find( _T("N") ) != -1 ) ? 1 : 0 ); return;
10155                                 case ID_CNTX_SRCAR_SOUTH :      pCmdUI->SetCheck( ( strPref.Find( _T("S") ) != -1 ) ? 1 : 0 ); return;
10156                                 case ID_CNTX_SRCAR_WEST :       pCmdUI->SetCheck( ( strPref.Find( _T("W") ) != -1 ) ? 1 : 0 ); return;
10157                                 case ID_CNTX_SRCAR_EAST :       pCmdUI->SetCheck( ( strPref.Find( _T("E") ) != -1 ) ? 1 : 0 ); return;
10158                                 case ID_CNTX_DSTAR_NORTH :      pCmdUI->SetCheck( ( strPref.Find( _T("n") ) != -1 ) ? 1 : 0 ); return;
10159                                 case ID_CNTX_DSTAR_SOUTH :      pCmdUI->SetCheck( ( strPref.Find( _T("s") ) != -1 ) ? 1 : 0 ); return;
10160                                 case ID_CNTX_DSTAR_WEST :       pCmdUI->SetCheck( ( strPref.Find( _T("w") ) != -1 ) ? 1 : 0 ); return;
10161                                 case ID_CNTX_DSTAR_EAST :       pCmdUI->SetCheck( ( strPref.Find( _T("e") ) != -1 ) ? 1 : 0 ); return;
10162                         }
10163                         int iCnt = 0;
10164                         bool bSet = pCmdUI->m_nID == ID_CNTX_SRCAR_SET || pCmdUI->m_nID == ID_CNTX_DSTAR_SET;
10165                         CString str = ( pCmdUI->m_nID == ID_CNTX_SRCAR_SET || pCmdUI->m_nID == ID_CNTX_SRCAR_CLEAR ) ? _T("NEWS") : _T("news");
10166                         for ( int i = 0 ; i < 4 ; i++ )
10167                                 if ( strPref.Find( str.Mid( i, 1 ) ) != -1 ) iCnt++;
10168                         if ( iCnt == 4 && bSet || iCnt == 0 && ! bSet )
10169                                 pCmdUI->Enable( FALSE );
10170                 }
10171         }
10172 }
10173 
10174 void CGMEView::OnCntxSrcarSouth()
10175 {
10176         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxSrcarSouth in ")+path+name+_T("\r\n"));
10177         SwapAutoRouterPref( _T("S") );
10178 }
10179 
10180 void CGMEView::OnCntxSrcarNorth()
10181 {
10182         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxSrcarNorth in ")+path+name+_T("\r\n"));
10183         SwapAutoRouterPref( _T("N") );
10184 }
10185 
10186 void CGMEView::OnCntxSrcarEast()
10187 {
10188         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxSrcarEast in ")+path+name+_T("\r\n"));
10189         SwapAutoRouterPref( _T("E") );
10190 }
10191 
10192 void CGMEView::OnCntxSrcarWest()
10193 {
10194         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxSrcarWest in ")+path+name+_T("\r\n"));
10195         SwapAutoRouterPref( _T("W") );
10196 }
10197 
10198 void CGMEView::OnCntxDstarEast()
10199 {
10200         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxDstarEast in ")+path+name+_T("\r\n"));
10201         SwapAutoRouterPref( _T("e") );
10202 }
10203 
10204 void CGMEView::OnCntxDstarNorth()
10205 {
10206         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxDstarNorth in ")+path+name+_T("\r\n"));
10207         SwapAutoRouterPref( _T("n") );
10208 }
10209 
10210 void CGMEView::OnCntxDstarSouth()
10211 {
10212         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxDstarSouth in ")+path+name+_T("\r\n"));
10213         SwapAutoRouterPref( _T("s") );
10214 }
10215 
10216 void CGMEView::OnCntxDstarWest()
10217 {
10218         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxDstarWest in ")+path+name+_T("\r\n"));
10219         SwapAutoRouterPref( _T("w") );
10220 }
10221 
10222 void CGMEView::OnCntxDstarClear()
10223 {
10224         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxDstarClear in ")+path+name+_T("\r\n"));
10225         SetAllAutoRouterPref( false, true );
10226 }
10227 
10228 void CGMEView::OnCntxSrcarClear()
10229 {
10230         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxSrcarClear in ")+path+name+_T("\r\n"));
10231         SetAllAutoRouterPref( true, true );
10232 }
10233 
10234 void CGMEView::OnCntxDstarSet()
10235 {
10236         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxDstarSet in ")+path+name+_T("\r\n"));
10237         SetAllAutoRouterPref( false, false );
10238 }
10239 
10240 void CGMEView::OnCntxSrcarSet()
10241 {
10242         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnCntxSrcarSet in ")+path+name+_T("\r\n"));
10243         SetAllAutoRouterPref( true, false );
10244 }
10245 
10246 void CGMEView::SwapAutoRouterPref( const CString& strP )
10247 {
10248         CGMEEventLogger::LogGMEEvent(_T("CGMEView::SwapAutoRouterPref in ")+path+name+_T("\r\n"));
10249         if( contextSelection ) {
10250                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextSelection->GetName()+_T(" ")+contextSelection->GetID()+_T("\r\n"));
10251                 CComPtr<IMgaFCO> spFCO = contextSelection->mgaFco;
10252                 if ( spFCO ) {
10253                         BeginTransaction(TRANSACTION_GENERAL);
10254                         CComBSTR bstrPref;
10255                         COMTHROW( spFCO->get_RegistryValue( CComBSTR( AUTOROUTER_PREF ), &bstrPref ) );
10256                         CString strPref( bstrPref );
10257                         int iPos = strPref.Find( strP );
10258                         if ( iPos == -1 )
10259                                 if ( strP == _T("n") || strP == _T("s") || strP == _T("w") || strP == _T("e") )
10260                                         strPref = strP + strPref;
10261                                 else
10262                                         strPref += strP;
10263                         else
10264                                 strPref.Replace( strP, _T("") );
10265                         COMTHROW( spFCO->put_RegistryValue( CComBSTR( AUTOROUTER_PREF ), CComBSTR( strPref ) ) );
10266                         CommitTransaction();
10267                 }
10268         }
10269 }
10270 
10271 void CGMEView::SetAllAutoRouterPref( bool bSrc, bool bClear )
10272 {
10273         CGMEEventLogger::LogGMEEvent(_T("CGMEView::SetAllAutoRouterPref in ")+path+name+_T("\r\n"));
10274         if( contextSelection ) {
10275                 CGMEEventLogger::LogGMEEvent(_T("    ")+contextSelection->GetName()+_T(" ")+contextSelection->GetID()+_T("\r\n"));
10276                 CComPtr<IMgaFCO> spFCO = contextSelection->mgaFco;
10277                 if ( spFCO ) {
10278                         BeginTransaction(TRANSACTION_GENERAL);
10279                         CComBSTR bstrPref;
10280                         COMTHROW( spFCO->get_RegistryValue( CComBSTR( AUTOROUTER_PREF ), &bstrPref ) );
10281                         CString strPref( bstrPref );
10282                         CString src = _T("NEWS");
10283                         CString dst = _T("news");
10284                         for ( int i = 0 ; i < 4 ; i++ )
10285                                 strPref.Replace( ( bSrc ) ? src.Mid( i, 1 ) : dst.Mid( i, 1 ), _T("") );
10286                         if ( ! bClear )
10287                                 if ( bSrc )
10288                                         strPref = src + strPref;
10289                                 else
10290                                         strPref += dst;
10291                         COMTHROW( spFCO->put_RegistryValue( CComBSTR( AUTOROUTER_PREF ), CComBSTR( strPref ) ) );
10292                         CommitTransaction();
10293                 }
10294         }
10295 }
10296 
10297 void CGMEView::OnPrintMetafile()
10298 {
10299         CString filePath = _T(""); // "c:\\tmp\\meta.emf";
10300         // call FileOpenDialog
10301         CFileDialog filedlg(FALSE, _T("emf"), name, OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY,
10302                 _T("Enhanced Metafile Files (*.emf)|*.emf|All Files (*.*)|*.*||"));
10303         if (filedlg.DoModal() != IDOK)
10304                 return;
10305         filePath = filedlg.GetPathName();
10306         CMetaFileDC cDC;
10307         CDC* pDC = GetDC();
10308         BOOL ret = cDC.CreateEnhanced(pDC,filePath,NULL,_T("GME Model"));
10309         ReleaseDC(pDC);
10310         if (ret == FALSE) {
10311                 AfxMessageBox(_T("Unable to create metafile."), MB_OK | MB_ICONSTOP);
10312                 return;
10313         }
10314 
10315         cDC.m_bPrinting = TRUE;         // HACK by Peter (c)
10316 
10317         OnDraw(&cDC);
10318 
10319         HENHMETAFILE hEmf = cDC.CloseEnhanced();
10320         if ( hEmf ) {
10321                 DeleteEnhMetaFile(hEmf);
10322         }
10323 }
10324 
10325 void CGMEView::ZoomRect(CRect srect)
10326 {
10327         CRect crect;
10328         GetClientRect(&crect);
10329         int curzoom = m_zoomVal;
10330         CPoint home = CPoint(srect.left, srect.top);
10331         CSize orisize_srect(srect.Width(), srect.Height());
10332         srect.OffsetRect(-home);
10333 
10334         // convert srect to client coordinates like extent
10335         {
10336                 CWindowDC dc(NULL);
10337                 dc.SetMapMode(MM_ISOTROPIC);
10338                 dc.SetWindowExt(100,100);
10339                 dc.SetViewportExt(curzoom, curzoom);
10340                 dc.DPtoLP(&srect);
10341         }
10342         int zoom = (int)min(100.*crect.Height()/srect.Height(), 100.*crect.Width()/srect.Width());
10343         m_zoomVal = (zoom<ZOOM_MIN)? ZOOM_MIN: ((zoom>ZOOM_MAX)? ZOOM_MAX: zoom);
10344 
10345         if (m_zoomVal != curzoom)
10346                 frame->propBar.SetZoomVal(m_zoomVal);
10347         CMainFrame::theInstance->WriteStatusZoom(m_zoomVal);
10348         m_zoomP.x = m_zoomP.y = 0;
10349         if (curzoom == m_zoomVal)
10350                 return;
10351 
10352         CPoint point = home;
10353         point.x += orisize_srect.cx/2;
10354         point.y += orisize_srect.cy/2;
10355 
10356 // prevous zoom value : curzoom
10357 // new zoom value stored in m_zoomVal
10358 // point : win client coordinates - this image point has to be centered
10359         SetZoomPoint(curzoom, point);
10360         Invalidate();
10361 }
10362 
10363 void CGMEView::ZoomToFCOs(CRect srect)
10364 {
10365         // perform a zoom to that rectangle
10366         CRect crect;
10367         GetClientRect(&crect);
10368         CSize sizeSb;
10369         GetScrollBarSizes(sizeSb);
10370         if (m_noHscroll)        // let's suppose it will be after zoom
10371                 crect.bottom -= sizeSb.cy; 
10372         if (m_noVscroll)        // let's suppose it will be
10373                 crect.right -= sizeSb.cx;
10374 
10375         int curzoom = m_zoomVal;
10376         CRect ori_proj = srect;
10377         srect.OffsetRect(-CPoint(srect.left, srect.top));
10378 
10379         int zoom = (int)min(100.*crect.Height()/srect.Height(), 100.*crect.Width()/srect.Width());
10380         m_zoomVal = (zoom<ZOOM_MIN)? ZOOM_MIN: ((zoom>ZOOM_MAX)? ZOOM_MAX: zoom);
10381 
10382         if (m_zoomVal != curzoom)
10383                 frame->propBar.SetZoomVal(m_zoomVal);
10384         CMainFrame::theInstance->WriteStatusZoom(m_zoomVal);
10385         m_zoomP.x = m_zoomP.y = 0;
10386 
10387         CPoint scp = GetScrollPosition();       // upper corner of scrolling
10388 
10389         {
10390                 CWindowDC dc(NULL);
10391                 dc.SetMapMode(MM_ISOTROPIC);
10392                 dc.SetWindowExt(100,100);
10393                 dc.SetViewportExt(curzoom, curzoom);
10394                 dc.LPtoDP(&ori_proj);
10395                 dc.LPtoDP(&scp);
10396         }
10397         CPoint home = CPoint(ori_proj.left, ori_proj.top);
10398         CSize orisize_srect(ori_proj.Width(), ori_proj.Height());
10399 
10400         CPoint point = home - scp;
10401         point.x += orisize_srect.cx/2;
10402         point.y += orisize_srect.cy/2;
10403 
10404 // prevous zoom value : curzoom
10405 // new zoom value stored in m_zoomVal
10406 // point : win client coordinates - this image point has to be centered
10407         SetZoomPoint(curzoom, point);
10408         Invalidate();
10409 }
10410 
10411 void CGMEView::OnZoomIn()
10412 {
10413         int zoom = m_zoomVal+5;
10414         zoom = (zoom<ZOOM_MIN)? ZOOM_MIN: ((zoom>ZOOM_MAX)? ZOOM_MAX: zoom);
10415         ZoomPercent( zoom);
10416 }
10417 
10418 void CGMEView::OnZoomOut()
10419 {
10420         int zoom = m_zoomVal-5;
10421         zoom = (zoom<ZOOM_MIN)? ZOOM_MIN: ((zoom>ZOOM_MAX)? ZOOM_MAX: zoom);
10422         ZoomPercent( zoom);
10423 }
10424 
10425 void CGMEView::ZoomPercent(long percent)
10426 {
10427         OnZoom(0, (LPARAM)percent);
10428 }
10429 
10430 LRESULT CGMEView::OnZoom(WPARAM, LPARAM lParam)
10431 {
10432         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnZoom() in ")+path+name+_T("\r\n"));
10433         // BOOL userdef = (BOOL)wParam;
10434         int zoom = (int)lParam;
10435 
10436         // zoom it 
10437         if (zoom > 0)
10438         {
10439                 int curzoom = m_zoomVal;
10440                 m_zoomVal = (zoom<ZOOM_MIN)? ZOOM_MIN: ((zoom>ZOOM_MAX)? ZOOM_MAX: zoom);
10441                 if (m_zoomVal != zoom)
10442                         frame->propBar.SetZoomVal(m_zoomVal);
10443                 CMainFrame::theInstance->WriteStatusZoom(m_zoomVal);
10444                 m_zoomP.x = m_zoomP.y = 0;
10445                 if (curzoom == m_zoomVal)
10446                         return 0;
10447 
10448                 CPoint point;
10449                 CRect client(0,0,0,0);
10450                 GetClientRect(&client);
10451 
10452                 CRect rect;
10453                 GetClientRect(&rect);
10454 
10455                 CRect objext, annext, extent;
10456                 CGuiObject::GetExtent(children, objext);
10457                 CGuiAnnotator::GetExtent(annotators, annext);
10458                 extent.UnionRect(&objext, &annext);
10459                 extent.right = (int)(extent.right*EXTENT_ERROR_CORR); // ??
10460                 extent.bottom = (int)(extent.bottom*EXTENT_ERROR_CORR); // ??
10461                 CSize s(extent.right, extent.bottom);
10462 
10463                 CWindowDC dc(NULL);
10464                 dc.SetMapMode(MM_ISOTROPIC);
10465                 dc.SetWindowExt(100,100);
10466                 dc.SetViewportExt(curzoom, curzoom);
10467                 CPoint expoint(extent.right, extent.bottom);
10468                 dc.LPtoDP((LPPOINT)&expoint);
10469 
10470                 point.x = (expoint.x < client.Width())? point.x = expoint.x/2 :point.x = client.Width()/2;
10471                 point.y = (expoint.y < client.Height())? point.y = expoint.y/2 :point.y = client.Height()/2;
10472                 
10473                 SetZoomPoint(curzoom, point);
10474                 frame->propBar.SetZoomVal(m_zoomVal);
10475                 CMainFrame::theInstance->WriteStatusZoom(m_zoomVal);
10476                 Invalidate();
10477         }
10478         else
10479         {
10480                 CRect rect;
10481                 GetClientRect(&rect);
10482 
10483                 CRect objext, annext, extent;
10484                 CGuiObject::GetExtent(children, objext);
10485                 CGuiAnnotator::GetExtent(annotators, annext);
10486                 extent.UnionRect(&objext, &annext);
10487                 extent.right = (int)(extent.right*EXTENT_ERROR_CORR); // ??
10488                 extent.bottom = (int)(extent.bottom*EXTENT_ERROR_CORR); // ??
10489                 CSize s(extent.right, extent.bottom);
10490 //              s.cx = s.cx + END_SCROLL_OFFSET;
10491 //              s.cy = s.cy + END_SCROLL_OFFSET;
10492                 switch (zoom)
10493                 {
10494                 case ZOOM_WIDTH:
10495                         m_zoomVal = (int)(100.*rect.Width()/s.cx);
10496                         break;
10497                 case ZOOM_HEIGHT:
10498                         m_zoomVal = (int)(100.*rect.Height()/s.cy);
10499                         break;
10500                 case ZOOM_ALL:
10501                         m_zoomVal = (int)min(100.*rect.Height()/s.cy, 100.*rect.Width()/s.cx);
10502                         break;
10503                 }
10504                 frame->propBar.SetZoomVal(m_zoomVal);
10505                 CMainFrame::theInstance->WriteStatusZoom(m_zoomVal);
10506                 Invalidate();
10507         }
10508         return 0;
10509 }
10510 
10511 LRESULT CGMEView::OnPannRefresh(WPARAM, LPARAM)
10512 {
10513         DoPannWinRefresh();
10514         return 0;
10515 }
10516 
10517 LRESULT CGMEView::OnPannScroll(WPARAM wParam, LPARAM lParam)
10518 {
10519         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnPannScroll() in ")+path+name+_T("\r\n"));
10520         int relx = (DWORD)wParam;
10521         int rely = (DWORD)lParam;
10522         CPoint current = GetScrollPosition();       // upper corner of scrolling
10523         current.x += relx;
10524         current.y += rely;
10525         ScrollToPosition(current);                                  // set upper left position
10526         Invalidate();
10527         return 0;
10528 }
10529 
10530 LRESULT CGMEView::OnDecoratorViewRefreshRequest(WPARAM wParam, LPARAM lParam)
10531 {
10532         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnDecoratorViewRefreshRequest() in ") + path + name + _T("\r\n"));
10533         refresh_mode_enum refreshMode = (refresh_mode_enum) lParam;
10534         switch(refreshMode) {
10535                 case RM_REGENERATE_PARENT_ALSO:
10536                         {
10537                                 ResetParent(true);
10538                         }
10539                         // Intentionally no break!
10540                 case RM_REGENERATE_SELF:
10541                         {
10542                                 Reset(true);
10543                         }
10544                         break;
10545                 case RM_REGENERATE_ALL_VIEWS:
10546                         {
10547                                 GetDocument()->ResetAllViews();
10548                         }
10549                         break;
10550                 default: break; // RM_NOREFRESH, RM_REDRAW_SELF
10551         }
10552         return 0;
10553 }
10554 
10555 LRESULT CGMEView::OnExecutePendingRequests(WPARAM wParam, LPARAM lParam)
10556 {
10557         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnExecutePendingRequests() in ") + path + name + _T("\r\n"));
10558         
10559         executingPendingRequests = true;
10560         try {
10561                 CComPtr<IMgaTerritory> terr;
10562                 COMTHROW(theApp.mgaProject->get_ActiveTerritory(&terr));
10563                 if (!terr)
10564                         BeginTransaction();
10565                 TryToExecutePendingRequests();
10566                 if (!terr)
10567                         CommitTransaction();
10568         }
10569         catch(hresult_exception &e) {
10570                 // silent failure (not critical)
10571                 AbortTransaction(e.hr);
10572         }
10573 
10574         executingPendingRequests = false;
10575         return 0;
10576 }
10577 
10578 void CGMEView::OnCntxNamePositionNorth()
10579 {
10580         ChangeNamePosition(0);
10581 }
10582 
10583 void CGMEView::OnCntxNamePositionEast()
10584 {
10585         ChangeNamePosition(2);
10586 }
10587 
10588 void CGMEView::OnCntxNamePositionSouth()
10589 {
10590         ChangeNamePosition(4);
10591 }
10592 
10593 void CGMEView::OnCntxNamePositionWest()
10594 {
10595         ChangeNamePosition(6);
10596 }
10597 
10598 void CGMEView::OnUpdateCntxNamePositionNorth( CCmdUI* pCmdUI )
10599 {
10600         UpdateNamePositionMenuItem( pCmdUI, 0);
10601 }
10602 
10603 void CGMEView::OnUpdateCntxNamePositionEast( CCmdUI* pCmdUI )
10604 {
10605         UpdateNamePositionMenuItem( pCmdUI, 2);
10606 }
10607 
10608 void CGMEView::OnUpdateCntxNamePositionSouth( CCmdUI* pCmdUI )
10609 {
10610         UpdateNamePositionMenuItem( pCmdUI, 4);
10611 }
10612 
10613 void CGMEView::OnUpdateCntxNamePositionWest( CCmdUI* pCmdUI )
10614 {
10615         UpdateNamePositionMenuItem( pCmdUI, 6);
10616 }
10617 
10618 void CGMEView::UpdateNamePositionMenuItem( CCmdUI* pCmdUI, int p_this_value)
10619 {
10620         CGMEEventLogger::LogGMEEvent(_T("CGMEView::UpdateNamePositionMenuItem\r\n"));
10621 
10622         ASSERT(p_this_value == 0 || p_this_value == 2 || p_this_value == 4 || p_this_value == 6);
10623 
10624         bool any_sel = !selected.IsEmpty();
10625         pCmdUI->Enable( any_sel);
10626         if( !any_sel) return;
10627 
10628         // calculate the common selected namePos attribute value of the selected objects
10629         int common_value( -1);
10630         bool all_equal( true);
10631 
10632         try {
10633                 BeginTransaction(TRANSACTION_READ_ONLY);
10634 
10635                 bool first_value( true), res(true);
10636                 POSITION pos = selected.GetHeadPosition();
10637                 while(pos && all_equal) {
10638                         CGuiObject *obj = selected.GetNext(pos);
10639                         int v( -1);
10640 
10641                         if( obj && obj->mgaFco)
10642                                 res = GetNamePositionVal( obj->mgaFco, &v);
10643 
10644                         if( first_value)
10645                         {
10646                                 common_value = v;
10647                                 first_value = false;
10648                         }
10649                         all_equal = all_equal && res && common_value == v && common_value == p_this_value;
10650                 }
10651 
10652                 CommitTransaction();
10653         }
10654         catch(hresult_exception &e) {
10655                 all_equal = false;
10656                 AbortTransaction(e.hr);
10657                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::UpdateNamePositionMenuItem - Unable to get NamePosition preference value.\r\n"));
10658         }
10659 
10660         // set the radiobutton like icon on/off based on the all_equal
10661         pCmdUI->SetRadio( all_equal);
10662 }
10663 
10664 void CGMEView::ChangeNamePosition( int p_val)
10665 {
10666         CGMEEventLogger::LogGMEEvent(_T("CGMEView::ChangeNamePosition\r\n"));
10667 
10668         try {
10669                 BeginTransaction();
10670                 POSITION pos = selected.GetHeadPosition();
10671                 while(pos) {
10672                         CGuiObject *obj = selected.GetNext(pos);
10673                         if( obj && obj->mgaFco)
10674                                 SetNamePositionVal( obj->mgaFco, p_val);
10675                 }
10676 
10677                 CommitTransaction();
10678         }
10679         catch(hresult_exception &e) {
10680                 AbortTransaction(e.hr);
10681                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::ChangeNamePosition - Unable to change NamePosition preference value.\r\n"));
10682         }
10683 }
10684 
10685 // 
10686 // code below has to be in sync with the objectinspector's preference.cpp
10687 //
10688 void CGMEView::SetNamePositionVal(CComPtr<IMgaFCO>& p_ccpMgaFCO, int val)
10689 {       
10690         CGMEEventLogger::LogGMEEvent(_T("CGMEView::SetNamePositionVal\r\n"));
10691 
10692         ASSERT( p_ccpMgaFCO);
10693         if( !p_ccpMgaFCO) return;
10694 
10695         const CComBSTR bstrRegPath(L"namePosition");
10696         CString valString;
10697         valString.Format(_T("%d"), val);
10698         CComBSTR bstrValue( valString);
10699 
10700         // For a specific object we modify the registry value
10701         COMTHROW(p_ccpMgaFCO->put_RegistryValue(bstrRegPath,bstrValue));
10702 }
10703 
10704 bool CGMEView::GetNamePositionVal(CComPtr<IMgaFCO>& p_ccpMgaFCO, int* p_valRet)
10705 {       
10706         ASSERT( p_ccpMgaFCO);
10707         ASSERT( p_valRet);
10708         if( !p_ccpMgaFCO) return false;
10709 
10710         const CComBSTR bstrRegPath(L"namePosition");
10711         CString strRegValue;
10712 
10713         // Getting regnode
10714         CComPtr<IMgaRegNode> ccpMgaRegNode;
10715         COMTHROW(p_ccpMgaFCO->get_RegistryNode(bstrRegPath,&ccpMgaRegNode));
10716 
10717         // Getting regnode status
10718         long lRegNodeStatus;
10719         COMTHROW(ccpMgaRegNode->get_Status(&lRegNodeStatus));
10720 
10721 
10722         //Status of definition: 0: this node, -1: in meta, >=1: inherited
10723         if(lRegNodeStatus==0)
10724         {
10725                 /* Getting the value of the registry node */
10726 
10727                 CComBSTR bstrRegValue;
10728                 COMTHROW(ccpMgaRegNode->get_Value(&bstrRegValue));
10729 
10730                 strRegValue=bstrRegValue;
10731 
10732         }
10733         else if(lRegNodeStatus==-1)
10734         {
10735                 /* Getting value from meta */
10736 
10737                 // Getting Meta
10738                 CComPtr<IMgaMetaFCO> ccpMetaFCO;
10739                 COMTHROW(p_ccpMgaFCO->get_Meta(&ccpMetaFCO));
10740 
10741                 // Getting registry value from meta
10742                 CComBSTR bstrRegValue;
10743                 COMTHROW(ccpMetaFCO->get_RegistryValue(bstrRegPath,&bstrRegValue));
10744 
10745                 strRegValue=bstrRegValue;
10746         }
10747         else if(lRegNodeStatus>=1)
10748         {
10749                 /* Getting inherited value */
10750 
10751                 // Getting ancestor FCO
10752                 CComPtr<IMgaFCO> ccpAncestorFCO;
10753                 COMTHROW(p_ccpMgaFCO->get_DerivedFrom(&ccpAncestorFCO));
10754 
10755                 // Getting registry value from the ancestor
10756                 CComBSTR bstrRegValue;
10757                 COMTHROW(ccpAncestorFCO->get_RegistryValue(bstrRegPath,&bstrRegValue));
10758 
10759                 strRegValue=bstrRegValue;
10760         }
10761         else if(lRegNodeStatus==-2)  // ATTRSTATUS_INVALID - It does happen.
10762         {
10763                 strRegValue=_T("");
10764         }
10765         else
10766         {
10767                 ASSERT(("Undocumented(and undesired) MGA feature",false));
10768                 CGMEEventLogger::LogGMEEvent(_T("CGMEView::GetNamePositionVal: Undocumented(and undesired) MGA feature\r\n"));
10769                 strRegValue=_T("");
10770         }
10771 
10772         int val = -1;
10773         if( _stscanf((LPCTSTR)strRegValue, _T("%d"), &val) != 1 || val < 0 || val > 8)
10774         {
10775                 *p_valRet = -1;
10776                 return false;
10777         }
10778 
10779         *p_valRet = val;
10780         return true;
10781 }
10782 
10783 bool CGMEView::AskUserAndDetachIfNeeded( CComPtr<IMgaFCO>& mgaFco)
10784 {
10785         // check whether dependends of mgaFco exist
10786         CComPtr<IMgaFCOs> der_objs;
10787         COMTHROW(mgaFco->get_DerivedObjects( &der_objs));
10788         long cnt = 0;
10789         if( der_objs) COMTHROW( der_objs->get_Count( &cnt));
10790         if( cnt > 0) // if dependents exist should they be deleted?
10791         {
10792                 bool question_asked = false;
10793                 bool detach_answered = false;
10794                 MGACOLL_ITERATE(IMgaFCO, der_objs) {
10795                         CComPtr<IMgaFCO> one_derived(MGACOLL_ITER);
10796 
10797                         VARIANT_BOOL prim_deriv;
10798                         COMTHROW( one_derived->get_IsPrimaryDerived( &prim_deriv));
10799                         if( prim_deriv == VARIANT_TRUE)
10800                         {
10801                                 if( !question_asked) // pop up dialog only for the first time
10802                                 {
10803                                         CComBSTR nm;
10804                                         COMTHROW( mgaFco->get_Name( &nm));
10805                                         CString msg = _T("There are objects primary derived from: \"");
10806                                         msg += nm;
10807                                         msg += _T("\". Would you like to delete them as well?\n");
10808                                         msg += _T("If you answer 'No' the derived objects will be detached, thus preserved.");
10809 
10810                                         // this answer will be applied to all deriveds of this fco
10811                                         int resp = AfxMessageBox( msg, MB_YESNOCANCEL);
10812                                         if( resp == IDCANCEL) COMTHROW(E_MGA_MUST_ABORT);
10813                                         else if( resp == IDNO) detach_answered = true;
10814                                         
10815                                         question_asked = true;
10816                                 }
10817 
10818                                 // if detach and preserve selected by the user:
10819                                 if( detach_answered)
10820                                         COMTHROW( one_derived->DetachFromArcheType());
10821                         }
10822                 }MGACOLL_ITERATE_END;
10823 
10824                 return detach_answered; // refresh needed for GMEActiveBrowser?
10825         }
10826         return false;
10827 }
10828 
10829 // called when VK_RETURN pressed on a model in a view
10830 void CGMEView::OnShowSelectedModel()
10831 {
10832         if(selected.GetCount()) {
10833                 GMEEVENTLOG_GUIOBJS(selected);
10834                 CComPtr<IMgaFCOs> coll;
10835                 GetDocument()->CreateFcoList( &selected, coll, this);
10836 
10837                 long cnt = 0;
10838                 try {
10839                         BeginTransaction(TRANSACTION_READ_ONLY);
10840                         if( coll) COMTHROW( coll->get_Count( &cnt));
10841                         CommitTransaction();
10842                 }
10843                 catch(hresult_exception e) {
10844                         AbortTransaction(e.hr);
10845                 }
10846 
10847                 for( long i = 1; i <= cnt; ++i) {
10848                         try {
10849                                 BeginTransaction(TRANSACTION_READ_ONLY);
10850                                 CComPtr<IMgaFCO> fco;
10851                                 COMTHROW( coll->get_Item( i, &fco));
10852                                 objtype_enum ot = OBJTYPE_ATOM;
10853                                 if( fco) COMTHROW( fco->get_ObjType( &ot));
10854                                 CommitTransaction();
10855 
10856                                 if( fco && ot == OBJTYPE_MODEL)
10857                                 {
10858                                         CComPtr<IMgaModel> cm;
10859                                         COMTHROW( fco.QueryInterface( &cm));
10860                                         if( cm) ShowModel( cm);
10861                                 }
10862                                 else if( fco && ot == OBJTYPE_REFERENCE) 
10863                                 {
10864                                         CComPtr<IMgaModel> next_mod;
10865                                         CComPtr<IMgaFCO> next_fco;
10866                                         CComBSTR         special_case_id_of_next_fco; // next_fco might sit in a folder, we will
10867                                                                                       // focus on it in the treebrowser in this case
10868                                         CComQIPtr<IMgaReference> rf( fco);
10869                                         try {
10870                                                 BeginTransaction(TRANSACTION_READ_ONLY);
10871                                                 COMTHROW( rf->get_Referred( &next_fco));
10872                                                 objtype_enum ot = OBJTYPE_ATOM;
10873                                                 if( next_fco) 
10874                                                 {
10875                                                         COMTHROW( next_fco->get_ObjType( &ot));
10876                                                         if( ot == OBJTYPE_MODEL)
10877                                                         {
10878                                                                 COMTHROW( next_fco.QueryInterface( &next_mod));
10879                                                         }
10880                                                         else
10881                                                         {
10882                                                                 CComPtr<IMgaObject> parent;
10883                                                                 COMTHROW( next_fco->GetParent( &parent, NULL));
10884                                                                 
10885                                                                 if( parent)
10886                                                                 {
10887                                                                         HRESULT hr = parent.QueryInterface( &next_mod);
10888                                                                         if( FAILED( hr)) // next_fco is sitting in a folder
10889                                                                                 COMTHROW( next_fco->get_ID( &special_case_id_of_next_fco));
10890                                                                 }
10891                                                         }
10892                                                 }
10893                                                 
10894                                                 CommitTransaction();
10895                                         }
10896                                         catch(hresult_exception e) {
10897                                                 AbortTransaction(e.hr);
10898                                                 next_mod = 0;
10899                                         }
10900 
10901                                         if( special_case_id_of_next_fco.Length() > 0)
10902                                         {
10903                                                 CGMEConsole::theInstance->Message( _T("Reference target is child of a folder, thus it is shown in the TreeBrowser only."), MSG_INFO);
10904                                                 CGMEBrowser::theInstance->FocusItem( special_case_id_of_next_fco);
10905                                         }
10906                                         else if( next_fco && next_mod) ShowModel( next_mod);
10907                                 }
10908                         }
10909                         catch(hresult_exception e) {
10910                                 AbortTransaction(e.hr);
10911                         }
10912                 }
10913         }
10914 }
10915 
10916 void CGMEView::OnRename()
10917 {
10918         CGMEObjectInspector::theInstance->m_ObjectInspector.EditName();
10919 }
10920 
10921 // called when VK_B + CTRL is pressed
10922 void CGMEView::OnFocusBrowser()
10923 {
10924         OnCntxLocate();
10925 }
10926 
10927 // called when VK_I + CTRL is pressed
10928 void CGMEView::OnFocusInspector()
10929 {
10930         HWND hwnd = CGMEObjectInspector::theInstance->GetSafeHwnd();
10931         if( hwnd) ::SetFocus( hwnd);
10932 }
10933 
10934 // called when TAB is pressed
10935 void CGMEView::OnCycleAspect()
10936 {
10937         ASSERT( currentAspect);
10938         ASSERT( guiMeta);
10939         if( !currentAspect || !guiMeta) return;
10940         int aspNum = guiMeta->aspects.GetCount();
10941         ASSERT( aspNum >= 1);
10942         if( aspNum <= 1) return; // if 1 aspect no reason for continuing
10943 
10944         ChangeAspect( (currentAspect->index + 1) % aspNum);
10945         // statement above changes the currentAspect->index to the new value
10946         if( CMainFrame::theInstance)
10947                 CMainFrame::theInstance->ChangePartBrowserAspect( currentAspect->index);
10948 }
10949 
10950 // called when TAB is pressed
10951 void CGMEView::OnCycleAspectBackwards()
10952 {
10953         ASSERT( currentAspect);
10954         ASSERT( guiMeta);
10955         if( !currentAspect || !guiMeta) return;
10956         int aspNum = guiMeta->aspects.GetCount();
10957         ASSERT( aspNum >= 1);
10958         if( aspNum <= 1) return; // if 1 aspect no reason for continuing
10959 
10960         ChangeAspect( (currentAspect->index - 1 + aspNum) % aspNum);
10961         // statement above changes the currentAspect->index to the new value
10962         if( CMainFrame::theInstance)
10963                 CMainFrame::theInstance->ChangePartBrowserAspect( currentAspect->index);
10964 }
10965 
10966 // called when '`' is pressed (above the TAB key)
10967 void CGMEView::OnCycleAllAspects()
10968 {
10969         if( CMainFrame::theInstance)
10970                 CMainFrame::theInstance->CyclePartBrowserAspect();
10971 }
10972 
10973 void CGMEView::OnHistoryBack()
10974 {
10975         GetDocument()->back();
10976 }
10977 
10978 void CGMEView::OnHistoryForw()
10979 {
10980         GetDocument()->forw();
10981 }
10982 
10983 void CGMEView::OnKeyConnect()
10984 {
10985         CGMEEventLogger::LogGMEEvent(_T("CGMEView::OnKeyConnect in ")+path+name+_T("\r\n"));
10986         if( lastObject) {
10987                 CGuiObject *obj = lastObject;
10988                 if(obj) {
10989                         CGuiPort *port = lastPort;
10990                         if(connSrc == 0) {
10991                                 connSrc = obj;
10992                                 connSrcPort = port;
10993                                 connSrcHotSide = GME_CENTER;
10994                                 tmpConnectMode = true;
10995                                 SetCursor(autoconnect2Cursor);
10996                         }
10997                         else {
10998                                 Connect(connSrc,connSrcPort,connSrcHotSide,obj,port, GME_CENTER, ::GetKeyState(VK_SHIFT) < 0);
10999                                 ClearConnSpecs();
11000                                 tmpConnectMode = false;
11001                                 SetCursor(editCursor);
11002                         }
11003                         ShowCursor(TRUE);
11004                 }
11005         }
11006 }
11007 
11008 void CGMEView::OnKeyCycleObjInspectorFrwd()
11009 {
11010         CGMEObjectInspector::theInstance->CyclePanel( VARIANT_TRUE);
11011 }
11012 
11013 void CGMEView::OnKeyCycleObjInspectorBkwd()
11014 {
11015         CGMEObjectInspector::theInstance->CyclePanel( VARIANT_FALSE);
11016 }
11017 
11018 void CGMEView::OnViewMultiUserShowObjectOwner()
11019 {
11020         theApp.mgaProject->SourceControlObjectOwner( currentModId);
11021 }
11022 
11023 void CGMEView::OnUpdateViewMultiUserShowObjectOwner( CCmdUI* pCmdUI)
11024 {
11025         pCmdUI->Enable( theApp.isMultiUserProj());
11026 }
11027 
11028 
11029 void CGMEView::OnViewShowconnectedportsonly()
11030 {
11031         showConnectedPortsOnly = !showConnectedPortsOnly;
11032         GetDocument()->ResetAllViews();
11033 }
11034 
11035 void CGMEView::OnUpdateViewShowconnectedportsonly(CCmdUI *pCmdUI)
11036 {
11037         pCmdUI->SetCheck(showConnectedPortsOnly);
11038 }