// Ryzom - MMORPG Framework // Copyright (C) 2010 Winch Gate Property Limited // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as // published by the Free Software Foundation, either version 3 of the // License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // #include "stdafx.h" #include "nel/misc/path.h" #include "nel/misc/config_file.h" #include "nel/misc/o_xml.h" #include "nel/misc/i_xml.h" #include "nel/misc/dynloadlib.h" #include "georges_edit.h" #include "reg_shell_ext.h" #include "main_frm.h" #include "child_frm.h" #include "georges_edit_doc.h" #include "left_view.h" #include "splash_screen.h" using namespace NLMISC; using namespace NLGEORGES; using namespace std; const char* TypeFilter = "Type Files (*.typ)|*.typ|All Files (*.*)|*.*||"; const char* DfnFilter = "Form Definition Files (*.dfn)|*.dfn|All Files (*.*)|*.*||"; CSplashScreen* splashScreen=new CSplashScreen; ///////////////////////////////////////////////////////////////////////////// // CGeorgesEditApp BEGIN_MESSAGE_MAP(CGeorgesEditApp, CWinApp) //{{AFX_MSG_MAP(CGeorgesEditApp) ON_COMMAND(ID_APP_ABOUT, OnAppAbout) ON_COMMAND(ID_VIEW_REFRESH, OnViewRefresh) ON_COMMAND(ID_FILE_SAVE_ALL, OnFileSaveAll) ON_COMMAND(ID_FILE_CLOSE_ALL, OnFileCloseAll) ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_ALL, OnUpdateFileSaveAll) //}}AFX_MSG_MAP // Standard file based document commands ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew) ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen) END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CGeorgesEditApp construction CGeorgesEditApp::CGeorgesEditApp() : MemStream (false, false, 1024*1024) { Superuser = true; DefaultType = "default.typ"; DefaultDfn = "default.dfn"; m_pMainWnd = NULL; RememberListSize = 10; MaxUndo = 20; ResizeMain = true; ExeStandalone = false; StartExpanded = true; FormClipBoardFormatStruct = RegisterClipboardFormat ("GeorgesFormStruct"); FormClipBoardFormatVirtualStruct = RegisterClipboardFormat ("GeorgesFormVirtualStruct"); FormClipBoardFormatArray = RegisterClipboardFormat ("GeorgesFormArray"); FormClipBoardFormatType = RegisterClipboardFormat ("GeorgesFormType"); nlassert (FormClipBoardFormatStruct); nlassert (FormClipBoardFormatVirtualStruct); nlassert (FormClipBoardFormatArray); nlassert (FormClipBoardFormatType); _TemplateForm = NULL; _TemplateType = NULL; _TemplateDfn = NULL; } CGeorgesEditApp::~CGeorgesEditApp () { } ///////////////////////////////////////////////////////////////////////////// // The one and only CGeorgesEditApp object CGeorgesEditApp theApp; ///////////////////////////////////////////////////////////////////////////// // CGeorgesEditApp initialization BOOL CGeorgesEditApp::InitInstance() { return TRUE; } CMyMultiDocTemplate::CMyMultiDocTemplate (const char *ext, UINT nIDResource, CRuntimeClass* pDocClass, CRuntimeClass* pFrameClass, CRuntimeClass* pViewClass) : CMultiDocTemplate ( nIDResource, pDocClass, pFrameClass, pViewClass ) { _Ext = ext; _ExtMaj = _Ext; _Ext = strlwr (_Ext); _ExtMaj[0] = toupper (_ExtMaj[0]); } void CMyMultiDocTemplate::getDfnName (string &dfnName) { dfnName = _Ext + ".dfn"; } BOOL CMyMultiDocTemplate::GetDocString(CString& rString, enum DocStringIndex index) const { switch (index) { case fileNewName: case windowTitle: case docName: rString = (_ExtMaj + " Form").c_str (); return TRUE; case filterName: rString = (_ExtMaj + " Form Filename (*." + _Ext+ ")").c_str (); return TRUE; case filterExt: rString = ("." + _Ext).c_str (); return TRUE; default: return CMultiDocTemplate::GetDocString(rString, index); } } BOOL CGeorgesEditApp::initInstance (int nCmdShow, bool exeStandalone, int x, int y, int cx, int cy) { // Some things have just to be done once per launch of the application that is // completely different from an opening/closing of the main frame static bool isInitialized = false; ExeStandalone = exeStandalone; splashScreen->Create(IDD_SPLASHSCREEN, theApp.GetMainWnd()); splashScreen->ShowWindow(TRUE); splashScreen->addLine(string("Georges Initialization")); // Filter addSearchPath splashScreen->addLine(string("Filter addSearchPath")); NLMISC::createDebug(); InfoLog->addNegativeFilter("adding the path"); WarningLog->addNegativeFilter("Exception will be launched"); if (!isInitialized && exeStandalone) { m_nCmdShow = nCmdShow; ExePath = GetCommandLine (); if (ExePath.size()>0) { if (ExePath[0] == '\"') { uint end=ExePath.find ('\"', 1); if (end != string::npos) { ExePath = ExePath.substr (1, end-1); } else { nlassert (0); // no! } } else { uint end=ExePath.find (' ', 1); ExePath = ExePath.substr (0, end); } } // Init CPath loadCfg (); initCfg (); } if (!isInitialized) { // Fill the image list splashScreen->addLine(string("Fill the image list")); ImageList.create (16, 16); ImageList.addResourceIcon (m_hInstance, IDR_ARRAY); ImageList.addResourceIcon (m_hInstance, IDR_HEADER); ImageList.addResourceIcon (m_hInstance, IDR_HOLD); ImageList.addResourceIcon (m_hInstance, IDR_ROOT); ImageList.addResourceIcon (m_hInstance, IDR_STRUCT); ImageList.addResourceIcon (m_hInstance, IDR_VSTRUCT); ImageList.addResourceIcon (m_hInstance, IDR_TYPEDFN); ImageList.addResourceIcon (m_hInstance, IDR_TYPEFORM); ImageList.addResourceIcon (m_hInstance, IDR_TYPETYPE); // Add icon splashScreen->addLine(string("Add icon")); std::vector result; string iconPathName = RootSearchPath+TypeDfnSubDirectory; if (!iconPathName.empty ()) { CPath::getPathContent (iconPathName, true, false, true, result); uint i; for (i=0; iaddLine(string("Standard initialization")); if (!isInitialized) { // const char *open = "Open(\"%1\")"; // const char *copy = "Georges Copy(\"%1\")"; // const char *derive = "Derive(\"%1\")"; // const char *createForm = "CreateForm(\"%1\")"; // const char *notepad = "notepad.exe \"%1\""; // *** Registry // MFC settings splashScreen->addLine(string("MFC settings")); SetRegistryKey(_T("Nevrax")); LoadStdProfileSettings(16); // Load standard INI file options (including MRU) // EnableShellOpen(); // Application path string appPath = "\""; appPath += ExePath; appPath += "\""; bool okRegister = true; if (ExeStandalone) { splashScreen->addLine(string("Associate Georges file extensions")); okRegister &= RegisterApp ("Georges.Type", "Georges Type Files", appPath.c_str (), 3); okRegister &= RegisterApp ("Georges.Dfn", "Georges Dfn Files", appPath.c_str (), 3); okRegister &= RegisterApp ("Georges.Form", "Georges Form Files", appPath.c_str (), 3); okRegister &= RegisterShellFileExt (".typ", "Georges.Type"); okRegister &= RegisterShellFileExt (".dfn", "Georges.Dfn"); // Register Type and DFN for superuser /* if (Superuser) { // Register the application splashScreen->addLine(string("Register the application")); okRegister &= RegisterApp ("Georges.Type", "Georges Type Files", appPath.c_str (), 1); okRegister &= RegisterApp ("Georges.Dfn", "Georges Dfn Files", appPath.c_str (), 2); okRegister &= RegisterApp ("Georges.Form", "Georges Form Files", appPath.c_str (), 3); // Register the command splashScreen->addLine(string("Register the command")); okRegister &= RegisterAppCommand ("Georges.Type", "Open", (appPath+" %1").c_str ()); okRegister &= RegisterAppCommand ("Georges.Dfn", "Open", (appPath+" %1").c_str ()); okRegister &= RegisterAppCommand ("Georges.Dfn", "Create Form", (appPath+" /dde").c_str ()); okRegister &= RegisterAppCommand ("Georges.Type", "Open With Notepad", notepad); okRegister &= RegisterAppCommand ("Georges.Dfn", "Open With Notepad", notepad); // Register the DDE command (avoid strange Visual compile error..) splashScreen->addLine(string("Register the DDE command")); okRegister &= RegisterDDECommand ("Georges.Type", "Open", open, m_pszExeName); okRegister &= RegisterDDECommand ("Georges.Dfn", "Open", open, m_pszExeName); okRegister &= RegisterDDECommand ("Georges.Dfn", "Create Form", createForm, m_pszExeName); // Register the file extension splashScreen->addLine(string("Register the file extension")); okRegister &= RegisterShellFileExt (".typ", "Georges.Type"); okRegister &= RegisterShellFileExt (".dfn", "Georges.Dfn"); } else { // Register the command splashScreen->addLine(string("Register the command")); UnregisterAppCommand ("Georges.Dfn", "Open"); okRegister &= RegisterAppCommand ("Georges.Dfn", "Create Form", (appPath+" /dde").c_str ()); UnregisterAppCommand ("Georges.Dfn", "Open With Notepad"); // Register the DDE command (avoid strange Visual compile error..) splashScreen->addLine(string("Register the DDE command")); okRegister &= RegisterDDECommand ("Georges.Dfn", "Create Form", createForm, m_pszExeName); // Register the file extension splashScreen->addLine(string("Register the file extension")); okRegister &= RegisterShellFileExt (".dfn", "Georges.Dfn"); // Unregister type and dfn splashScreen->addLine(string("Unregister type and dfn")); UnregisterApp ("Georges.Type"); } // Register non super user commands splashScreen->addLine(string("Register non super user commands")); okRegister &= RegisterAppCommand ("Georges.Form", "Open", (appPath+" %1").c_str ()); okRegister &= RegisterAppCommand ("Georges.Form", "Georges Copy", (appPath+" /dde").c_str ()); okRegister &= RegisterAppCommand ("Georges.Form", "Derive", (appPath+" /dde").c_str ()); okRegister &= RegisterAppCommand ("Georges.Form", "Open With Notepad", notepad); // Register dde commands splashScreen->addLine(string("Register dde commands")); okRegister &= RegisterDDECommand ("Georges.Form", "Open", open, m_pszExeName); okRegister &= RegisterDDECommand ("Georges.Form", "Georges Copy", copy, m_pszExeName); okRegister &= RegisterDDECommand ("Georges.Form", "Derive", derive, m_pszExeName); */ } // Ok register ? if (!okRegister) nlwarning ("Register Georges: problem during Georges registration. Do you have administrator privileges ?"); // Register the application's document templates. Document templates // serve as the connection between documents, frame windows and views. // Are we a superuser ? if (Superuser) { // Form _TemplateForm = new CMultiDocTemplate( IDR_TYPEFORM, RUNTIME_CLASS(CGeorgesEditDocForm), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CLeftView)); AddDocTemplate(_TemplateForm); // Type _TemplateType = new CMultiDocTemplate( IDR_TYPETYPE, RUNTIME_CLASS(CGeorgesEditDocType), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CLeftView)); AddDocTemplate(_TemplateType); // Dfn _TemplateDfn = new CMultiDocTemplate( IDR_TYPEDFN, RUNTIME_CLASS(CGeorgesEditDocDfn), RUNTIME_CLASS(CChildFrame), // custom MDI child frame RUNTIME_CLASS(CLeftView)); AddDocTemplate(_TemplateDfn); } else { // For each form uint i; for (i=0; iaddLine(string("create main MDI Frame window")); CMainFrame* pMainFrame = new CMainFrame; nlassert (pMainFrame); ((CMainFrame*)pMainFrame)->createX = x; ((CMainFrame*)pMainFrame)->createY = y; ((CMainFrame*)pMainFrame)->createCX = cx; ((CMainFrame*)pMainFrame)->createCY = cy; if (!pMainFrame->LoadFrame(IDR_MAINFRAME)) return FALSE; m_pMainWnd = pMainFrame; // Enable drag/drop open m_pMainWnd->DragAcceptFiles(); if (!isInitialized) { // Enable DDE Execute open // EnableShellOpen(); // RegisterShellFileTypes(TRUE); isInitialized = true; } // Parse command line for standard shell commands, DDE, file open splashScreen->addLine(string("Parse command line")); CCommandLineInfo cmdInfo; ParseCommandLine(cmdInfo); // Dispatch commands specified on the command line splashScreen->addLine(string("Dispatch commands specified")); if (cmdInfo.m_nShellCommand == CCommandLineInfo::FileNew) cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; /*if (!ProcessShellCommand(cmdInfo)) return FALSE;*/ // Load and init plugins splashScreen->addLine(string("Load and init plugins")); loadPlugins (); // Init windows ResizeMain = (x==-1); loadState (); // The main window has been initialized, so show and update it. pMainFrame->ShowWindow(SW_SHOW /*m_nCmdShow*/); pMainFrame->UpdateWindow(); splashScreen->ShowWindow(false); return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) // No message handlers //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() // App command to run the dialog void CGeorgesEditApp::OnAppAbout() { CAboutDlg aboutDlg; aboutDlg.DoModal(); } void CGeorgesEditApp::outputError (const char* message) { if (m_pMainWnd) m_pMainWnd->MessageBox (message, "Georges Edit", MB_OK|MB_ICONEXCLAMATION); else MessageBox (NULL, message, "Georges Edit", MB_OK|MB_ICONEXCLAMATION); } void CGeorgesEditApp::getConfigFilePath (std::string &output) { // Get the config file path char sDrive[MAX_PATH]; char sDir[MAX_PATH]; char sPath[MAX_PATH]; _splitpath (theApp.ExePath.c_str (), sDrive, sDir, NULL, NULL); _makepath (sPath, sDrive, sDir, "georges", ".cfg"); output = sPath; } bool CGeorgesEditApp::loadCfg () { // Open the config file std::string configPath; getConfigFilePath (configPath); CConfigFile &cf = ConfigFile;; // Root search path try { cf.load (configPath); CConfigFile::CVar *rootDirectory = cf.getVarPtr ("RootSearchDirectory"); if (rootDirectory) { RootSearchPath = rootDirectory->asString (); if (RootSearchPath.size ()) { char c = RootSearchPath[RootSearchPath.size ()-1]; if ((c != '\\') && (c != '/')) RootSearchPath += "\\"; } } // Type and Dfn sub directory CConfigFile::CVar *typeDfnSubDirectory = cf.getVarPtr ("TypDfnSubFolder"); if (typeDfnSubDirectory) { // Last char is good ? string copy = typeDfnSubDirectory->asString (); const char *ptr = copy.c_str (); while ((*ptr == '/') || (*ptr == '\\')) ptr++; TypeDfnSubDirectory = ptr; if (TypeDfnSubDirectory.size ()) { char c = TypeDfnSubDirectory[TypeDfnSubDirectory.size ()-1]; if ((c != '\\') && (c != '/')) TypeDfnSubDirectory += "\\"; } } // RememberListSize CConfigFile::CVar *remember = cf.getVarPtr ("RememberListSize"); if (remember) RememberListSize = remember->asInt (); // StartExpanded CConfigFile::CVar *start_expanded = cf.getVarPtr ("StartExpanded"); if (start_expanded) StartExpanded = start_expanded->asInt () != 0; // MaxUndo CConfigFile::CVar *max_undo = cf.getVarPtr ("MaxUndo"); if (max_undo) MaxUndo = max_undo->asInt (); // DefaultType CConfigFile::CVar *defaultType = cf.getVarPtr ("DefaultType"); if (defaultType) DefaultType = defaultType->asString (); // DefaultDfn CConfigFile::CVar *defaultDfn = cf.getVarPtr ("DefaultDfn"); if (defaultDfn) DefaultDfn = defaultDfn->asString (); // Plugins CConfigFile::CVar *plugins = cf.getVarPtr ("Plugins"); if (plugins) { PluginsNames.reserve (plugins->size()); uint i; for (i=0; i<(uint)plugins->size(); i++) PluginsNames.push_back (plugins->asString (i)); } // User types CConfigFile::CVar *user_type = cf.getVarPtr ("UserType"); if (user_type) { UserTypes.reserve (user_type->size()); uint i; for (i=0; i<(uint)user_type->size(); i++) UserTypes.push_back (user_type->asString (i)); } // Super user CConfigFile::CVar *superuser = cf.getVarPtr ("SuperUser"); if (superuser) Superuser = superuser->asInt () != 0; } catch (Exception &) { char message[512]; smprintf (message, 512, "Can't load georges.cfg config file."); outputError (message); } return true; } bool CGeorgesEditApp::saveCfg () { // Config path std::string configPath; getConfigFilePath (configPath); CConfigFile &cf = ConfigFile; // Root search path try { cf.load (configPath); CConfigFile::CVar *rootDirectory = cf.getVarPtr ("RootSearchDirectory"); if (rootDirectory) rootDirectory->setAsString (RootSearchPath.c_str ()); // Type and Dfn sub directory CConfigFile::CVar *typeDfnSubDirectory = cf.getVarPtr ("TypDfnSubFolder"); if (typeDfnSubDirectory) typeDfnSubDirectory->setAsString (TypeDfnSubDirectory.c_str ()); // RememberListSize CConfigFile::CVar *remember= cf.getVarPtr ("RememberListSize"); if (remember) remember->setAsInt (RememberListSize); // StartExpanded CConfigFile::CVar *start_expanded= cf.getVarPtr ("StartExpanded"); if (start_expanded) start_expanded->setAsInt (StartExpanded); // MaxUndo CConfigFile::CVar *max_undo= cf.getVarPtr ("MaxUndo"); if (max_undo) max_undo->setAsInt (MaxUndo); // DefaultType CConfigFile::CVar *defaultType = cf.getVarPtr ("DefaultType"); if (defaultType) defaultType->setAsString (DefaultType.c_str ()); // DefaultDfn CConfigFile::CVar *defaultDfn = cf.getVarPtr ("DefaultDfn"); if (defaultDfn) defaultDfn->setAsString (DefaultDfn.c_str ()); // Save the list try { cf.save (); } catch (Exception &) { char message[512]; smprintf (message, 512, "Can't save georges.cfg config file."); outputError (message); } } catch (Exception &) { char message[512]; smprintf (message, 512, "Can't load georges.cfg config file."); outputError (message); } return true; } void CGeorgesEditApp::initCfg () { // Clear the search path list CPath::removeAllAlternativeSearchPath (); // Add search path CPath::addSearchPath (RootSearchPath, true, true,(IProgressCallback*)splashScreen); } bool CGeorgesEditApp::getColor (NLMISC::CRGBA &color) { // Get custom colors COLORREF arrayColor[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; HKEY hKey; if (RegOpenKeyEx(HKEY_CURRENT_USER, GEORGES_EDIT_BASE_REG_KEY"\\Custom Colors", 0, KEY_READ, &hKey)==ERROR_SUCCESS) { DWORD len=sizeof(arrayColor); DWORD type; RegQueryValueEx (hKey, "", 0, &type, (LPBYTE)(arrayColor), &len); RegCloseKey (hKey); } // Reset the struct CHOOSECOLOR cc; memset (&cc, 0, sizeof(CHOOSECOLOR)); // Fill the struct cc.lStructSize=sizeof(CHOOSECOLOR); cc.rgbResult=RGB (color.R, color.G, color.B); cc.lpCustColors=arrayColor; cc.Flags=CC_RGBINIT|CC_ANYCOLOR|CC_FULLOPEN; // Open it if (ChooseColor (&cc)) { color = CRGBA (GetRValue (cc.rgbResult), GetGValue (cc.rgbResult), GetBValue (cc.rgbResult)); // Save the custom colors HKEY hKey; if (RegCreateKey(HKEY_CURRENT_USER, GEORGES_EDIT_BASE_REG_KEY"\\Custom Colors", &hKey)==ERROR_SUCCESS) { RegSetValueEx (hKey, "", 0, REG_BINARY, (LPBYTE)(arrayColor), sizeof(arrayColor)); RegCloseKey (hKey); } return true; } return false; } bool CGeorgesEditApp::yesNo (const char* message) { if (m_pMainWnd) return m_pMainWnd->MessageBox (message, "Georges Edit", MB_YESNO|MB_ICONQUESTION) != IDNO; else return MessageBox (NULL, message, "Georges Edit", MB_YESNO|MB_ICONQUESTION) != IDNO; } void CGeorgesEditApp::loadPlugins () { uint i; for (i=0; idialogInit (*m_pMainWnd); // Hide it plugin->activate (false); } } else { char message[512]; smprintf (message, 512, "Bad interface in plugin \"%s\"", PluginsNames[i].c_str ()); outputError (message); } } else { char message[512]; smprintf (message, 512, "Can't found plugin \"%s\"", PluginsNames[i].c_str ()); outputError (message); } } } void CGeorgesEditApp::releasePlugins () { uint i; for (i=0; iGetActiveDocument ()); if (doc) { if (doc->isForm ()) return doc; else return NULL; } else return NULL; } else return NULL; } void CGeorgesEditApp::getSearchPath (std::string &searchPath) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); searchPath = RootSearchPath; } NLGEORGES::IEditDocument *CGeorgesEditApp::createDocument (const char *dfnName, const char *pathName) { AFX_MANAGE_STATE(AfxGetStaticModuleState()); // Get the form templaet CMultiDocTemplate *docTemplate = getFormDocTemplate (dfnName); if (docTemplate) { // Create a new document CGeorgesEditDocForm *doc = (CGeorgesEditDocForm*)docTemplate->CreateNewDocument(); nlassert (doc); nlassert (doc->isForm ()); // Create the frame CFrameWnd* pFrame = docTemplate->CreateNewFrame(doc, NULL); nlassert (pFrame); // Set default title docTemplate->SetDefaultTitle (doc); // Init the document if (doc->initDocument (dfnName, true)) { // Set the filename if (strcmp (pathName, "") != 0) { doc->SetPathName ( pathName, FALSE ); // Create the file doc->OnSaveDocument( pathName ); } // Init the frame docTemplate->InitialUpdateFrame (pFrame, doc, TRUE); doc->changeSubSelection ((CGeorgesEditDocSub *)NULL, NULL); doc->UpdateAllViews (NULL); return doc; } else { docTemplate->RemoveDocument( doc ); doc = NULL; } } return NULL; } ///////////////////////////////////////////////////////////////////////////// // CGeorgesEditApp message handlers int CGeorgesEditApp::ExitInstance() { // Save the app profile (because it is a DLL) if (m_pCmdInfo == NULL || m_pCmdInfo->m_nShellCommand != CCommandLineInfo::AppUnregister) { if (!afxContextIsDLL) SaveStdProfileSettings(); } return CWinApp::ExitInstance(); } CGeorgesEditApp::CPlugin::CPlugin (HINSTANCE hModule, IEditPlugin *plugin) { PluginModule = hModule; PluginInterface = plugin; Activated = false; } void CGeorgesEditApp::onNewDocView (CGeorgesEditDoc *doc) { if (doc->isForm ()) { uint i; for (i=0; ionCreateDocument (doc); } } } bool CGeorgesEditApp::isPluginActivated (NLGEORGES::IEditPlugin *plugin) const { uint i; for (i=0; iFileBrowserDlg.refresh (); } } void CGeorgesEditApp::saveWindowState (const CWnd *wnd, const char *name, bool controlBar) { HKEY hKey; nlverify (RegCreateKey (HKEY_CURRENT_USER, GEORGES_EDIT_BASE_REG_KEY"\\Windows states", &hKey) == ERROR_SUCCESS); // Get the position WINDOWPLACEMENT wndpl; wnd->GetWindowPlacement( &wndpl ); // Set the registry nlverify (RegSetValueEx (hKey, name, 0, REG_BINARY, (BYTE*)&wndpl, sizeof(WINDOWPLACEMENT)) == ERROR_SUCCESS); // Close the key nlverify (RegCloseKey (hKey) == ERROR_SUCCESS); } void CGeorgesEditApp::loadWindowState (CWnd *wnd, const char *name, bool mdiChildWnd, bool controlBar) { HKEY hKey; if (RegOpenKey (HKEY_CURRENT_USER, GEORGES_EDIT_BASE_REG_KEY"\\Windows states", &hKey) == ERROR_SUCCESS) { // Get the value WINDOWPLACEMENT wndpl; DWORD type; DWORD len = sizeof (WINDOWPLACEMENT); // Get from the registry if (RegQueryValueEx (hKey, name, 0, &type, (BYTE*)&wndpl, &len) == ERROR_SUCCESS) { // Length ok ? if (len == sizeof (WINDOWPLACEMENT)) { // Set window placement // Other children if (mdiChildWnd) { wndpl.showCmd = SW_SHOW; wnd->SetWindowPos (NULL, 0, 0, wndpl.rcNormalPosition.right-wndpl.rcNormalPosition.left, wndpl.rcNormalPosition.bottom-wndpl.rcNormalPosition.top, SWP_NOMOVE|SWP_NOZORDER|SWP_NOOWNERZORDER); } else { wnd->SetWindowPlacement( &wndpl ); } } } nlverify (RegCloseKey (hKey) == ERROR_SUCCESS); } } void CGeorgesEditApp::saveState () { // Save the main window state nlassert (m_pMainWnd); if (ResizeMain) saveWindowState (m_pMainWnd, "main", false); saveWindowState (&((CMainFrame*)m_pMainWnd)->FileBrowser, "browser", true); saveWindowState (&((CMainFrame*)m_pMainWnd)->OutputConsole, "output", true); } void CGeorgesEditApp::loadState () { nlassert (m_pMainWnd); if (ResizeMain) loadWindowState (m_pMainWnd, "main", false, false); loadWindowState (&((CMainFrame*)m_pMainWnd)->FileBrowser, "browser", false, true); loadWindowState (&((CMainFrame*)m_pMainWnd)->OutputConsole, "output", false, true); } void CGeorgesEditApp::OnFileSaveAll() { SaveAllModified (); } void CGeorgesEditApp::OnFileCloseAll() { SaveAllModified (); CloseAllDocuments (FALSE); } void CGeorgesEditApp::OnUpdateFileSaveAll(CCmdUI* pCmdUI) { pCmdUI->Enable (getActiveDocument () != NULL); } bool CGeorgesEditApp::SerialIntoMemStream (const char *formName, CGeorgesEditDoc *doc, uint slot, bool copyToClipboard) { // Ok, get the node const CFormDfn *parentDfn; uint lastElement; const CFormDfn *nodeDfn; const CType *nodeType; CFormElm *node; UFormDfn::TEntryType type; bool array; bool parentVDfnArray; nlverify (((const CFormElm*)(doc->getRootNode (slot)))->getNodeByName ( formName, &parentDfn, lastElement, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, NLGEORGES_FIRST_ROUND)); // Output mode if (MemStream.isReading ()) MemStream.invert (); // Init the stream MemStream.clear (); // Create a serial COXml serialOutput; serialOutput.init (&MemStream); // Catch some prb try { // Serial the string string name; if (parentDfn) name = parentDfn->getEntry(lastElement).getFilename (); else { // Get the string CString str = doc->GetPathName (); name = str; uint pos = name.rfind ('.'); if (pos != string::npos) { // Keep the extension name = name.substr (pos+1); name += ".dfn"; } } MemStream.serial (name); // Data presents ? bool presents = node != NULL; // Serial the flag MemStream.serial (presents); if (presents) { // Serial the buffer xmlNodePtr nodeXml = xmlNewDocNode (serialOutput.getDocument (), NULL, (const xmlChar*)"CLIPBOARD", NULL); xmlDocSetRootElement (serialOutput.getDocument (), nodeXml); // Struct type ? if (node) { if (array) { (safe_cast (node))->write (nodeXml, doc->getFormPtr(), NULL); } else { if (type == UFormDfn::EntryDfn) { (safe_cast (node))->write (nodeXml, doc->getFormPtr(), NULL); } else if (type == UFormDfn::EntryVirtualDfn) { (safe_cast (node))->write (nodeXml, doc->getFormPtr(), NULL); } else if (type == UFormDfn::EntryType) { (safe_cast (node))->write (nodeXml, doc->getFormPtr(), NULL); } } } else { (safe_cast (node))->write (nodeXml, doc->getFormPtr(), NULL); } } // Flush the XML stream serialOutput.flush (); // Debug test /* FILE *output = fopen ("c:\\toto.txt", "wb"); fwrite ((void*)MemStream.buffer (), 1, MemStream.length (), output); fclose (output); */ // Write to clipboard if (copyToClipboard) { // Is an array ? if (array) { ((CMainFrame*)m_pMainWnd)->dataToClipboard (FormClipBoardFormatArray, (void*)MemStream.buffer (), MemStream.length ()); } else { // Dfn ? if (type == UFormDfn::EntryDfn ) { ((CMainFrame*)m_pMainWnd)->dataToClipboard (FormClipBoardFormatStruct, (void*)MemStream.buffer (), MemStream.length ()); } // Virtual Dfn ? else if (parentDfn && type == UFormDfn::EntryVirtualDfn && !array) { ((CMainFrame*)m_pMainWnd)->dataToClipboard (FormClipBoardFormatVirtualStruct, (void*)MemStream.buffer (), MemStream.length ()); } // Type ? else // if (parentDfn && type == UFormDfn::EntryType && !array) { ((CMainFrame*)m_pMainWnd)->dataToClipboard (FormClipBoardFormatType, (void*)MemStream.buffer (), MemStream.length ()); } } } // Ok return true; } catch (Exception &) { nlstop; } // Not ok return false; } void CGeorgesEditApp::FillMemStreamWithBuffer (const uint8 *buffer, uint size) { // Input mode if (!theApp.MemStream.isReading ()) theApp.MemStream.invert (); // Init the stream theApp.MemStream.clear (); // Buffer to fill uint8 *bufferPtr = theApp.MemStream.bufferToFill (size); memcpy (bufferPtr, buffer, size); } bool CGeorgesEditApp::FillMemStreamWithClipboard (const char *formName, CGeorgesEditDoc *doc, uint slot) { // Input mode if (!theApp.MemStream.isReading ()) theApp.MemStream.invert (); // The form pointer CForm *form = doc->getFormPtr (); // Ok, get the node const CFormDfn *parentDfn; uint lastElement; const CFormDfn *nodeDfn; const CType *nodeType; CFormElm *node; UFormDfn::TEntryType type; bool array; bool parentVDfnArray; nlverify (((CFormElm*)doc->getRootNode(slot))->getNodeByName ( formName, &parentDfn, lastElement, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, NLGEORGES_FIRST_ROUND)); // Get the clipboard type UINT clipboardType; if (array) clipboardType = theApp.FormClipBoardFormatArray; else if (type == UFormDfn::EntryType) clipboardType = theApp.FormClipBoardFormatType; else if (type == UFormDfn::EntryDfn) clipboardType = theApp.FormClipBoardFormatStruct; else // if (type == UFormDfn::EntryVirtualDfn) clipboardType = theApp.FormClipBoardFormatVirtualStruct; // Get the clipboard size uint size; // Get the clipboard size if (((CMainFrame*)theApp.m_pMainWnd)->clipboardSize (clipboardType, size)) { // Init the stream theApp.MemStream.clear (); // Fill the input buffer uint8 *bufferPtr = theApp.MemStream.bufferToFill (size); nlverify (((CMainFrame*)theApp.m_pMainWnd)->dataFromClipboard (clipboardType, bufferPtr)); return true; } else return false; } bool CGeorgesEditApp::SerialFromMemStream (const char *formName, CGeorgesEditDoc *doc, uint slot) { // The form pointer CForm *form = doc->getFormPtr (); // Ok, get the node const CFormDfn *parentDfn; uint lastElement; const CFormDfn *nodeDfn; const CType *nodeType; CFormElm *node; UFormDfn::TEntryType type; bool array; bool parentVDfnArray; nlverify (((CFormElm*)(doc->getRootNode (slot)))->getNodeByName ( formName, &parentDfn, lastElement, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, NLGEORGES_FIRST_ROUND)); // Get the clipboard type UINT clipboardType; if (array) clipboardType = theApp.FormClipBoardFormatArray; else if (type == UFormDfn::EntryType) clipboardType = theApp.FormClipBoardFormatType; else if (type == UFormDfn::EntryDfn) clipboardType = theApp.FormClipBoardFormatStruct; else // if (type == UFormDfn::EntryVirtualDfn) clipboardType = theApp.FormClipBoardFormatVirtualStruct; // Catch some prb try { // Serial the string string nameParent; string name; if (parentDfn) nameParent = parentDfn->getEntry(lastElement).getFilename (); else { // Get the string CString str = doc->GetPathName (); nameParent = str; uint pos = nameParent.rfind ('.'); if (pos != string::npos) { // Keep the extension nameParent = nameParent.substr (pos+1); nameParent += ".dfn"; } } theApp.MemStream.serial (name); // Same DFN ? if (name == nameParent) { // Is in the clipboard bool present; theApp.MemStream.serial (present); // Is present if (present) { // Create the node bool created; nlverify (((CFormElm*)(doc->getRootNode (slot)))->createNodeByName ( formName, &parentDfn, lastElement, &nodeDfn, &nodeType, &node, type, array, created)); // For struct if (clipboardType == theApp.FormClipBoardFormatStruct) { // Struct pointer CFormElmStruct *formStruct = safe_cast((CFormElm*)node); // Create a serial CIXml serialInput; serialInput.init (theApp.MemStream); // Clean the node formStruct->clean (); // Serial it // Get first struct node xmlNodePtr nodeXml = CIXml::getFirstChildNode (serialInput.getRootNode (), "STRUCT"); if (nodeXml) { formStruct->read (nodeXml, doc->FormLoader, (CFormDfn*)nodeDfn, form); } } // For array else if (clipboardType == theApp.FormClipBoardFormatArray) { // Struct pointer CFormElmArray *formArray = safe_cast((CFormElm*)node); // Create a serial CIXml serialInput; serialInput.init (theApp.MemStream); // Clean the node formArray->clean (); // Serial it // Get first struct node xmlNodePtr nodeXml = CIXml::getFirstChildNode (serialInput.getRootNode (), "ARRAY"); if (nodeXml) { // Should be a type or a DFN nlassert ((nodeType) || (nodeDfn)); formArray->read (nodeXml, doc->FormLoader, form); } } // For atom else if (clipboardType == theApp.FormClipBoardFormatType) { // Struct pointer CFormElmAtom *formAtom = safe_cast((CFormElm*)node); // Create a serial CIXml serialInput; serialInput.init (theApp.MemStream); // Serial it // Get first struct node xmlNodePtr nodeXml = CIXml::getFirstChildNode (serialInput.getRootNode (), "ATOM"); if (nodeXml) { // Should be a type nlassert (nodeType); formAtom->read (nodeXml, doc->FormLoader, (CType*)nodeType, form); } } // For virtual struct else if (clipboardType == theApp.FormClipBoardFormatVirtualStruct) { // Struct pointer CFormElmVirtualStruct *vitualStruct = safe_cast((CFormElm*)node); // Create a serial CIXml serialInput; serialInput.init (theApp.MemStream); // Clean the node vitualStruct->clean (); // Serial it // Get first struct node xmlNodePtr nodeXml = CIXml::getFirstChildNode (serialInput.getRootNode (), "VSTRUCT"); if (nodeXml) { vitualStruct->read (nodeXml, doc->FormLoader, form); } } } // if (present) else { // Does the node exist ? // Ok, get the node const CFormDfn *parentDfn; uint lastElement; const CFormDfn *nodeDfn; const CType *nodeType; CFormElm *node; UFormDfn::TEntryType type; bool array; bool parentVDfnArray; if (((CFormElm*)(doc->getRootNode (slot)))->getNodeByName ( formName, &parentDfn, lastElement, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, NLGEORGES_FIRST_ROUND)) { // Delete the node if it exist in this form if (node && (node->getForm () == doc->getFormPtr ()) ) { nlverify (((CFormElm*)(doc->getRootNode (slot)))->deleteNodeByName ( formName, &parentDfn, lastElement, &nodeDfn, &nodeType, &node, type, array)); } } } // Not ok return true; } } catch (Exception &e) { nlwarning ("Error while paste: %s", e.what()); } // Not ok return false; } BOOL CGeorgesEditApp::OnDDECommand(LPTSTR lpszCommand) { if (strncmp (lpszCommand, "Open", 4) == 0) { string name = lpszCommand; name = name.substr (6, name.size ()-8); OpenDocumentFile (name.c_str ()); } else if (strncmp (lpszCommand, "Georges Copy", 4) == 0) { // Get ext name string name = lpszCommand; name = name.substr (6, name.size ()-8); // Get the extension char ext[MAX_PATH]; _splitpath (name.c_str (), NULL, NULL, NULL, ext); string dfnName = string (ext+1) + ".dfn"; // Get the doc template CMultiDocTemplate *docTemplate = getFormDocTemplate (dfnName.c_str ()); if (docTemplate) { // Create a new document CGeorgesEditDocForm *doc = (CGeorgesEditDocForm*)docTemplate->CreateNewDocument(); nlassert (doc); nlassert (doc->isForm ()); // Create the frame CFrameWnd* pFrame = docTemplate->CreateNewFrame(doc, NULL); nlassert (pFrame); if (doc->loadFormFile (name.c_str ())) { doc->updateDocumentStructure (); // Init the frame docTemplate->InitialUpdateFrame (pFrame, doc, TRUE); // Init the document if (doc->initDocument (dfnName.c_str (), false)) { doc->changeSubSelection ((CGeorgesEditDocSub *)NULL, NULL); doc->UpdateAllViews (NULL); } else { docTemplate->RemoveDocument( doc ); doc = NULL; char tmp[512]; smprintf (tmp, 512, "Can't open document '%s'.", name.c_str ()); outputError (tmp); } } else { docTemplate->RemoveDocument( doc ); doc = NULL; char tmp[512]; smprintf (tmp, 512, "Can't open document '%s'.", name.c_str ()); outputError (tmp); } } else { char tmp[512]; smprintf (tmp, 512, "Can't open document '%s'.", name.c_str ()); outputError (tmp); } } else if (strncmp (lpszCommand, "Derive", 6) == 0) { // Get ext name string name = lpszCommand; name = name.substr (8, name.size ()-10); // Get the extension char ext[MAX_PATH]; _splitpath (name.c_str (), NULL, NULL, NULL, ext); string dfnName = string (ext+1) + ".dfn"; // Create a document CGeorgesEditDocForm *doc = (CGeorgesEditDocForm*)createDocument (dfnName.c_str (), ""); if (doc) { char nameFile[MAX_PATH]; char extFile[MAX_PATH]; _splitpath (name.c_str (), NULL, NULL, nameFile, extFile); doc->addParent ((string (nameFile) + extFile).c_str ()); doc->updateDocumentStructure (); doc->UpdateAllViews (NULL); } else { char tmp[512]; smprintf (tmp, 512, "Can't derive from document '%s'.", name.c_str ()); outputError (tmp); } } else if (strncmp (lpszCommand, "CreateForm", 10) == 0) { // Get ext name string name = lpszCommand; name = name.substr (10, name.size ()-12); // Get the extension char name2[MAX_PATH]; char ext[MAX_PATH]; _splitpath (name.c_str (), NULL, NULL, name2, ext); string dfnName = name2; dfnName += ext; // Create a document CGeorgesEditDocForm *doc = (CGeorgesEditDocForm*)createDocument (dfnName.c_str (), ""); if (doc) { doc->updateDocumentStructure (); doc->UpdateAllViews (NULL); } else { char tmp[512]; smprintf (tmp, 512, "Can't create a file from dfn '%s'.", name.c_str ()); outputError (tmp); } } return CWinApp::OnDDECommand(lpszCommand); } CMultiDocTemplate *CGeorgesEditApp::getFormDocTemplate (const char *dfnName) { if (Superuser) { return _TemplateForm; } else { POSITION pos = GetFirstDocTemplatePosition (); while (pos) { // Get the template CMyMultiDocTemplate *docTemp = safe_cast (GetNextDocTemplate(pos)); // Check its dfn name std::string dfnNameTemplate; docTemp->getDfnName (dfnNameTemplate); if (dfnName == dfnNameTemplate) return docTemp; } } // Not found return NULL; }