From e8f584c7645ac60c29a6f728bfabdbd2f211e748 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Tue, 11 Aug 2009 23:55:57 +0000 Subject: [PATCH] [BUG_FIXED] Fix a crash issue due to tip feature (to check). [NEW_FEATURE] Add import plugins feature (load on the fly). [NEW_FEATURE] Add import theme (stylers.xml) feature. [ENHANCE] Prevent crash from some uncertain context. git-svn-id: svn://svn.tuxfamily.org/svnroot/notepadplus/repository/trunk@519 f5eea248-9336-0410-98b8-ebc06183d4e3 --- PowerEditor/src/MISC/Common/Common.cpp | 35 ++ PowerEditor/src/MISC/Common/Common.h | 2 +- .../MISC/PluginsManager/PluginsManager.cpp | 441 ++++++++++-------- .../src/MISC/PluginsManager/PluginsManager.h | 30 +- PowerEditor/src/Notepad_plus.cpp | 143 ++++-- PowerEditor/src/Notepad_plus.h | 1 + PowerEditor/src/Notepad_plus.rc | 8 +- PowerEditor/src/Parameters.cpp | 130 +++--- PowerEditor/src/Parameters.h | 32 +- .../WinControls/ColourPicker/WordStyleDlg.cpp | 12 +- .../WinControls/ColourPicker/WordStyleDlg.h | 18 +- PowerEditor/src/WinControls/Window.h | 8 +- PowerEditor/src/menuCmdID.h | 4 +- PowerEditor/src/resource.h | 6 + 14 files changed, 532 insertions(+), 338 deletions(-) diff --git a/PowerEditor/src/MISC/Common/Common.cpp b/PowerEditor/src/MISC/Common/Common.cpp index c17f61d58..85dc41a41 100644 --- a/PowerEditor/src/MISC/Common/Common.cpp +++ b/PowerEditor/src/MISC/Common/Common.cpp @@ -484,3 +484,38 @@ generic_string PathRemoveFileSpec(generic_string & path) } return path; } + +generic_string PathAppend(generic_string &strDest, const generic_string str2append) +{ + if (strDest == TEXT("") && str2append == TEXT("")) // "" + "" + { + strDest = TEXT("\\"); + return strDest; + } + + if (strDest == TEXT("") && str2append != TEXT("")) // "" + titi + { + strDest = str2append; + return strDest; + } + + if (strDest[strDest.length() - 1] == '\\' && (str2append != TEXT("") && str2append[0] == '\\')) // toto\ + \titi + { + strDest.erase(strDest.length() - 1, 1); + strDest += str2append; + return strDest; + } + + if ((strDest[strDest.length() - 1] == '\\' && (str2append != TEXT("") && str2append[0] != '\\')) // toto\ + titi + || (strDest[strDest.length() - 1] != '\\' && (str2append != TEXT("") && str2append[0] == '\\'))) // toto + \titi + { + strDest += str2append; + return strDest; + } + + // toto + titi + strDest += TEXT("\\"); + strDest += str2append; + + return strDest; +} diff --git a/PowerEditor/src/MISC/Common/Common.h b/PowerEditor/src/MISC/Common/Common.h index b907115b7..5a851e168 100644 --- a/PowerEditor/src/MISC/Common/Common.h +++ b/PowerEditor/src/MISC/Common/Common.h @@ -139,6 +139,6 @@ private: #endif generic_string PathRemoveFileSpec(generic_string & path); - +generic_string PathAppend(generic_string &strDest, const generic_string str2append); #endif //M30_IDE_COMMUN_H diff --git a/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp b/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp index 8b7b6342a..776790a5e 100644 --- a/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp +++ b/PowerEditor/src/MISC/PluginsManager/PluginsManager.cpp @@ -21,6 +21,195 @@ const TCHAR * USERMSG = TEXT("This plugin is not compatible with current version of Notepad++.\n\n\ Do you want to remove this plugin from plugins directory to prevent this message from the next launch time?"); +bool PluginsManager::unloadPlugin(int index, HWND nppHandle) +{ + SCNotification scnN; + scnN.nmhdr.code = NPPN_SHUTDOWN; + scnN.nmhdr.hwndFrom = nppHandle; + scnN.nmhdr.idFrom = 0; + _pluginInfos[index]->_pBeNotified(&scnN); + + //::DestroyMenu(_pluginInfos[index]->_pluginMenu); + //_pluginInfos[index]->_pluginMenu = NULL; + + if (::FreeLibrary(_pluginInfos[index]->_hLib)) + _pluginInfos[index]->_hLib = NULL; + else + printStr(TEXT("not ok")); + //delete _pluginInfos[index]; +// printInt(index); + //vector::iterator it = _pluginInfos.begin() + index; + //_pluginInfos.erase(it); + //printStr(TEXT("remove")); + return true; +} + +int PluginsManager::loadPlugin(const TCHAR *pluginFilePath, vector & dll2Remove) +{ + PluginInfo *pi = new PluginInfo; + try { + pi->_moduleName = PathFindFileName(pluginFilePath); + + pi->_hLib = ::LoadLibrary(pluginFilePath); + if (!pi->_hLib) + throw generic_string(TEXT("Load Library is failed.\nMake \"Runtime Library\" setting of this project as \"Multi-threaded(/MT)\" may cure this problem.")); + + pi->_pFuncIsUnicode = (PFUNCISUNICODE)GetProcAddress(pi->_hLib, "isUnicode"); +#ifdef UNICODE + if (!pi->_pFuncIsUnicode || !pi->_pFuncIsUnicode()) + throw generic_string(TEXT("This ANSI plugin is not compatible with your Unicode Notepad++.")); +#else + if (pi->_pFuncIsUnicode) + throw generic_string(TEXT("This Unicode plugin is not compatible with your ANSI mode Notepad++.")); +#endif + + pi->_pFuncSetInfo = (PFUNCSETINFO)GetProcAddress(pi->_hLib, "setInfo"); + + if (!pi->_pFuncSetInfo) + throw generic_string(TEXT("Missing \"setInfo\" function")); + + pi->_pFuncGetName = (PFUNCGETNAME)GetProcAddress(pi->_hLib, "getName"); + if (!pi->_pFuncGetName) + throw generic_string(TEXT("Missing \"getName\" function")); + + pi->_pBeNotified = (PBENOTIFIED)GetProcAddress(pi->_hLib, "beNotified"); + if (!pi->_pBeNotified) + throw generic_string(TEXT("Missing \"beNotified\" function")); + + pi->_pMessageProc = (PMESSAGEPROC)GetProcAddress(pi->_hLib, "messageProc"); + if (!pi->_pMessageProc) + throw generic_string(TEXT("Missing \"messageProc\" function")); + + pi->_pFuncSetInfo(_nppData); + + pi->_pFuncGetFuncsArray = (PFUNCGETFUNCSARRAY)GetProcAddress(pi->_hLib, "getFuncsArray"); + if (!pi->_pFuncGetFuncsArray) + throw generic_string(TEXT("Missing \"getFuncsArray\" function")); + + pi->_funcItems = pi->_pFuncGetFuncsArray(&pi->_nbFuncItem); + + if ((!pi->_funcItems) || (pi->_nbFuncItem <= 0)) + throw generic_string(TEXT("Missing \"FuncItems\" array, or the nb of Function Item is not set correctly")); + + pi->_pluginMenu = ::CreateMenu(); + + GetLexerCountFn GetLexerCount = (GetLexerCountFn)::GetProcAddress(pi->_hLib, "GetLexerCount"); + // it's a lexer plugin + if (GetLexerCount) + { + GetLexerNameFn GetLexerName = (GetLexerNameFn)::GetProcAddress(pi->_hLib, "GetLexerName"); + if (!GetLexerName) + throw generic_string(TEXT("Loading GetLexerName function failed.")); + + GetLexerStatusTextFn GetLexerStatusText = (GetLexerStatusTextFn)::GetProcAddress(pi->_hLib, "GetLexerStatusText"); + + if (!GetLexerStatusText) + throw generic_string(TEXT("Loading GetLexerStatusText function failed.")); + + // Assign a buffer for the lexer name. + char lexName[MAX_EXTERNAL_LEXER_NAME_LEN]; + lexName[0] = '\0'; + TCHAR lexDesc[MAX_EXTERNAL_LEXER_DESC_LEN]; + lexDesc[0] = '\0'; + + int numLexers = GetLexerCount(); + + NppParameters * nppParams = NppParameters::getInstance(); + + ExternalLangContainer *containers[30]; +#ifdef UNICODE + WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); +#endif + for (int x = 0; x < numLexers; x++) + { + GetLexerName(x, lexName, MAX_EXTERNAL_LEXER_NAME_LEN); + GetLexerStatusText(x, lexDesc, MAX_EXTERNAL_LEXER_DESC_LEN); +#ifdef UNICODE + const TCHAR *pLexerName = wmc->char2wchar(lexName, CP_ACP); +#else + const TCHAR *pLexerName = lexName; +#endif + if (!nppParams->isExistingExternalLangName(pLexerName) && nppParams->ExternalLangHasRoom()) + containers[x] = new ExternalLangContainer(pLexerName, lexDesc); + else + containers[x] = NULL; + } + + TCHAR xmlPath[MAX_PATH]; + lstrcpy(xmlPath, nppParams->getNppPath().c_str()); + PathAppend(xmlPath, TEXT("plugins\\Config")); + PathAppend(xmlPath, pi->_moduleName.c_str()); + PathRemoveExtension(xmlPath); + PathAddExtension(xmlPath, TEXT(".xml")); + + if (!PathFileExists(xmlPath)) + { + lstrcpyn(xmlPath, TEXT("\0"), MAX_PATH ); + lstrcpy(xmlPath, nppParams->getAppDataNppDir() ); + PathAppend(xmlPath, TEXT("plugins\\Config")); + PathAppend(xmlPath, pi->_moduleName.c_str()); + PathRemoveExtension( xmlPath ); + PathAddExtension( xmlPath, TEXT(".xml") ); + + if (! PathFileExists( xmlPath ) ) + { + throw generic_string(generic_string(xmlPath) + TEXT(" is missing.")); + } + } + + TiXmlDocument *_pXmlDoc = new TiXmlDocument(xmlPath); + + if (!_pXmlDoc->LoadFile()) + { + delete _pXmlDoc; + _pXmlDoc = NULL; + throw generic_string(generic_string(xmlPath) + TEXT(" failed to load.")); + } + + for (int x = 0; x < numLexers; x++) // postpone adding in case the xml is missing/corrupt + if (containers[x] != NULL) + nppParams->addExternalLangToEnd(containers[x]); + + nppParams->getExternalLexerFromXmlTree(_pXmlDoc); + nppParams->getExternalLexerDoc()->push_back(_pXmlDoc); +#ifdef UNICODE + const char *pDllName = wmc->wchar2char(pluginFilePath, CP_ACP); +#else + const char *pDllName = pluginFilePath; +#endif + ::SendMessage(_nppData._scintillaMainHandle, SCI_LOADLEXERLIBRARY, 0, (LPARAM)pDllName); + + } + + _pluginInfos.push_back(pi); + return (_pluginInfos.size() - 1); + } + catch(generic_string s) + { + s += TEXT("\n\n"); + s += USERMSG; + if (::MessageBox(NULL, s.c_str(), pluginFilePath, MB_YESNO) == IDYES) + { + dll2Remove.push_back(pluginFilePath); + } + delete pi; + return -1; + } + catch(...) + { + generic_string msg = TEXT("Fail loaded"); + msg += TEXT("\n\n"); + msg += USERMSG; + if (::MessageBox(NULL, msg.c_str(), pluginFilePath, MB_YESNO) == IDYES) + { + dll2Remove.push_back(pluginFilePath); + } + delete pi; + return -1; + } +} + + bool PluginsManager::loadPlugins(const TCHAR *dir) { if (_isDisabled) @@ -28,7 +217,7 @@ bool PluginsManager::loadPlugins(const TCHAR *dir) vector dllNames; vector dll2Remove; - generic_string nppPath = (NppParameters::getInstance())->getNppPath(); + generic_string nppPath = (NppParameters::getInstance())->getNppPath(); generic_string pluginsFullPathFilter = (dir && dir[0])?dir:nppPath; @@ -56,165 +245,9 @@ bool PluginsManager::loadPlugins(const TCHAR *dir) for ( ; i < dllNames.size() ; i++) { - PluginInfo *pi = new PluginInfo; - try { - TCHAR tmpStr[MAX_PATH]; - lstrcpy(tmpStr, dllNames[i].c_str()); - lstrcpy(pi->_moduleName, PathFindFileName(tmpStr)); - - pi->_hLib = ::LoadLibrary(dllNames[i].c_str()); - if (!pi->_hLib) - throw generic_string(TEXT("Load Library is failed.\nMake \"Runtime Library\" setting of this project as \"Multi-threaded(/MT)\" may cure this problem.")); - - pi->_pFuncIsUnicode = (PFUNCISUNICODE)GetProcAddress(pi->_hLib, "isUnicode"); -#ifdef UNICODE - if (!pi->_pFuncIsUnicode || !pi->_pFuncIsUnicode()) - throw generic_string(TEXT("This ANSI plugin is not compatible with your Unicode Notepad++.")); -#else - if (pi->_pFuncIsUnicode) - throw generic_string(TEXT("This Unicode plugin is not compatible with your ANSI mode Notepad++.")); -#endif - - pi->_pFuncSetInfo = (PFUNCSETINFO)GetProcAddress(pi->_hLib, "setInfo"); - - if (!pi->_pFuncSetInfo) - throw generic_string(TEXT("Missing \"setInfo\" function")); - - pi->_pFuncGetName = (PFUNCGETNAME)GetProcAddress(pi->_hLib, "getName"); - if (!pi->_pFuncGetName) - throw generic_string(TEXT("Missing \"getName\" function")); - - pi->_pBeNotified = (PBENOTIFIED)GetProcAddress(pi->_hLib, "beNotified"); - if (!pi->_pBeNotified) - throw generic_string(TEXT("Missing \"beNotified\" function")); - - pi->_pMessageProc = (PMESSAGEPROC)GetProcAddress(pi->_hLib, "messageProc"); - if (!pi->_pMessageProc) - throw generic_string(TEXT("Missing \"messageProc\" function")); - - pi->_pFuncSetInfo(_nppData); - - pi->_pFuncGetFuncsArray = (PFUNCGETFUNCSARRAY)GetProcAddress(pi->_hLib, "getFuncsArray"); - if (!pi->_pFuncGetFuncsArray) - throw generic_string(TEXT("Missing \"getFuncsArray\" function")); - - pi->_funcItems = pi->_pFuncGetFuncsArray(&pi->_nbFuncItem); - - if ((!pi->_funcItems) || (pi->_nbFuncItem <= 0)) - throw generic_string(TEXT("Missing \"FuncItems\" array, or the nb of Function Item is not set correctly")); - - pi->_pluginMenu = ::CreateMenu(); - - GetLexerCountFn GetLexerCount = (GetLexerCountFn)::GetProcAddress(pi->_hLib, "GetLexerCount"); - // it's a lexer plugin - if (GetLexerCount) - { - GetLexerNameFn GetLexerName = (GetLexerNameFn)::GetProcAddress(pi->_hLib, "GetLexerName"); - if (!GetLexerName) - throw generic_string(TEXT("Loading GetLexerName function failed.")); - - GetLexerStatusTextFn GetLexerStatusText = (GetLexerStatusTextFn)::GetProcAddress(pi->_hLib, "GetLexerStatusText"); - - if (!GetLexerStatusText) - throw generic_string(TEXT("Loading GetLexerStatusText function failed.")); - - // Assign a buffer for the lexer name. - char lexName[MAX_EXTERNAL_LEXER_NAME_LEN]; - lexName[0] = '\0'; - TCHAR lexDesc[MAX_EXTERNAL_LEXER_DESC_LEN]; - lstrcpy(lexDesc, TEXT("")); - - int numLexers = GetLexerCount(); - - NppParameters * nppParams = NppParameters::getInstance(); - - ExternalLangContainer *containers[30]; -#ifdef UNICODE - WcharMbcsConvertor *wmc = WcharMbcsConvertor::getInstance(); -#endif - for (int x = 0; x < numLexers; x++) - { - GetLexerName(x, lexName, MAX_EXTERNAL_LEXER_NAME_LEN); - GetLexerStatusText(x, lexDesc, MAX_EXTERNAL_LEXER_DESC_LEN); -#ifdef UNICODE - const TCHAR *pLexerName = wmc->char2wchar(lexName, CP_ACP); -#else - const TCHAR *pLexerName = lexName; -#endif - if (!nppParams->isExistingExternalLangName(pLexerName) && nppParams->ExternalLangHasRoom()) - containers[x] = new ExternalLangContainer(pLexerName, lexDesc); - else - containers[x] = NULL; - } - - TCHAR xmlPath[MAX_PATH]; - lstrcpy(xmlPath, nppParams->getNppPath().c_str()); - PathAppend(xmlPath, TEXT("plugins\\Config")); - PathAppend(xmlPath, pi->_moduleName); - PathRemoveExtension(xmlPath); - PathAddExtension(xmlPath, TEXT(".xml")); - - if (!PathFileExists(xmlPath)) - { - lstrcpyn( xmlPath, TEXT("\0"), MAX_PATH ); - lstrcpy( xmlPath, nppParams->getAppDataNppDir() ); - PathAppend(xmlPath, TEXT("plugins\\Config")); - PathAppend( xmlPath, pi->_moduleName ); - PathRemoveExtension( xmlPath ); - PathAddExtension( xmlPath, TEXT(".xml") ); - - if (! PathFileExists( xmlPath ) ) - { - throw generic_string(generic_string(xmlPath) + TEXT(" is missing.")); - } - } - - TiXmlDocument *_pXmlDoc = new TiXmlDocument(xmlPath); - - if (!_pXmlDoc->LoadFile()) - { - delete _pXmlDoc; - _pXmlDoc = NULL; - throw generic_string(generic_string(xmlPath) + TEXT(" failed to load.")); - } - - for (int x = 0; x < numLexers; x++) // postpone adding in case the xml is missing/corrupt - if (containers[x] != NULL) - nppParams->addExternalLangToEnd(containers[x]); - - nppParams->getExternalLexerFromXmlTree(_pXmlDoc); - nppParams->getExternalLexerDoc()->push_back(_pXmlDoc); -#ifdef UNICODE - const char *pDllName = wmc->wchar2char(dllNames[i].c_str(), CP_ACP); -#else - const char *pDllName = dllNames[i].c_str(); -#endif - ::SendMessage(_nppData._scintillaMainHandle, SCI_LOADLEXERLIBRARY, 0, (LPARAM)pDllName); - } - _pluginInfos.push_back(pi); - } - catch(generic_string s) - { - s += TEXT("\n\n"); - s += USERMSG; - if (::MessageBox(NULL, s.c_str(), dllNames[i].c_str(), MB_YESNO) == IDYES) - { - dll2Remove.push_back(dllNames[i]); - } - delete pi; - } - catch(...) - { - generic_string msg = TEXT("Fail loaded"); - msg += TEXT("\n\n"); - msg += USERMSG; - if (::MessageBox(NULL, msg.c_str(), dllNames[i].c_str(), MB_YESNO) == IDYES) - { - dll2Remove.push_back(dllNames[i]); - } - delete pi; - } + loadPlugin(dllNames[i].c_str(), dll2Remove); } + } for (size_t j = 0 ; j < dll2Remove.size() ; j++) @@ -250,52 +283,68 @@ bool PluginsManager::getShortcutByCmdID(int cmdID, ShortcutKey *sk) return false; } + +void PluginsManager::addInMenuFromPMIndex(int i) +{ + vector & pluginCmdSCList = (NppParameters::getInstance())->getPluginCommandList(); + ::InsertMenu(_hPluginsMenu, i, MF_BYPOSITION | MF_POPUP, (UINT_PTR)_pluginInfos[i]->_pluginMenu, _pluginInfos[i]->_pFuncGetName()); + + unsigned short j = 0; + for ( ; j < _pluginInfos[i]->_nbFuncItem ; j++) + { + if (_pluginInfos[i]->_funcItems[j]._pFunc == NULL) + { + ::InsertMenu(_pluginInfos[i]->_pluginMenu, j, MF_BYPOSITION | MF_SEPARATOR, 0, TEXT("")); + continue; + } + + _pluginsCommands.push_back(PluginCommand(_pluginInfos[i]->_moduleName.c_str(), j, _pluginInfos[i]->_funcItems[j]._pFunc)); + + int cmdID = ID_PLUGINS_CMD + (_pluginsCommands.size() - 1); + _pluginInfos[i]->_funcItems[j]._cmdID = cmdID; + generic_string itemName = _pluginInfos[i]->_funcItems[j]._itemName; + + if (_pluginInfos[i]->_funcItems[j]._pShKey) + { + ShortcutKey & sKey = *(_pluginInfos[i]->_funcItems[j]._pShKey); + PluginCmdShortcut pcs(Shortcut(itemName.c_str(), sKey._isCtrl, sKey._isAlt, sKey._isShift, sKey._key), cmdID, _pluginInfos[i]->_moduleName.c_str(), j); + pluginCmdSCList.push_back(pcs); + itemName += TEXT("\t"); + itemName += pcs.toString(); + } + else + { //no ShortcutKey is provided, add an disabled shortcut (so it can still be mapped, Paramaters class can still index any changes and the toolbar wont funk out + Shortcut sc(itemName.c_str(), false, false, false, 0x00); + PluginCmdShortcut pcs(sc, cmdID, _pluginInfos[i]->_moduleName.c_str(), j); //VK_NULL and everything disabled, the menu name is left alone + pluginCmdSCList.push_back(pcs); + } + ::InsertMenu(_pluginInfos[i]->_pluginMenu, j, MF_BYPOSITION, cmdID, itemName.c_str()); + + if (_pluginInfos[i]->_funcItems[j]._init2Check) + ::CheckMenuItem(_hPluginsMenu, cmdID, MF_BYCOMMAND | MF_CHECKED); + } + /*UNLOAD + ::InsertMenu(_pluginInfos[i]->_pluginMenu, j++, MF_BYPOSITION | MF_SEPARATOR, 0, TEXT("")); + ::InsertMenu(_pluginInfos[i]->_pluginMenu, j, MF_BYPOSITION, ID_PLUGINS_REMOVING + i, TEXT("Remove this plugin")); + */ +} + void PluginsManager::setMenu(HMENU hMenu, const TCHAR *menuName) { if (hasPlugins()) { - vector & pluginCmdSCList = (NppParameters::getInstance())->getPluginCommandList(); + //vector & pluginCmdSCList = (NppParameters::getInstance())->getPluginCommandList(); const TCHAR *nom_menu = (menuName && menuName[0])?menuName:TEXT("Plugins"); - _hPluginsMenu = ::CreateMenu(); - ::InsertMenu(hMenu, 9, MF_BYPOSITION | MF_POPUP, (UINT_PTR)_hPluginsMenu, nom_menu); + if (!_hPluginsMenu) + { + _hPluginsMenu = ::CreateMenu(); + ::InsertMenu(hMenu, 9, MF_BYPOSITION | MF_POPUP, (UINT_PTR)_hPluginsMenu, nom_menu); + } for (size_t i = 0 ; i < _pluginInfos.size() ; i++) { - ::InsertMenu(_hPluginsMenu, i, MF_BYPOSITION | MF_POPUP, (UINT_PTR)_pluginInfos[i]->_pluginMenu, _pluginInfos[i]->_pFuncGetName()); - - for (int j = 0 ; j < _pluginInfos[i]->_nbFuncItem ; j++) - { - if (_pluginInfos[i]->_funcItems[j]._pFunc == NULL) - { - ::InsertMenu(_pluginInfos[i]->_pluginMenu, j, MF_BYPOSITION | MF_SEPARATOR, 0, TEXT("")); - continue; - } - - _pluginsCommands.push_back(PluginCommand(_pluginInfos[i]->_moduleName, j, _pluginInfos[i]->_funcItems[j]._pFunc)); - - int cmdID = ID_PLUGINS_CMD + (_pluginsCommands.size() - 1); - _pluginInfos[i]->_funcItems[j]._cmdID = cmdID; - generic_string itemName = _pluginInfos[i]->_funcItems[j]._itemName; - - if (_pluginInfos[i]->_funcItems[j]._pShKey) - { - ShortcutKey & sKey = *(_pluginInfos[i]->_funcItems[j]._pShKey); - PluginCmdShortcut pcs(Shortcut(itemName.c_str(), sKey._isCtrl, sKey._isAlt, sKey._isShift, sKey._key), cmdID, _pluginInfos[i]->_moduleName, (unsigned short)j); - pluginCmdSCList.push_back(pcs); - itemName += TEXT("\t"); - itemName += pcs.toString(); - } - else - { //no ShortcutKey is provided, add an disabled shortcut (so it can still be mapped, Paramaters class can still index any changes and the toolbar wont funk out - PluginCmdShortcut pcs(Shortcut(itemName.c_str(), false, false, false, 0x00), cmdID, _pluginInfos[i]->_moduleName, (unsigned short)j); //VK_NULL and everything disabled, the menu name is left alone - pluginCmdSCList.push_back(pcs); - } - ::InsertMenu(_pluginInfos[i]->_pluginMenu, j, MF_BYPOSITION, cmdID, itemName.c_str()); - - if (_pluginInfos[i]->_funcItems[j]._init2Check) - ::CheckMenuItem(_hPluginsMenu, cmdID, MF_BYCOMMAND | MF_CHECKED); - } + addInMenuFromPMIndex(i); } } } diff --git a/PowerEditor/src/MISC/PluginsManager/PluginsManager.h b/PowerEditor/src/MISC/PluginsManager/PluginsManager.h index 260fcbd63..f9178a3e9 100644 --- a/PowerEditor/src/MISC/PluginsManager/PluginsManager.h +++ b/PowerEditor/src/MISC/PluginsManager/PluginsManager.h @@ -55,7 +55,7 @@ struct PluginInfo { FuncItem *_funcItems; int _nbFuncItem; - TCHAR _moduleName[64]; + generic_string _moduleName; }; class PluginsManager { @@ -72,8 +72,12 @@ public: void init(const NppData & nppData) { _nppData = nppData; }; + + int loadPlugin(const TCHAR *pluginFilePath, vector & dll2Remove); bool loadPlugins(const TCHAR *dir = NULL); + bool unloadPlugin(int index, HWND nppHandle); + void runPluginCommand(size_t i) { if (i < _pluginsCommands.size()) if (_pluginsCommands[i]._pFunc != NULL) @@ -91,23 +95,28 @@ public: } }; + void addInMenuFromPMIndex(int i); void setMenu(HMENU hMenu, const TCHAR *menuName); bool getShortcutByCmdID(int cmdID, ShortcutKey *sk); void notify(SCNotification *notification) { for (size_t i = 0 ; i < _pluginInfos.size() ; i++) { - // To avoid the plugin change the data in SCNotification - // Each notification to pass to a plugin is a copy of SCNotification instance - SCNotification scNotif = *notification; - _pluginInfos[i]->_pBeNotified(&scNotif); + if (_pluginInfos[i]->_hLib) + { + // To avoid the plugin change the data in SCNotification + // Each notification to pass to a plugin is a copy of SCNotification instance + SCNotification scNotif = *notification; + _pluginInfos[i]->_pBeNotified(&scNotif); + } } }; void relayNppMessages(UINT Message, WPARAM wParam, LPARAM lParam) { for (size_t i = 0 ; i < _pluginInfos.size() ; i++) { - _pluginInfos[i]->_pMessageProc(Message, wParam, lParam); + if (_pluginInfos[i]->_hLib) + _pluginInfos[i]->_pMessageProc(Message, wParam, lParam); } }; @@ -118,10 +127,13 @@ public: for (size_t i = 0 ; i < _pluginInfos.size() ; i++) { - if (generic_stricmp(_pluginInfos[i]->_moduleName, moduleName) == 0) + if (_pluginInfos[i]->_moduleName == moduleName) { - _pluginInfos[i]->_pMessageProc(Message, wParam, lParam); - return true; + if (_pluginInfos[i]->_hLib) + { + _pluginInfos[i]->_pMessageProc(Message, wParam, lParam); + return true; + } } } return false; diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 4f0b6f722..eff6e0a69 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -74,7 +74,6 @@ Notepad_plus::Notepad_plus(): Window(), _mainWindowStatus(0), _pDocTab(NULL), _p _autoCompleteMain(&_mainEditView), _autoCompleteSub(&_subEditView), _smartHighlighter(&_findReplaceDlg), _nativeLangEncoding(CP_ACP), _isFileOpening(false) { - ZeroMemory(&_prevSelectedRange, sizeof(_prevSelectedRange)); _winVersion = (NppParameters::getInstance())->getWinVersion(); @@ -300,15 +299,13 @@ void Notepad_plus::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdL vector fileNames; vector patterns; patterns.push_back(TEXT("*.xml")); - - generic_string nppDir(pNppParams->getNppPath()); - ::PathRemoveFileSpec(nppDir); - + + generic_string nppDir = pNppParams->getNppPath(); #ifdef UNICODE LocalizationSwitcher & localizationSwitcher = pNppParams->getLocalizationSwitcher(); - wstring localizationDir = nppDir.c_str(); - - localizationDir += TEXT("\\localization\\"); + wstring localizationDir = nppDir; + PathAppend(localizationDir, TEXT("localization\\")); + getMatchedFileNames(localizationDir.c_str(), patterns, fileNames, false, false); for (size_t i = 0 ; i < fileNames.size() ; i++) { @@ -322,7 +319,7 @@ void Notepad_plus::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdL // Get themes from both npp install themes dir and app data themes dir with the per user // overriding default themes of the same name. generic_string themeDir(pNppParams->getAppDataNppDir()); - themeDir.append(TEXT("\\themes\\")); + PathAppend(themeDir, TEXT("themes\\")); getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false); for (size_t i = 0 ; i < fileNames.size() ; i++) @@ -333,7 +330,7 @@ void Notepad_plus::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdL fileNames.clear(); themeDir.clear(); themeDir = nppDir.c_str(); // <- should use the pointer to avoid the constructor of copy - themeDir.append(TEXT("\\themes\\")); + PathAppend(themeDir, TEXT("themes\\")); getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false); for (size_t i = 0 ; i < fileNames.size() ; i++) { @@ -2621,30 +2618,35 @@ BOOL Notepad_plus::notify(SCNotification *notification) ::GetCursorPos(&p); ::ScreenToClient(_hSelf, &p); HWND hWin = ::RealChildWindowFromPoint(_hSelf, p); - - static generic_string tip = TEXT(""); + const int tipMaxLen = 1024; + static TCHAR tip[tipMaxLen]; + tip[0] = '\0'; + generic_string tipTmp(TEXT("")); int id = int(lpttt->hdr.idFrom); if (hWin == _rebarTop.getHSelf()) { - getNameStrFromCmd(id, tip); + getNameStrFromCmd(id, tipTmp); } else if (hWin == _mainDocTab.getHSelf()) { BufferID idd = _mainDocTab.getBufferByIndex(id); Buffer * buf = MainFileManager->getBufferByID(idd); - tip = buf->getFullPathName(); + tipTmp = buf->getFullPathName(); } else if (hWin == _subDocTab.getHSelf()) { BufferID idd = _subDocTab.getBufferByIndex(id); Buffer * buf = MainFileManager->getBufferByID(idd); - tip = buf->getFullPathName(); + tipTmp = buf->getFullPathName(); } else break; - lpttt->lpszText = (TCHAR *)tip.c_str(); + if (tipTmp.length() < tipMaxLen) + lstrcpy(tip, tipTmp.c_str()); + + lpttt->lpszText = tip; } break; @@ -4197,13 +4199,55 @@ void Notepad_plus::command(int id) break; } - case IDM_SETTING_FILEASSOCIATION_DLG : - { - RegExtDlg regExtDlg; - regExtDlg.init(_hInst, _hSelf); - regExtDlg.doDialog(_isRTL); - break; - } + case IDM_SETTING_IMPORTPLUGIN : + { + // get plugin source path + TCHAR *extFilterName = TEXT("Notepad++ pligin"); + TCHAR *extFilter = TEXT(".dll"); + TCHAR *destDir = TEXT("plugins"); + + vector copiedFiles = addNppComponents(destDir, extFilterName, extFilter); + + // load plugin + vector dll2Remove; + for (size_t i = 0 ; i < copiedFiles.size() ; i++) + { + int index = _pluginsManager.loadPlugin(copiedFiles[i].c_str(), dll2Remove); + if (_pluginsManager.getMenuHandle()) + _pluginsManager.addInMenuFromPMIndex(index); + } + if (!_pluginsManager.getMenuHandle()) + _pluginsManager.setMenu(_mainMenuHandle, NULL); + ::DrawMenuBar(_hSelf); + break; + } + + case IDM_SETTING_IMPORTSTYLETHEMS : + { + // get plugin source path + TCHAR *extFilterName = TEXT("Notepad++ style theme"); + TCHAR *extFilter = TEXT(".xml"); + TCHAR *destDir = TEXT("themes"); + + // load styler + NppParameters *pNppParams = NppParameters::getInstance(); + ThemeSwitcher & themeSwitcher = pNppParams->getThemeSwitcher(); + + vector copiedFiles = addNppComponents(destDir, extFilterName, extFilter); + for (size_t i = 0 ; i < copiedFiles.size() ; i++) + { + generic_string themeName(themeSwitcher.getThemeFromXmlFileName(copiedFiles[i].c_str())); + if (!themeSwitcher.themeNameExists(themeName.c_str())) + { + themeSwitcher.addThemeFromXml(copiedFiles[i].c_str()); + if (_configStyleDlg.isCreated()) + { + _configStyleDlg.addLastThemeEntry(); + } + } + } + break; + } case IDM_SETTING_SHORTCUT_MAPPER : { @@ -4287,7 +4331,6 @@ void Notepad_plus::command(int id) case IDM_HELP : { generic_string tmp((NppParameters::getInstance())->getNppPath()); - ::PathRemoveFileSpec(tmp); generic_string nppHelpPath = tmp.c_str(); nppHelpPath += TEXT("\\NppHelp.chm"); @@ -4340,8 +4383,11 @@ void Notepad_plus::command(int id) case IDM_UPDATE_NPP : { generic_string updaterDir = (NppParameters::getInstance())->getNppPath(); - updaterDir += TEXT("\\updater\\"); - generic_string updaterFullPath = updaterDir + TEXT("gup.exe"); + PathAppend(updaterDir ,TEXT("updater")); + + generic_string updaterFullPath = updaterDir; + PathAppend(updaterFullPath, TEXT("gup.exe")); + generic_string param = TEXT("-verbose -v"); param += VERSION_VALUE; Process updater(updaterFullPath.c_str(), param.c_str(), updaterDir.c_str()); @@ -4540,6 +4586,13 @@ void Notepad_plus::command(int id) int i = id - ID_PLUGINS_CMD; _pluginsManager.runPluginCommand(i); } +/*UNLOAD + else if ((id >= ID_PLUGINS_REMOVING) && (id < ID_PLUGINS_REMOVING_END)) + { + int i = id - ID_PLUGINS_REMOVING; + _pluginsManager.unloadPlugin(i, _hSelf); + } +*/ else if ((id >= IDM_WINDOW_MRU_FIRST) && (id <= IDM_WINDOW_MRU_LIMIT)) { activateDoc(id-IDM_WINDOW_MRU_FIRST); @@ -9938,3 +9991,41 @@ void Notepad_plus::setFindReplaceFolderFilter(const TCHAR *dir, const TCHAR *fil } _findReplaceDlg.setFindInFilesDirFilter(dir, filter); } + +vector Notepad_plus::addNppComponents(const TCHAR *destDir, const TCHAR *extFilterName, const TCHAR *extFilter) +{ + FileDialog fDlg(_hSelf, _hInst); + fDlg.setExtFilter(extFilterName, extFilter, NULL); + + //setFileOpenSaveDlgFilters(fDlg); + vector copiedFiles; + + if (stringVector *pfns = fDlg.doOpenMultiFilesDlg()) + { + // Get plugins dir + generic_string destDirName = (NppParameters::getInstance())->getNppPath(); + PathAppend(destDirName, destDir); + + if (!::PathFileExists(destDirName.c_str())) + { + ::CreateDirectory(destDirName.c_str(), NULL); + } + + destDirName += TEXT("\\"); + + size_t sz = pfns->size(); + for (size_t i = 0 ; i < sz ; i++) + { + if (::PathFileExists(pfns->at(i).c_str())) + { + // copy to plugins directory + generic_string destName = destDirName; + destName += ::PathFindFileName(pfns->at(i).c_str()); + //printStr(destName.c_str()); + if (::CopyFile(pfns->at(i).c_str(), destName.c_str(), FALSE)) + copiedFiles.push_back(destName.c_str()); + } + } + } + return copiedFiles; +} diff --git a/PowerEditor/src/Notepad_plus.h b/PowerEditor/src/Notepad_plus.h index 446f33ba8..b4cc3c15b 100644 --- a/PowerEditor/src/Notepad_plus.h +++ b/PowerEditor/src/Notepad_plus.h @@ -220,6 +220,7 @@ public: bool findInFiles(); bool replaceInFiles(); void setFindReplaceFolderFilter(const TCHAR *dir, const TCHAR *filters); + vector addNppComponents(const TCHAR *destDir, const TCHAR *extFilterName, const TCHAR *extFilter); static HWND gNppHWND; //static handle to Notepad++ window, NULL if non-existant private: diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index 58c5f6768..129fa6d4e 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -539,7 +539,13 @@ BEGIN BEGIN MENUITEM "Preferences...", IDM_SETTING_PREFERECE MENUITEM "Styler Configurator...", IDM_LANGSTYLE_CONFIG_DLG - MENUITEM "Shortcut Mapper...", IDM_SETTING_SHORTCUT_MAPPER + MENUITEM "Shortcut Mapper...", IDM_SETTING_SHORTCUT_MAPPER + MENUITEM SEPARATOR + POPUP "Import" + BEGIN + MENUITEM "Import plugin(s)...", IDM_SETTING_IMPORTPLUGIN + MENUITEM "Import style theme(s)...", IDM_SETTING_IMPORTSTYLETHEMS + END END POPUP "Macro" diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index ca3b80fcc..b2eba60b0 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -537,14 +537,15 @@ NppParameters::NppParameters() : _pXmlDoc(NULL),_pXmlUserDoc(NULL), _pXmlUserSty _nppPath = nppPath; //Initialize current directory to startup directory - ::GetCurrentDirectory(MAX_PATH, _currentDirectory); + TCHAR curDir[MAX_PATH]; + ::GetCurrentDirectory(MAX_PATH, curDir); + _currentDirectory = curDir; - _appdataNppDir[0] = '\0'; - TCHAR notepadStylePath[MAX_PATH]; - lstrcpy(notepadStylePath, _nppPath.c_str()); + _appdataNppDir = TEXT(""); + generic_string notepadStylePath(_nppPath); PathAppend(notepadStylePath, notepadStyleFile); - _asNotepadStyle = (PathFileExists(notepadStylePath) == TRUE); + _asNotepadStyle = (PathFileExists(notepadStylePath.c_str()) == TRUE); ::AddFontResource(LINEDRAW_FONT); //Load initial accelerator key definitions @@ -609,7 +610,7 @@ bool NppParameters::reloadStylers(TCHAR *stylePath) bool loadOkay = _pXmlUserStylerDoc->LoadFile(); if (!loadOkay) { - ::MessageBox(NULL, TEXT("Load stylers.xml failed!"), TEXT("Configurator"),MB_OK); + ::MessageBox(NULL, TEXT("Load stylers.xml failed!"), stylePath, MB_OK); delete _pXmlUserStylerDoc; _pXmlUserStylerDoc = NULL; return false; @@ -629,15 +630,14 @@ bool NppParameters::reloadStylers(TCHAR *stylePath) bool NppParameters::reloadLang() { - TCHAR nativeLangPath[MAX_PATH]; - lstrcpy(nativeLangPath, _nppPath.c_str()); - PathAppend(nativeLangPath, TEXT("nativeLang.xml")); + generic_string nativeLangPath(_nppPath); + PathAppend(nativeLangPath, generic_string(TEXT("nativeLang.xml"))); - if (!PathFileExists(nativeLangPath)) + if (!PathFileExists(nativeLangPath.c_str())) { - lstrcpy(nativeLangPath, _userPath); - PathAppend(nativeLangPath, TEXT("nativeLang.xml")); - if (!PathFileExists(nativeLangPath)) + nativeLangPath = _userPath; + PathAppend(nativeLangPath, generic_string(TEXT("nativeLang.xml"))); + if (!PathFileExists(nativeLangPath.c_str())) return false; } @@ -646,7 +646,7 @@ bool NppParameters::reloadLang() _pXmlNativeLangDocA = new TiXmlDocumentA(); - bool loadOkay = _pXmlNativeLangDocA->LoadUnicodeFilePath(nativeLangPath); + bool loadOkay = _pXmlNativeLangDocA->LoadUnicodeFilePath(nativeLangPath.c_str()); if (!loadOkay) { delete _pXmlNativeLangDocA; @@ -663,30 +663,30 @@ bool NppParameters::load() for (int i = 0 ; i < NB_LANG ; _langList[i] = NULL, i++); // Make localConf.xml path - TCHAR localConfPath[MAX_PATH]; - lstrcpy(localConfPath, _nppPath.c_str()); + generic_string localConfPath(_nppPath); PathAppend(localConfPath, localConfFile); // Test if localConf.xml exist - bool isLocal = (PathFileExists(localConfPath) == TRUE); + bool isLocal = (PathFileExists(localConfPath.c_str()) == TRUE); if (isLocal) { - lstrcpy(_userPath, _nppPath.c_str()); + _userPath = _nppPath; } else { ITEMIDLIST *pidl; SHGetSpecialFolderLocation(NULL, CSIDL_APPDATA, &pidl); - SHGetPathFromIDList(pidl, _userPath); + TCHAR tmp[MAX_PATH]; + SHGetPathFromIDList(pidl, tmp); + _userPath = tmp; PathAppend(_userPath, TEXT("Notepad++")); + _appdataNppDir = _userPath; - lstrcpy(_appdataNppDir, _userPath); - - if (!PathFileExists(_userPath)) + if (!PathFileExists(_userPath.c_str())) { - ::CreateDirectory(_userPath, NULL); + ::CreateDirectory(_userPath.c_str(), NULL); } } @@ -707,20 +707,19 @@ bool NppParameters::load() //---------------------------------------// // langs.xml : for every user statically // //---------------------------------------// - TCHAR langs_xml_path[MAX_PATH]; - lstrcpy(langs_xml_path, _nppPath.c_str()); - - PathAppend(langs_xml_path, TEXT("langs.xml")); - if (!PathFileExists(langs_xml_path)) - { - TCHAR srcLangsPath[MAX_PATH]; - lstrcpy(srcLangsPath, _nppPath.c_str()); - PathAppend(srcLangsPath, TEXT("langs.model.xml")); + generic_string langs_xml_path(_nppPath); - ::CopyFile(srcLangsPath, langs_xml_path, TRUE); + PathAppend(langs_xml_path, TEXT("langs.xml")); + if (!PathFileExists(langs_xml_path.c_str())) + { + generic_string srcLangsPath(_nppPath); + PathAppend(srcLangsPath, TEXT("langs.model.xml")); + ::CopyFile(srcLangsPath.c_str(), langs_xml_path.c_str(), TRUE); } _pXmlDoc = new TiXmlDocument(langs_xml_path); + + bool loadOkay = _pXmlDoc->LoadFile(); if (!loadOkay) { @@ -735,16 +734,14 @@ bool NppParameters::load() //---------------------------// // config.xml : for per user // //---------------------------// - TCHAR configPath[MAX_PATH]; - lstrcpy(configPath, _userPath); + generic_string configPath(_userPath); PathAppend(configPath, TEXT("config.xml")); - TCHAR srcConfigPath[MAX_PATH]; - lstrcpy(srcConfigPath, _nppPath.c_str()); + generic_string srcConfigPath(_nppPath); PathAppend(srcConfigPath, TEXT("config.model.xml")); - if (!::PathFileExists(configPath)) - ::CopyFile(srcConfigPath, configPath, FALSE); + if (!::PathFileExists(configPath.c_str())) + ::CopyFile(srcConfigPath.c_str(), configPath.c_str(), FALSE); _pXmlUserDoc = new TiXmlDocument(configPath); loadOkay = _pXmlUserDoc->LoadFile(); @@ -753,7 +750,7 @@ bool NppParameters::load() int res = ::MessageBox(NULL, TEXT("Load config.xml failed!\rDo you want to recover your config.xml?"), TEXT("Configurator"),MB_YESNO); if (res ==IDYES) { - ::CopyFile(srcConfigPath, configPath, FALSE); + ::CopyFile(srcConfigPath.c_str(), configPath.c_str(), FALSE); loadOkay = _pXmlUserDoc->LoadFile(); if (!loadOkay) @@ -780,16 +777,15 @@ bool NppParameters::load() // stylers.xml : for per user // //----------------------------// - lstrcpy(_stylerPath, _userPath); + _stylerPath = _userPath; PathAppend(_stylerPath, TEXT("stylers.xml")); - if (!PathFileExists(_stylerPath)) + if (!PathFileExists(_stylerPath.c_str())) { - TCHAR srcStylersPath[MAX_PATH]; - lstrcpy(srcStylersPath, _nppPath.c_str()); + generic_string srcStylersPath(_nppPath); PathAppend(srcStylersPath, TEXT("stylers.model.xml")); - ::CopyFile(srcStylersPath, _stylerPath, TRUE); + ::CopyFile(srcStylersPath.c_str(), _stylerPath.c_str(), TRUE); } if ( _nppGUI._themeName.empty() || (!PathFileExists(_nppGUI._themeName.c_str())) ) @@ -802,7 +798,7 @@ bool NppParameters::load() loadOkay = _pXmlUserStylerDoc->LoadFile(); if (!loadOkay) { - ::MessageBox(NULL, TEXT("Load stylers.xml failed!"), TEXT("Configurator"),MB_OK); + ::MessageBox(NULL, TEXT("Load stylers.xml failed!"), _stylerPath.c_str(), MB_OK); delete _pXmlUserStylerDoc; _pXmlUserStylerDoc = NULL; isAllLaoded = false; @@ -817,7 +813,7 @@ bool NppParameters::load() //-----------------------------------// // userDefineLang.xml : for per user // //-----------------------------------// - lstrcpy(_userDefineLangPath, _userPath); + _userDefineLangPath = _userPath; PathAppend(_userDefineLangPath, TEXT("userDefineLang.xml")); _pXmlUserLangDoc = new TiXmlDocument(_userDefineLangPath); @@ -836,19 +832,18 @@ bool NppParameters::load() // In case of absence of user's nativeLang.xml, // // We'll look in the Notepad++ Dir. // //----------------------------------------------// - TCHAR nativeLangPath[MAX_PATH]; - lstrcpy(nativeLangPath, _userPath); + generic_string nativeLangPath(_userPath); PathAppend(nativeLangPath, TEXT("nativeLang.xml")); - if (!PathFileExists(nativeLangPath)) + if (!PathFileExists(nativeLangPath.c_str())) { - lstrcpy(nativeLangPath, _nppPath.c_str()); + nativeLangPath = _nppPath; PathAppend(nativeLangPath, TEXT("nativeLang.xml")); } _pXmlNativeLangDocA = new TiXmlDocumentA(); - loadOkay = _pXmlNativeLangDocA->LoadUnicodeFilePath(nativeLangPath); + loadOkay = _pXmlNativeLangDocA->LoadUnicodeFilePath(nativeLangPath.c_str()); if (!loadOkay) { delete _pXmlNativeLangDocA; @@ -861,8 +856,7 @@ bool NppParameters::load() //---------------------------------// // toolbarIcons.xml : for per user // //---------------------------------// - TCHAR toolbarIconsPath[MAX_PATH]; - lstrcpy(toolbarIconsPath, _userPath); + generic_string toolbarIconsPath(_userPath); PathAppend(toolbarIconsPath, TEXT("toolbarIcons.xml")); _pXmlToolIconsDoc = new TiXmlDocument(toolbarIconsPath); @@ -877,16 +871,15 @@ bool NppParameters::load() //------------------------------// // shortcuts.xml : for per user // //------------------------------// - lstrcpy(_shortcutsPath, _userPath); + _shortcutsPath = _userPath; PathAppend(_shortcutsPath, TEXT("shortcuts.xml")); - if (!PathFileExists(_shortcutsPath)) + if (!PathFileExists(_shortcutsPath.c_str())) { - TCHAR srcShortcutsPath[MAX_PATH]; - lstrcpy(srcShortcutsPath, _nppPath.c_str()); + generic_string srcShortcutsPath(_nppPath); PathAppend(srcShortcutsPath, TEXT("shortcuts.xml")); - ::CopyFile(srcShortcutsPath, _shortcutsPath, TRUE); + ::CopyFile(srcShortcutsPath.c_str(), _shortcutsPath.c_str(), TRUE); } _pXmlShortcutDoc = new TiXmlDocument(_shortcutsPath); @@ -911,16 +904,15 @@ bool NppParameters::load() //---------------------------------// // contextMenu.xml : for per user // //---------------------------------// - lstrcpy(_contextMenuPath, _userPath); + _contextMenuPath = _userPath; PathAppend(_contextMenuPath, TEXT("contextMenu.xml")); - if (!PathFileExists(_contextMenuPath)) + if (!PathFileExists(_contextMenuPath.c_str())) { - TCHAR srcContextMenuPath[MAX_PATH]; - lstrcpy(srcContextMenuPath, _nppPath.c_str()); + generic_string srcContextMenuPath(_nppPath); PathAppend(srcContextMenuPath, TEXT("contextMenu.xml")); - ::CopyFile(srcContextMenuPath, _contextMenuPath, TRUE); + ::CopyFile(srcContextMenuPath.c_str(), _contextMenuPath.c_str(), TRUE); } _pXmlContextMenuDoc = new TiXmlDocument(_contextMenuPath); @@ -937,7 +929,7 @@ bool NppParameters::load() //----------------------------// // session.xml : for per user // //----------------------------// - lstrcpy(_sessionPath, _userPath); + _sessionPath = _userPath; PathAppend(_sessionPath, TEXT("session.xml")); // Don't load session.xml if not required in order to speed up!! @@ -1325,17 +1317,17 @@ void NppParameters::setWorkingDir(const TCHAR * newPath) { if (newPath && newPath[0]) { - lstrcpyn(_currentDirectory, newPath, MAX_PATH); //dont use sizeof + _currentDirectory = newPath; } else { if (PathFileExists(_nppGUI._defaultDirExp)) { - lstrcpyn(_currentDirectory, _nppGUI._defaultDirExp, MAX_PATH); + _currentDirectory = _nppGUI._defaultDirExp; } else { - lstrcpyn(_currentDirectory, _nppPath.c_str(), MAX_PATH); + _currentDirectory = _nppPath.c_str(); } } } @@ -2007,7 +1999,7 @@ void NppParameters::insertScintKey(TiXmlNode *scintKeyRoot, const ScintillaKeyMa void NppParameters::writeSession(const Session & session, const TCHAR *fileName) { - const TCHAR *pathName = fileName?fileName:_sessionPath; + const TCHAR *pathName = fileName?fileName:_sessionPath.c_str(); _pXmlSessionDoc = new TiXmlDocument(pathName); TiXmlNode *root = _pXmlSessionDoc->InsertEndChild(TiXmlElement(TEXT("NotepadPlus"))); diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index d17c3fd28..a8b7d6162 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -236,7 +236,7 @@ struct Style int _keywordClass; generic_string *_keywords; - Style():_styleID(-1), _fgColor(COLORREF(-1)), _bgColor(COLORREF(-1)), _colorStyle(COLORSTYLE_ALL), _fontName(NULL), _fontStyle(-1), _fontSize(-1), _keywordClass(-1), _keywords(NULL){}; + Style():_styleID(-1), _styleDesc(NULL), _fgColor(COLORREF(-1)), _bgColor(COLORREF(-1)), _colorStyle(COLORSTYLE_ALL), _fontName(NULL), _fontStyle(-1), _fontSize(-1), _keywordClass(-1), _keywords(NULL){}; ~Style(){ if (_keywords) @@ -330,7 +330,10 @@ public: int getNbStyler() const {return _nbStyler;}; void setNbStyler(int nb) {_nbStyler = nb;}; - Style & getStyler(int index) {return _styleArray[index];}; + Style & getStyler(int index) { + assert(index != -1); + return _styleArray[index]; + }; bool hasEnoughSpace() {return (_nbStyler < MAX_STYLE);}; void addStyler(int styleID, TiXmlNode *styleNode); @@ -869,11 +872,6 @@ friend class NppParameters; public : ThemeSwitcher(){}; - struct ThemeDefinition { - TCHAR *_themeName; - TCHAR *_xmlFileName; - }; - void addThemeFromXml(generic_string xmlFullPath) { _themeList.push_back(pair(getThemeFromXmlFileName(xmlFullPath.c_str()), xmlFullPath)); }; @@ -1170,8 +1168,8 @@ public: ScintillaAccelerator * getScintillaAccelerator() {return _pScintAccelerator;}; generic_string getNppPath() const {return _nppPath;}; - const TCHAR * getAppDataNppDir() const {return _appdataNppDir;}; - const TCHAR * getWorkingDir() const {return _currentDirectory;}; + const TCHAR * getAppDataNppDir() const {return _appdataNppDir.c_str();}; + const TCHAR * getWorkingDir() const {return _currentDirectory.c_str();}; void setWorkingDir(const TCHAR * newPath); bool loadSession(Session & session, const TCHAR *sessionFileName); @@ -1271,7 +1269,7 @@ private: UserLangContainer *_userLangArray[NB_MAX_USER_LANG]; int _nbUserLang; - TCHAR _userDefineLangPath[MAX_PATH]; + generic_string _userDefineLangPath; ExternalLangContainer *_externalLangArray[NB_MAX_EXTERNAL_LANG]; int _nbExternalLang; @@ -1310,14 +1308,14 @@ private: vector _contextMenuItems; Session _session; - TCHAR _shortcutsPath[MAX_PATH]; - TCHAR _contextMenuPath[MAX_PATH]; - TCHAR _sessionPath[MAX_PATH]; + generic_string _shortcutsPath; + generic_string _contextMenuPath; + generic_string _sessionPath; generic_string _nppPath; - TCHAR _userPath[MAX_PATH]; - TCHAR _stylerPath[MAX_PATH]; - TCHAR _appdataNppDir[MAX_PATH]; // sentinel of the absence of "doLocalConf.xml" : (_appdataNppDir == TEXT(""))?"doLocalConf.xml present":"doLocalConf.xml absent" - TCHAR _currentDirectory[MAX_PATH]; + generic_string _userPath; + generic_string _stylerPath; + generic_string _appdataNppDir; // sentinel of the absence of "doLocalConf.xml" : (_appdataNppDir == TEXT(""))?"doLocalConf.xml present":"doLocalConf.xml absent" + generic_string _currentDirectory; Accelerator *_pAccelerator; ScintillaAccelerator * _pScintAccelerator; diff --git a/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp b/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp index 210906fee..ade97de83 100644 --- a/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp +++ b/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp @@ -96,7 +96,6 @@ BOOL CALLBACK WordStyleDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lPar { pair & themeInfo = themeSwitcher.getElementFromIndex(i); int j = ::SendMessage(_hSwitch2ThemeCombo, CB_ADDSTRING, 0, (LPARAM)themeInfo.first.c_str()); - ::SendMessage(_hSwitch2ThemeCombo, CB_SETITEMDATA, j, (LPARAM)themeInfo.second.c_str()); if (! themeInfo.second.compare( nppParamInst->getNppGUI()._themeName ) ) { _currentThemeIndex = j; @@ -592,7 +591,11 @@ void WordStyleDlg::switchToTheme() generic_string prevThemeName(_themeName); _themeName.clear(); - _themeName.assign( (TCHAR *)::SendMessage(_hSwitch2ThemeCombo, CB_GETITEMDATA, iSel, 0) ); + + NppParameters *nppParamInst = NppParameters::getInstance(); + ThemeSwitcher & themeSwitcher = nppParamInst->getThemeSwitcher(); + pair & themeInfo = themeSwitcher.getElementFromIndex(iSel); + _themeName = themeInfo.second; if (_isThemeDirty) { @@ -609,9 +612,6 @@ void WordStyleDlg::switchToTheme() if ( mb_response == IDYES ) (NppParameters::getInstance())->writeStyles(_lsArray, _globalStyles); } - - - NppParameters *nppParamInst = NppParameters::getInstance(); nppParamInst->reloadStylers(&_themeName[0]); loadLangListFromNppParam(); @@ -659,7 +659,7 @@ void WordStyleDlg::setVisualFromStyleList() Style & style = getCurrentStyler(); // Global override style - if (lstrcmp(style._styleDesc, TEXT("Global override")) == 0) + if (style._styleDesc && lstrcmp(style._styleDesc, TEXT("Global override")) == 0) { showGlobalOverrideCtrls(true); } diff --git a/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.h b/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.h index fd82ef45d..27209bbec 100644 --- a/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.h +++ b/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.h @@ -107,6 +107,13 @@ public : void apply(); + void addLastThemeEntry() { + NppParameters *nppParamInst = NppParameters::getInstance(); + ThemeSwitcher & themeSwitcher = nppParamInst->getThemeSwitcher(); + pair & themeInfo = themeSwitcher.getElementFromIndex(themeSwitcher.size() - 1); + ::SendMessage(_hSwitch2ThemeCombo, CB_ADDSTRING, 0, (LPARAM)themeInfo.first.c_str()); + }; + private : @@ -151,8 +158,12 @@ private : Style & getCurrentStyler() { int styleIndex = ::SendDlgItemMessage(_hSelf, IDC_STYLES_LIST, LB_GETCURSEL, 0, 0); + if (styleIndex == LB_ERR) styleIndex = 0; + if (_currentLexerIndex == 0) + { return _globalStyles.getStyler(styleIndex); + } else { LexerStyler & lexerStyler = _lsArray.getLexerFromIndex(_currentLexerIndex - 1); @@ -223,14 +234,13 @@ private : _isThemeDirty = true; ::EnableWindow(::GetDlgItem(_hSelf, IDC_SAVECLOSE_BUTTON), TRUE); return TRUE; - } + }; void setStyleListFromLexer(int index); void setVisualFromStyleList(); void updateGlobalOverrideCtrls(); - void showGlobalOverrideCtrls(bool show) - { + void showGlobalOverrideCtrls(bool show) { if (show) { updateGlobalOverrideCtrls(); @@ -243,7 +253,7 @@ private : ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_ITALIC_CHECK), show?SW_SHOW:SW_HIDE); ::ShowWindow(::GetDlgItem(_hSelf, IDC_GLOBAL_UNDERLINE_CHECK), show?SW_SHOW:SW_HIDE); _isShownGOCtrls = show; - } + }; }; #endif //WORD_STYLE_H diff --git a/PowerEditor/src/WinControls/Window.h b/PowerEditor/src/WinControls/Window.h index 2c0affcfb..c08e37f19 100644 --- a/PowerEditor/src/WinControls/Window.h +++ b/PowerEditor/src/WinControls/Window.h @@ -83,13 +83,7 @@ public: }; HWND getHSelf() const { - /* - if (!_hSelf) - { - ::MessageBox(NULL, TEXT("_hSelf == NULL"), TEXT("class Window"), MB_OK); - throw int(999); - } - */ + //assert(_hSelf); return _hSelf; }; diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index 1d6641ae3..c216f3682 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -285,9 +285,9 @@ #define IDM_SETTING_TAB_REPLCESPACE (IDM_SETTING + 2) #define IDM_SETTING_HISTORY_SIZE (IDM_SETTING + 3) #define IDM_SETTING_EDGE_SIZE (IDM_SETTING + 4) - #define IDM_SETTING_FILEASSOCIATION_DLG (IDM_SETTING + 5) + #define IDM_SETTING_IMPORTPLUGIN (IDM_SETTING + 5) + #define IDM_SETTING_IMPORTSTYLETHEMS (IDM_SETTING + 6) - #define IDM_SETTING_HISTORY_DONT_CHECK (IDM_SETTING + 7) #define IDM_SETTING_TRAYICON (IDM_SETTING + 8) #define IDM_SETTING_SHORTCUT_MAPPER (IDM_SETTING + 9) #define IDM_SETTING_REMEMBER_LAST_SESSION (IDM_SETTING + 10) diff --git a/PowerEditor/src/resource.h b/PowerEditor/src/resource.h index ee9572a65..89464389a 100644 --- a/PowerEditor/src/resource.h +++ b/PowerEditor/src/resource.h @@ -173,6 +173,12 @@ #define ID_PLUGINS_CMD 22000 #define ID_PLUGINS_CMD_LIMIT 22500 +/*UNLOAD +#define ID_PLUGINS_REMOVING 22501 +#define ID_PLUGINS_REMOVING_END 22600 +*/ + + //#define IDM 40000 #define IDCMD 50000