[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
This commit is contained in:
Don Ho 2009-08-11 23:55:57 +00:00
parent dd70030c5c
commit e8f584c764
14 changed files with 532 additions and 338 deletions

View File

@ -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;
}

View File

@ -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

View File

@ -21,48 +21,36 @@
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::loadPlugins(const TCHAR *dir)
bool PluginsManager::unloadPlugin(int index, HWND nppHandle)
{
if (_isDisabled)
return false;
SCNotification scnN;
scnN.nmhdr.code = NPPN_SHUTDOWN;
scnN.nmhdr.hwndFrom = nppHandle;
scnN.nmhdr.idFrom = 0;
_pluginInfos[index]->_pBeNotified(&scnN);
vector<generic_string> dllNames;
vector<generic_string> dll2Remove;
generic_string nppPath = (NppParameters::getInstance())->getNppPath();
//::DestroyMenu(_pluginInfos[index]->_pluginMenu);
//_pluginInfos[index]->_pluginMenu = NULL;
generic_string pluginsFullPathFilter = (dir && dir[0])?dir:nppPath;
if (::FreeLibrary(_pluginInfos[index]->_hLib))
_pluginInfos[index]->_hLib = NULL;
else
printStr(TEXT("not ok"));
//delete _pluginInfos[index];
// printInt(index);
//vector<PluginInfo *>::iterator it = _pluginInfos.begin() + index;
//_pluginInfos.erase(it);
//printStr(TEXT("remove"));
return true;
}
pluginsFullPathFilter += TEXT("\\plugins\\*.dll");
WIN32_FIND_DATA foundData;
HANDLE hFindFile = ::FindFirstFile(pluginsFullPathFilter.c_str(), &foundData);
if (hFindFile != INVALID_HANDLE_VALUE)
{
generic_string plugins1stFullPath = (dir && dir[0])?dir:nppPath;
plugins1stFullPath += TEXT("\\plugins\\");
plugins1stFullPath += foundData.cFileName;
dllNames.push_back(plugins1stFullPath);
while (::FindNextFile(hFindFile, &foundData))
{
generic_string fullPath = (dir && dir[0])?dir:nppPath;
fullPath += TEXT("\\plugins\\");
fullPath += foundData.cFileName;
dllNames.push_back(fullPath);
}
::FindClose(hFindFile);
size_t i = 0;
for ( ; i < dllNames.size() ; i++)
{
int PluginsManager::loadPlugin(const TCHAR *pluginFilePath, vector<generic_string> & dll2Remove)
{
PluginInfo *pi = new PluginInfo;
try {
TCHAR tmpStr[MAX_PATH];
lstrcpy(tmpStr, dllNames[i].c_str());
lstrcpy(pi->_moduleName, PathFindFileName(tmpStr));
pi->_moduleName = PathFindFileName(pluginFilePath);
pi->_hLib = ::LoadLibrary(dllNames[i].c_str());
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."));
@ -122,7 +110,7 @@ bool PluginsManager::loadPlugins(const TCHAR *dir)
char lexName[MAX_EXTERNAL_LEXER_NAME_LEN];
lexName[0] = '\0';
TCHAR lexDesc[MAX_EXTERNAL_LEXER_DESC_LEN];
lstrcpy(lexDesc, TEXT(""));
lexDesc[0] = '\0';
int numLexers = GetLexerCount();
@ -150,16 +138,16 @@ bool PluginsManager::loadPlugins(const TCHAR *dir)
TCHAR xmlPath[MAX_PATH];
lstrcpy(xmlPath, nppParams->getNppPath().c_str());
PathAppend(xmlPath, TEXT("plugins\\Config"));
PathAppend(xmlPath, pi->_moduleName);
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() );
lstrcpyn(xmlPath, TEXT("\0"), MAX_PATH );
lstrcpy(xmlPath, nppParams->getAppDataNppDir() );
PathAppend(xmlPath, TEXT("plugins\\Config"));
PathAppend( xmlPath, pi->_moduleName );
PathAppend(xmlPath, pi->_moduleName.c_str());
PathRemoveExtension( xmlPath );
PathAddExtension( xmlPath, TEXT(".xml") );
@ -185,36 +173,81 @@ bool PluginsManager::loadPlugins(const TCHAR *dir)
nppParams->getExternalLexerFromXmlTree(_pXmlDoc);
nppParams->getExternalLexerDoc()->push_back(_pXmlDoc);
#ifdef UNICODE
const char *pDllName = wmc->wchar2char(dllNames[i].c_str(), CP_ACP);
const char *pDllName = wmc->wchar2char(pluginFilePath, CP_ACP);
#else
const char *pDllName = dllNames[i].c_str();
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(), dllNames[i].c_str(), MB_YESNO) == IDYES)
if (::MessageBox(NULL, s.c_str(), pluginFilePath, MB_YESNO) == IDYES)
{
dll2Remove.push_back(dllNames[i]);
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(), dllNames[i].c_str(), MB_YESNO) == IDYES)
if (::MessageBox(NULL, msg.c_str(), pluginFilePath, MB_YESNO) == IDYES)
{
dll2Remove.push_back(dllNames[i]);
dll2Remove.push_back(pluginFilePath);
}
delete pi;
return -1;
}
}
bool PluginsManager::loadPlugins(const TCHAR *dir)
{
if (_isDisabled)
return false;
vector<generic_string> dllNames;
vector<generic_string> dll2Remove;
generic_string nppPath = (NppParameters::getInstance())->getNppPath();
generic_string pluginsFullPathFilter = (dir && dir[0])?dir:nppPath;
pluginsFullPathFilter += TEXT("\\plugins\\*.dll");
WIN32_FIND_DATA foundData;
HANDLE hFindFile = ::FindFirstFile(pluginsFullPathFilter.c_str(), &foundData);
if (hFindFile != INVALID_HANDLE_VALUE)
{
generic_string plugins1stFullPath = (dir && dir[0])?dir:nppPath;
plugins1stFullPath += TEXT("\\plugins\\");
plugins1stFullPath += foundData.cFileName;
dllNames.push_back(plugins1stFullPath);
while (::FindNextFile(hFindFile, &foundData))
{
generic_string fullPath = (dir && dir[0])?dir:nppPath;
fullPath += TEXT("\\plugins\\");
fullPath += foundData.cFileName;
dllNames.push_back(fullPath);
}
::FindClose(hFindFile);
size_t i = 0;
for ( ; i < dllNames.size() ; i++)
{
loadPlugin(dllNames[i].c_str(), dll2Remove);
}
}
for (size_t j = 0 ; j < dll2Remove.size() ; j++)
@ -250,21 +283,14 @@ bool PluginsManager::getShortcutByCmdID(int cmdID, ShortcutKey *sk)
return false;
}
void PluginsManager::setMenu(HMENU hMenu, const TCHAR *menuName)
void PluginsManager::addInMenuFromPMIndex(int i)
{
if (hasPlugins())
{
vector<PluginCmdShortcut> & 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);
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++)
unsigned short j = 0;
for ( ; j < _pluginInfos[i]->_nbFuncItem ; j++)
{
if (_pluginInfos[i]->_funcItems[j]._pFunc == NULL)
{
@ -272,7 +298,7 @@ void PluginsManager::setMenu(HMENU hMenu, const TCHAR *menuName)
continue;
}
_pluginsCommands.push_back(PluginCommand(_pluginInfos[i]->_moduleName, j, _pluginInfos[i]->_funcItems[j]._pFunc));
_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;
@ -281,14 +307,15 @@ void PluginsManager::setMenu(HMENU hMenu, const TCHAR *menuName)
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);
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
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
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());
@ -296,6 +323,28 @@ void PluginsManager::setMenu(HMENU hMenu, const TCHAR *menuName)
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<PluginCmdShortcut> & pluginCmdSCList = (NppParameters::getInstance())->getPluginCommandList();
const TCHAR *nom_menu = (menuName && menuName[0])?menuName:TEXT("Plugins");
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++)
{
addInMenuFromPMIndex(i);
}
}
}

View File

@ -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<generic_string> & 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,22 +95,27 @@ 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++)
{
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++)
{
if (_pluginInfos[i]->_hLib)
_pluginInfos[i]->_pMessageProc(Message, wParam, lParam);
}
};
@ -118,12 +127,15 @@ public:
for (size_t i = 0 ; i < _pluginInfos.size() ; i++)
{
if (generic_stricmp(_pluginInfos[i]->_moduleName, moduleName) == 0)
if (_pluginInfos[i]->_moduleName == moduleName)
{
if (_pluginInfos[i]->_hLib)
{
_pluginInfos[i]->_pMessageProc(Message, wParam, lParam);
return true;
}
}
}
return false;
};

View File

@ -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();
@ -301,14 +300,12 @@ void Notepad_plus::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdL
vector<generic_string> 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();
wstring localizationDir = nppDir;
PathAppend(localizationDir, TEXT("localization\\"));
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,11 +4199,53 @@ void Notepad_plus::command(int id)
break;
}
case IDM_SETTING_FILEASSOCIATION_DLG :
case IDM_SETTING_IMPORTPLUGIN :
{
RegExtDlg regExtDlg;
regExtDlg.init(_hInst, _hSelf);
regExtDlg.doDialog(_isRTL);
// get plugin source path
TCHAR *extFilterName = TEXT("Notepad++ pligin");
TCHAR *extFilter = TEXT(".dll");
TCHAR *destDir = TEXT("plugins");
vector<generic_string> copiedFiles = addNppComponents(destDir, extFilterName, extFilter);
// load plugin
vector<generic_string> 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<generic_string> 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;
}
@ -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<generic_string> Notepad_plus::addNppComponents(const TCHAR *destDir, const TCHAR *extFilterName, const TCHAR *extFilter)
{
FileDialog fDlg(_hSelf, _hInst);
fDlg.setExtFilter(extFilterName, extFilter, NULL);
//setFileOpenSaveDlgFilters(fDlg);
vector<generic_string> 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;
}

View File

@ -220,6 +220,7 @@ public:
bool findInFiles();
bool replaceInFiles();
void setFindReplaceFolderFilter(const TCHAR *dir, const TCHAR *filters);
vector<generic_string> addNppComponents(const TCHAR *destDir, const TCHAR *extFilterName, const TCHAR *extFilter);
static HWND gNppHWND; //static handle to Notepad++ window, NULL if non-existant
private:

View File

@ -540,6 +540,12 @@ BEGIN
MENUITEM "Preferences...", IDM_SETTING_PREFERECE
MENUITEM "Styler Configurator...", IDM_LANGSTYLE_CONFIG_DLG
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"

View File

@ -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());
generic_string langs_xml_path(_nppPath);
PathAppend(langs_xml_path, TEXT("langs.xml"));
if (!PathFileExists(langs_xml_path))
if (!PathFileExists(langs_xml_path.c_str()))
{
TCHAR srcLangsPath[MAX_PATH];
lstrcpy(srcLangsPath, _nppPath.c_str());
generic_string srcLangsPath(_nppPath);
PathAppend(srcLangsPath, TEXT("langs.model.xml"));
::CopyFile(srcLangsPath, langs_xml_path, TRUE);
::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")));

View File

@ -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<generic_string, generic_string>(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<MenuItemUnit> _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;

View File

@ -96,7 +96,6 @@ BOOL CALLBACK WordStyleDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM lPar
{
pair<generic_string, generic_string> & 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<generic_string, generic_string> & 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);
}

View File

@ -107,6 +107,13 @@ public :
void apply();
void addLastThemeEntry() {
NppParameters *nppParamInst = NppParameters::getInstance();
ThemeSwitcher & themeSwitcher = nppParamInst->getThemeSwitcher();
pair<generic_string, generic_string> & 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

View File

@ -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;
};

View File

@ -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)

View File

@ -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