GME  13
GMEApp.cpp
Go to the documentation of this file.
00001 // GMEApp.cpp : Defines the class behaviors for the application.
00002 //
00003 
00004 #include "stdafx.h"
00005 #include <afxwin.h> // for CWaitCursor
00006 #include "GMEApp.h"
00007 #include "GMEVersion.h"
00008 
00009 
00010 #include "Parser.h"
00011 
00012 #include "GMEstd.h"
00013 #include "GuiMeta.h"
00014 #include "MainFrm.h"
00015 #include "ChildFrm.h"
00016 #include "GMEDoc.h"
00017 #include "GMEView.h"
00018 #include "GMEChildFrame.h"
00019 #include "GMEBrowser.h"
00020 #include "GMEObjectInspector.h"
00021 #include <locale.h>
00022 #include "MgaOpenDlg.h"
00023 #include "GmeDocTemplate.h"
00024 #include "ProjectPropertiesDlg.h"
00025 #include "GmeLib.h"
00026 #include "GMEOLEApp.h"
00027 #include "GMEEventLogger.h"
00028 #include "GMEPrintDialog.h"
00029 
00030 #include "CrashRpt.h"
00031 #ifdef _DEBUG
00032 #pragma comment(lib, "CrashRptd.lib")
00033 #else
00034 #pragma comment(lib, "CrashRpt.lib")
00035 #endif
00036 
00037 #import "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorlib.tlb" no_implementation
00038 namespace CSGUI {
00039 using namespace mscorlib;
00040 }
00041 #import "CSGUI.tlb" no_implementation
00042 
00043 #ifndef _DEBUG
00044 #pragma comment(linker, "\"/manifestdependency:type='win32' name='Core' version='1.0.0.0' language='*'\"")
00045 #pragma comment(linker, "\"/manifestdependency:type='win32' name='Meta' version='1.0.0.0' language='*'\"")
00046 #pragma comment(linker, "\"/manifestdependency:type='win32' name='Mga' version='1.0.0.0' language='*'\"")
00047 #endif
00048 
00049 #include "CrashTest.h"
00050 #include <Gdiplus.h>
00051 #include "GraphicsUtil.h"
00052 #include <signal.h>
00053 
00054 
00055 #ifdef _DEBUG
00056 #define new DEBUG_NEW
00057 #undef THIS_FILE
00058 static char THIS_FILE[] = __FILE__;
00059 #endif
00060 
00061 // ATL ///////////////////////////////////////////////////////////////////////////
00062 #include <atlsafe.h>
00063 #include "mga_i.c"
00064 #include "meta_i.c"
00065 #include "Splash.h"
00066 
00067 CComModule _Module;
00068 
00069 
00071 
00073 // CGMEApp
00074 
00075 BEGIN_MESSAGE_MAP(CGMEApp, CWinAppEx)
00076         //{{AFX_MSG_MAP(CGMEApp)
00077         ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
00078         ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
00079         ON_COMMAND(ID_FILE_NEW, OnFileNew)
00080         ON_UPDATE_COMMAND_UI(ID_FILE_CLOSEPROJECT, OnUpdateFileCloseproject)
00081         ON_COMMAND(ID_FILE_CLOSEPROJECT, OnFileCloseproject)
00082         ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateFileNew)
00083         ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, OnUpdateFileOpen)
00084         ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
00085         ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
00086         ON_UPDATE_COMMAND_UI(ID_EDIT_REDO, OnUpdateEditRedo)
00087         ON_UPDATE_COMMAND_UI(ID_FILE_EXPORTXML, OnUpdateFileExportxml)
00088         ON_COMMAND(ID_FILE_EXPORTXML, OnFileExportxml)
00089         ON_COMMAND(ID_FILE_IMPORTXML, OnFileImportxml)
00090         ON_UPDATE_COMMAND_UI(ID_EDIT_PROJECTPROPERTIES, OnUpdateEditProjectproperties)
00091         ON_COMMAND(ID_EDIT_PROJECTPROPERTIES, OnEditProjectproperties)
00092         ON_COMMAND(ID_FILE_SETTINGS, OnFileSettings)
00093         ON_COMMAND(ID_FILE_CLEARLOCKS, OnFileClearLocks)
00094         ON_COMMAND(ID_EDIT_CLEARUNDO, OnEditClearUndo)
00095         ON_UPDATE_COMMAND_UI(ID_EDIT_CLEARUNDO, OnUpdateEditClearUndo)
00096         ON_COMMAND(ID_HELP_CONTENTS, OnHelpContents)
00097         ON_COMMAND(ID_FILE_CHECKALL, OnFileCheckall)
00098         ON_UPDATE_COMMAND_UI(ID_FILE_CHECKALL, OnUpdateFileCheckall)
00099         ON_UPDATE_COMMAND_UI(ID_FILE_SAVEPROJECT, OnUpdateFileSave)
00100         ON_UPDATE_COMMAND_UI(ID_FILE_SAVEPROJECTAS, OnUpdateFileSaveAs)
00101         ON_COMMAND(ID_FILE_SAVEPROJECTAS, OnFileSaveAs)
00102         ON_COMMAND(ID_FILE_SAVEPROJECT, OnFileSave)
00103         ON_COMMAND(ID_FILE_ABORTPROJECT, OnFileAbortProject)
00104         ON_UPDATE_COMMAND_UI(ID_FILE_ABORTPROJECT, OnUpdateFileAbortProject)
00105         ON_COMMAND(ID_FILE_REGCOMPONENTS, OnFileRegcomponents)
00106         ON_COMMAND(ID_FILE_REGPARADIGMS, OnFileRegparadigms)
00107         ON_UPDATE_COMMAND_UI(ID_FILE_REGCOMPONENTS, OnUpdateFileRegcomponents)
00108         ON_UPDATE_COMMAND_UI(ID_FILE_UPDATETHROUGHXML, OnUpdateFileXMLUpdate)
00109         ON_COMMAND(ID_FILE_UPDATETHROUGHXML, OnFileXMLUpdate)
00110         ON_COMMAND(ID_FILE_DISPLAY_CONSTRAINTS, OnFileDisplayConstraints)
00111         ON_UPDATE_COMMAND_UI(ID_FILE_DISPLAY_CONSTRAINTS, OnUpdateFileDisplayConstraints)
00112         ON_COMMAND(ID_APP_EXIT, OnAppExit)
00113         ON_UPDATE_COMMAND_UI(ID_EDIT_UNDO, OnUpdateEditUndo)
00114         //}}AFX_MSG_MAP
00115         // Standard file based document commands
00116 //      ON_COMMAND(ID_FILE_NEW, CWinAppEx::OnFileNew)
00117 //      ON_COMMAND(ID_FILE_OPEN, CWinAppEx::OnFileOpen)
00118         // Standard print setup command
00119         ON_COMMAND(ID_FILE_PRINT_SETUP, OnUniquePrintSetup) // CWinAppEx::OnFilePrintSetup)
00120         // MRU - most recently used project menu
00121         ON_UPDATE_COMMAND_UI(ID_FILE_MRU_PRJ1, OnUpdateRecentProjectMenu)
00122         ON_COMMAND_EX_RANGE(ID_FILE_MRU_PRJ1, ID_FILE_MRU_PRJ16, OnOpenRecentProject)
00123         ON_COMMAND_RANGE(ID_FILE_RUNPLUGIN1, ID_FILE_RUNPLUGIN_LAST, OnRunPlugin)
00124         ON_COMMAND_RANGE(ID_FILE_INTERPRET1, ID_FILE_INTERPRET_LAST, OnRunInterpreter)
00125         ON_UPDATE_COMMAND_UI_RANGE( ID_FILE_RUNPLUGIN1, ID_FILE_RUNPLUGIN_LAST, OnUpdateFilePluginX)
00126         ON_UPDATE_COMMAND_UI_RANGE( ID_FILE_INTERPRET1, ID_FILE_INTERPRET_LAST, OnUpdateFileInterpretX)
00127         ON_COMMAND(ID_FOCUS_BROWSER, OnFocusBrowser)
00128         ON_COMMAND(ID_FOCUS_INSPECTOR, OnFocusInspector)
00129 END_MESSAGE_MAP()
00130 
00132 // The one and only CGMEApp object
00133 
00134 CGMEApp theApp;
00135 
00136 // This identifier was generated to be statistically unique for your app.
00137 // You may change it if you prefer to choose a specific identifier.
00138 
00139 
00140 /*static*/ const TCHAR * CGMEApp::m_no_model_open_string = _T("_NO_MODEL_IS_OPEN_");
00141 
00142 static CComBSTR StringFromGUID2(const CComVariant& guid)
00143 {
00144         ASSERT(guid.vt == (VT_UI1 | VT_ARRAY));
00145         GUID guid2;
00146         CopyTo(guid, guid2);
00147         CComBSTR strGuid;
00148         CopyTo(guid2, &strGuid.m_str);
00149         return strGuid;
00150 }
00151 
00153 // CGMEApp construction
00154 
00155 CGMEApp::CGMEApp() :
00156     m_RecentProjectList(0, _T("Recent Project List"), _T("Project%d"), 8)
00157   , m_compFilterOn( false)
00158 {
00159         multipleView = false;
00160         useAutoRouting = true;
00161         labelAvoidance = false;
00162         defZoomLev = _T("100");
00163         mouseOverNotify = false;
00164         maintainHistory = false;
00165         realFmtStr = _T("%.12g");
00166         // TODO: add construction code here,
00167 
00168         // Place all significant initialization in InitInstance
00169         SIZE size;
00170         size.cx = 16;
00171         size.cy = 16;
00172         m_userImages.SetImageSize(size);
00173 }
00174 
00175 CGMEApp::~CGMEApp()
00176 {
00177 }
00178 
00179 class CGMECommandLineInfo : public CCommandLineInfo {
00180 public:
00181         bool bNoProtect, bOpenLast;
00182         CString run;
00183         CGMECommandLineInfo() : bNoProtect(false), bOpenLast(false) { ; }
00184 
00185         virtual void ParseParam(const TCHAR* pszParam, BOOL bFlag, BOOL bLast) {
00186                 
00187                 if(bFlag && !_wcsicmp(pszParam, L"d")) bNoProtect = true;
00188                 else if(bFlag && !_wcsicmp(pszParam, L"l")) bOpenLast = true;
00189                 else if(bFlag && _wcsnicmp(pszParam, L"run:", 4) == 0)
00190                 {
00191                         run = pszParam + 4;
00192                 }
00193                 else CCommandLineInfo::ParseParam(pszParam, bFlag, bLast);
00194         }
00195 
00196 };
00197 
00198 
00199 bool CheckInterfaceVersions()   {
00200                 bool err = false;
00201                 LPCOLESTR components[] = {
00202                         L"Mga.MgaProject",
00203                         L"Mga.MgaMetaProject",
00204                         L"Mga.CoreProject",
00205                         L"Mga.MgaRegistrar",
00206                         L"Mga.MgaParser",
00207                         L"Mga.AddOn.ConstraintManager",
00208                         NULL };
00209                 CString errstring;
00210                 HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
00211                 TCHAR hrbuf[20];
00212                 if(hr != S_OK) AfxMessageBox(CString(_T("Coinitialize failure. Err: #")) + _ltot(hr,hrbuf,16));
00213                 for(LPCOLESTR *p = components; *p; p++) {
00214                         GMEInterfaceVersion verid = GMEInterfaceVersion_None;
00215                         CComPtr<IUnknown> unk;
00216                         CString ee;
00217                         if(S_OK != (hr = unk.CoCreateInstance(*p))) {
00218                                 {
00219                                         _com_error error(hr);
00220                                         errstring.Format(_T("Cannot create object %%s (Err: #%X, %s)"), hr, error.ErrorMessage());
00221                                 }
00222 gerr:
00223                                 CString a;
00224                                 a.Format(errstring, *p, verid/0x1000, verid%0x1000, GMEInterfaceVersion_Current/0x1000,GMEInterfaceVersion_Current%0x1000);
00225                                 AfxMessageBox(a);
00226                                 err = true;
00227                                 continue;
00228                         }
00229                         CComQIPtr<IGMEVersionInfo> vinf = unk;
00230                         if(!vinf) {
00231                                 errstring = _T("Incompatible version of object %s (does not support version information)");
00232                                 goto gerr;
00233                         }
00234                         if(S_OK != vinf->get_version(&verid)) {
00235                                 errstring = _T("Get_Version failed for object %s");
00236                                 goto gerr;
00237                         }
00238                         if(verid != GMEInterfaceVersion_Current) {
00239                                 errstring = _T("Interface version for class %s (%d.%d) differs from GME interface version (%d.%d)");
00240                                 goto gerr;
00241                         }
00242                 }
00243                 return err;
00244 }
00245 
00246 
00248 // CGMEApp initialization
00249 
00250 BOOL CGMEApp::InitInstance()
00251 {
00252         // InitCommonControlsEx() is required on Windows XP if an application
00253         // manifest specifies use of ComCtl32.dll version 6 or later to enable
00254         // visual styles.  Otherwise, any window creation will fail.
00255         INITCOMMONCONTROLSEX InitCtrls;
00256         InitCtrls.dwSize = sizeof(InitCtrls);
00257         // Set this to include all the common control classes you want to use
00258         // in your application.
00259         InitCtrls.dwICC = ICC_WIN95_CLASSES;
00260         InitCommonControlsEx(&InitCtrls);
00261 
00262 #if _MSC_VER < 1700
00263         // See MSDN example code for CWinApp::InitInstance: http://msdn.microsoft.com/en-us/library/ae6yx0z0.aspx
00264         // MFC module state handling code is changed with VC80.
00265         // We follow the Microsoft's suggested way, but in case of any trouble the set the
00266         // HKCU\Software\GME\AfxSetAmbientActCtxMod key to 0
00267         UINT uAfxSetAmbientActCtxMod = 1;
00268         HKEY hKey;
00269         if (RegOpenKeyEx(HKEY_CURRENT_USER, _T("Software\\GME\\"),
00270                                          0, KEY_QUERY_VALUE, &hKey) == ERROR_SUCCESS)
00271         {
00272                 TCHAR szData[128];
00273                 DWORD dwKeyDataType;
00274                 DWORD dwDataBufSize = sizeof(szData)/sizeof(TCHAR);
00275 
00276                 if (RegQueryValueEx(hKey, _T("AfxSetAmbientActCtxMod"), NULL, &dwKeyDataType,
00277                                                         (LPBYTE) &szData, &dwDataBufSize) == ERROR_SUCCESS)
00278                 {
00279                         uAfxSetAmbientActCtxMod = _tcstoul(szData, NULL, 10);
00280                 }
00281 
00282                 RegCloseKey(hKey);
00283         }
00284         if (uAfxSetAmbientActCtxMod != 0)
00285         {
00286                 AfxSetAmbientActCtx(FALSE);
00287         }
00288 #endif
00289 
00290         CWinAppEx::InitInstance();
00291 
00292         // CG: The following block was added by the Splash Screen component.
00293         CGMECommandLineInfo cmdInfo;
00294         ParseCommandLine(cmdInfo);
00295         
00296         if( cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen || cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister)
00297                 ;
00298         cmdInfo.m_bShowSplash = false;
00299 
00300         CSplashWnd::EnableSplashScreen(cmdInfo.m_bShowSplash);
00301         // CG: The following block was inserted by 'Status Bar' component.
00302         {
00303                 //Set up date and time defaults so they're the same as system defaults
00304                 setlocale(LC_ALL, "");
00305         }
00306 
00307         //if(CheckInterfaceVersions()) return FALSE;
00308 
00309 
00310         // Initialize OLE libraries
00311         if (!AfxOleInit())
00312         {
00313                 AfxMessageBox(IDP_OLE_INIT_FAILED);
00314                 return FALSE;
00315         }
00316 
00317         AfxEnableControlContainer();
00318 
00319         EnableTaskbarInteraction();
00320 
00321         // Standard initialization
00322         // If you are not using these features and wish to reduce the size
00323         //  of your final executable, you should remove from the following
00324         //  the specific initialization routines you do not need.
00325 
00326 #ifdef _AFXDLL
00327         //Enable3dControls(); // deprecated
00328 #else
00329         Enable3dControlsStatic();       // Call this when linking to MFC statically
00330 #endif
00331 
00332 
00333         // Enable assigning shortcut keys to the menus
00334         InitKeyboardManager();
00335 
00336         // Enabling user tools
00337         EnableUserTools(ID_TOOLS_EXTERNAL_TOOLS, ID_USER_TOOL1, ID_USER_TOOL10, RUNTIME_CLASS(CUserTool)/*, IDR_MENU_ARGS, IDR_MENU_DIRS*/);
00338 
00339         InitContextMenuManager();
00340 
00341         // Change the registry key under which our settings are stored.
00342         // TODO: You should modify this string to be something appropriate
00343         // such as the name of your company or organization.
00344         SetRegistryKey(_T("GME\\GUI"));
00345 
00346         LoadStdProfileSettings();  // Load standard INI file options (including MRU)
00347         m_RecentProjectList.ReadList();
00348 
00349 
00350         // Load Accelerator Table for CGMEView
00351 
00352         m_GMEView_hAccel = LoadAccelerators(m_hInstance, MAKEINTRESOURCE(IDR_GMEVIEW));
00353         ASSERT( m_GMEView_hAccel );
00354 
00355         // Register the application's document templates.  Document templates
00356         //  serve as the connection between documents, frame windows and views.
00357 
00358         pDocTemplate = new CGmeDocTemplate(
00359                 IDR_GMETYPE,
00360                 RUNTIME_CLASS(CGMEDoc),
00361                 RUNTIME_CLASS(CChildFrame), // custom MDI child frame
00362 #if !defined(ACTIVEXGMEVIEW)
00363                 RUNTIME_CLASS(CGMEView));
00364 #else
00365                 RUNTIME_CLASS(CGMEChildFrame));
00366 #endif
00367         pDocTemplate->SetContainerInfo(IDR_GMETYPE_CNTR_IP);
00368         AddDocTemplate(pDocTemplate);
00369 
00370 
00371 
00372         // create main MDI Frame window
00373         CMainFrame* pMainFrame = new CMainFrame;
00374         if (!pMainFrame->LoadFrame(IDR_MAINFRAME))
00375         {
00376                 // n.b. if LoadFrame fails, CFrameWnd::PostNcDestroy is called which does `delete this`
00377                 // delete pMainFrame;
00378                 return FALSE;
00379         }
00380         m_pMainWnd = pMainFrame;
00381         pMainFrame->CheckForOffscreenPanes();
00382 
00383 #if !defined(ADDCRASHTESTMENU) && defined(_DEBUG)
00384         bNoProtect = true;
00385 #else
00386         bNoProtect = cmdInfo.bNoProtect;
00387 #endif
00388         
00389         //initialize the logfile - first check registry to see if the user wants logging
00390         MSGTRY
00391         {
00392                 CComPtr<IMgaRegistrar> registrar;
00393                 COMTHROW(registrar.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar")));
00394                 VARIANT_BOOL enablelogging;
00395                 COMTHROW( registrar->get_EventLoggingEnabled(REGACCESS_USER, &enablelogging) );
00396                 if(enablelogging != VARIANT_FALSE)
00397                 {
00398                         CGMEEventLogger::initialize();
00399                         CGMEEventLogger::LogGMEEvent("GME started\r\n");
00400                 }
00401         }
00402         MSGCATCH(_T("Error while trying to get logfile settings"),;);
00403 
00404         ASSERT((CMainFrame*)m_pMainWnd);
00405         CGMEOLEApp *t_pGmeOleApp = new CGMEOLEApp();
00406         ((CMainFrame*)m_pMainWnd)->setGmeOleApp( t_pGmeOleApp );
00407 
00408         // Register all OLE server factories as running.  This enables the
00409         //  OLE libraries to create objects from other applications.
00410         COleObjectFactory::RegisterAll();
00411                 // Note: MDI applications register all server objects without regard
00412                 //  to the /Embedding or /Automation on the command line.
00413         // Note: we switched the default REGCLS_MULTIPLEUSE behavior to REGCLS_SINGLEUSE,
00414         // see GMEOLEApp.cpp's MY_IMPLEMENT_OLECREATE macro, and
00415         // "How to use single or multiple instances of an OLE object in MFC by using Visual C++" KB article:
00416         // http://support.microsoft.com/kb/141154
00417 
00418         // Check to see if launched as OLE server
00419         if (cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated)
00420         {
00421                 // Application was run with /Embedding or /Automation.  Don't show the
00422                 //  main window in this case.
00423 
00424                 //
00425                 // load settings in this case as well
00426                 GetSettings();
00427 
00428                 return TRUE;
00429         }
00430 
00431         // Updates system registry with all creatable classes (_OLECREATE)
00432         // PETER: It works only with administrator priviledges
00433         COleObjectFactory::UpdateRegistryAll();
00434         
00435         // Make sure the type library is registered or dual interface won't work.
00436         AfxOleRegisterTypeLib(AfxGetInstanceHandle(), __uuidof(__GmeLib));
00437 
00438         // Dispatch commands specified on the command line
00439         if ((cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister || cmdInfo.m_nShellCommand == CCommandLineInfo::AppUnregister) && !ProcessShellCommand(cmdInfo))
00440                 return FALSE;
00441 
00442         // The main window has been initialized, so show and update it.
00443         pMainFrame->ShowWindow(m_nCmdShow);
00444         pMainFrame->UpdateWindow();
00445 
00446 
00447         dynmenus_need_refresh = true;
00448 
00449         GetSettings();
00450         m_pMainWnd->DragAcceptFiles(TRUE);
00451 
00452         return TRUE;
00453 }
00454 
00455 BOOL CGMEApp::PreTranslateMessage(MSG* pMsg)
00456 {
00457         // CG: The following lines were added by the Splash Screen component.
00458         if (CSplashWnd::PreTranslateAppMessage(pMsg))
00459                 return TRUE;
00460         // KMS: m_pMainWnd->PreTranslateMessage here for Alt-F,C. Otherwise, CGMEView::PreTranslateMessage TranslateAccelerator will return TRUE
00461         if (m_pMainWnd && m_pMainWnd->PreTranslateMessage(pMsg))
00462                 return TRUE;
00463 
00464         return CWinAppEx::PreTranslateMessage(pMsg);
00465 }
00466 
00467 
00468 
00470 // CGMEApp emergency
00471 
00472 void CGMEApp::EmergencySave(void)
00473 {
00474         CGMEEventLogger::LogGMEEvent("EMERGENCY EVENT\r\n");
00475         if (mgaProject && (proj_type_is_mga || proj_type_is_xmlbackend)) {
00476                 CString embackupname = currentConnection;
00477                 int p = embackupname.ReverseFind('.');
00478                 if ((p == -1) || embackupname.Find('\\', p) != -1)
00479                         p = embackupname.GetLength();
00480                 CString emcode;
00481                 static int emnum;
00482                 emcode.Format(_T("-emergency%ld"), ++emnum);
00483                 embackupname.Insert(p, emcode);
00484                 long status = 0;
00485                 mgaProject->get_ProjectStatus(&status); // ignore failure
00486                 if (status == 3 || status == 4) // i.e. in tx
00487                         mgaProject->AbortTransaction(); // ignore failure
00488                 HRESULT hr = mgaProject->Save(PutInBstr(embackupname), VARIANT_TRUE);
00489                 if (proj_type_is_xmlbackend) {
00490                         AfxMessageBox(_T("Your current work can be found in the local checkout directory."));
00491                 } else {
00492                         CString emergencySaveMsg;
00493                         emergencySaveMsg.FormatMessage(_T("Your current work %1 been saved to %2.\n")
00494                                                                                    _T("The original project file has not been modified. ")
00495                                                                                    _T("We apologize for the inconvenience."),
00496                                                                                    (hr == S_OK)? _T("has") : _T("might have"),
00497                                                                                    embackupname);
00498                         AfxMessageBox(emergencySaveMsg);
00499                         m_RecentProjectList.AddAndWriteList(embackupname);
00500                 }
00501         }
00502 }
00503 
00504 BOOL CGMEApp::OpenCommandLineProject()
00505 {
00506         CGMECommandLineInfo cmdInfo;
00507         ParseCommandLine(cmdInfo);
00508         // We don't want a new document at startup
00509         if(cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew)
00510                 cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
00511         if (cmdInfo.m_nShellCommand == CCommandLineInfo::AppRegister)
00512                 cmdInfo.bOpenLast = true;
00513         if(cmdInfo.m_nShellCommand == CCommandLineInfo::FileOpen)
00514         {
00515                 CString conn = cmdInfo.m_strFileName;
00516                 if(conn.Find(_T("=")) < 0) {
00517                         if (conn.Right(4).CompareNoCase(_T(".xme")) == 0)
00518                                 conn.Insert(0, _T("XML="));
00519                         else
00520                                 conn.Insert(0,_T("MGA="));
00521                 }
00522                 OpenProject(conn);
00523 
00524                 cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
00525                 return TRUE;
00526         }
00527         else if(cmdInfo.bOpenLast && !m_RecentProjectList[0].IsEmpty())
00528         {
00529                 OpenProject(m_RecentProjectList[0]);
00530                 cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing;
00531                 return TRUE;
00532         } else if(cmdInfo.run != "")
00533         {
00534                 if (CMainFrame::theInstance)
00535                         CMainFrame::theInstance->m_console.m_Console.RunCode(CComBSTR(cmdInfo.run));
00536                 return TRUE;
00537         }
00538 
00539         // Dispatch commands specified on the command line
00540         //if (!ProcessShellCommand(cmdInfo))
00541         //      return FALSE;
00542         if (!(cmdInfo.m_bRunEmbedded || cmdInfo.m_bRunAutomated))
00543         {
00544                 ShowWelcomeWindow();
00545         }
00546         return FALSE;
00547 }
00548 
00549 BOOL CGMEApp::ShowWelcomeWindow()
00550 {
00551         CSGUI::_WelcomeScreenExpPtr ws;
00552         ws.CreateInstance(L"CSGUI.WelcomeScreenExp");
00553         if (ws)
00554         try {
00555                 ATL::CComSafeArray<BSTR> recents;
00556                 for (int i = 0; i < m_RecentProjectList.GetSize(); i++)
00557                 {
00558                         recents.Add(CComBSTR(m_RecentProjectList[i]));
00559                 }
00560                 VARIANT vrecents;
00561                 vrecents.parray = (SAFEARRAY*)recents;
00562                 vrecents.vt = VT_ARRAY | VT_BSTR;
00563                 ws->SetRecentProjects(_variant_t(vrecents));
00564                 _bstr_t SelectedProject = ws->ShowWelcomeWindow((unsigned long)m_pMainWnd->GetSafeHwnd());
00565 
00566                 if (SelectedProject != _bstr_t()) {
00567                         if (SelectedProject == ws->CREATE_SENTINEL) {
00568                                 OnFileNew();
00569                         } else {
00570                                 CString conn = static_cast<const wchar_t*>(SelectedProject);
00571                                 if(conn.Find(_T("=")) < 0) {
00572                                         if (conn.Right(4).CompareNoCase(_T(".xme")) == 0)
00573                                                 conn.Insert(0, _T("XML="));
00574                                         else if (conn.Right(4).CompareNoCase(_T(".mgx")) == 0)
00575                                         {
00576                                                 CString filename, dirname;
00577                                                 GetFullPathName(conn, filename, dirname);
00578                                                 conn = CString(L"MGX=\"") + dirname + L"\"";
00579                                         }
00580                                         else
00581                                                 conn.Insert(0,_T("MGA="));
00582                                 }
00583                                 OpenProject(conn);
00584                         }
00585                 }
00586         } catch (_com_error& e) {
00587                 //AfxMessageBox(e.ErrorMessage());
00588         }
00589         return TRUE;
00590 }
00591 
00592 int CGMEApp::Run()
00593 {
00594         CoFreeUnusedLibraries();        // JIRA 221: GME 9.12.15 Crashing
00595                                                                 // Unload ConstraintManager.dll, GME crashes if the system unloads it by itself
00596 
00597         Gdiplus::GdiplusStartupInput  gdiplusStartupInput;
00598         Gdiplus::GdiplusStartupOutput  gdiplusStartupOutput;
00599         ULONG_PTR gdiplusToken;
00600         ULONG_PTR gdiplusHookToken;
00601 
00602         // Tihamer: Initializing GDI+
00603         // See "Special CWinApp Services" MSDN topic http://msdn.microsoft.com/en-us/library/001tckck.aspx
00604         gdiplusStartupInput.SuppressBackgroundThread = TRUE;
00605         VERIFY(Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, &gdiplusStartupOutput) == Gdiplus::Ok);
00606         gdiplusStartupOutput.NotificationHook(&gdiplusHookToken);
00607         graphics.Initialize();
00608 
00609 
00610         // KMS: set up CrashRpt info
00611         CR_INSTALL_INFO info;
00612         memset(&info, 0, sizeof(CR_INSTALL_INFO));
00613         info.cb = sizeof(CR_INSTALL_INFO);
00614         info.pszAppName = _T("GME");
00615         info.pszAppVersion = _T(GME_VERSION_ID);
00616         info.pszEmailSubject = _T("GME CrashRpt");
00617         info.pszEmailTo = _T("gme-supp@isis.vanderbilt.edu");
00618         info.pszUrl = _T("http://symbols.isis.vanderbilt.edu/GME/crashrpt.php");
00619         info.dwFlags = CR_INST_SEH_EXCEPTION_HANDLER | CR_INST_PURE_CALL_HANDLER | CR_INST_SECURITY_ERROR_HANDLER
00620                 | CR_INST_INVALID_PARAMETER_HANDLER | CR_INST_SIGABRT_HANDLER | CR_INST_SIGINT_HANDLER | CR_INST_SIGTERM_HANDLER;
00621                 // missing: CR_INST_NEW_OPERATOR_ERROR_HANDLER: the default std::bad_alloc is fine (sometimes we handle it)
00622 #ifdef _DEBUG
00623         bNoProtect = true;
00624 #endif
00625         bNoProtect = bNoProtect || static_cast<bool>(IsDebuggerPresent());
00626         if (!bNoProtect) {
00627                 if (crInstall(&info) != 0)
00628                 {
00629                         TCHAR buff[1024];
00630                         crGetLastErrorMsg(buff, 1024);
00631                         AfxMessageBox(buff);
00632                         return FALSE;
00633                 }
00634         }
00635 
00636         OpenCommandLineProject();
00637 
00638         int retVal = 0;
00639         if (bNoProtect) {
00640                 retVal = CWinAppEx::Run();
00641         } else {
00642                 __try {
00643                         retVal = CWinAppEx::Run();
00644                 }
00645                 __except(crExceptionFilter(GetExceptionCode(), GetExceptionInformation())) {
00646                         EmergencySave();
00647 
00648                         // KMS: As our state may be corrupted, TerminateProcess so we don't run any atexits and crash again
00649                         TerminateProcess(GetCurrentProcess(), GetExceptionCode());
00650                 }
00651         }
00652         // KMS: need to unload decorators before closing GDI+: e.g. ~Facilities() does GDI+ ops
00653         CoFreeUnusedLibraries();
00654         // Closing GDI+
00655         graphics.Uninitialize();
00656         gdiplusStartupOutput.NotificationUnhook(gdiplusHookToken);
00657         Gdiplus::GdiplusShutdown(gdiplusToken);
00658 
00659         return retVal;
00660 }
00661 
00663 // CGMEApp Autosave
00664 void CGMEApp::Autosave()
00665 {
00666 
00667         if(mgaProject == NULL || (0&&!proj_type_is_mga) || (!autosaveEnabled)) {
00668                 // The KillTimer function does not remove WM_TIMER messages 
00669                 // already posted to the message queue ...
00670                 CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave was called with no active project or autosave disabled.\r\n"));
00671                 return;
00672         }
00673 
00674         // Figure out the filename
00675         CString conn;
00676         if (autosaveUseDir) {
00677                 int p = currentConnection.ReverseFind('\\');
00678                 CString fname = currentConnection.Mid(p + 1);
00679 
00680                 conn = CString(_T("MGA=")) + autosaveDir + CString(_T("\\")) + fname + GME_AUTOSAVE_EXTENSION;
00681         }
00682         else {
00683                 conn = currentConnection + GME_AUTOSAVE_EXTENSION;
00684         }
00685 
00686         // autosave in case of xmlbackend means saving into the sourcecontrol
00687         if( proj_type_is_xmlbackend)
00688                 conn = currentConnection;
00689 
00690         // Check if in transaction
00691         bool inTrans;
00692         try {
00693                 long status;
00694                 COMTHROW(mgaProject->get_ProjectStatus(&status));
00695                 inTrans = (status & 0x08L) != 0;
00696         }
00697         catch(hresult_exception &) {
00698                 // Safe presumption
00699                 inTrans = true;
00700         }
00701 
00702         if (inTrans) {
00703                 CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave failed ") + 
00704                         conn + _T(". We are in transaction.\r\n"));
00705                 return;
00706         }
00707 
00708         // Save the project
00709         try {
00710                 COMTHROW(mgaProject->Save(CComBSTR(conn), VARIANT_TRUE));
00711                 CGMEEventLogger::LogGMEEvent(_T("CGMEApp::Autosave succeeded ") + 
00712                         conn + _T("\r\n"));
00713         }
00714         catch(hresult_exception &e) {
00715                 CGMEEventLogger::LogGMEEvent(_T("WARNING: CGMEApp::Autosave failed ") + 
00716                         conn + _T(" ") + e.what() + _T("\r\n"));
00717         }
00718 }
00719 
00720 
00722 // CGMEApp MGA project management
00723 
00724 
00725 void CGMEApp::CloseProject(bool updateStatusBar, bool force_abort)
00726 {
00727 
00728         CWaitCursor wait;
00729         
00730         if(CGMEDataSource::myData) // it is true when object copied to the clipboard from the view
00731                 OleFlushClipboard();
00732         
00733         if( CMainFrame::theInstance != NULL ) {
00734                 CMainFrame::theInstance->StopAutosaveTimer();
00735                 CMainFrame::theInstance->SetPartBrowserMetaModel(NULL);
00736                 CMainFrame::theInstance->SetPartBrowserBg(::GetSysColor(COLOR_APPWORKSPACE));
00737         }
00738 
00739         if( CGMEBrowser::theInstance != NULL )
00740                 CGMEBrowser::theInstance->CloseProject();
00741         
00742         if(CGMEObjectInspector::theInstance!=NULL)
00743                 CGMEObjectInspector::theInstance->CloseProject();
00744 
00745         if(CGMESearch::theInstance!=NULL)
00746                 CGMESearch::theInstance->CloseProject();
00747 
00748         if (CGMEPartBrowser::theInstance)
00749                 CGMEPartBrowser::theInstance->SetProject(CComPtr<IMgaProject>(0));
00750 
00751 
00752 
00753         if( guiMetaProject != NULL )
00754         {
00755                 delete guiMetaProject;
00756                 guiMetaProject = NULL;
00757         }
00758 
00759         mgaMetaProject = NULL;
00760         UpdateComponentLists();
00761 
00762         if( mgaProject != NULL ) {
00763                 mgaClient = NULL;
00764                 if(mgaProject->Close((abort_on_close || force_abort) ? VARIANT_TRUE : VARIANT_FALSE) != S_OK) {
00765                         AfxMessageBox(CString(_T("Error occurred ")) + ((abort_on_close || force_abort) ? _T("aborting") : _T("closing")) + _T(" the project"));
00766                 }
00767                 mgaProject.Release();
00768         }
00769         
00770 
00771         if(updateStatusBar) {
00772                 CMainFrame::theInstance->WriteStatusParadigm(_T("-"));
00773                 CMainFrame::theInstance->WriteStatusMode(_T("EDIT"));
00774                 CMainFrame::theInstance->WriteStatusZoom(100);
00775         }
00776         projectName.Empty();
00777         ChangedProjectConnStrings();
00778 
00779         if(CGMEDoc::theInstance)
00780                 CGMEDoc::theInstance->SetTitle(_T(""));
00781         if(CMainFrame::theInstance) {
00782                 CMainFrame::theInstance->SetTitle(m_pszAppName);
00783                 CMainFrame::theInstance->UpdateTitle(0);//WAS: "" .By passing 0 instead of "" we won't get title such as "GME-" after a project was closed
00784         }
00785 }
00786 
00787 
00788 void CGMEApp::ChangedProjectConnStrings() {
00789         if(!mgaProject) {  // project closed
00790                 paradigmDir.Empty();
00791                 projectDir.Empty();
00792                 proj_type_is_mga = false;
00793         proj_type_is_xmlbackend = false;
00794                 return;
00795         }
00796         CString conn, metaconn;
00797         CComBstrObj cc;
00798         conn = cc;
00799         COMTHROW(mgaProject->get_ProjectConnStr(PutOut(cc)));
00800         conn = cc;
00801         cc.Empty();
00802         COMTHROW(mgaProject->get_ParadigmConnStr(PutOut(cc)));
00803         metaconn = cc;
00804         if(!conn.IsEmpty()) {
00805                 TCHAR cd[200];
00806                 GetCurrentDirectory(200, cd);
00807                 projectDir = cd;
00808                 if (conn.Find(_T("MGA=")) == 0) {
00809                         proj_type_is_mga = true;
00810                         int epos = conn.ReverseFind('\\');
00811                         if(epos >= 4) {
00812                                 projectDir = conn.Mid(4, epos-4);
00813                                 if(projectDir.IsEmpty()) projectDir= '\\';
00814                                 SetCurrentDirectory(projectDir);
00815                         }
00816                 }
00817                 else proj_type_is_mga = false;
00818 
00819         if( conn.Find(_T("MGX=")) == 0 ) 
00820             proj_type_is_xmlbackend = true;
00821         else
00822             proj_type_is_xmlbackend = false;
00823         }       
00824         if(!metaconn.IsEmpty()) {
00825                 if (metaconn.Find(_T("MGA=")) == 0) {
00826                         int epos = metaconn.ReverseFind('\\');
00827                         if(epos >= 4) {
00828                                 paradigmDir = metaconn.Mid(4, epos-4);
00829                                 if(paradigmDir.IsEmpty()) paradigmDir= '\\';
00830                         }
00831                 }
00832         }
00833 }
00834 
00835 
00836 // throws exceptions!!
00837 void CGMEApp::UpdateProjectName(bool retrievePath) {
00838         if( mgaProject == NULL ) {
00839                 projectName.Empty();
00840         }
00841         else {
00842 
00843 
00844                 CComObjPtr<IMgaTerritory> terry;
00845                 COMTHROW(mgaProject->CreateTerritory(NULL, PutOut(terry), NULL) );
00846                 CComBSTR nm;
00847         
00848                 MSGTRY
00849                 {
00850                         COMTHROW(mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY));
00851                         COMTHROW(mgaProject->get_Name(&nm));
00852                         COMTHROW(mgaProject->CommitTransaction());
00853                 }
00854                 MSGCATCH(_T("Error getting project name"), mgaProject->AbortTransaction())
00855 
00856                 CopyTo(nm,projectName);
00857         }
00858 
00859         if(CGMEDoc::theInstance)
00860                 CGMEDoc::theInstance->SetTitle(projectName);
00861         UpdateMainFrameTitle(projectName, retrievePath);
00862 }
00863 
00864 void CGMEApp::UpdateMainFrameTitle(const CString& projName, bool retrievePath)
00865 {
00866         CString projectName = projName;
00867 
00868         if (retrievePath) {
00869                 CDocument* pDocument = CGMEDoc::theInstance;
00870                 if (pDocument) {
00871                         POSITION pos = pDocument->GetFirstViewPosition();
00872                         while (pos != NULL) {
00873 #if !defined(ACTIVEXGMEVIEW)
00874                                 CGMEView* pView = (CGMEView*) pDocument->GetNextView(pos);
00875                                 ASSERT(pView);
00876                                 pView->RetrievePath();
00877                                 pView->SetTitles();
00878                         }
00879 #endif
00880                 }
00881         }
00882         CMDIChildWnd* pChild  = CMainFrame::theInstance->MDIGetActive();
00883         if (pChild && pChild->IsKindOf(RUNTIME_CLASS(CChildFrame))) {
00884 #if !defined (ACTIVEXGMEVIEW)
00885                 if (retrievePath) {
00886                         CGMEView* view = (CGMEView*)pChild->GetActiveView();
00887                         if (view) {
00888                                 view->RetrievePath();
00889                                 view->SetTitles();
00890                         }
00891                 }
00892 #endif
00893                 CChildFrame* childFrame = STATIC_DOWNCAST(CChildFrame, pChild);
00894                 projectName = childFrame->GetTitle() + _T(" - ") + childFrame->GetAppTitle();
00895         }
00896         if (mgaProject && isMgaProj()) {
00897                 CString filename, dirname;
00898                 getMgaPaths(filename, dirname);
00899                 projectName = projectName + L" (" + filename + L")";
00900         }
00901         CMainFrame::theInstance->UpdateTitle(projectName);
00902 }
00903 
00904 void CGMEApp::FindConstraintManager()
00905 {
00906         CComPtr<IMgaComponents> comps;
00907         COMTHROW( mgaProject->get_AddOnComponents(&comps));
00908         MGACOLL_ITERATE(IMgaComponent, comps) {
00909                 CComBSTR name;
00910                 COMTHROW(MGACOLL_ITER->get_ComponentName(&name));
00911                 if(name == _T("ConstraintManager")) {
00912                         mgaConstMgr = CComQIPtr<IMgaComponentEx>(MGACOLL_ITER); 
00913                         COMTHROW(mgaConstMgr->put_InteractiveMode(VARIANT_TRUE));
00914                         break;
00915                 }
00916         } MGACOLL_ITERATE_END;
00917 }
00918 
00919 
00920 void CGMEApp::UpdateComponentToolbar()
00921 {
00922                 if (!CMainFrame::theInstance)
00923                         return;
00924                 CComponentBar &componentBar = CMainFrame::theInstance->m_wndComponentBar;
00925                 componentBar.ShowWindow(SW_HIDE);
00926                 CMainFrame::theInstance->ShowPane(&componentBar, FALSE, FALSE, FALSE);
00927 
00928                 // Removing the add-in and plug-in buttons
00929                 const CObList &componentButtons = componentBar.GetAllButtons();
00930                 for(POSITION pos = componentButtons.GetHeadPosition(); pos!= NULL; )
00931                 {
00932                         const CMFCToolBarButton* pCurrent = (const CMFCToolBarButton*) componentButtons.GetNext(pos); 
00933                         if(pCurrent->m_bUserButton == TRUE)
00934                         {
00935                                 // FIXME: this doesn't work, so we leak all the icons. Maybe we could m_userImages.UpdateImage instead?
00936                                 // VERIFY(m_userImages.DeleteImage(pCurrent->GetImage()));
00937                                 int buttonIndex = componentBar.ButtonToIndex(pCurrent);
00938                                 componentBar.RemoveButton(buttonIndex);
00939                         }
00940                 }
00941 
00942                 componentBar.AdjustLayout();    // CMFCToolBar::AdjustLayout
00943                 componentBar.AdjustSizeImmediate(TRUE);
00944                 componentBar.RecalcLayout();    // CPane::RecalcLayout
00945 
00946                 if (!mgaMetaProject)
00947                 {
00948                         return;
00949                 }
00950 
00951                 // Updating the Component toolbar
00952                 CComPtr<IMgaRegistrar> registrar;
00953                 if(registrar.CoCreateInstance(L"Mga.MgaRegistrar") != S_OK) return;
00954 
00955 
00956                 // Traversing  the plugins and interpreters
00957                 int plugins_size = min(plugins.GetSize(), ID_FILE_RUNPLUGIN_LAST - ID_FILE_RUNPLUGIN1);
00958                 int interpreters_size = min(interpreters.GetSize(), ID_FILE_INTERPRET_LAST - ID_FILE_INTERPRET1);
00959                 for(int i = 0; i < plugins_size + interpreters_size; ++i)
00960                 {
00961                         // Querying component name
00962                         CComBSTR componentName;
00963                         if(i < plugins_size) // if it is a plugin
00964                         {
00965                                 componentName = plugins[i];
00966                         }
00967                         else                                    // if it is an interpreter
00968                         {
00969                                 componentName = interpreters[i-plugins_size];
00970                         }
00971 
00972                         // Obtaining ToolTip
00973                         HRESULT errCode;
00974                         CString toolTip;
00975                         errCode = registrar->get_ComponentExtraInfo(REGACCESS_PRIORITY, componentName, CComBSTR(L"Tooltip"), PutOut(toolTip));
00976                         if(errCode != S_OK || toolTip.IsEmpty())
00977                         {
00978                                 toolTip = componentName;
00979                         }
00980                         if(i < plugins_size)
00981                         {
00982                                 pluginTooltips.Add(toolTip);
00983                         }
00984                         else
00985                         {
00986                                 interpreterTooltips.Add(toolTip);
00987                         }
00988 
00989                         // Querying icon information
00990                         CString iconInfo;
00991                         errCode = registrar->get_ComponentExtraInfo(REGACCESS_PRIORITY, componentName, CComBSTR(L"Icon"), PutOut(iconInfo));
00992                         if(errCode != S_OK || iconInfo.IsEmpty()) 
00993                         {
00994                                 continue;
00995                         }
00996                         
00997                         // Loading icon
00998                         HICON hIcon = NULL; //, hictofree = NULL;
00999                         int commaPos;
01000                         HMODULE hModule = NULL;
01001                         if((commaPos = iconInfo.Find(',')) >= 0)  //Format:   <modulename>,<resourceID>
01002                         {
01003                                 if(commaPos)  // module name present;
01004                                 {
01005                                         // XP doesn't support LOAD_LIBRARY_AS_IMAGE_RESOURCE
01006                                         hModule = LoadLibraryEx(iconInfo.Left(commaPos), NULL, LOAD_LIBRARY_AS_DATAFILE);
01007                                 }
01008                                 else // No module name provided,
01009                                 {
01010                                         _bstr_t modulePath;
01011                                         registrar->get_LocalDllPath(componentName, modulePath.GetAddress());
01012                                         if(modulePath.length() != 0)
01013                                         {
01014                                                 // XP doesn't support LOAD_LIBRARY_AS_IMAGE_RESOURCE
01015                                                 hModule = LoadLibraryEx(modulePath, NULL, LOAD_LIBRARY_AS_DATAFILE);
01016                                         }
01017                                 }
01018                         }
01019 
01020                         int cx = m_userImages.GetImageSize().cx;
01021                         int cy = m_userImages.GetImageSize().cy;
01022 
01023                         if( hModule != NULL )
01024                         {
01025                                 hIcon = (HICON)::LoadImage(hModule, iconInfo.Mid(commaPos+1), IMAGE_ICON, cx, cy, LR_DEFAULTCOLOR);
01026                         }
01027                         else
01028                         {
01029                                 // simple .ico file with path
01030                                 hIcon =(HICON)LoadImage(NULL, iconInfo, IMAGE_ICON, cx, cy, LR_LOADFROMFILE);
01031                         }
01032                         
01033                         // If icon is not found either in the DLL or a standalone file
01034                         if(!hIcon)
01035                         {
01036                                 // Displaying component not found icon: red X
01037                                 hIcon = (HICON)LoadImage(AfxGetResourceHandle(), MAKEINTRESOURCE(IDI_COMPNOTFOUND), IMAGE_ICON, 16,16, LR_DEFAULTCOLOR); 
01038                         }
01039 
01040                         //Adding button icon
01041                         int nIndex = m_userImages.AddIcon(hIcon);
01042                         ASSERT(nIndex >= 0);
01043                         BOOL succ = CMFCToolBar::SetUserImages(&m_userImages);
01044                         ASSERT(succ == TRUE);
01045 
01046                         // Adding button
01047                         INT_PTR commandID = (i < plugins_size) ? ID_FILE_RUNPLUGIN1 + i : ID_FILE_INTERPRET1 + i - plugins_size;
01048                         CMFCToolBarButton toolBarButton(commandID, nIndex, componentName + '\n' + toolTip, TRUE);
01049 
01050                         VERIFY(componentBar.InsertButton(toolBarButton) != -1);
01051                         if (hModule)
01052                                 FreeLibrary(hModule);
01053                 }
01054                 if (plugins_size + interpreters_size != 0) {
01055                         componentBar.AdjustLayout();    // CMFCToolBar::AdjustLayout
01056                         componentBar.AdjustSizeImmediate(TRUE);
01057                         componentBar.RecalcLayout();    // CPane::RecalcLayout
01058                         CMainFrame::theInstance->ShowPane(&componentBar, TRUE, FALSE, FALSE);
01059                         componentBar.ShowWindow(SW_SHOW);
01060                 }
01061 }
01062 
01063 
01064 void CGMEApp::UpdateComponentLists(bool restart_addons)
01065 {
01066         ClearDisabledComps();   
01067         plugins .RemoveAll();
01068         pluginTooltips.RemoveAll();
01069         interpreters.RemoveAll();
01070         interpreterTooltips.RemoveAll();
01071         CStringArray tempaddons; tempaddons.Copy(addons);
01072         addons.RemoveAll();
01073         mgaConstMgr = NULL;
01074         if(mgaMetaProject) {
01075                 CComBSTR b;
01076                 COMTHROW(mgaMetaProject->get_Name(&b));
01077                 CComPtr<IMgaRegistrar> reg;
01078                 COMTHROW(reg.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar")));
01079                 {
01080                         CComVariant v;
01081                         COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_PLUGIN, REGACCESS_BOTH, &v));
01082                         CopyTo(v, plugins);
01083                 }
01084                 {
01085                         CComVariant v;
01086                         COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_INTERPRETER, REGACCESS_BOTH, &v));
01087                         CopyTo(v, interpreters);
01088                 }
01089                 {
01090                         CComVariant v;
01091                         COMTHROW(reg->get_AssociatedComponents(b, COMPONENTTYPE_ADDON, REGACCESS_BOTH, &v));
01092 
01093                         CopyTo(v, addons);
01094                         if(restart_addons) {
01095                                 bool redo = false;
01096                                 if(tempaddons.GetSize() != addons.GetSize()) redo = true;
01097                                 else {
01098                                         for(int j = 0 ; j < tempaddons.GetSize(); j++) {
01099                                                 if(addons[j].Compare(tempaddons[j])) {
01100                                                         redo = true;
01101                                                         break;
01102                                                 }
01103                                         }
01104                                 }
01105                                 if(redo && AfxMessageBox(_T("AddOn configuration has changed.\nRestart addons?"), MB_YESNO) == IDYES) {
01106                                         COMTHROW(mgaProject->EnableAutoAddOns(VARIANT_FALSE));
01107                                         COMTHROW(mgaProject->EnableAutoAddOns(VARIANT_TRUE));
01108                                 }
01109                         }
01110                 }
01111                 // access constraint mgr
01112                 FindConstraintManager();
01113 
01114         }
01115         dynmenus_need_refresh = true;
01116         UpdateComponentToolbar();
01117 }
01118 
01119 void CGMEApp::UpdateDynMenus(CMenu *toolmenu)
01120 {
01121         CString runPluginLabel = _T("R&un Plug-In");
01122         CString runInterpreterLabel = _T("Run In&terpreter");
01123         CString label;
01124         // [ Begin workaround
01125         // If you just go left to the Window menu next to the Tools menu, and back to the Tools menu (so not even abandoming the menubar)
01126         // the original menu (without added intepreters and plugins) is switched back.
01127         // To workaround this we check always if the original plugin and interpreter placeholder menus are present,
01128         // because if they are present we have to populate the interpreters plugins again.
01129         // Step 1: Get tools menu if we got NULL menu
01130         if (toolmenu == NULL) {
01131                 CMenu* mainMenu = CMainFrame::theInstance->GetMenu();
01132                 if (mainMenu == NULL || mainMenu->m_hMenu == NULL) {
01133                         HMENU mainHMenu = CMainFrame::theInstance->GetMenuBar()->GetHMenu();
01134                         mainMenu = CMenu::FromHandle(mainHMenu);
01135                 }
01136                 ASSERT(mainMenu);
01137                 for(UINT idxa = 0; idxa < mainMenu->GetMenuItemCount(); idxa++) {
01138                         CString labela;
01139                         mainMenu->GetMenuString(idxa, labela, MF_BYPOSITION);
01140                         if (!labela.CompareNoCase(_T("&Tools"))) {
01141                                 toolmenu = mainMenu->GetSubMenu(idxa);
01142                                 break;
01143                         }
01144                 }
01145         }
01146         // Step 2: Check if placeholder menus are present -> we switch trigger in that case
01147         if (toolmenu != NULL) {
01148                 for(UINT idx = 0; idx < toolmenu->GetMenuItemCount(); idx++) {
01149                         toolmenu->GetMenuString(idx, label, MF_BYPOSITION);
01150                         UINT menuID = toolmenu->GetMenuItemID(idx);
01151                         if (menuID == ID_TOOLS_RUNPLUG || menuID == ID_FILE_RUNINTERPRETER) {
01152                                 dynmenus_need_refresh = true;
01153                                 break;
01154                         }
01155                 }
01156         }
01157         // End workaround ]
01158         if (!dynmenus_need_refresh)
01159                 return;
01160         ASSERT(toolmenu);
01161         bool found = false;
01162         for(UINT idx = 0; idx < toolmenu->GetMenuItemCount(); idx++) {
01163                 toolmenu->GetMenuString(idx, label, MF_BYPOSITION);
01164                 UINT menuID = toolmenu->GetMenuItemID(idx);
01165                 if (!label.CompareNoCase(runPluginLabel) ||
01166                         menuID == ID_TOOLS_RUNPLUG || menuID == ID_FILE_RUNPLUGIN1)
01167                 {
01168                         if (dynmenus_need_refresh) {
01169                                 toolmenu->DeleteMenu(idx, MF_BYPOSITION);
01170                                 if (plugins.GetSize() == 1) {
01171                                         toolmenu->InsertMenu(idx, MF_BYPOSITION | MF_ENABLED,
01172                                                                                 ID_FILE_RUNPLUGIN1, pluginTooltips[0]);
01173                                 } else {
01174                                         CMenu pluginmenu;
01175                                         pluginmenu.CreatePopupMenu();
01176                                         for(int i = 0; i < min(plugins.GetSize(), ID_FILE_RUNPLUGIN_LAST - ID_FILE_RUNPLUGIN1); ++i) {
01177                                                 pluginmenu.AppendMenu(MF_ENABLED, ID_FILE_RUNPLUGIN1 + i, pluginTooltips[i]);
01178                                         }
01179                                         toolmenu->InsertMenu(idx,
01180                                                                 plugins.GetSize() ? MF_BYPOSITION | MF_POPUP | MF_ENABLED : MF_BYPOSITION | MF_POPUP | MF_GRAYED,
01181                                                                 (UINT_PTR)pluginmenu.Detach(), runPluginLabel);
01182                                 }
01183                                 found = true;
01184                         }
01185                 } else if (!label.CompareNoCase(runInterpreterLabel) ||
01186                                         menuID == ID_FILE_RUNINTERPRETER || menuID == ID_FILE_INTERPRET1)
01187                 {
01188                         if (dynmenus_need_refresh) {
01189                                 toolmenu->DeleteMenu(idx, MF_BYPOSITION);
01190                                 if (interpreters.GetSize() == 1) {
01191                                         toolmenu->InsertMenu(idx, MF_BYPOSITION | MF_ENABLED,
01192                                                                                 ID_FILE_INTERPRET1, interpreterTooltips[0]);
01193                                 } else {
01194                                         CMenu pluginmenu;
01195                                         pluginmenu.CreatePopupMenu();
01196 
01197                                         struct TooltipSorter {
01198                                                 CString tooltip;
01199                                                 int id;
01200                                                 bool operator<(const TooltipSorter& that) {
01201                                                         return this->tooltip < that.tooltip;
01202                                                 }
01203                                         };
01204                                         std::vector<TooltipSorter> interpreters_sorted;
01205 
01206                                         for (int i = 0; i < min(interpreters.GetSize(), ID_FILE_INTERPRET_LAST - ID_FILE_INTERPRET1); ++i) {
01207                                                 TooltipSorter tt = { interpreterTooltips[i], ID_FILE_INTERPRET1 + i };
01208                                                 interpreters_sorted.push_back(std::move(tt));
01209                                         }
01210                                         std::sort(begin(interpreters_sorted), end(interpreters_sorted));
01211                                         std::for_each(begin(interpreters_sorted), end(interpreters_sorted), [&](const TooltipSorter& tt)
01212                                         {
01213                                                 pluginmenu.AppendMenu(MF_ENABLED, tt.id, tt.tooltip);
01214                                         });
01215                                         toolmenu->InsertMenu(idx,
01216                                                                 interpreters.GetSize() ? MF_BYPOSITION | MF_POPUP | MF_ENABLED : MF_BYPOSITION | MF_POPUP | MF_GRAYED,
01217                                                                 (UINT_PTR)pluginmenu.Detach(), runInterpreterLabel);
01218                                 }
01219                                 found = true;
01220                         }
01221                 }
01222         }
01223         if (found)
01224                 dynmenus_need_refresh = false;
01225 }
01226 
01227 
01228 // throws exceptions!!
01229 void CGMEApp::AfterOpenOrCreateProject(const CString &conn)
01230 {
01231         UpdateProjectName();
01232         if( mgaProject != NULL ) {
01233                 abort_on_close = false;
01234 // get meta
01235                 COMTHROW( mgaProject->get_RootMeta(&mgaMetaProject) );
01236                 UpdateComponentLists();
01237 
01238 // create guimetaproject
01239                 ASSERT( guiMetaProject == NULL );
01240                 guiMetaProject = new CGuiMetaProject(mgaMetaProject);
01241                 CMainFrame::theInstance->WriteStatusParadigm(guiMetaProject->displayedName);
01242                 CMainFrame::theInstance->SetTitle(guiMetaProject->displayedName);
01243                 UpdateProjectName();
01244 
01245 // Register OLE Server / MGA Client
01246                 CGMEOLEApp *oleApp = ((CMainFrame*)m_pMainWnd)->mGmeOleApp;
01247                 CComBSTR clientName(OLESTR("GME.Application"));
01248                 COMTHROW(mgaProject->RegisterClient(clientName, oleApp->GetIDispatch(FALSE), &mgaClient)); // mgaClient increments the refcount of oleApp->idispatch by 1
01249 
01250                 ((CMainFrame*)m_pMainWnd)->setMgaProj();
01251 
01252 // notify object inspector
01253                 ASSERT(CGMEObjectInspector::theInstance!=NULL);
01254                 CGMEObjectInspector::theInstance->SetProject(mgaProject);
01255 
01256 // notify Part Browser
01257                 ASSERT(CGMEPartBrowser::theInstance!=NULL);
01258                 CGMEPartBrowser::theInstance->SetProject(mgaProject);
01259 
01260 // by swapping the order of SetProject (first ObjectInspector, then Browser), 
01261 // the user will see the properties of the initally selected project at once
01262 // notify browser
01263                 ASSERT( CGMEBrowser::theInstance != NULL );
01264                 CGMEBrowser::theInstance->SetProject(mgaProject);
01265 
01266 // notify search control
01267                 ASSERT(CGMESearch::theInstance!=NULL);
01268                 CGMESearch::theInstance->SetProject(mgaProject);
01269 
01270 
01271 // change dir
01272                 ChangedProjectConnStrings();
01273 // record connection name
01274                 currentConnection = conn;
01275                 m_RecentProjectList.AddAndWriteList(conn);
01276                 if (!CGMEDoc::theInstance) {
01277                         CWinAppEx::OnFileNew();
01278                 }
01279 // start autosave
01280                 if (autosaveEnabled) {
01281                         CMainFrame::theInstance->StartAutosaveTimer(autosaveFreq);
01282                 }
01283         }
01284 }
01285 
01286 
01287 static int guidcmp(VARIANT &qGUID, VARIANT &pGUID)      {
01288         GUID g1, g2;
01289         CopyTo(qGUID, g1);
01290         CopyTo(pGUID, g2);
01291         return memcmp(&g1, &g2, sizeof(g1));
01292 }
01293 
01294 static int versioncmp(CComBSTR &qVer, CComBSTR &pVer) {
01295         CString q(qVer);
01296         CString p(pVer);
01297 
01298         if ((!p.IsEmpty()) && (!q.IsEmpty())) {
01299                 return p.Compare(q);
01300         }
01301         return 1;
01302 }
01303 
01304 
01305 bool DiagnoseParadigm(CString metaname, bool syscheck = false) {
01306         CComPtr<IMgaRegistrar> reg;
01307         try {
01308                 HRESULT hr = reg.CoCreateInstance(CComBSTR(L"Mga.MgaRegistrar"));
01309                 if(hr != S_OK) {
01310                         throw CString(_T("Cannot create the registrar component\n")
01311                                                   _T("We recommend you to reinstall GME"));
01312                 }
01313                 CComBSTR conn;
01314                 CComVariant guid;
01315                 hr = reg->QueryParadigm(CComBSTR(metaname), &conn, &guid, 
01316                         syscheck ? REGACCESS_SYSTEM : REGACCESS_PRIORITY);
01317                 if(hr != S_OK) {
01318                         throw CString(_T("Cannot access registry info for paradigm ") + metaname +
01319                                                   _T("\nWe recommend you remove and re-register the paradigm"));
01320                 }
01321                 CComObjPtr<IMgaMetaProject> paradigm;
01322                 hr =  paradigm.CoCreateInstance(OLESTR("MGA.MgaMetaProject"));
01323                 if(hr != S_OK) {
01324                         throw CString(_T("Cannot create the meta component\n")
01325                                                   _T("We recommend you reinstall GME"));
01326                 }
01327 
01328                 hr = paradigm->Open(conn);
01329 
01330                 if(hr != S_OK) {
01331                         throw CString(_T("Cannot open the paradigm ") + metaname + _T("\n")
01332                                                   _T("Probable cause is file non-existence,\n")
01333                                                   _T("insufficient access, or format error\n")
01334                                                   _T("Connection string: ") + CString(conn));
01335                 }
01336 
01337 
01338                 CComBSTR parname;
01339                 CComVariant gguid;
01340                 hr = paradigm->get_Name(&parname);
01341                 if(hr == S_OK) paradigm->get_GUID(&gguid);
01342                 hr |= paradigm->Close();
01343 
01344                 if(hr != S_OK) {
01345                         throw CString(_T("Cannot read the paradigm ") + metaname + _T("\n")
01346                                                   _T("Probable cause is file format error\n")
01347                                                   _T("Connection string: ") + CString(conn));
01348                 }
01349                 if(!( parname == CComBSTR( (LPCTSTR) metaname))) {
01350                         throw CString(_T("The paradigm opened '") + CString(parname) + _T("'\n")
01351                                                   _T("differs from the requested paradigm '")+ metaname + _T("'\n")
01352                                                   _T("We recommend you unregister '") + metaname + _T("'\n")
01353                                                   _T("Connection string: ") + CString(conn));
01354 
01355                 }
01356 
01357                 CComBstrObj parg1, parg2;
01358                 GUID g;
01359                 CopyTo(gguid, g);
01360                 CopyTo(g, parg1);
01361                 CopyTo(guid, g);
01362                 CopyTo(g, parg2);
01363                 if(parg1 != parg2) {
01364                         throw CString(_T("The GUID in paradigm '") + CString(parname) + _T("'\n")
01365                                                   _T("{") + CString(parg1) + _T("}\n")
01366                                                   _T("differs from the requested GUID for '")+ metaname + _T("'\n")
01367                                                   _T("{") + CString(parg2) + _T("}\n")
01368                                                   _T("We recommend you unregister '") + metaname + _T("'\n")
01369                                                   _T("Connection string: ") + CString(conn));
01370                 }
01371         } catch( CString &c) {
01372                 if(!syscheck) {
01373                         AfxMessageBox(c); 
01374                         CComBSTR cc; CComVariant gg;
01375                         if(reg && E_NOTFOUND != reg->QueryParadigm(CComBSTR(metaname), &cc, &gg, REGACCESS_SYSTEM)) {
01376                                 if(DiagnoseParadigm(metaname, true)) {
01377                                         AfxMessageBox(_T("SYSTEM registry for '") + metaname + _T("' is correct\n")
01378                                                                 _T("We recommend you remove the USER registration for ") + metaname);
01379                                 }
01380                                 else {
01381                                         AfxMessageBox(_T("SYSTEM registry for '") + metaname + _T("' is also incorrect\n")
01382                                                                 _T("We recommend you reinstall the paradigm."));
01383                                 }
01384                         }
01385                 }
01386                 return false;
01387         }
01388         catch(...) {
01389                 return false;
01390         }
01391         return true;
01392 }
01393 
01394 
01395 
01396 void CGMEApp::OpenProject(const CString &conn) {
01397 
01398         MSGTRY
01399         {
01400                 if (conn.Left(4) == _T("XML=")) {
01401                         CString fullPath = conn.Right(conn.GetLength() - 4);
01402                         TCHAR buffer[MAX_PATH];
01403                         TCHAR* filepart = NULL;
01404                         GetFullPathName(fullPath, MAX_PATH, buffer, &filepart);
01405                         if (filepart == NULL) {
01406                                 COMTHROW(E_FILEOPEN);
01407                         }
01408                         CString filename = filepart;
01409                         CString title = filename.Left(filename.ReverseFind('.'));
01410                         Importxml(fullPath, filepart, title);
01411                         return;
01412                 }
01413 
01414                 CWaitCursor wait;
01415 
01416                 ASSERT( mgaProject == 0 );
01417                 COMTHROW( mgaProject.CoCreateInstance(OLESTR("Mga.MgaProject")) );
01418 
01419                 VARIANT_BOOL enableAutoAddOns = VARIANT_TRUE;
01420                 VARIANT_BOOL readable_only;
01421 
01422                 COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE));
01423                 HRESULT hr = mgaProject->Open(PutInBstr(conn), &readable_only);
01424                 if(hr != S_OK) {
01425                         _bstr_t mgaProjectOpenError;
01426                         GetErrorInfo(mgaProjectOpenError.GetAddress());
01427                         CComBSTR parn;
01428                         CComBSTR parv;
01429                         long version;
01430                         CComVariant parg;
01431                         VARIANT_BOOL ro_mode;
01432                         if( conn.Left(5) == _T("MGX=\""))
01433                         {
01434                                 if( E_FILEOPEN == hr) {
01435                                         consoleMessage( _T("Could not open project!"), MSG_ERROR);
01436                                 }
01437                                 else if( E_MGA_PARADIGM_INVALID == hr) {
01438                                         consoleMessage( _T("Project could not access its original version of paradigm!"), MSG_ERROR);
01439                                 }
01440                                 else if( E_MGA_PARADIGM_NOTREG == hr) {
01441                                         consoleMessage( _T("Project could not access its paradigm!"), MSG_ERROR);
01442                                 }
01443                                 else if( E_MGA_META_INCOMPATIBILITY == hr) {
01444                                         consoleMessage( _T("Versioned project is not compatible with the registered paradigm!"), MSG_ERROR);
01445                                 }
01446                                 else if( E_UNKNOWN_STORAGE == hr) { 
01447                                         // no additional comment in this case
01448                                 }
01449                                 else {
01450                                         consoleMessage( _T("Could not open project (unknown error)!"), MSG_ERROR);
01451                                 }
01452                                 CloseProject();
01453                                 return; // ensures no more exception handlers or explanatory messages (or QueryProjectInfo calls)
01454                         }
01455 
01456                         COMTHROW(mgaProject->QueryProjectInfo(PutInBstr(conn), &version, &parn, &parv, &parg, &ro_mode));
01457                         while (true) {
01458                                 CString msg;
01459                                 CComVariant guidpar;
01460                                 CString newparname;
01461                                 bool tryit = false;
01462 
01463                                 if(hr == E_MGA_MODULE_INCOMPATIBILITY) {
01464                                         msg = _T("WARNING: The project data is not in the current MGA format\n")
01465                                                 _T("Do you want to upgrade it?");
01466                                         if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) {
01467                                                 tryit = true;
01468                                         }
01469                                 }
01470                                 if(hr == E_MGA_PARADIGM_INVALID) {
01471                                         msg = _T("WARNING: Project could not access its original version of\n")
01472                                                 _T("paradigm '") + CString(parn) + _T("'\n");
01473                                         if (mgaProjectOpenError.length())
01474                                                 msg += static_cast<const wchar_t*>(mgaProjectOpenError);
01475                                         msg += _T("Do you want to try with the current version of the paradigm?");
01476                                         if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) {
01477                                                 guidpar = true;
01478                                                 tryit = true;
01479                                                 newparname = parn;
01480                                         }
01481                                 }
01482                                 if(hr == E_MGA_PARADIGM_NOTREG) {
01483                                         CString msg = _T("Could not find paradigm '") + CString(parn) + "'";
01484                                         if (parv != "") {
01485                                                 msg += CString(" version ") + static_cast<const wchar_t*>(parv);
01486                                         } else if (parg.vt == (VT_UI1 | VT_ARRAY)) {
01487                                                 msg += CString(" with GUID ") + StringFromGUID2(parg);
01488                                         }
01489                                         IMgaRegistrarPtr registrar;
01490                                         COMTHROW(registrar.CreateInstance(L"Mga.MgaRegistrar"));
01491                                         _variant_t current_guid;
01492                                         _bstr_t current_version;
01493                                         registrar->QueryParadigm(static_cast<BSTR>(parn), _bstr_t().GetAddress(), current_guid.GetAddress(), REGACCESS_BOTH);
01494                                         registrar->VersionFromGUID(static_cast<BSTR>(parn), current_guid, current_version.GetAddress(), REGACCESS_BOTH);
01495                                         if (current_guid.vt != VT_EMPTY || current_version.length())
01496                                         {
01497                                                 CString msg_current = msg;
01498                                                 msg_current += L"\nDo you want to open with the current version (";
01499                                                 if (current_version.length())
01500                                                 {
01501                                                         msg_current += static_cast<const wchar_t*>(current_version);
01502                                                 }
01503                                                 else if (current_guid.vt == (VT_UI1 | VT_ARRAY))
01504                                                 {
01505                                                         msg_current += StringFromGUID2(current_guid);
01506                                                 }
01507                                                 msg_current += L")?";
01508                                                 int mbRes = AfxMessageBox(msg_current, MB_YESNOCANCEL);
01509                                                 if (mbRes == IDCANCEL)
01510                                                 {
01511                                                         break;
01512                                                 }
01513                                                 if (mbRes == IDYES)
01514                                                 {
01515                                                         guidpar = true;
01516                                                         tryit = true;
01517                                                         newparname = parn;
01518                                                 }
01519                                         }
01520 
01521                                         if (!tryit)
01522                                         {
01523                                                 if (CString(parn) == _T("MetaGME2000"))
01524                                                         msg += _T("\n (In GME3 the MetaGME2000 paradigm was renamed to MetaGME)");
01525                                                 msg += _T("\nDo you want to import with another registered paradigm ?");
01526                                                 if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) {
01527                                         
01528                                                         CComObjPtr<IMgaLauncher> launcher;
01529                                                         COMTHROW( launcher.CoCreateInstance(CComBSTR(L"Mga.MgaLauncher")) );
01530                                                         if (SUCCEEDED(launcher->MetaDlg(METADLG_NONE))) {
01531                                                                 guidpar = true;
01532                                                                 newparname.Empty();
01533                                                                 COMTHROW( launcher->get_ParadigmName(PutOut(newparname)) );
01534                                                                 tryit = !newparname.IsEmpty();
01535                                                         }
01536                                                 }
01537                                         }
01538                                 }
01539                                 if(hr == E_MGA_META_INCOMPATIBILITY && (parv.Length() > 0)) {
01540                                         msg = _T("WARNING: Versioned project is not compatible with the paradigm '") + CString(parn) + _T("'\n") 
01541                                                 _T(" (Eg.: Same version string was assigned to incompatible paradigms)\n")
01542                                                 _T("Do you want to open it based on the paradigm GUID?");
01543                                         if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) {
01544                                                 guidpar = parg;
01545                                                 tryit = true;
01546                                                 newparname = parn;
01547                                         }
01548                                 }
01549                                 if(hr == E_MGA_COMPONENT_ERROR) {
01550                                         _bstr_t err(_T("ERROR: automatic addon components could not start up:\n"));
01551                     err += mgaProjectOpenError;
01552                                         err += "\nDo you want to open the project without addons?";
01553                                         if (AfxMessageBox(err, MB_YESNO) == IDYES) {
01554                                                 enableAutoAddOns = VARIANT_FALSE;
01555                                                 mgaProject->EnableAutoAddOns(enableAutoAddOns);
01556                                                 tryit = true;
01557                                         }
01558                                 }
01559                                 if(tryit) {
01560                                         hr = mgaProject->OpenEx(PutInBstr(conn), CComBSTR(newparname), guidpar);
01561                                         if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) {
01562                                                 DiagnoseParadigm(CString(parn));
01563                                         }
01564                                 }
01565                                 else break;
01566                         }
01567                         COMTHROW(hr);
01568                 }
01569 
01570                 if(readable_only != VARIANT_FALSE) {
01571                         AfxMessageBox(_T("WARNING: Project file is read-only\nChange file access or use Save As to save your work"));
01572                 }
01573                 else {
01574                         CComVariant g, g2;
01575                         CComBSTR pname; 
01576                         CComBSTR pver, pver2;
01577                         {
01578                                 CComPtr<IMgaTerritory> t;
01579                                 COMTHROW(mgaProject->CreateTerritory(NULL, &t, NULL));
01580                                 COMTHROW(mgaProject->BeginTransaction(t, TRANSACTION_READ_ONLY));
01581                                 COMTHROW(mgaProject->get_MetaName(&pname));
01582                                 COMTHROW(mgaProject->get_MetaGUID(&g));
01583                                 COMTHROW(mgaProject->get_MetaVersion(&pver));
01584                                 // COMTHROW(mgaProject->AbortTransaction()); PETER: Why abort ?
01585                                 COMTHROW(mgaProject->CommitTransaction());
01586                                 CComPtr<IMgaRegistrar> mgareg;
01587                                 COMTHROW(mgareg.CoCreateInstance(OLESTR("MGA.MgaRegistrar")));
01588                                 CComBSTR connstr;
01589                                 COMTHROW(mgareg->QueryParadigm(pname, &connstr, &g2, REGACCESS_PRIORITY));
01590                                 mgareg->VersionFromGUID(pname, g2, &pver2, REGACCESS_PRIORITY);
01591                         }
01592                         if(guidcmp(g, g2) && versioncmp(pver, pver2)) {
01593                                 CString project_version = pver;
01594                                 if (project_version == _T(""))
01595                                         project_version = StringFromGUID2(g);
01596                                 CString registered_paradigm_version = pver2;
01597                                 if (pver2 == _T(""))
01598                                         registered_paradigm_version = StringFromGUID2(g2);
01599                                 CString prompt;
01600                                 prompt.Format(_T("The '%s' paradigm version used to save this file, '%s', is not the currently-registered version, '%s'.\n\n")
01601                                                                 _T("Do you want to upgrade to the current paradigm?"),
01602                                                                 static_cast<const TCHAR*>(pname), project_version, registered_paradigm_version);
01603                                 int answer = AfxMessageBox(prompt, MB_YESNO);
01604                                 if(answer == IDYES) {
01605                                         COMTHROW(mgaProject->Close(VARIANT_FALSE));
01606 
01607                                         // PETER: Create new MgaProject COM object (workaround MGA addon bug)
01608                                         mgaProject.Release();
01609                                         COMTHROW( mgaProject.CoCreateInstance(OLESTR("Mga.MgaProject")) );
01610                                         COMTHROW( mgaProject->EnableAutoAddOns(enableAutoAddOns));
01611                                         
01612                                         HRESULT hr = mgaProject->OpenEx(PutInBstr(conn), pname, g2);
01613                                         if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) {
01614                                                 AfxMessageBox(_T("Paradigm error"));
01615                                                 DiagnoseParadigm(CString(pname));
01616                                         }
01617                                         else if(hr != S_OK) {
01618                                                 AfxMessageBox(_T("Upgrade failed, probably due to incompatibility.\n")
01619                                                                            _T("You can probably reopen the file without upgrade,\n")
01620                                                                            _T("and use the 'Upgrade through XML' function later."));
01621                                                 throw_last_com_error(hr);
01622                                         }
01623                                         else readable_only = false;
01624                                         COMTHROW(hr);
01625                                 }
01626                         }       
01627                 }
01628                 AfterOpenOrCreateProject(conn);
01629                 hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED);
01630                 ASSERT(SUCCEEDED(hr));
01631         }
01632         MSGCATCH(_T("Could not open project"), CloseProject(true, true))
01633         
01634         UpdateProjectName();
01635 
01636 }
01637 
01638 
01639 
01640 void CGMEApp::CreateProject(const CString &metaname, const CString &conn)
01641 {
01642         CString msg;
01643         try
01644         {
01645                 CWaitCursor wait;
01646 
01647                 // create the project
01648                 msg = _T("Fatal error while initializing project");
01649                 ASSERT( mgaProject == 0 );
01650                 COMTHROW( mgaProject.CoCreateInstance(L"Mga.MgaProject") );
01651                 ASSERT( mgaProject != NULL );
01652 
01653                 COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE));
01654                 msg = _T("Could not create project");
01655                 HRESULT hr = mgaProject->Create(PutInBstr(conn), PutInBstr(metaname)) ;
01656             if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) {
01657                         TCHAR buf[200];
01658                     _stprintf_s(buf, _T("Could not open current version of paradigm %s"), 
01659                                 static_cast<const TCHAR*>(metaname));
01660 
01661                         AfxMessageBox(buf);
01662                         DiagnoseParadigm(metaname);
01663                 }
01664                 if(hr == E_MGA_COMPONENT_ERROR) {
01665                         _bstr_t errorInfo;
01666                         GetErrorInfo(errorInfo.GetAddress());
01667                         _bstr_t err(_T("ERROR: automatic addon components could not start up:\n"));
01668                         err += errorInfo;
01669                         err += "\nDo you want to create the project without addons?";
01670                         if (AfxMessageBox(err, MB_YESNO) == IDYES) {
01671                                 mgaProject->EnableAutoAddOns(VARIANT_FALSE);
01672                                 hr = mgaProject->Create(PutInBstr(conn), PutInBstr(metaname)) ;
01673                         }
01674                 }
01675                 if( hr == E_UNKNOWN_STORAGE && conn.Left(5) == _T("MGX=\"")) {
01676                         CloseProject();
01677                         return; // no more exception handler explanatory messages
01678                 }
01679             COMTHROW(hr);
01680 
01681                 AfterOpenOrCreateProject(conn);
01682                 // TODO: set RootFolder name to filename?
01683                 hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED);
01684                 ASSERT(SUCCEEDED(hr));
01685         }
01686         MSGCATCH(_T("Could not create project"), CloseProject())
01687 }
01688 
01689 
01690 void CGMEApp::SaveProject(const CString &conn) {
01691         if( mgaProject != NULL ) {
01692                 HRESULT hr = mgaProject->Save(CComBSTR(conn), VARIANT_FALSE);
01693                 if(hr != S_OK) {
01694                         CComBSTR error;
01695                         if (GetErrorInfo(&error)) {
01696                                 CString errmsg = _T("Could not save project: ");
01697                                 errmsg += error;
01698                                 if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) {
01699                                         // FIXME: KMS: not too sure why this is ACCESS_DENIED from MoveFile instead of SHARING_VIOLATION
01700                                         errmsg += _T("\nCheck that no other GME has this file open");
01701                                 }
01702                                 AfxMessageBox(errmsg);
01703                         } else {
01704                                 AfxMessageBox(_T("ERROR: Could not save project\nCheck access permissions"));
01705                         }
01706                 }
01707         }
01708 
01709         if ((!conn.IsEmpty()) && (currentConnection != conn)) {
01710                 ChangedProjectConnStrings();
01711                 currentConnection = conn;
01712                 m_RecentProjectList.AddAndWriteList(conn);
01713         }
01714 }       
01715 
01716 
01717 
01718 // ********************************************************************************************
01719 
01720 
01721 void CGMEApp::GetSettings()
01722 {
01723         bool oldUseAutoRouting = useAutoRouting;
01724         MSGTRY
01725         {
01726                 CComObjPtr<IMgaRegistrar> registrar;
01727                 COMTHROW( registrar.CoCreateInstance(L"Mga.MgaRegistrar") );
01728 
01729                 // Icons
01730                 CComBSTR bstr;
01731                 COMTHROW( registrar->get_IconPath(REGACCESS_BOTH,&bstr));
01732                 CopyTo(bstr,bitmapPath);
01733 
01734                 // Multiview
01735                 VARIANT_BOOL enabledmv;
01736                 COMTHROW( registrar->get_ShowMultipleView(REGACCESS_USER, &enabledmv) );
01737                 multipleView = (enabledmv != VARIANT_FALSE);
01738 
01739                 // Autosave
01740                 VARIANT_BOOL autosaveenable;
01741                 COMTHROW( registrar->get_AutosaveEnabled(REGACCESS_USER, &autosaveenable) );
01742                 autosaveEnabled = (autosaveenable == VARIANT_FALSE) ? FALSE : TRUE;
01743 
01744                 long autosavefreq;
01745                 COMTHROW( registrar->get_AutosaveFreq(REGACCESS_USER, &autosavefreq) );
01746                 autosaveFreq = (int)autosavefreq;
01747 
01748                 VARIANT_BOOL autosaveusedir;
01749                 COMTHROW( registrar->get_AutosaveUseDir(REGACCESS_USER, &autosaveusedir) );
01750                 autosaveUseDir = (autosaveusedir == VARIANT_FALSE) ? 0 : 1;
01751 
01752                 COMTHROW( registrar->get_AutosaveDir(REGACCESS_USER, PutOut(autosaveDir)) );
01753 
01754                 //Event Logging
01755                 VARIANT_BOOL enablelogging;
01756                 COMTHROW( registrar->get_EventLoggingEnabled(REGACCESS_USER, &enablelogging) );
01757                 if(enablelogging != VARIANT_FALSE)
01758                 {
01759                         CGMEEventLogger::initialize();
01760                         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::GetSettings() Event Logging Enabled\r\n"));
01761                 }
01762                 else
01763                 {
01764                         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::GetSettings() Event Logging Disabled\r\n"));
01765                         CGMEEventLogger::StopLogging();
01766                 }
01767 
01768                 // Autorouter
01769                 VARIANT_BOOL useautorouting = VARIANT_TRUE;
01770                 COMTHROW( registrar->get_UseAutoRouting(REGACCESS_USER, &useautorouting) );
01771                 useAutoRouting = (useautorouting != VARIANT_FALSE);
01772 
01773                 VARIANT_BOOL labelavoidance;
01774                 COMTHROW( registrar->get_LabelAvoidance(REGACCESS_USER, &labelavoidance) );
01775                 labelAvoidance = (labelavoidance != VARIANT_FALSE);
01776 
01777                 // Default Zoom Level
01778                 CComBSTR bstr_zl;
01779                 COMTHROW( registrar->GetDefZoomLevel( REGACCESS_USER, &bstr_zl));
01780                 if( bstr_zl)
01781                         CopyTo( bstr_zl, defZoomLev);
01782 
01783                 // SendMouseOver notification
01784                 VARIANT_BOOL send_mouse_over;
01785                 COMTHROW( registrar->GetMouseOverNotify(REGACCESS_USER, &send_mouse_over));
01786                 mouseOverNotify = ( send_mouse_over != VARIANT_FALSE);
01787 
01788                 // Real number format string
01789                 CComBSTR bstr_fmt;
01790                 COMTHROW( registrar->GetRealNmbFmtStr( REGACCESS_USER, &bstr_fmt));
01791                 if( bstr_fmt)
01792                         CopyTo( bstr_fmt, realFmtStr);
01793 
01794                 // History Maintained?
01795                 VARIANT_BOOL history_maintained;
01796                 COMTHROW( registrar->GetNavigation( REGACCESS_USER, &history_maintained));
01797                 maintainHistory = ( history_maintained != VARIANT_FALSE);
01798         }
01799         MSGCATCH(_T("Error while trying to get program settings"),;);
01800         if(CGMEDoc::theInstance) {
01801                 // Global AutoRouting policy changed, convert opened views if necessary
01802                 if (!useAutoRouting && oldUseAutoRouting) {
01803                         CComPtr<IUnknown> nullPtr;
01804                         CGMEDoc::theInstance->ConvertPathToCustom(nullPtr);
01805                 }
01806                 if (autosaveEnabled) {
01807                         CMainFrame::theInstance->StartAutosaveTimer(autosaveFreq);
01808                 }
01809                 else {
01810                         CMainFrame::theInstance->StopAutosaveTimer();
01811                 }
01812                 CGMEDoc::theInstance->ResetAllViews();
01813         }
01814 }
01815 
01816 LONG GetRegKey(HKEY key, LPCTSTR subkey, LPTSTR retdata)
01817 {
01818         HKEY hKey;
01819     LONG lResult = RegOpenKeyEx(key, subkey, 0, KEY_QUERY_VALUE, &hKey); 
01820   
01821     if( lResult == ERROR_SUCCESS)
01822         {
01823          long lDataSize = MAX_PATH;
01824                 TCHAR data[MAX_PATH];
01825   
01826                 RegQueryValue( hKey, NULL, data, &lDataSize);
01827                 lstrcpy( retdata,data);
01828                 RegCloseKey( hKey);
01829     }
01830   
01831     return lResult;
01832 }
01833   
01834 HINSTANCE GotoURL(LPCTSTR url, int showcmd)
01835 {
01836         TCHAR key[MAX_PATH + MAX_PATH];
01837   
01838     // First try ShellExecute()
01839     HINSTANCE hResult = ShellExecute( NULL, _T("open"), url, NULL,NULL, showcmd);
01840     //HINSTANCE hResult;
01841     // If it failed, get the .htm regkey and lookup the program
01842     if((UINT)hResult <= HINSTANCE_ERROR)
01843         {
01844                 if( GetRegKey( HKEY_CLASSES_ROOT, _T(".htm"), key) == ERROR_SUCCESS)
01845                 {
01846              lstrcat( key, _T("\\shell\\open\\command")); 
01847   
01848              if( GetRegKey( HKEY_CLASSES_ROOT,key,key) == ERROR_SUCCESS)
01849                          {
01850                                 TCHAR *pos;
01851                  pos = _tcsstr( key, _T("\"%1\"")); 
01852   
01853                  if( pos == NULL)
01854                                  {
01855                                         // No quotes found
01856                     pos = _tcsstr( key, _T("%1")); // Check for % 1, without quotes
01857                     if( pos == NULL)    // No  parameter at all...
01858                          pos = key+lstrlen( key)-1;
01859                      else
01860                          *pos = '\0';    //  Remove the parameter
01861                  }
01862                  else
01863                      *pos = '\0';
01864                                         // Remove the parameter
01865   
01866                  lstrcat(pos, _T(" "));
01867                  lstrcat(pos, url);
01868   
01869                                  // FIXME: should use CreateProcess
01870                  hResult = (HINSTANCE)WinExec( CStringA(key),showcmd);
01871              }
01872          }
01873         }
01874   
01875      return hResult;
01876 }
01877 
01879 // CGMEApp message handlers
01880 
01881 // *******************************************************************************
01882 // *******************************************************************************
01883 //                                                              FILE
01884 // *******************************************************************************
01885 // *******************************************************************************
01886 
01887 
01888 void CGMEApp::OnFileOpen() 
01889 {
01890         CMgaOpenDlg dlg(CMgaOpenDlg::OpenDialog);
01891         CString conn = dlg.AskConnectionString(true, true);
01892 
01893         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileOpen ")+conn+_T("\r\n"));
01894 
01895         if( conn.IsEmpty() )
01896                 return;
01897 
01898         CWaitCursor wait;
01899 
01900         if( mgaProject != NULL )
01901                 CloseProject();
01902 
01903         if (conn.Left(4) == _T("MGX=")) {
01904                 CString fullPath = conn.Right(conn.GetLength() - 4);
01905                 TCHAR buffer[MAX_PATH];
01906                 TCHAR* filepart = NULL;
01907                 GetFullPathName(fullPath, MAX_PATH, buffer, &filepart);
01908                 if (filepart == NULL) {
01909                         DisplayError(_T("Error opening MGX file"), E_FILEOPEN);
01910                         return;
01911                 }
01912                 // FIXME: KMS: yes, the quotes are necessary...
01913                 conn = _T("MGX=\"");
01914                 // FIXME: KMS: yes, a trailing slash makes it not work
01915                 conn += fullPath.Left(fullPath.GetLength() - _tcslen(filepart) - 1);
01916                 conn += _T("\"");
01917         }
01918         OpenProject(conn);
01919 }
01920 
01921 
01922 #define PROJECT_STATUS_CHANGED 4
01923 
01924 void CGMEApp::OnAppExit()
01925 {
01926         if (SaveAllModified())
01927         {
01928                 CWinAppEx::OnAppExit();
01929                 return;
01930         }
01931 }
01932 
01933 BOOL CGMEApp::SaveAllModified() 
01934 {
01935         // Focus must be killed to flush ObjectInspector and Browser
01936         ::SetFocus(NULL);
01937         if (mgaProject != NULL && (proj_type_is_mga || proj_type_is_xmlbackend)) {
01938                 int ret = IDNO;
01939                 long l;
01940                 COMTHROW(mgaProject->get_ProjectStatus(&l));
01941                 if (l & PROJECT_STATUS_CHANGED)
01942                 {
01943                         CString filename;
01944                         CString connstr = static_cast<const wchar_t*>(mgaProject->ProjectConnStr);
01945                         if (connstr.Mid(0, 4) == "MGA=")
01946                         {
01947                                 CString dirname;
01948                                 GetFullPathName(connstr.Mid(4), filename, dirname);
01949                                 filename = L" (" + filename + ")";
01950                         }
01951                         CString message = _T("Do you want to save changes to '") + projectName + L"'" + filename + _T("?");
01952                         ret = AfxMessageBox(message,  MB_YESNOCANCEL);
01953                 }
01954                 if (ret == IDCANCEL) {
01955                         return FALSE;
01956                 } else if (ret == IDNO) {
01957                         abort_on_close = true;
01958                         OnFileAbortProject();
01959                 } else {
01960                         ((CMainFrame*)m_pMainWnd)->clearMgaProj();
01961                         return SafeCloseProject();
01962                 }
01963         }
01964         return TRUE;
01965 }
01966 
01967 int CGMEApp::ExitInstance() 
01968 {
01969         CloseProject(false);
01970 
01971 #ifdef _DEBUG
01972         // Do this under Debug to silence memory leaks
01973         // Don't do it under Release, since we may yet crash, and it's wasteful since we're exiting anyway
01974         crUninstall();
01975 #endif
01976 
01977         return CWinAppEx::ExitInstance();
01978 }
01979 
01980 void CGMEApp::OnFileNew() 
01981 {
01982         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileNew\r\n"));
01983 
01984         MSGTRY  {
01985                 CString metaname;
01986                 CString dataconn;
01987                 CMgaOpenDlg dlg(CMgaOpenDlg::NewDialog);
01988 
01989                 CComObjPtr<IMgaLauncher> launcher;
01990                 COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher", 0, CLSCTX_INPROC_SERVER) );
01991 
01992         meta_label:
01993                 HRESULT hr = launcher->MetaDlg(METADLG_NEWFILE);
01994                 if( hr == S_FALSE )
01995                         return;
01996                 COMTHROW( hr );
01997 
01998                 metaname.Empty();
01999                 COMTHROW( launcher->get_ParadigmName(PutOut(metaname)) );
02000 
02001                 dataconn = dlg.AskConnectionString(false, false);
02002 
02003                 if( dlg.pressed_back )
02004                         goto meta_label;
02005 
02006                 if( dataconn.IsEmpty() )
02007                         return;
02008 
02009                 CWaitCursor wait;
02010 
02011                 if( mgaProject != NULL )
02012                         CloseProject();
02013 
02014                 CreateProject(metaname, dataconn);
02015 
02016                 if (mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend)) {
02017                         OnFileSave();
02018                 }
02019         }
02020         MSGCATCH(_T("Error creating new project"),;)
02021 
02022 }
02023 
02024 BOOL CGMEApp::OnOpenRecentProject(UINT nID)
02025 {
02026         ASSERT_VALID(this);
02027 
02028         ASSERT(nID >= ID_FILE_MRU_PRJ1);
02029         ASSERT(nID < ID_FILE_MRU_PRJ1 + (UINT)m_RecentProjectList.GetSize());
02030 
02031         int nIndex = nID - ID_FILE_MRU_PRJ1;
02032         CString conn = m_RecentProjectList[nIndex];
02033 
02034         ASSERT(conn.GetLength() != 0);
02035 
02036         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnOpenRecentProject ")+conn+_T("\r\n"));
02037 
02038         CWaitCursor wait;
02039 
02040         if( mgaProject != NULL )
02041                 CloseProject();
02042 
02043         OpenProject(conn);
02044 
02045         return TRUE;
02046 }
02047 
02048 
02049 bool CGMEApp::SafeCloseProject() {
02050 // In case of an MGA file, try to save it first to find out 
02051         abort_on_close = false;
02052         if(mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend)) {
02053                 HRESULT hr = mgaProject->Save(NULL, VARIANT_FALSE);
02054                 if(hr != S_OK) {
02055                         CComBSTR error;
02056                         if (GetErrorInfo(&error)) {
02057                 CString errmsg = _T("Could not save project: ");
02058 
02059                 errmsg += error;
02060                 if (hr == HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED)) {
02061                                     // FIXME: KMS: not too sure why this is ACCESS_DENIED from MoveFile instead of SHARING_VIOLATION
02062                     errmsg += _T("\nCheck that no other GME has this file open");
02063                 }
02064                 AfxMessageBox(errmsg);
02065                 return false;
02066             }
02067             else {
02068                 AfxMessageBox(_T("ERROR: Could not save project\nCheck access permissions"));
02069                 return false;
02070             }
02071         }
02072                 abort_on_close = true;
02073         }
02074 
02075         BeginWaitCursor();
02076         if(CGMEDoc::theInstance)
02077                 CGMEDoc::theInstance->OnCloseDocument();
02078         EndWaitCursor();
02079         return true;
02080 }
02081 
02082 void CGMEApp::OnFileCloseproject() 
02083 {
02084         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileCloseproject\r\n"));
02085         SaveAllModified();
02086 #ifdef _DEBUG
02087         //CoFreeUnusedLibraries();
02088         HMODULE mga = GetModuleHandle(L"Mga.dll");
02089         if (mga)
02090         {
02091                 typedef HRESULT (__stdcall *DllCanUnloadNow)(void);
02092                 DllCanUnloadNow proc = (DllCanUnloadNow)GetProcAddress(mga, "DllCanUnloadNow");
02093                 if (proc && (*proc)() != S_OK)
02094                 {
02095                         DebugBreak();
02096                         // If Mga.dll is compiled with /D_ATL_DEBUG_INTERFACES, this will dump the leaks via OutputDebugString (then crash later)
02097                         FreeLibrary(mga);
02098                 }
02099         }
02100 #endif
02101 }
02102 
02103 
02104 void CGMEApp::OnFileSaveAs() {
02105         CMgaOpenDlg dlg(CMgaOpenDlg::SaveAsDialog);
02106         CString conn = dlg.AskMGAConnectionString();
02107 
02108         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSaveAs ")+conn+_T("\r\n"));
02109 
02110         if( conn.IsEmpty() )
02111                 return;
02112         BeginWaitCursor();
02113         SaveProject(conn);
02114         EndWaitCursor();
02115 }
02116 
02117 void CGMEApp::OnFileSave() 
02118 {
02119         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSave\r\n"));
02120         // GME-307 Focus must be killed to flush ObjectInspector and Browser
02121         ::SetFocus(NULL);
02122 
02123         BeginWaitCursor();
02124         SaveProject(_T(""));
02125         EndWaitCursor();
02126 }
02127 
02128 void CGMEApp::OnFileAbortProject() 
02129 {
02130         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileAbortProject\r\n"));
02131         ((CMainFrame*)m_pMainWnd)->clearMgaProj();
02132 
02133         long l;
02134         COMTHROW(mgaProject->get_ProjectStatus(&l));
02135         if(!abort_on_close && IsUndoPossible() && (l & PROJECT_STATUS_CHANGED) &&
02136                 AfxMessageBox(_T("Discard edits to project ") + projectName + _T("?"), 
02137                 MB_OKCANCEL) == IDCANCEL) {
02138                 return;
02139         }
02140         abort_on_close = true;
02141 
02142         BeginWaitCursor();
02143         if(CGMEDoc::theInstance)
02144                 CGMEDoc::theInstance->OnCloseDocument(true);
02145         EndWaitCursor();
02146 }
02147 
02148 
02149 void CGMEApp::OnFileExportxml() 
02150 {
02151         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileExportxml "));
02152         MSGTRY
02153         {
02154                 CComPtr<IMgaDumper> dumper;
02155                 COMTHROW( dumper.CoCreateInstance(L"Mga.MgaDumper") );
02156                 ASSERT( dumper != NULL );
02157 
02158                 CString initialFile;
02159                 CString initialDir;
02160                 if (theApp.isMgaProj()) {
02161                         getMgaPaths(initialFile, initialDir);
02162                         if (initialFile.Right(3) == _T("mga")) {
02163                                 initialFile.Truncate(initialFile.GetLength() - 3);
02164                                 initialFile += _T("xme");
02165                         }
02166                 }
02167 
02168                 CFileDialog dlg(FALSE, _T("xme"), initialFile,
02169                         OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_NOCHANGEDIR,
02170                         _T("Exported Files (*.xme)|*.xme|All Files (*.*)|*.*||"));
02171                 if (initialDir)
02172                 {
02173                         dlg.GetOFN().lpstrInitialDir = initialDir;
02174                 }
02175                 if( dlg.DoModal() != IDOK )
02176                 {
02177                         CGMEEventLogger::LogGMEEvent(_T("Canceled\r\n"));
02178                         return;
02179                 }
02180                 CGMEEventLogger::LogGMEEvent(dlg.GetPathName()+_T("\r\n"));
02181 
02182                 CWaitCursor wait;
02183                 IMgaDumper2Ptr dumper2 = (IMgaDumper*)dumper;
02184                 if (dumper2 && m_pMainWnd)
02185                         dumper2->__DumpProject2(theApp.mgaProject, _bstr_t(dlg.GetPathName()), (ULONGLONG)(m_pMainWnd->GetSafeHwnd()));
02186                 else
02187                         dumper->__DumpProject(theApp.mgaProject, _bstr_t(dlg.GetPathName()));
02188 
02189                 if( CMainFrame::theInstance) CMainFrame::theInstance->m_console.Message( CString( _T("Project successfully exported into ")) + dlg.GetPathName() + _T("."), 1);
02190         }
02191         MSGCATCH(_T("Error while generating XML file"),;)
02192 }
02193 
02194 
02195 void CGMEApp::OnFileImportxml() 
02196 {
02197         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileImportxml "));
02198 
02199         CString new_file_name = _T("");
02200 
02201         MSGTRY
02202         {
02203                 CFileDialog dlg(TRUE, _T("xme"), (LPCTSTR) new_file_name,
02204                         OFN_EXPLORER | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT |
02205                         OFN_FILEMUSTEXIST,
02206                         _T("GME Exported Files (*.xme;*.xml)|*.xme; *.xml|All Files (*.*)|*.*||"));
02207                 if( dlg.DoModal() != IDOK )
02208                 {
02209                         CGMEEventLogger::LogGMEEvent(_T("Cancelled\r\n"));
02210                         return;
02211                 }
02212                 CGMEEventLogger::LogGMEEvent(dlg.GetPathName()+_T("\r\n"));
02213                 CString fullPath = dlg.GetPathName();
02214                 CString fname = dlg.GetFileName();
02215                 CString ftitle = dlg.GetFileTitle();
02216                 Importxml(fullPath, fname, ftitle);
02217         }
02218         MSGCATCH(_T("Error importing XML file"),;)
02219 }               
02220                 
02221 void CGMEApp::Importxml(CString fullPath, CString fname, CString ftitle)
02222 {
02223                 CComPtr<IMgaParser> parser;
02224                 COMTHROW( parser.CoCreateInstance(L"Mga.MgaParser") );
02225                 ASSERT( parser != NULL );
02226 
02227                 CString folderPath = fullPath.Left(fullPath.GetLength() - fname.GetLength());
02228 
02229                 if (fullPath.Right(3).CompareNoCase(_T("xml")) == 0 ) {
02230                         AfxMessageBox(
02231                                         _T("Newer versions of GME use the \".xme.\" filename extension\n")
02232                                         _T("for exported XML data files.\n")
02233                                         _T("Please, rename your existing files to avoid further problems!\n"), 
02234                                         MB_OK | MB_ICONINFORMATION);
02235                 }
02236 
02237                 bool newproject = !mgaProject;
02238                 if (newproject) {
02239                         CString dataconn;
02240                         COMTRY {
02241                                 CComBstrObj xmeparadigm, xmeparversion, xmebasename, xmeversion;
02242                                 CComVariant xmeparguid, parguid;
02243 
02244                                 COMTHROW( parser->GetXMLInfo(PutInBstr(fullPath), PutOut(xmeparadigm), PutOut(xmeparversion), &xmeparguid, PutOut(xmebasename), PutOut(xmeversion)) );
02245                                 parguid = xmeparguid;
02246 
02247                                 CMgaOpenDlg opdlg(CMgaOpenDlg::ImportDialog);
02248                                 if (ftitle.IsEmpty())
02249                                         opdlg.SetFileNameHint(PutInCString(xmebasename));
02250                                 else
02251                                         opdlg.SetFileNameHint(ftitle);
02252                                 opdlg.SetFolderPathHint(folderPath);
02253                                 dataconn = opdlg.AskConnectionString(false, false);
02254                                 if (dataconn.IsEmpty()) {
02255                                    CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileImportxml exited because empty connection string has been given"));
02256                                    return;
02257                                 }
02258 
02259                                 {
02260                                         CComPtr<IMgaRegistrar> reg;
02261                                         COMTHROW( reg.CoCreateInstance(L"Mga.MgaRegistrar") );
02262                                         CComBstrObj conn;
02263                                         HRESULT h1 = reg->QueryParadigm(xmeparadigm, PutOut(conn), &xmeparguid, REGACCESS_PRIORITY);
02264                                         CComVariant regparguid;
02265                                         conn.Empty();
02266                                         HRESULT h2 = reg->QueryParadigm(xmeparadigm, PutOut(conn), &regparguid, REGACCESS_PRIORITY);
02267                                         CComBstrObj regCurrentVersion;
02268                                         if (SUCCEEDED(h2)) {
02269                                                 reg->VersionFromGUID(xmeparadigm, regparguid, &regCurrentVersion.p, REGACCESS_PRIORITY);
02270                                         }
02271 
02272                                         CComVariant regGuidFromVersion;
02273                                         HRESULT h3GuidFromVersion = E_FAIL;
02274                                         if (xmeparversion.Length() != 0) {
02275                                                 h3GuidFromVersion = reg->GUIDFromVersion(xmeparadigm, xmeparversion, &regGuidFromVersion, REGACCESS_PRIORITY);
02276                                                 if (SUCCEEDED(h3GuidFromVersion))
02277                                                 {
02278                                                         xmeparguid = regGuidFromVersion;
02279                                                 } else
02280                                                 {
02281                                                         h1 = E_MGA_PARADIGM_NOTREG;
02282                                                 }
02283                                         }
02284 
02285                                         TCHAR buf[300];
02286                                         if(h2 != S_OK) {
02287                                                 ASSERT(h1 != S_OK);
02288                                                 CString msg = _T("Could not find paradigm paradigm '") + CString(xmeparadigm) + "'";
02289                                                 if (CString(xmeparadigm) == _T("MetaGME2000"))
02290                                                         msg += _T("\n (In GME3 the MetaGME2000 paradigm was renamed to MetaGME)");
02291                                                 msg += _T("\nDo you want to import with an other registered paradigm ?");
02292                                                 if (AfxMessageBox(msg ,MB_OKCANCEL) == IDOK) {  
02293                                                         CComObjPtr<IMgaLauncher> launcher;
02294                                                         COMTHROW( launcher.CoCreateInstance(CComBSTR(L"Mga.MgaLauncher")) );
02295                                                         if (SUCCEEDED(launcher->MetaDlg(METADLG_NONE))) {
02296                                                                 // parguid = true;
02297                                                                 parguid.Clear();
02298                                                                 xmeparadigm.Empty();
02299                                                                 COMTHROW( launcher->get_ParadigmName(PutOut(xmeparadigm)) );
02300                                                         }
02301                                                         else {
02302                                                                 return;   // safe before create
02303                                                         }
02304                                                 }
02305                                                 else {
02306                                                         return;   // safe before create
02307                                                 }
02308                                         }
02309                                         else {
02310                                                 CComBstrObj bstrxmeparguid, bstrregparguid;
02311                                                 GUID gg;
02312 
02313                                                 CopyTo(xmeparguid,gg);
02314                                                 CopyTo(gg, bstrxmeparguid);
02315 
02316                                                 CopyTo(regparguid,gg);
02317                                                 CopyTo(gg, bstrregparguid);
02318 
02319                                                 if(h1 != S_OK) {
02320                                                         _stprintf_s(buf, _T("Could not locate paradigm %s, version '%s'.\n\n")
02321                                                                                  _T("Do you want to upgrade to the current version ('%s') instead?"),
02322                                                                                  static_cast<const TCHAR*>(xmeparadigm),
02323                                                                                  static_cast<const TCHAR*>(xmeparversion.Length() != 0 ? xmeparversion : bstrxmeparguid),
02324                                                                                  static_cast<const TCHAR*>(regCurrentVersion.Length() != 0 ? regCurrentVersion : bstrregparguid));
02325                                                         if(AfxMessageBox(buf, MB_OKCANCEL | MB_ICONQUESTION) == IDOK) {
02326                                                                 parguid = regparguid;
02327                                                         }
02328                                                         else {
02329                                                                 // AfxMessageBox(_T("Import canceled"));
02330                                                                 return; // safe before create
02331                                                         }       
02332 
02333                                                 }
02334                                                 else if(bstrxmeparguid.Compare(bstrregparguid)) {
02335                                                         _stprintf_s(buf, _T("This model was exported using paradigm %s, version '%s'.\n\n")
02336                                                                                  _T("Do you want to upgrade to the current version ('%s')?"),
02337                                                                                  static_cast<const TCHAR*>(xmeparadigm),
02338                                                                                  static_cast<const TCHAR*>(xmeparversion.Length() != 0 ? xmeparversion : bstrxmeparguid),
02339                                                                                  static_cast<const TCHAR*>(regCurrentVersion.Length() != 0 ? regCurrentVersion : bstrregparguid));
02340                                                         int answer = AfxMessageBox(buf,MB_YESNOCANCEL | MB_ICONQUESTION);
02341                                                         if(answer == IDYES) {
02342                                                                 parguid = regparguid;
02343                                                         }
02344                                                         else if(answer == IDCANCEL) {
02345                                                                 // AfxMessageBox(_T("Import canceled"));
02346                                                                 return;  // safe before create
02347                                                         }
02348                                                 }
02349                                         }
02350                                 }
02351                                 COMTHROW( mgaProject.CoCreateInstance(L"Mga.MgaProject") );
02352                                 COMTHROW( mgaProject->EnableAutoAddOns(VARIANT_TRUE));
02353                                 HRESULT hr = mgaProject->CreateEx(PutInBstr(dataconn), PutInBstr(xmeparadigm), parguid);
02354                                 if(hr == E_MGA_PARADIGM_NOTREG || hr == E_MGA_PARADIGM_INVALID) {
02355                                         TCHAR buf[300];
02356                                         CComBstrObj parguid1;
02357                                         GUID gg;
02358                                         CopyTo(parguid,gg);
02359                                         CopyTo(gg, parguid1);
02360                                         _stprintf_s(buf, _T("Could not open paradigm %s\nVersion ID: %s"), 
02361                                                 static_cast<const TCHAR*>(xmeparadigm), static_cast<const TCHAR*>(parguid1));
02362 
02363                                         AfxMessageBox(buf);
02364                                 }
02365                                 if(hr == E_MGA_COMPONENT_ERROR) {
02366                                         _bstr_t errorInfo;
02367                                         GetErrorInfo(errorInfo.GetAddress());
02368                                         _bstr_t err(_T("ERROR: automatic addon components could not start up:\n"));
02369                                         err += errorInfo;
02370                                         err += "\nDo you want to create the project without addons?";
02371                                         if (AfxMessageBox(err, MB_YESNO) == IDYES) {
02372                                                 mgaProject->EnableAutoAddOns(VARIANT_FALSE);
02373                                                 hr = mgaProject->CreateEx(PutInBstr(dataconn), PutInBstr(xmeparadigm), parguid);
02374                                         }
02375                                 }
02376                                 COMTHROW(hr);
02377                                 AfterOpenOrCreateProject(dataconn); 
02378                         } catch(hresult_exception &e) {
02379                                 CloseProject();
02380                                 DisplayError(_T("Could not create the project"), e.hr); 
02381                                 throw;
02382                         }
02383                 }
02384 
02385                 //UpdateProjectName(); // moved below
02386 
02387                 CWaitCursor wait;
02388                 if(mgaConstMgr) COMTHROW(mgaConstMgr->Enable(false));
02389 
02390                 CString file_name = fullPath;
02391                 if( CMainFrame::theInstance) CMainFrame::theInstance->m_console.Message( CString( _T("Importing ")) + file_name + _T("..."), 1);
02392                 IMgaParser2Ptr parser2 = (IMgaParser*)parser;
02393                 if (parser2 && m_pMainWnd)
02394                         parser2->__ParseProject2(theApp.mgaProject, _bstr_t(fullPath), (ULONGLONG)(m_pMainWnd->GetSafeHwnd()));
02395                 else
02396                         COMTHROW(parser->ParseProject(theApp.mgaProject, PutInBstr(fullPath)));
02397                 
02398                 // mgaproject has been filled with data, let's update title:
02399                 UpdateProjectName();
02400 
02401                 if(newproject && (proj_type_is_mga||proj_type_is_xmlbackend)) {
02402                         OnFileSave();
02403                 }
02404 
02405                 if (CMainFrame::theInstance)
02406                         CMainFrame::theInstance->m_console.Message(fullPath + _T(" was successfully imported."), 1);
02407                 else
02408                         AfxMessageBox(fullPath + _T(" was successfully imported."));
02409 
02410         if (mgaConstMgr)
02411                 COMTHROW(mgaConstMgr->Enable(true));
02412         HRESULT hr = mgaProject->Notify(GLOBALEVENT_OPEN_PROJECT_FINISHED);
02413         ASSERT(SUCCEEDED(hr));
02414 }
02415 
02416 
02417 
02418 void CGMEApp::OnFileXMLUpdate() 
02419 {
02420         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileXMLUpdate\r\n"));
02421     ASSERT(mgaProject);
02422     ASSERT(mgaMetaProject);
02423 
02424         TCHAR xmlname[MAX_PATH];
02425         GetTempFileName(_T("."), _T("XEX"),0, xmlname);
02426         
02427         if(currentConnection.Find(_T("MGA=")) != 0) {
02428                 AfxMessageBox(_T("Function is available only for .mga models"));
02429         }
02430 
02431         CString fname = currentConnection.Mid(4);
02432         CString backupname;
02433 
02434         MSGTRY
02435         {
02436                 CWaitCursor wait;
02437                 CComBstrObj parname;
02438                 COMTHROW( mgaMetaProject->get_Name(PutOut(parname)) );
02439                 CComBstrObj metaconn;
02440 
02441                 CComBstrObj currentguid;
02442                 {
02443                         CComVariant parguid;
02444                         COMTHROW( mgaMetaProject->get_GUID(&parguid) );
02445 
02446                         CComPtr<IMgaRegistrar> reg;
02447                         COMTHROW( reg.CoCreateInstance(L"Mga.MgaRegistrar") );
02448                         CComVariant pg2;
02449 
02450                         COMTHROW(reg->QueryParadigm(parname, PutOut(metaconn), &pg2, REGACCESS_PRIORITY));
02451 
02452                         CComBstrObj parguid1;
02453                         GUID gg;
02454                         CopyTo(parguid,gg);
02455                         CopyTo(gg, parguid1);
02456 
02457                         CopyTo(pg2,gg);
02458                         CopyTo(gg, currentguid);
02459 
02460                         if(!parguid1.Compare(currentguid)) {
02461                                 TCHAR buf[200];
02462                                 _stprintf_s(buf, _T("There is no need to upgrade this model\nIts Meta Version ID is the current ID\nCurrent ID: %s"), 
02463                                         static_cast<const TCHAR*>(currentguid));
02464                                 AfxMessageBox(buf);
02465                                 return;
02466                         }
02467                 }
02468 
02469                 CComPtr<IMgaDumper> dumper;
02470                 COMTHROW( dumper.CoCreateInstance(L"Mga.MgaDumper") );
02471                 ASSERT( dumper != NULL );
02472 
02473                 COMTHROW( dumper->DumpProject(theApp.mgaProject, PutInBstr(CString(xmlname))) );
02474 
02475 
02476                 SafeCloseProject();
02477                 ASSERT(!mgaProject);
02478 
02479                 backupname = fname;
02480                 int p = backupname.ReverseFind('.');
02481                 if(!p || backupname.Find('\\',p) != -1) p = backupname.GetLength();
02482                 backupname.Insert(p,_T("-backup"));
02483                 DeleteFile(backupname);
02484                 if(!MoveFile(fname, backupname)) {
02485                         backupname = fname;
02486                         CString buf;
02487                         buf.Format(L"Could not save original file '%s' to '%s'",
02488                                 static_cast<const TCHAR*>(fname), static_cast<const TCHAR*>(backupname)); 
02489                         AfxMessageBox(buf);
02490                         COMTHROW(E_NOTFOUND);
02491                 }
02492 
02493 
02494 
02495                 CreateProject(PutInCString(parname), currentConnection);
02496 
02497                 if(!mgaProject || !mgaMetaProject) {
02498                         AfxMessageBox(_T("Error creating project"));
02499                         return;
02500                 }
02501 
02502                 UpdateComponentLists();
02503                 ChangedProjectConnStrings();
02504 
02505                 CComPtr<IMgaParser> parser;
02506                 COMTHROW( parser.CoCreateInstance(L"Mga.MgaParser") );
02507                 ASSERT( parser != NULL );
02508             if(mgaConstMgr) COMTHROW(mgaConstMgr->Enable(false));
02509                 IMgaParser2Ptr parser2 = (IMgaParser*)parser;
02510                 if (parser2 && m_pMainWnd)
02511                         COMTHROW(parser2->ParseProject2(mgaProject,PutInBstr(CString(xmlname)), (ULONGLONG)(m_pMainWnd->GetSafeHwnd())));
02512                 else
02513                         COMTHROW(parser->ParseProject(mgaProject,PutInBstr(CString(xmlname))) );
02514                 {
02515                         CString buf = CString(_T("The model has been updated\nCurrent ID: "))
02516                                 + currentguid + L"\nThe original model has been saved to " + backupname;
02517                         AfxMessageBox(buf);
02518                 }
02519         }
02520         catch(hresult_exception &e)     {
02521                 if(backupname.IsEmpty()) {
02522                         CString buf;
02523                         buf.Format(L"The upgrade failed: 0x%x\nThe model has not been closed", e.hr);
02524                         AfxMessageBox(buf);
02525                 }
02526                 else {
02527                         if(backupname.Compare(fname)) {
02528                                 if(MoveFile(backupname, fname)) backupname = fname;
02529                         }
02530                         CString buf;
02531                         buf.Format(L"The upgrade failed: 0x%x\nThe original model is in file %s", e.hr, 
02532                                 static_cast<const TCHAR*>(backupname));
02533                         AfxMessageBox(buf);
02534                 }
02535         }
02536 
02537     if (mgaConstMgr) COMTHROW(mgaConstMgr->Enable(true));
02538 }
02539 
02540 
02541 
02542 void CGMEApp::OnFileRegcomponents() 
02543 {
02544         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileRegcomponents "));
02545         MSGTRY
02546         {
02547                 CComObjPtr<IMgaLauncher> launcher;
02548                 COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") );
02549                 COMTHROW( launcher->put_ParadigmName(PutInBstr(guiMetaProject->name)));
02550                 COMTHROW( launcher->put_ComponentType(COMPONENTTYPE_ALL) );
02551 
02552                 ATLASSERT(mgaProject);
02553                 CComBSTR runningcomps;
02554                 {
02555                         CComPtr<IMgaComponents> comps;
02556                         COMTHROW(mgaProject->get_AddOnComponents(&comps));
02557                         MGACOLL_ITERATE(IMgaComponent, comps) {
02558                                 CComQIPtr<IMgaComponentEx> compx = MGACOLL_ITER;
02559                                 CComBSTR p;
02560                                 if(compx) COMTHROW(compx->get_ComponentProgID(&p));
02561                                 else COMTHROW(MGACOLL_ITER->get_ComponentName(&p));
02562                                 if(runningcomps) runningcomps += _T(" ");
02563                                 runningcomps += p;
02564                         }
02565                         MGACOLL_ITERATE_END;
02566                 }
02567                 // FIXME: huge kludge here: enables CCompDlg to show which addons are running
02568                 COMTHROW(launcher->put_Parameter(CComVariant(runningcomps)));
02569 
02570                 CGMEEventLogger::LogGMEEvent(CString(runningcomps)+_T("\r\n"));
02571 
02572                 COMTHROW( launcher->ComponentDlg(COMPONENTDLG_INTERP));
02573                 UpdateComponentLists(true);
02574         }
02575         MSGCATCH(_T("Error while trying to register the interpreter"),;)
02576 }
02577 
02578 void CGMEApp::OnFileSettings() 
02579 {
02580         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileSettings\r\n"));
02581         MSGTRY
02582         {
02583                 CComObjPtr<IMgaLauncher> launcher;
02584                 COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") );
02585                 COMTHROW( launcher->GmeDlg());
02586         }
02587         MSGCATCH(_T("Error while trying to get GME settings"),;)
02588         GetSettings();
02589 }
02590 
02591 void CGMEApp::OnFileClearLocks() 
02592 {
02593         if( mgaProject != NULL || mgaMetaProject != NULL )
02594                 return;
02595 
02596         MSGTRY
02597         {
02598                 CMgaOpenDlg dlg(CMgaOpenDlg::ClearLocksDialog);
02599                 CString conn = dlg.AskConnectionString(false, true);
02600 
02601                 if( conn.IsEmpty() )
02602                         return;
02603 
02604                 CWaitCursor wait;
02605 
02606                 CComObjPtr<IMgaProject> project;
02607                 COMTHROW( project.CoCreateInstance(OLESTR("MGA.MgaProject")) );
02608                 ASSERT( project != NULL );
02609                 COMTHROW( project->CheckLocks(PutInBstr(conn), VARIANT_TRUE) );
02610 
02611                 AfxMessageBox(_T("Database locks are cleared"));
02612         }
02613         MSGCATCH(_T("Error while clearing locks in database"),;)
02614 }
02615 
02616 void CGMEApp::OnHelpContents() 
02617 {
02618         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnHelpContents\r\n"));
02619 
02620         MSGTRY {
02621                 CComObjPtr<IMgaLauncher> launcher;
02622                 COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher") );
02623                 COMTHROW( launcher->ShowHelp(NULL) );
02624         }
02625         MSGCATCH(_T("Error while showing help contents."),;)
02626 }
02627 
02628 void CGMEApp::OnFileCheckall() 
02629 {
02630         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileCheckall\r\n"));
02631         ASSERT(mgaConstMgr);
02632         if (!mgaConstMgr)
02633                 return;
02634         // message boxes displayed from constraint manager if in interactive mode
02635         mgaConstMgr->ObjectsInvokeEx(mgaProject, NULL, NULL, NULL);
02636 }
02637 
02638 void CGMEApp::OnFileDisplayConstraints() 
02639 {
02640         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileDisplayConstraints\r\n"));
02641         ASSERT(mgaConstMgr);
02642         if (!mgaConstMgr)
02643                 return;
02644         mgaConstMgr->ObjectsInvokeEx(mgaProject, NULL, NULL, CONSTMGR_SHOW_CONSTRAINTS);
02645         
02646 }
02647 
02648 
02649 
02650 void CGMEApp::OnFileRegparadigms() 
02651 {
02652         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnFileRegparadigms\r\n"));
02653         MSGTRY
02654         {
02655                 CComPtr<IMgaLauncher> launcher;
02656                 COMTHROW( launcher.CoCreateInstance(L"Mga.MgaLauncher", 0, CLSCTX_INPROC_SERVER) );
02657 
02658                 while(1) {
02659                         HRESULT hr = launcher->MetaDlg(METADLG_PARREG);
02660                         if( hr == S_FALSE )     return;
02661 
02662                         COMTHROW( launcher->put_ComponentType(COMPONENTTYPE_ALL) );
02663 
02664                         bool workonrunningparadigm = false;
02665                         if(guiMetaProject) {
02666                                 CComBstrObj metaname;
02667                                 COMTHROW( launcher->get_ParadigmName(PutOut(metaname)) );
02668                                 if(metaname == PutInBstr(guiMetaProject->name)) workonrunningparadigm = true;
02669                         }
02670 
02671                         if(workonrunningparadigm) {
02672                                 ATLASSERT(mgaProject);
02673                                 CComBSTR runningcomps;
02674                                 CComPtr<IMgaComponents> comps;
02675                                 COMTHROW(mgaProject->get_AddOnComponents(&comps));
02676                                 MGACOLL_ITERATE(IMgaComponent, comps) {
02677                                         CComQIPtr<IMgaComponentEx> compx = MGACOLL_ITER;
02678                                         CComBSTR p;
02679                                         if(compx) COMTHROW(compx->get_ComponentProgID(&p));
02680                                         else COMTHROW(MGACOLL_ITER->get_ComponentName(&p));
02681                                         if(runningcomps) runningcomps += _T(" ");
02682                                         runningcomps += p;
02683                                 }
02684                                 MGACOLL_ITERATE_END;
02685                                 COMTHROW(launcher->put_Parameter(CComVariant(runningcomps)));
02686                         }
02687 
02688                         COMTHROW( launcher->ComponentDlg(COMPONENTDLG_INTERP));
02689 
02690                         if(workonrunningparadigm) UpdateComponentLists(true);
02691                 }
02692         } MSGCATCH(_T("Error registering paradigms"), ;);
02693 }
02694 
02695 
02696 // *******************************************************************************
02697 
02698 void CGMEApp::OnUpdateFileNew(CCmdUI* pCmdUI) 
02699 {
02700         pCmdUI->Enable(guiMetaProject == NULL);
02701 }
02702 
02703 void CGMEApp::OnUpdateFileOpen(CCmdUI* pCmdUI) 
02704 {
02705         pCmdUI->Enable(guiMetaProject == NULL);
02706 }
02707 
02708 void CGMEApp::OnUpdateFileCloseproject(CCmdUI* pCmdUI) 
02709 {
02710         pCmdUI->Enable(guiMetaProject != NULL);
02711 }
02712 
02713 void CGMEApp::OnUpdateFileSave(CCmdUI* pCmdUI) 
02714 {
02715         pCmdUI->Enable(mgaProject != NULL && (proj_type_is_mga||proj_type_is_xmlbackend));
02716 }
02717 
02718 void CGMEApp::OnUpdateFileSaveAs(CCmdUI* pCmdUI) 
02719 {
02720         pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga);
02721 }
02722 
02723 void CGMEApp::OnUpdateFileAbortProject(CCmdUI* pCmdUI) 
02724 {
02725         pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga);
02726 }
02727 
02728 void CGMEApp::OnUpdateFileExportxml(CCmdUI* pCmdUI) 
02729 {
02730         pCmdUI->Enable(guiMetaProject != NULL);
02731 }
02732 
02733 void CGMEApp::OnUpdateFileXMLUpdate(CCmdUI* pCmdUI) 
02734 {
02735         pCmdUI->Enable(mgaProject != NULL && proj_type_is_mga);
02736 }
02737 
02738 void CGMEApp::OnUpdateFileCheckall(CCmdUI* pCmdUI) 
02739 {
02740         pCmdUI->Enable(mgaConstMgr != NULL);
02741 }
02742 
02743 void CGMEApp::OnUpdateFileDisplayConstraints(CCmdUI* pCmdUI) 
02744 {
02745         pCmdUI->Enable(mgaConstMgr != NULL);    
02746         
02747 }
02748 
02749 void CGMEApp::OnUpdateFileRegcomponents(CCmdUI* pCmdUI) 
02750 {
02751         pCmdUI->Enable(guiMetaProject != NULL);
02752 }
02753 
02754 void CGMEApp::OnUpdateRecentProjectMenu(CCmdUI* pCmdUI)
02755 {
02756         ASSERT_VALID(this);
02757         m_RecentProjectList.UpdateMenu(pCmdUI,guiMetaProject == NULL);
02758 }
02759 
02760 
02761 // *******************************************************************************
02762 // *******************************************************************************
02763 //                                                              EDIT
02764 // *******************************************************************************
02765 // *******************************************************************************
02766 
02767 
02768 void CGMEApp::OnEditProjectproperties() 
02769 {
02770         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditProjectproperties ") + projectName +_T("\r\n"));
02771         CProjectPropertiesDlg dlg;
02772         if(dlg.DoModal() == IDOK) {
02773                 if(CGMEDoc::theInstance)
02774                         CGMEDoc::theInstance->SetTitle(projectName);
02775                 UpdateMainFrameTitle(projectName);
02776         }
02777 }
02778 
02779 
02780 void CGMEApp::OnEditUndo() 
02781 {
02782         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditUndo\r\n"));
02783         mgaProject->Undo();
02784 }
02785 
02786 void CGMEApp::OnEditRedo() 
02787 {
02788         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditRedo\r\n"));
02789         mgaProject->Redo();
02790 }
02791 
02792 void CGMEApp::OnEditClearUndo() 
02793 {
02794         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnEditClearUndo\r\n"));
02795         if( mgaProject == NULL )
02796                 return;
02797 
02798         if(AfxMessageBox(_T("You are about to lose all Undo/Redo information. Proceed?"),MB_YESNO | MB_ICONQUESTION) == IDYES) {
02799                 MSGTRY
02800                 {
02801                         COMTHROW( mgaProject->FlushUndoQueue() );
02802                 }
02803                 MSGCATCH(_T("Error while clearing the undo queue"),;)
02804         }
02805 }
02806 
02807 
02808 // *******************************************************************************
02809 
02810 void CGMEApp::OnUpdateEditUndo(CCmdUI* pCmdUI) 
02811 {
02812         if(guiMetaProject != NULL) {
02813                 short undoSize;
02814                 short redoSize;
02815                 mgaProject->UndoRedoSize(&undoSize,&redoSize);
02816                 pCmdUI->Enable(undoSize > 0);
02817         }
02818         else
02819                 pCmdUI->Enable(FALSE);
02820 }
02821 
02822 void CGMEApp::OnUpdateEditRedo(CCmdUI* pCmdUI) 
02823 {
02824         if(guiMetaProject != NULL) {
02825                 short undoSize;
02826                 short redoSize;
02827                 mgaProject->UndoRedoSize(&undoSize,&redoSize);
02828                 pCmdUI->Enable(redoSize > 0);
02829         }
02830         else
02831                 pCmdUI->Enable(FALSE);
02832 }
02833 
02834 void CGMEApp::OnUpdateEditClearUndo(CCmdUI* pCmdUI) 
02835 {
02836         if(mgaProject != NULL) {
02837                 short undoSize;
02838                 short redoSize;
02839                 mgaProject->UndoRedoSize(&undoSize,&redoSize);
02840                 pCmdUI->Enable(undoSize > 0);
02841         }
02842         else
02843                 pCmdUI->Enable(FALSE);
02844 }
02845 
02846 void CGMEApp::OnUpdateEditProjectproperties(CCmdUI* pCmdUI) 
02847 {
02848         pCmdUI->Enable(CGMEDoc::theInstance != 0);
02849 }
02850 
02851 
02852 
02853 /*
02854 void CGMEApp::OnUpdateFileRunplugin1(CCmdUI* pCmdUI) 
02855 {
02856         
02857         CMenu *filemenu = pCmdUI->m_pMenu;
02858         UINT idx = pCmdUI->m_nIndex;
02859 if(idx == 0) return;
02860         CString label;
02861         ASSERT(filemenu);
02862         filemenu->GetMenuString(idx,label,MF_BYPOSITION);
02863         filemenu->DeleteMenu(idx,MF_BYPOSITION);
02864         CMenu pluginmenu;
02865         pluginmenu.CreatePopupMenu();
02866         pluginmenu.GetMenuItemID
02867         for(int i = 0; i < comps.GetSize(); ++i)        {
02868                         pluginmenu.AppendMenu(MF_ENABLED, pCmdUI->m_nID + i,comps[i]);
02869         }
02870         filemenu->InsertMenu(idx,
02871                                                 comps.GetSize() ? MF_BYPOSITION|MF_POPUP|MF_ENABLED: MF_BYPOSITION|MF_POPUP|MF_GRAYED,
02872                                                 (UINT)pluginmenu.Detach(),label);
02873         
02874 }
02875 */
02876 
02877 void CGMEApp::OnRunPlugin(UINT nID) {
02878         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnRunPlugin ")+plugins[nID - ID_FILE_RUNPLUGIN1]+_T("\r\n"));
02879 
02880         // Focus must be killed to flush ObjectInspector and Browser
02881         ::SetFocus(NULL);
02882 
02883         RunComponent(plugins[nID - ID_FILE_RUNPLUGIN1]);
02884 }
02885 
02886 void CGMEApp::OnRunInterpreter(UINT nID) {
02887         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::OnRunInterpreter ")+interpreters[nID - ID_FILE_INTERPRET1]+_T("\r\n"));
02888 
02889         // Focus must be killed to flush ObjectInspector and Browser
02890         ::SetFocus(NULL);
02891 
02892         RunComponent(interpreters[nID - ID_FILE_INTERPRET1]);
02893 }
02894 
02895 
02896 
02897 void CGMEApp::RunComponent(const CString &compname)
02898 {
02899 
02900         IMgaLauncherPtr launcher;
02901         launcher.CreateInstance(L"Mga.MgaLauncher");
02902         if(!launcher) {
02903                 AfxMessageBox(_T("Cannot start up component launcher"));
02904         }
02905         else {
02906                 CComPtr<IMgaFCO> focus;
02907                 CComPtr<IMgaFCOs> selfcos;
02908                 COMTHROW(selfcos.CoCreateInstance(OLESTR("Mga.MgaFCOs")));
02909                 CMDIChildWnd *pChild  = CMainFrame::theInstance->MDIGetActive();
02910                 if (pChild) {
02911 #if !defined (ACTIVEXGMEVIEW)
02912                         CGMEView *view = (CGMEView*)pChild->GetActiveView();
02913                         if (view) {
02914                                 COMTHROW(view->currentModel.QueryInterface(&focus));
02915                                 POSITION pos = view->selected.GetHeadPosition();
02916                                 while (pos) {
02917                                         CGuiFco *gfco = view->selected.GetNext(pos);
02918                                         COMTHROW(selfcos->Append(gfco->mgaFco));
02919                                 }
02920                         }
02921 #endif
02922                 }
02923 
02924                 if(theApp.bNoProtect) COMTHROW( launcher->put_Parameter(CComVariant(true)));
02925                 // 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
02926                 COleMessageFilter* messageFilter = AfxOleGetMessageFilter();
02927                 messageFilter->EnableBusyDialog(FALSE);
02928                 messageFilter->EnableNotRespondingDialog(FALSE);
02929                 std::shared_ptr<COleMessageFilter> busyRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableBusyDialog(TRUE); } );
02930                 std::shared_ptr<COleMessageFilter> notRespondingRestore(messageFilter, [](COleMessageFilter* filter){ filter->EnableNotRespondingDialog(TRUE); } );
02931                 if(launcher->RunComponent(PutInBstr(compname), mgaProject, focus, selfcos, GME_MENU_START) != S_OK) {
02932                         CComObjPtr<IErrorInfo> errinfo;
02933                         GetErrorInfo(0, PutOut(errinfo));
02934                         if (errinfo) {
02935                                 _bstr_t desc;
02936                                 errinfo->GetDescription(desc.GetAddress());
02937                                 std::wstring error;
02938                                 error += L"Component execution failed: ";
02939                                 error += desc;
02940                                 AfxMessageBox(error.c_str());
02941                         } else {
02942                                 AfxMessageBox(_T("Component execution failed"));
02943                         }
02944                 }
02945         }
02946 }
02947 
02948 class CGmePrintSetup : public CPrintDialog
02949 {
02950 public:
02951         enum { IDD = IDD_PRINT_DIALOG  };
02952         CGmePrintSetup() : CPrintDialog(true, 0, NULL) {}
02953 };
02954 
02955 void CGMEApp::OnUniquePrintSetup()
02956 {
02957         CGmePrintSetup setup;
02958         setup.m_pd.Flags =      PD_PRINTSETUP |  // actually the current aspect
02959                                                                 PD_ENABLESETUPTEMPLATE |
02960                                                                 PD_ENABLEPRINTHOOK | PD_ENABLESETUPHOOK ;
02961         setup.m_pd.hInstance = AfxGetInstanceHandle();
02962         setup.m_pd.lpSetupTemplateName = MAKEINTRESOURCE(IDD_PRINTSETUP_DIALOG);
02963         DoPrintDialog(&setup);
02964 }
02965 
02966 void CGMEApp::ImportDroppedFile(const CString& fname)
02967 {
02968         CGMEEventLogger::LogGMEEvent(_T("CGMEApp::ImportDroppedFile "));
02969 
02970         CString file_name = fname;
02971 
02972         MSGTRY
02973         {
02974                 int fnameStart = fname.ReverseFind('\\');
02975                 if (fnameStart == -1)
02976                         fnameStart = fname.ReverseFind('/');
02977 
02978                 CString ftitle;
02979                 CString fpath;
02980                 if (fnameStart != -1) {
02981                         fpath = fname.Left(fnameStart + 1);
02982                         ftitle = fname.Right(fname.GetLength() - fnameStart - 1);
02983                         int extStart = ftitle.ReverseFind('.');
02984                         if (extStart != -1)
02985                                 ftitle = ftitle.Left(extStart);
02986                 }
02987                 Importxml(file_name, file_name.Right(file_name.GetLength() - fnameStart), ftitle);
02988         }
02989         MSGCATCH(_T("Error importing XML file"),;)
02990 }
02991 
02992 void CGMEApp::RegisterDroppedFile( const CString& fname, bool userReg/* = true*/)
02993 {
02994         try
02995         {
02996                 CWaitCursor wait;
02997                 IMgaRegistrarPtr registrar;
02998                 COMTHROW(registrar.CreateInstance(L"Mga.MgaRegistrar"));
02999 
03000                 regaccessmode_enum reg_access = REGACCESS_USER;
03001 
03002                 _bstr_t newname;
03003                 registrar->__RegisterParadigmFromData(_bstr_t(fname), newname.GetAddress(), reg_access);
03004 
03005                 CMainFrame::theInstance->m_console.Message( _T("Done."), 1);
03006         }
03007         catch( hresult_exception &e)
03008         {
03009                 CMainFrame::theInstance->m_console.Message( _T("Error while registering paradigm."), 3);
03010         }
03011         catch(_com_error &e)
03012         {
03013                 _bstr_t error(L"");
03014                 if (e.Description() != _bstr_t())
03015                         error = e.Description();
03016                 else
03017                         GetErrorInfo(e.Error(), error.GetAddress());
03018                 CMainFrame::theInstance->m_console.Message(CString("Error while registering paradigm: ") + static_cast<const wchar_t*>(error), 3);
03019         }
03020 }
03021 
03022 void CGMEApp::OnUpdateFilePluginX(CCmdUI* pCmdUI)
03023 {
03024         bool enabled = m_vecDisabledPlugIns.find( pCmdUI->m_nID) == m_vecDisabledPlugIns.end();
03025         if( pCmdUI->m_nID >= ID_FILE_RUNPLUGIN1 && pCmdUI->m_nID <= ID_FILE_RUNPLUGIN_LAST)
03026                 pCmdUI->Enable( enabled );
03027 }
03028 
03029 void CGMEApp::OnUpdateFileInterpretX(CCmdUI* pCmdUI)
03030 {
03031         bool enabled = m_vecDisabledComps.find( pCmdUI->m_nID) == m_vecDisabledComps.end();
03032         if( pCmdUI->m_nID >= ID_FILE_INTERPRET1 && pCmdUI->m_nID <= ID_FILE_INTERPRET_LAST)
03033                 pCmdUI->Enable( enabled );
03034 }
03035 
03036 // this method is used internally
03037 void CGMEApp::ClearDisabledComps()
03038 {
03039         m_vecDisabledPlugIns.clear();
03040         m_vecDisabledComps.clear();
03041 }
03042 
03043 // this method is called from CGMEOLEApp::DisableComp
03044 //                        and CGMEApp::UpdateCompList4CurrentKind
03045 void CGMEApp::DisableComp( const CString& pCompToFind, bool pbHide)
03046 {
03047         UINT id_of_comp = 0;
03048         bool is_plugin = false;
03049         for(int i = 0; !id_of_comp && i < plugins.GetSize(); ++i)       
03050         {
03051                 if( plugins[i] == pCompToFind)
03052                 {
03053                         id_of_comp = ID_FILE_RUNPLUGIN1 + i;
03054                         is_plugin = true;
03055                 }
03056         }
03057 
03058         for(int i = 0; !id_of_comp && i < interpreters.GetSize(); ++i)
03059         {
03060                 if( interpreters[i] == pCompToFind)
03061                 {
03062                         id_of_comp = ID_FILE_INTERPRET1 + i;
03063                         is_plugin = false;
03064                 }
03065         }
03066 
03067         if( id_of_comp) // a valid command ID
03068         {
03069                 //ActivateComp( id_of_comp, is_plugin, pbShow);
03070                 if( is_plugin)
03071                 {
03072                         ONE_ID_LIST::const_iterator pos = m_vecDisabledPlugIns.find( id_of_comp);
03073                         if( pbHide) // disable, so id_of_comp must be inserted into the vector
03074                         {
03075                                 if( m_vecDisabledPlugIns.end() == pos) // not found
03076                                         m_vecDisabledPlugIns.insert( m_vecDisabledPlugIns.end(), id_of_comp);
03077                         }
03078                         else // enable, so remove id_of_comp from the vector
03079                         {
03080                                 if( m_vecDisabledPlugIns.end() != pos) // if really found
03081                                         m_vecDisabledPlugIns.erase( pos);
03082                         }
03083                 }
03084                 else
03085                 {
03086                         ONE_ID_LIST::const_iterator pos = m_vecDisabledComps.find( id_of_comp);
03087                         if( pbHide) // disable, so id_of_comp must be inserted into the vector
03088                         {
03089                                 if( m_vecDisabledComps.end() == pos) // not found
03090                                         m_vecDisabledComps.insert( m_vecDisabledComps.end(), id_of_comp);
03091                         }
03092                         else // enable, so remove id_of_comp from the vector
03093                         {
03094                                 if( m_vecDisabledComps.end() != pos) // if really found
03095                                         m_vecDisabledComps.erase( pos);
03096                         }
03097                 }
03098         }
03099 }
03100 
03101 // this method is called from CGMEOLEApp::DisableCompForKinds
03102 void CGMEApp::DisableCompForKinds( const CString& pComp, const CString& pKindSeq)
03103 {
03104         int nm_of_tokens = 0; // will count the parsed kind names
03105         int pos = 0;
03106         CString t_kind;
03107         t_kind = pKindSeq.Tokenize( _T(";"), pos); // tokenize by ';'
03108         while( t_kind != _T(""))
03109         {
03110                 ONE_COMP_LIST &my_comps = m_compsOfKind[ t_kind ];
03111                 ONE_COMP_LIST::const_iterator it = my_comps.find( pComp);
03112                 if( it == my_comps.end()) // not found, so insert it
03113                         m_compsOfKind[ t_kind ].insert( pComp);
03114 
03115                 ++nm_of_tokens;
03116                 t_kind = pKindSeq.Tokenize( _T(";"), pos); // move to next token
03117         }
03118 }
03119 
03120 // this method is called from CGMEView::OnActivateView    (with the kindname shown)
03121 //                            CGMEView::~CGMEView         (with the special string: _NO_MODEL_IS_OPEN_ == m_no_model_open_string)
03122 //                            CGMEApp::SetCompFiltering   (with one from the items above)
03123 void CGMEApp::UpdateCompList4CurrentKind( const CString& pKind)
03124 {
03125         // if filter is OFF return
03126         if( !m_compFilterOn) 
03127         {
03128                 return;
03129         }
03130 
03131         // kind name should not be empty
03132         if( pKind.IsEmpty()) { ASSERT(0); return; }
03133 
03134         ClearDisabledComps(); // reset all to original state (enabled)
03135 
03136         if( m_compsOfKind.find( pKind) != m_compsOfKind.end()) // if it has an entry
03137         {
03138                 ONE_COMP_LIST &my_comps = m_compsOfKind[ pKind]; // this key already existed
03139                 for( ONE_COMP_LIST::const_iterator it = my_comps.begin(); it != my_comps.end(); ++it)
03140                 {
03141                         DisableComp( *it, true); // disable comps which are registered for this kind
03142                 }
03143         } // if this kind has no assigned [excluded] component set: NOP [every component is enabled]
03144 }
03145 
03146 void CGMEApp::SetCompFiltering( bool pOn)
03147 { 
03148         m_compFilterOn = pOn;
03149         if( !m_compFilterOn) // if turned OFF
03150         {
03151                 ClearDisabledComps(); // reset all to original state (enabled)
03152         }
03153         else // turned ON
03154         {
03155                 // find the current view
03156                 bool found = false;
03157                 CMDIChildWnd *pChild  = CMainFrame::theInstance->MDIGetActive();
03158                 if( pChild) 
03159                 {
03160 #if !defined (ACTIVEXGMEVIEW)
03161                         CGMEView *view = (CGMEView*)pChild->GetActiveView();
03162                         if( view && view->guiMeta)
03163                         {
03164                                 found = true;
03165                                 this->UpdateCompList4CurrentKind( view->guiMeta->name);
03166                         }
03167 #endif
03168                 }
03169 
03170                 if( !found)
03171                         this->UpdateCompList4CurrentKind( CGMEApp::m_no_model_open_string);
03172         }
03173 }
03174 
03175 bool CGMEApp::GetCompFiltering()
03176 {
03177         return m_compFilterOn;
03178 }
03179 
03180 bool CGMEApp::SetWorkingDirectory( LPCTSTR pPath)
03181 {
03182         return SetCurrentDirectory( pPath) == TRUE;
03183         //int sc = _chdir( pPath);
03184         //return sc == 0;
03185 }
03186 
03187 void CGMEApp::UpdateMainTitle(bool retrievePath)
03188 {
03189         if (CMainFrame::theInstance)
03190                 UpdateMainFrameTitle(projectName, retrievePath);
03191 }
03192 
03193 bool CGMEApp::IsUndoPossible(void) const
03194 {
03195         if(!mgaProject)
03196                 return false;
03197 
03198         if (guiMetaProject != NULL) {
03199                 short undoSize;
03200                 short redoSize;
03201                 mgaProject->UndoRedoSize(&undoSize,&redoSize);
03202                 return undoSize > 0;
03203         }
03204 
03205         return false;
03206 }
03207 
03208 void CGMEApp::OnFocusBrowser()
03209 {
03210         if( !mgaProject) return;
03211 
03212         CComObjPtr<IMgaTerritory> terry;
03213         COMTHROW(mgaProject->CreateTerritory(NULL, PutOut(terry), NULL) );
03214 
03215         LPUNKNOWN objs = CGMEObjectInspector::theInstance->GetObjects();
03216         CComQIPtr<IMgaObjects> one_obj_coll( objs);
03217         long len = 0;
03218         if( one_obj_coll) COMTHROW( one_obj_coll->get_Count( &len));
03219         if( len >= 1)
03220         {
03221                 MSGTRY
03222                 {
03223                         CComPtr<IMgaObject> one_obj, one_obj2;
03224                         long status = OBJECT_ZOMBIE;
03225                         CComBSTR id;
03226                         COMTHROW( one_obj_coll->get_Item( 1, &one_obj));
03227                         COMTHROW( mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY));
03228 
03229                         if( one_obj)  COMTHROW( terry->OpenObj( one_obj, &one_obj2));
03230                         if( one_obj2) {
03231                                 COMTHROW( one_obj2->get_Status( &status));
03232                                 COMTHROW( one_obj2->get_ID( &id));
03233                         }
03234 
03235                         COMTHROW( mgaProject->CommitTransaction());
03236 
03237                         if( id.Length() > 0 && status == OBJECT_EXISTS) 
03238                         {
03239                                 CGMEBrowser::theInstance->FocusItem( id);
03240                                 return;
03241                         }
03242                 }
03243                 MSGCATCH(_T("Error getting project rootfolder"), mgaProject->AbortTransaction())
03244         }
03245 
03246         MSGTRY
03247         {
03248                 CComBSTR id;
03249                 CComPtr<IMgaFolder> rf;
03250                 COMTHROW(mgaProject->BeginTransaction(terry,TRANSACTION_READ_ONLY));
03251                 COMTHROW(mgaProject->get_RootFolder( &rf));
03252                 if( rf) COMTHROW(rf->get_ID(&id));
03253                 COMTHROW(mgaProject->CommitTransaction());
03254 
03255                 if( id.Length() > 0) 
03256                         CGMEBrowser::theInstance->FocusItem( id);
03257         }
03258         MSGCATCH(_T("Error getting project rootfolder"), mgaProject->AbortTransaction())
03259 }
03260 
03261 void CGMEApp::OnFocusInspector()
03262 {
03263         HWND hwnd = CGMEObjectInspector::theInstance->GetSafeHwnd();
03264         if( hwnd) ::SetFocus( hwnd);
03265 }
03266 
03267 void CGMEApp::consoleMessage( const CString& p_msg, short p_type)
03268 {
03269         if( CMainFrame::theInstance) // 99.99% of cases
03270                 CMainFrame::theInstance->m_console.Message( p_msg, p_type);
03271         else
03272                 AfxMessageBox( p_msg);
03273 }