From 814e6591b5c37da7c6d84c4b67a6e73d645a318f Mon Sep 17 00:00:00 2001 From: Don HO Date: Fri, 27 Nov 2020 03:54:37 +0100 Subject: [PATCH] Fix function list is empty with new user profile issue The new behaviour of loading function list will be: 1. For the installer package: Try to load from %APPDATA%\Notepad++\functionList\, if it failed, then load from %PROGRAMFILES%\Notepad++\functionList\. In this way, users can override function list in %APPDATA%\Notepad++\functionList\ manually. Otherwise, function list won't be empty. 2. For the portable package: - with doLocalConf.xml : Load always from \functionList\ - without doLocalConf.xml : Try to load from %APPDATA%\Notepad++\functionList\, if it failed, then load from \functionList\ Fix #9134 --- .../installer/nsisInclude/functionList.nsh | 110 +++++++++--------- .../FunctionList/functionListPanel.cpp | 20 ++-- .../FunctionList/functionParser.cpp | 33 ++++-- .../WinControls/FunctionList/functionParser.h | 10 +- 4 files changed, 94 insertions(+), 79 deletions(-) diff --git a/PowerEditor/installer/nsisInclude/functionList.nsh b/PowerEditor/installer/nsisInclude/functionList.nsh index 2681c63e..a7c72ff4 100644 --- a/PowerEditor/installer/nsisInclude/functionList.nsh +++ b/PowerEditor/installer/nsisInclude/functionList.nsh @@ -29,140 +29,138 @@ SectionGroup "Function List Files" functionListComponent SetOverwrite off - ; UPDATE_PATH: the value is $UPDATE_PATH if doLocalConf.xml exit, - ; otherwise the value is $APPDATA\${APPNAME} ${MementoSection} "C" C_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\c.xml" ${MementoSectionEnd} ${MementoSection} "C++" C++_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\cpp.xml" ${MementoSectionEnd} ${MementoSection} "Java" Java_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\java.xml" ${MementoSectionEnd} ${MementoSection} "C#" C#_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\cs.xml" ${MementoSectionEnd} ${MementoSection} "Assembly" Assembly_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\asm.xml" ${MementoSectionEnd} ${MementoSection} "Bash" Bash_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\bash.xml" ${MementoSectionEnd} ${MementoSection} "SQL" SQL_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\sql.xml" ${MementoSectionEnd} ${MementoSection} "PHP" PHP_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\php.xml" ${MementoSectionEnd} ${MementoSection} "COBOL section free" COBOL-section-free - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\cobol-free.xml" ${MementoSectionEnd} ${MementoSection} "COBOL" COBOL_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\cobol.xml" ${MementoSectionEnd} ${MementoSection} "Perl" Perl_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\perl.xml" ${MementoSectionEnd} ${MementoSection} "JavaScript" JavaScript_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\javascript.js.xml" ${MementoSectionEnd} ${MementoSection} "Python" Python_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\python.xml" ${MementoSectionEnd} ${MementoSection} "ini" ini_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\ini.xml" ${MementoSectionEnd} ${MementoSection} "Inno Setup" Innosetup_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\inno.xml" ${MementoSectionEnd} ${MementoSection} "VHDL" VHDL_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\vhdl.xml" ${MementoSectionEnd} ${MementoSection} "KRL" KRL_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\krl.xml" ${MementoSectionEnd} ${MementoSection} "Override Map" OverrideMap_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\overrideMap.xml" ${MementoSectionEnd} ${MementoSection} "NSIS" NSIS_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\nsis.xml" ${MementoSectionEnd} ${MementoSection} "PowerShell" PowerShell_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\powershell.xml" ${MementoSectionEnd} ${MementoSection} "BATCH" BATCH_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\batch.xml" ${MementoSectionEnd} ${MementoSection} "Ruby" Ruby_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\ruby.xml" ${MementoSectionEnd} ${MementoSection} "BaanC" BaanC_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\baanc.xml" ${MementoSectionEnd} ${MementoSection} "Sinumerik" Sinumerik_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\sinumerik.xml" ${MementoSectionEnd} ${MementoSection} "AutoIt" AutoIt_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\autoit.xml" ${MementoSectionEnd} ${MementoSection} "UniVerse BASIC" UniVerseBASIC_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\universe_basic.xml" ${MementoSectionEnd} ${MementoSection} "XML" XML_FL - SetOutPath "$UPDATE_PATH\functionList" + SetOutPath "$INSTDIR\functionList" File ".\functionList\xml.xml" ${MementoSectionEnd} SectionGroupEnd @@ -171,111 +169,111 @@ SectionGroupEnd SectionGroup un.functionListComponent Section un.PHP_FL - Delete "$UPDATE_PATH\functionList\php.xml" + Delete "$INSTDIR\functionList\php.xml" SectionEnd Section un.Assembly_FL - Delete "$UPDATE_PATH\functionList\asm.xml" + Delete "$INSTDIR\functionList\asm.xml" SectionEnd Section un.SQL_FL - Delete "$UPDATE_PATH\functionList\sql.xml" + Delete "$INSTDIR\functionList\sql.xml" SectionEnd Section un.Bash_FL - Delete "$UPDATE_PATH\functionList\bash.xml" + Delete "$INSTDIR\functionList\bash.xml" SectionEnd Section un.COBOL-section-free_FL - Delete "$UPDATE_PATH\functionList\cobol-free.xml" + Delete "$INSTDIR\functionList\cobol-free.xml" SectionEnd Section un.Perl_FL - Delete "$UPDATE_PATH\functionList\perl.xml" + Delete "$INSTDIR\functionList\perl.xml" SectionEnd Section un.C_FL - Delete "$UPDATE_PATH\functionList\c.xml" + Delete "$INSTDIR\functionList\c.xml" SectionEnd Section un.C++_FL - Delete "$UPDATE_PATH\functionList\cpp.xml" + Delete "$INSTDIR\functionList\cpp.xml" SectionEnd Section un.Java_FL - Delete "$UPDATE_PATH\functionList\java.xml" + Delete "$INSTDIR\functionList\java.xml" SectionEnd Section un.C#_FL - Delete "$UPDATE_PATH\functionList\cs.xml" + Delete "$INSTDIR\functionList\cs.xml" SectionEnd Section un.JavaScript_FL - Delete "$UPDATE_PATH\functionList\javascript.js.xml" + Delete "$INSTDIR\functionList\javascript.js.xml" SectionEnd Section un.Python_FL - Delete "$UPDATE_PATH\functionList\python.xml" + Delete "$INSTDIR\functionList\python.xml" SectionEnd Section un.COBOL_FL - Delete "$UPDATE_PATH\functionList\cobol.xml" + Delete "$INSTDIR\functionList\cobol.xml" SectionEnd Section un.ini_FL - Delete "$UPDATE_PATH\functionList\ini.xml" + Delete "$INSTDIR\functionList\ini.xml" SectionEnd Section un.VHDL_FL - Delete "$UPDATE_PATH\functionList\vhdl.xml" + Delete "$INSTDIR\functionList\vhdl.xml" SectionEnd Section un.Innosetup_FL - Delete "$UPDATE_PATH\functionList\inno.xml" + Delete "$INSTDIR\functionList\inno.xml" SectionEnd Section un.XML_FL - Delete "$UPDATE_PATH\functionList\xml.xml" + Delete "$INSTDIR\functionList\xml.xml" SectionEnd Section un.NSIS_FL - Delete "$UPDATE_PATH\functionList\nsis.xml" + Delete "$INSTDIR\functionList\nsis.xml" SectionEnd Section un.KRL_FL - Delete "$UPDATE_PATH\functionList\krl.xml" + Delete "$INSTDIR\functionList\krl.xml" SectionEnd Section un.BATCH_FL - Delete "$UPDATE_PATH\functionList\batch.xml" + Delete "$INSTDIR\functionList\batch.xml" SectionEnd Section un.OverrideMap_FL - Delete "$UPDATE_PATH\functionList\overrideMap.xml" + Delete "$INSTDIR\functionList\overrideMap.xml" SectionEnd Section un.BaanC_FL - Delete "$UPDATE_PATH\functionList\baanc.xml" + Delete "$INSTDIR\functionList\baanc.xml" SectionEnd Section un.PowerShell_FL - Delete "$UPDATE_PATH\functionList\powershell.xml" + Delete "$INSTDIR\functionList\powershell.xml" SectionEnd Section un.AutoIt_FL - Delete "$UPDATE_PATH\functionList\autoit.xml" + Delete "$INSTDIR\functionList\autoit.xml" SectionEnd Section un.Ruby_FL - Delete "$UPDATE_PATH\functionList\ruby.xml" + Delete "$INSTDIR\functionList\ruby.xml" SectionEnd Section un.UniVerseBASIC_FL - Delete "$UPDATE_PATH\functionList\universe_basic.xml" + Delete "$INSTDIR\functionList\universe_basic.xml" SectionEnd Section un.Sinumerik_FL - Delete "$UPDATE_PATH\functionList\sinumerik.xml" + Delete "$INSTDIR\functionList\sinumerik.xml" SectionEnd SectionGroupEnd diff --git a/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp b/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp index 4a21d101..6b6eb1f7 100644 --- a/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp +++ b/PowerEditor/src/WinControls/FunctionList/functionListPanel.cpp @@ -476,26 +476,28 @@ void FunctionListPanel::init(HINSTANCE hInst, HWND hPere, ScintillaEditView **pp { DockingDlgInterface::init(hInst, hPere); _ppEditView = ppEditView; + + generic_string funcListXmlPath = (NppParameters::getInstance()).getUserPath(); + PathAppend(funcListXmlPath, TEXT("functionList")); + + generic_string funcListDefaultXmlPath = (NppParameters::getInstance()).getNppPath(); + PathAppend(funcListDefaultXmlPath, TEXT("functionList")); + bool doLocalConf = (NppParameters::getInstance()).isLocal(); if (!doLocalConf) { - generic_string funcListXmlPath = (NppParameters::getInstance()).getUserPath(); - PathAppend(funcListXmlPath, TEXT("functionList")); - if (!PathFileExists(funcListXmlPath.c_str())) - { - generic_string funcListDefaultXmlPath = (NppParameters::getInstance()).getNppPath(); - PathAppend(funcListDefaultXmlPath, TEXT("functionList")); + { if (PathFileExists(funcListDefaultXmlPath.c_str())) { ::CopyFile(funcListDefaultXmlPath.c_str(), funcListXmlPath.c_str(), TRUE); - _funcParserMgr.init(funcListXmlPath, ppEditView); + _funcParserMgr.init(funcListXmlPath, funcListDefaultXmlPath, ppEditView); } } else { - _funcParserMgr.init(funcListXmlPath, ppEditView); + _funcParserMgr.init(funcListXmlPath, funcListDefaultXmlPath, ppEditView); } } else @@ -504,7 +506,7 @@ void FunctionListPanel::init(HINSTANCE hInst, HWND hPere, ScintillaEditView **pp PathAppend(funcListDefaultXmlPath, TEXT("functionList")); if (PathFileExists(funcListDefaultXmlPath.c_str())) { - _funcParserMgr.init(funcListDefaultXmlPath, ppEditView); + _funcParserMgr.init(funcListDefaultXmlPath, funcListDefaultXmlPath, ppEditView); } } } diff --git a/PowerEditor/src/WinControls/FunctionList/functionParser.cpp b/PowerEditor/src/WinControls/FunctionList/functionParser.cpp index 85e738bc..3f0a6709 100644 --- a/PowerEditor/src/WinControls/FunctionList/functionParser.cpp +++ b/PowerEditor/src/WinControls/FunctionList/functionParser.cpp @@ -41,12 +41,19 @@ FunctionParsersManager::~FunctionParsersManager() } } -bool FunctionParsersManager::init(const generic_string& xmlDirPath, ScintillaEditView ** ppEditView) +bool FunctionParsersManager::init(const generic_string& xmlDirPath, const generic_string& xmlInstalledPath, ScintillaEditView ** ppEditView) { _ppEditView = ppEditView; _xmlDirPath = xmlDirPath; + _xmlDirInstalledPath = xmlInstalledPath; - return getOverrideMapFromXmlTree(); + bool isOK = getOverrideMapFromXmlTree(_xmlDirPath); + if (isOK) + return true; + else if (_xmlDirPath != _xmlDirInstalledPath && !_xmlDirInstalledPath.empty()) + return getOverrideMapFromXmlTree(_xmlDirInstalledPath); + else + return false; } bool FunctionParsersManager::getZonePaserParameters(TiXmlNode *classRangeParser, generic_string &mainExprStr, generic_string &openSymboleStr, generic_string &closeSymboleStr, std::vector &classNameExprArray, generic_string &functionExprStr, std::vector &functionNameExprArray) @@ -143,9 +150,9 @@ bool FunctionParsersManager::getUnitPaserParameters(TiXmlNode *functionParser, g } -bool FunctionParsersManager::loadFuncListFromXmlTree(LangType lType, const generic_string& overrideId, int udlIndex) +bool FunctionParsersManager::loadFuncListFromXmlTree(generic_string & xmlDirPath, LangType lType, const generic_string& overrideId, int udlIndex) { - generic_string funcListRulePath = _xmlDirPath; + generic_string funcListRulePath = xmlDirPath; funcListRulePath += TEXT("\\"); int index = -1; if (lType == L_USER) // UDL @@ -245,9 +252,9 @@ bool FunctionParsersManager::loadFuncListFromXmlTree(LangType lType, const gener return true; } -bool FunctionParsersManager::getOverrideMapFromXmlTree() +bool FunctionParsersManager::getOverrideMapFromXmlTree(generic_string & xmlDirPath) { - generic_string funcListRulePath = _xmlDirPath; + generic_string funcListRulePath = xmlDirPath; funcListRulePath += TEXT("\\overrideMap.xml"); TiXmlDocument xmlFuncListDoc(funcListRulePath); @@ -325,7 +332,9 @@ FunctionParser * FunctionParsersManager::getParser(const AssociationInfo & assoI else { // load it - if (loadFuncListFromXmlTree(static_cast(assoInfo._langID), _parsers[assoInfo._langID]->_id)) + if (loadFuncListFromXmlTree(_xmlDirPath, static_cast(assoInfo._langID), _parsers[assoInfo._langID]->_id)) + return _parsers[assoInfo._langID]->_parser; + else if (_xmlDirPath != _xmlDirInstalledPath && !_xmlDirInstalledPath.empty() && loadFuncListFromXmlTree(_xmlDirInstalledPath, static_cast(assoInfo._langID), _parsers[assoInfo._langID]->_id)) return _parsers[assoInfo._langID]->_parser; } } @@ -333,7 +342,9 @@ FunctionParser * FunctionParsersManager::getParser(const AssociationInfo & assoI { _parsers[assoInfo._langID] = new ParserInfo; // load it - if (loadFuncListFromXmlTree(static_cast(assoInfo._langID), _parsers[assoInfo._langID]->_id)) + if (loadFuncListFromXmlTree(_xmlDirPath, static_cast(assoInfo._langID), _parsers[assoInfo._langID]->_id)) + return _parsers[assoInfo._langID]->_parser; + else if (_xmlDirPath != _xmlDirInstalledPath && !_xmlDirInstalledPath.empty() && loadFuncListFromXmlTree(_xmlDirInstalledPath, static_cast(assoInfo._langID), _parsers[assoInfo._langID]->_id)) return _parsers[assoInfo._langID]->_parser; return nullptr; @@ -357,7 +368,9 @@ FunctionParser * FunctionParsersManager::getParser(const AssociationInfo & assoI else { // load it - if (loadFuncListFromXmlTree(static_cast(assoInfo._langID), _parsers[i]->_id, i)) + if (loadFuncListFromXmlTree(_xmlDirPath, static_cast(assoInfo._langID), _parsers[i]->_id, i)) + return _parsers[i]->_parser; + else if (_xmlDirPath != _xmlDirInstalledPath && !_xmlDirInstalledPath.empty() && loadFuncListFromXmlTree(_xmlDirInstalledPath, static_cast(assoInfo._langID), _parsers[i]->_id, i)) return _parsers[i]->_parser; } @@ -371,7 +384,7 @@ FunctionParser * FunctionParsersManager::getParser(const AssociationInfo & assoI } - return NULL; + return nullptr; } diff --git a/PowerEditor/src/WinControls/FunctionList/functionParser.h b/PowerEditor/src/WinControls/FunctionList/functionParser.h index 78768767..d5988795 100644 --- a/PowerEditor/src/WinControls/FunctionList/functionParser.h +++ b/PowerEditor/src/WinControls/FunctionList/functionParser.h @@ -158,18 +158,20 @@ class FunctionParsersManager final public: ~FunctionParsersManager(); - bool init(const generic_string& xmlPath, ScintillaEditView ** ppEditView); + bool init(const generic_string& xmlPath, const generic_string& xmlInstalledPath, ScintillaEditView ** ppEditView); bool parse(std::vector & foundInfos, const AssociationInfo & assoInfo); private: ScintillaEditView **_ppEditView = nullptr; - generic_string _xmlDirPath; + generic_string _xmlDirPath; // The 1st place to load function list files. Usually it's "%APPDATA%\Notepad++\functionList\" + generic_string _xmlDirInstalledPath; // Where Notepad++ is installed. The 2nd place to load function list files. Usually it's "%PROGRAMFILES%\Notepad++\functionList\" + ParserInfo* _parsers[L_EXTERNAL + nbMaxUserDefined] = {nullptr}; int _currentUDIndex = L_EXTERNAL; - bool getOverrideMapFromXmlTree(); - bool loadFuncListFromXmlTree(LangType lType, const generic_string& overrideId, int udlIndex = -1); + bool getOverrideMapFromXmlTree(generic_string & xmlDirPath); + bool loadFuncListFromXmlTree(generic_string & xmlDirPath, LangType lType, const generic_string& overrideId, int udlIndex = -1); bool getZonePaserParameters(TiXmlNode *classRangeParser, generic_string &mainExprStr, generic_string &openSymboleStr, generic_string &closeSymboleStr, std::vector &classNameExprArray, generic_string &functionExprStr, std::vector &functionNameExprArray); bool getUnitPaserParameters(TiXmlNode *functionParser, generic_string &mainExprStr, std::vector &functionNameExprArray, std::vector &classNameExprArray); FunctionParser * getParser(const AssociationInfo & assoInfo);