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
This commit is contained in:
Don Ho 2021-06-27 03:05:14 +02:00
parent da0fc02c5c
commit 3347044595
5 changed files with 92 additions and 54 deletions

View File

@ -16,116 +16,115 @@
SectionGroup "Themes" Themes SectionGroup "Themes" Themes
SetOverwrite off SetOverwrite on
; UPDATE_PATH: the value is $INSTDIR if doLocalConf.xml exit,
; otherwise the value is $APPDATA\${APPNAME}
Section "-Dark Mode Default" DarkModeDefault Section "-Dark Mode Default" DarkModeDefault
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\DarkModeDefault.xml" File ".\themes\DarkModeDefault.xml"
SectionEnd SectionEnd
${MementoSection} "Black Board" BlackBoard ${MementoSection} "Black Board" BlackBoard
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Black board.xml" File ".\themes\Black board.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Choco" Choco ${MementoSection} "Choco" Choco
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Choco.xml" File ".\themes\Choco.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Hello Kitty" HelloKitty ${MementoSection} "Hello Kitty" HelloKitty
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Hello Kitty.xml" File ".\themes\Hello Kitty.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Mono Industrial" MonoIndustrial ${MementoSection} "Mono Industrial" MonoIndustrial
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Mono Industrial.xml" File ".\themes\Mono Industrial.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Monokai" Monokai ${MementoSection} "Monokai" Monokai
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Monokai.xml" File ".\themes\Monokai.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Obsidian" Obsidian ${MementoSection} "Obsidian" Obsidian
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\obsidian.xml" File ".\themes\obsidian.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Plastic Code Wrap" PlasticCodeWrap ${MementoSection} "Plastic Code Wrap" PlasticCodeWrap
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Plastic Code Wrap.xml" File ".\themes\Plastic Code Wrap.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Ruby Blue" RubyBlue ${MementoSection} "Ruby Blue" RubyBlue
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Ruby Blue.xml" File ".\themes\Ruby Blue.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Twilight" Twilight ${MementoSection} "Twilight" Twilight
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Twilight.xml" File ".\themes\Twilight.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Vibrant Ink" VibrantInk ${MementoSection} "Vibrant Ink" VibrantInk
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Vibrant Ink.xml" File ".\themes\Vibrant Ink.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Deep Black" DeepBlack ${MementoSection} "Deep Black" DeepBlack
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Deep Black.xml" File ".\themes\Deep Black.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "vim Dark Blue" vimDarkBlue ${MementoSection} "vim Dark Blue" vimDarkBlue
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\vim Dark Blue.xml" File ".\themes\vim Dark Blue.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Bespin" Bespin ${MementoSection} "Bespin" Bespin
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Bespin.xml" File ".\themes\Bespin.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Zenburn" Zenburn ${MementoSection} "Zenburn" Zenburn
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Zenburn.xml" File ".\themes\Zenburn.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Solarized" Solarized ${MementoSection} "Solarized" Solarized
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Solarized.xml" File ".\themes\Solarized.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Solarized Light" Solarized-light ${MementoSection} "Solarized Light" Solarized-light
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Solarized-light.xml" File ".\themes\Solarized-light.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Hot Fudge Sundae" HotFudgeSundae ${MementoSection} "Hot Fudge Sundae" HotFudgeSundae
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\HotFudgeSundae.xml" File ".\themes\HotFudgeSundae.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "khaki" khaki ${MementoSection} "khaki" khaki
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\khaki.xml" File ".\themes\khaki.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Mossy Lawn" MossyLawn ${MementoSection} "Mossy Lawn" MossyLawn
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\MossyLawn.xml" File ".\themes\MossyLawn.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "Navajo" Navajo ${MementoSection} "Navajo" Navajo
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\Navajo.xml" File ".\themes\Navajo.xml"
${MementoSectionEnd} ${MementoSectionEnd}
${MementoSection} "DansLeRuSH Dark" DansLeRuSHDark ${MementoSection} "DansLeRuSH Dark" DansLeRuSHDark
SetOutPath "$UPDATE_PATH\themes" SetOutPath "$INSTDIR\themes"
File ".\themes\DansLeRuSH-Dark.xml" File ".\themes\DansLeRuSH-Dark.xml"
${MementoSectionEnd} ${MementoSectionEnd}
SectionGroupEnd SectionGroupEnd

View File

@ -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 // Get themes from both npp install themes dir and app data themes dir with the per user
// overriding default themes of the same name. // overriding default themes of the same name.
generic_string themeDir; generic_string appDataThemeDir;
if (nppParams.getAppDataNppDir() && nppParams.getAppDataNppDir()[0]) if (nppParams.getAppDataNppDir() && nppParams.getAppDataNppDir()[0])
{ {
themeDir = nppParams.getAppDataNppDir(); appDataThemeDir = nppParams.getAppDataNppDir();
PathAppend(themeDir, TEXT("themes\\")); PathAppend(appDataThemeDir, TEXT("themes\\"));
themeSwitcher.setThemeDirPath(themeDir); _notepad_plus_plus_core.getMatchedFileNames(appDataThemeDir.c_str(), patterns, fileNames, false, false);
_notepad_plus_plus_core.getMatchedFileNames(themeDir.c_str(), patterns, fileNames, false, false);
for (size_t i = 0, len = fileNames.size() ; i < len ; ++i) for (size_t i = 0, len = fileNames.size() ; i < len ; ++i)
{ {
themeSwitcher.addThemeFromXml(fileNames[i]); themeSwitcher.addThemeFromXml(fileNames[i]);
@ -214,20 +213,35 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin
} }
fileNames.clear(); 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()) generic_string nppThemeDir;
themeSwitcher.setThemeDirPath(themeDir); 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) for (size_t i = 0, len = fileNames.size(); i < len ; ++i)
{ {
generic_string themeName( themeSwitcher.getThemeFromXmlFileName(fileNames[i].c_str()) ); 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]); 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);
}
} }
} }

View File

@ -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")); TiXmlNode *lexersRoot = (_pXmlUserStylerDoc->FirstChild(TEXT("NotepadPlus")))->FirstChildElement(TEXT("LexerStyles"));
for (TiXmlNode *childNode = lexersRoot->FirstChildElement(TEXT("LexerType")); 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("");
} }

View File

@ -29,6 +29,7 @@
#include "NppDarkMode.h" #include "NppDarkMode.h"
#include <assert.h> #include <assert.h>
#include <tchar.h> #include <tchar.h>
#include <map>
#ifdef _WIN64 #ifdef _WIN64
@ -1270,40 +1271,34 @@ class ThemeSwitcher final
friend class NppParameters; friend class NppParameters;
public: public:
void addThemeFromXml(const generic_string& xmlFullPath) void addThemeFromXml(const generic_string& xmlFullPath) {
{
_themeList.push_back(std::pair<generic_string, generic_string>(getThemeFromXmlFileName(xmlFullPath.c_str()), xmlFullPath)); _themeList.push_back(std::pair<generic_string, generic_string>(getThemeFromXmlFileName(xmlFullPath.c_str()), xmlFullPath));
} }
void addDefaultThemeFromXml(const generic_string& xmlFullPath) void addDefaultThemeFromXml(const generic_string& xmlFullPath) {
{
_themeList.push_back(std::pair<generic_string, generic_string>(_defaultThemeLabel, xmlFullPath)); _themeList.push_back(std::pair<generic_string, generic_string>(_defaultThemeLabel, xmlFullPath));
} }
generic_string getThemeFromXmlFileName(const TCHAR *fn) const; 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]) if (!themeName || themeName[0])
return generic_string(); return generic_string();
generic_string themePath = _stylesXmlPath; generic_string themePath = _stylesXmlPath;
return themePath; return themePath;
} }
bool themeNameExists(const TCHAR *themeName) bool themeNameExists(const TCHAR *themeName) {
{
for (size_t i = 0; i < _themeList.size(); ++i ) 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 true;
} }
return false; return false;
} }
size_t size() const size_t size() const { return _themeList.size(); }
{
return _themeList.size();
}
std::pair<generic_string, generic_string> & getElementFromIndex(size_t index) std::pair<generic_string, generic_string> & getElementFromIndex(size_t index)
@ -1317,8 +1312,25 @@ public:
generic_string getDefaultThemeLabel() const { return _defaultThemeLabel; } 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: private:
std::vector<std::pair<generic_string, generic_string>> _themeList; std::vector<std::pair<generic_string, generic_string>> _themeList;
std::map<generic_string, generic_string> _themeStylerSavePath;
generic_string _themeDirPath; generic_string _themeDirPath;
const generic_string _defaultThemeLabel = TEXT("Default (stylers.xml)"); const generic_string _defaultThemeLabel = TEXT("Default (stylers.xml)");
generic_string _stylesXmlPath; generic_string _stylesXmlPath;
@ -1469,7 +1481,7 @@ public:
bool writeScintillaParams(); bool writeScintillaParams();
void createXmlTreeFromGUIParams(); 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); bool insertTabInfo(const TCHAR *langName, int tabInfo);
LexerStylerArray & getLStylerArray() {return _lexerStylerArray;}; LexerStylerArray & getLStylerArray() {return _lexerStylerArray;};

View File

@ -278,7 +278,10 @@ INT_PTR CALLBACK WordStyleDlg::run_dlgProc(UINT Message, WPARAM wParam, LPARAM l
_isDirty = false; _isDirty = false;
} }
_isThemeDirty = 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); ::EnableWindow(::GetDlgItem(_hSelf, IDC_SAVECLOSE_BUTTON), FALSE);
//_isSync = true; //_isSync = true;
display(false); display(false);