From 3347044595cae60c658ed39e4f2e1ea913eb66e2 Mon Sep 17 00:00:00 2001 From: Don Ho Date: Sun, 27 Jun 2021 03:05:14 +0200 Subject: [PATCH] Fix edit zone not being applied to dark mode issue Problem: After installing Notepad++ v8.1 under an user account (with admin privilege), then switch to another user account (with or without admin privilege), launch Notepad++ and turn dark mode on. The dark theme on edit zone won't be applied. Solution: Notepad++ installer copies all theme files in installed directory instead of "%APPDATA%\Notepad++\themes\". When theme is choosen or modified, it'll be saved in "%APPDATA%\Notepad++\themes\", and the saved theme file will override the original theme in installation directory. New behaviour of theme: Any theme selected via Style Configurator will be copied from its installation directory (C:\Program Files\Notepad++\themes\) into "%APPDATA%\Notepad++\themes\". If the theme exists in "%APPDATA%\Notepad++\themes", the original one in s installation directory (C:\Program Files\Notepad++\themes) will be ignored. Fix #10076, close #10077 --- PowerEditor/installer/nsisInclude/themes.nsh | 49 +++++++++---------- PowerEditor/src/Notepad_plus_Window.cpp | 38 +++++++++----- PowerEditor/src/Parameters.cpp | 14 +++++- PowerEditor/src/Parameters.h | 40 +++++++++------ .../WinControls/ColourPicker/WordStyleDlg.cpp | 5 +- 5 files changed, 92 insertions(+), 54 deletions(-) diff --git a/PowerEditor/installer/nsisInclude/themes.nsh b/PowerEditor/installer/nsisInclude/themes.nsh index 272393120..4c2b51090 100644 --- a/PowerEditor/installer/nsisInclude/themes.nsh +++ b/PowerEditor/installer/nsisInclude/themes.nsh @@ -16,116 +16,115 @@ SectionGroup "Themes" Themes - SetOverwrite off - ; UPDATE_PATH: the value is $INSTDIR if doLocalConf.xml exit, - ; otherwise the value is $APPDATA\${APPNAME} + SetOverwrite on + Section "-Dark Mode Default" DarkModeDefault - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\DarkModeDefault.xml" SectionEnd ${MementoSection} "Black Board" BlackBoard - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Black board.xml" ${MementoSectionEnd} ${MementoSection} "Choco" Choco - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Choco.xml" ${MementoSectionEnd} ${MementoSection} "Hello Kitty" HelloKitty - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Hello Kitty.xml" ${MementoSectionEnd} ${MementoSection} "Mono Industrial" MonoIndustrial - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Mono Industrial.xml" ${MementoSectionEnd} ${MementoSection} "Monokai" Monokai - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Monokai.xml" ${MementoSectionEnd} ${MementoSection} "Obsidian" Obsidian - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\obsidian.xml" ${MementoSectionEnd} ${MementoSection} "Plastic Code Wrap" PlasticCodeWrap - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Plastic Code Wrap.xml" ${MementoSectionEnd} ${MementoSection} "Ruby Blue" RubyBlue - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Ruby Blue.xml" ${MementoSectionEnd} ${MementoSection} "Twilight" Twilight - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Twilight.xml" ${MementoSectionEnd} ${MementoSection} "Vibrant Ink" VibrantInk - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Vibrant Ink.xml" ${MementoSectionEnd} ${MementoSection} "Deep Black" DeepBlack - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Deep Black.xml" ${MementoSectionEnd} ${MementoSection} "vim Dark Blue" vimDarkBlue - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\vim Dark Blue.xml" ${MementoSectionEnd} ${MementoSection} "Bespin" Bespin - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Bespin.xml" ${MementoSectionEnd} ${MementoSection} "Zenburn" Zenburn - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Zenburn.xml" ${MementoSectionEnd} ${MementoSection} "Solarized" Solarized - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Solarized.xml" ${MementoSectionEnd} ${MementoSection} "Solarized Light" Solarized-light - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Solarized-light.xml" ${MementoSectionEnd} ${MementoSection} "Hot Fudge Sundae" HotFudgeSundae - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\HotFudgeSundae.xml" ${MementoSectionEnd} ${MementoSection} "khaki" khaki - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\khaki.xml" ${MementoSectionEnd} ${MementoSection} "Mossy Lawn" MossyLawn - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\MossyLawn.xml" ${MementoSectionEnd} ${MementoSection} "Navajo" Navajo - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\Navajo.xml" ${MementoSectionEnd} ${MementoSection} "DansLeRuSH Dark" DansLeRuSHDark - SetOutPath "$UPDATE_PATH\themes" + SetOutPath "$INSTDIR\themes" File ".\themes\DansLeRuSH-Dark.xml" ${MementoSectionEnd} SectionGroupEnd diff --git a/PowerEditor/src/Notepad_plus_Window.cpp b/PowerEditor/src/Notepad_plus_Window.cpp index 7c575268f..a7cac4f5e 100644 --- a/PowerEditor/src/Notepad_plus_Window.cpp +++ b/PowerEditor/src/Notepad_plus_Window.cpp @@ -200,13 +200,12 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin // 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; + generic_string appDataThemeDir; if (nppParams.getAppDataNppDir() && nppParams.getAppDataNppDir()[0]) { - themeDir = nppParams.getAppDataNppDir(); - PathAppend(themeDir, TEXT("themes\\")); - themeSwitcher.setThemeDirPath(themeDir); - _notepad_plus_plus_core.getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false); + appDataThemeDir = nppParams.getAppDataNppDir(); + PathAppend(appDataThemeDir, TEXT("themes\\")); + _notepad_plus_plus_core.getMatchedFileNames(appDataThemeDir.c_str(), patterns, fileNames, false, false); for (size_t i = 0, len = fileNames.size() ; i < len ; ++i) { themeSwitcher.addThemeFromXml(fileNames[i]); @@ -214,20 +213,35 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin } fileNames.clear(); - themeDir.clear(); - themeDir = nppDir.c_str(); // <- should use the pointer to avoid the constructor of copy - PathAppend(themeDir, TEXT("themes\\")); - if (themeSwitcher.getThemeDirPath().empty()) - themeSwitcher.setThemeDirPath(themeDir); + generic_string nppThemeDir; + nppThemeDir = nppDir.c_str(); // <- should use the pointer to avoid the constructor of copy + PathAppend(nppThemeDir, TEXT("themes\\")); - _notepad_plus_plus_core.getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false); + // Set theme directory to their installation directory + themeSwitcher.setThemeDirPath(nppThemeDir); + + _notepad_plus_plus_core.getMatchedFileNames(nppThemeDir.c_str(), patterns, fileNames, false, false); for (size_t i = 0, len = fileNames.size(); i < len ; ++i) { generic_string themeName( themeSwitcher.getThemeFromXmlFileName(fileNames[i].c_str()) ); - if (! themeSwitcher.themeNameExists(themeName.c_str()) ) + if (!themeSwitcher.themeNameExists(themeName.c_str()) ) { themeSwitcher.addThemeFromXml(fileNames[i]); + + if (!appDataThemeDir.empty()) + { + generic_string appDataThemePath = appDataThemeDir; + + if (!::PathFileExists(appDataThemePath.c_str())) + { + ::CreateDirectory(appDataThemePath.c_str(), NULL); + } + + TCHAR* fn = PathFindFileName(fileNames[i].c_str()); + PathAppend(appDataThemePath, fn); + themeSwitcher.addThemeStylerSavePath(fileNames[i], appDataThemePath); + } } } diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 89809b755..f21ec7548 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -6929,7 +6929,7 @@ generic_string NppParameters::getWinVerBitStr() const } } -void NppParameters::writeStyles(LexerStylerArray & lexersStylers, StyleArray & globalStylers) +generic_string NppParameters::writeStyles(LexerStylerArray & lexersStylers, StyleArray & globalStylers) { TiXmlNode *lexersRoot = (_pXmlUserStylerDoc->FirstChild(TEXT("NotepadPlus")))->FirstChildElement(TEXT("LexerStyles")); for (TiXmlNode *childNode = lexersRoot->FirstChildElement(TEXT("LexerType")); @@ -7023,7 +7023,17 @@ void NppParameters::writeStyles(LexerStylerArray & lexersStylers, StyleArray & g } } - _pXmlUserStylerDoc->SaveFile(); + bool isSaved = _pXmlUserStylerDoc->SaveFile(); + if (!isSaved) + { + auto savePath = _themeSwitcher.getSavePathFrom(_pXmlUserStylerDoc->Value()); + if (!savePath.empty()) + { + _pXmlUserStylerDoc->SaveFile(savePath.c_str()); + return savePath; + } + } + return TEXT(""); } diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index cd5c96374..7b75daefd 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -29,6 +29,7 @@ #include "NppDarkMode.h" #include #include +#include #ifdef _WIN64 @@ -1270,40 +1271,34 @@ class ThemeSwitcher final friend class NppParameters; public: - void addThemeFromXml(const generic_string& xmlFullPath) - { + void addThemeFromXml(const generic_string& xmlFullPath) { _themeList.push_back(std::pair(getThemeFromXmlFileName(xmlFullPath.c_str()), xmlFullPath)); } - void addDefaultThemeFromXml(const generic_string& xmlFullPath) - { + void addDefaultThemeFromXml(const generic_string& xmlFullPath) { _themeList.push_back(std::pair(_defaultThemeLabel, xmlFullPath)); } generic_string getThemeFromXmlFileName(const TCHAR *fn) const; - generic_string getXmlFilePathFromThemeName(const TCHAR *themeName) const - { + generic_string getXmlFilePathFromThemeName(const TCHAR *themeName) const { if (!themeName || themeName[0]) return generic_string(); generic_string themePath = _stylesXmlPath; return themePath; } - bool themeNameExists(const TCHAR *themeName) - { + bool themeNameExists(const TCHAR *themeName) { for (size_t i = 0; i < _themeList.size(); ++i ) { - if (! (getElementFromIndex(i)).first.compare(themeName)) + auto themeNameOnList = getElementFromIndex(i).first; + if (lstrcmp(themeName, themeNameOnList.c_str()) == 0) return true; } return false; } - size_t size() const - { - return _themeList.size(); - } + size_t size() const { return _themeList.size(); } std::pair & getElementFromIndex(size_t index) @@ -1317,8 +1312,25 @@ public: generic_string getDefaultThemeLabel() const { return _defaultThemeLabel; } + generic_string getSavePathFrom(const generic_string& path) const { + const auto iter = _themeStylerSavePath.find(path); + if (iter == _themeStylerSavePath.end()) + { + return TEXT(""); + } + else + { + return iter->second; + } + }; + + void addThemeStylerSavePath(generic_string key, generic_string val) { + _themeStylerSavePath[key] = val; + }; + private: std::vector> _themeList; + std::map _themeStylerSavePath; generic_string _themeDirPath; const generic_string _defaultThemeLabel = TEXT("Default (stylers.xml)"); generic_string _stylesXmlPath; @@ -1469,7 +1481,7 @@ public: bool writeScintillaParams(); void createXmlTreeFromGUIParams(); - void writeStyles(LexerStylerArray & lexersStylers, StyleArray & globalStylers); + generic_string writeStyles(LexerStylerArray & lexersStylers, StyleArray & globalStylers); // return "" if saving file succeeds, otherwise return the new saved file path bool insertTabInfo(const TCHAR *langName, int tabInfo); LexerStylerArray & getLStylerArray() {return _lexerStylerArray;}; diff --git a/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp b/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp index 7ea2ef2f5..6c75ea1e2 100644 --- a/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp +++ b/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp @@ -278,7 +278,10 @@ INT_PTR CALLBACK WordStyleDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM l _isDirty = false; } _isThemeDirty = false; - (NppParameters::getInstance()).writeStyles(_lsArray, _globalStyles); + auto newSavedFilePath = (NppParameters::getInstance()).writeStyles(_lsArray, _globalStyles); + if (!newSavedFilePath.empty()) + updateThemeName(newSavedFilePath); + ::EnableWindow(::GetDlgItem(_hSelf, IDC_SAVECLOSE_BUTTON), FALSE); //_isSync = true; display(false);