GME
13
|
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), ®parguid, REGACCESS_PRIORITY); 02267 CComBstrObj regCurrentVersion; 02268 if (SUCCEEDED(h2)) { 02269 reg->VersionFromGUID(xmeparadigm, regparguid, ®CurrentVersion.p, REGACCESS_PRIORITY); 02270 } 02271 02272 CComVariant regGuidFromVersion; 02273 HRESULT h3GuidFromVersion = E_FAIL; 02274 if (xmeparversion.Length() != 0) { 02275 h3GuidFromVersion = reg->GUIDFromVersion(xmeparadigm, xmeparversion, ®GuidFromVersion, 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 }