From 1795dee12668081e2b0cb8640fde6d1ca5ffb513 Mon Sep 17 00:00:00 2001 From: "METANEOCORTEX\\Kotti" Date: Fri, 24 Feb 2023 15:09:55 +0100 Subject: [PATCH] +enh: Make Code/Text font prio list configurable --- Build/Notepad3.ini | 2 + res/StdDarkModeScheme.ini | 2 +- src/Config/Config.cpp | 96 +++++++++++++++++++++++------- src/Helpers.c | 4 +- src/Notepad3.c | 9 +-- src/StyleLexers/styleLexStandard.c | 2 +- src/Styles.c | 59 ++++++------------ src/TypeDefs.h | 3 + 8 files changed, 109 insertions(+), 68 deletions(-) diff --git a/Build/Notepad3.ini b/Build/Notepad3.ini index 1a4be32c8..4f4f2e0d9 100644 --- a/Build/Notepad3.ini +++ b/Build/Notepad3.ini @@ -68,6 +68,8 @@ SettingsVersion=5 ;HyperlinkShellExURLWithApp="" ;HyperlinkShellExURLCmdLnArgs="${URL}" (use ${URL} as place holder for clicked Hyperlink URL string) ;HyperlinkFileProtocolVerb="" (ShellExecuteEx()::lpVerb (""=default, "edit", "explore", "find", "open", "print", "properties", "runas") +;CodeFontPrefPrioList="Cascadia Code,Cascadia Mono,Cousine,Fira Code,Source Code Pro,Roboto Mono,DejaVu Sans Mono,Inconsolata,Consolas,Lucida Console" +;TextFontPrefPrioList="Cascadia Mono,Cousine,Roboto Mono,DejaVu Sans Mono,Inconsolata,Consolas,Lucida Console" [Statusbar Settings] ;VisibleSections=0 1 15 14 2 4 5 6 7 8 9 10 11 ;SectionPrefixes=Ln ,Col ,Sel ,Sb ,SLn ,Occ ,,,,,,,Ch ,Repl ,Eval ,U+, diff --git a/res/StdDarkModeScheme.ini b/res/StdDarkModeScheme.ini index ea09d86af..e1888697f 100644 --- a/res/StdDarkModeScheme.ini +++ b/res/StdDarkModeScheme.ini @@ -41,7 +41,7 @@ Change History Marker Reverted to Modified=fore:#A0C000; back:#A0C000 Change History Marker Reverted to Origin=fore:#40A0BF; back:#40A0BF Inline-IME Color=fore:#4EF64D [2nd Common Base] -2nd Default Style=font:Consolas +2nd Default Style=font:$Code 2nd Margins and Line Numbers=font:Consolas; size:-2; fore:#A5FAFA; back:#454545; alpha:180 2nd Matching Braces (Indicator)=fore:#0DF145; alpha:80; alpha2:220; indic_roundbox 2nd Matching Braces Error (Indicator)=fore:#F20C80; alpha:140; alpha2:220; indic_roundbox diff --git a/src/Config/Config.cpp b/src/Config/Config.cpp index 7a06e4b30..cfe334e80 100644 --- a/src/Config/Config.cpp +++ b/src/Config/Config.cpp @@ -96,6 +96,17 @@ static const WCHAR* const _s_RecentReplace = L"Recent Replace"; // ---------------------------------------------------------------------------- +const WCHAR* const CodeFontPrioList[] = { L"Cascadia Code", L"Cascadia Mono", L"Cousine", L"Fira Code", + L"Source Code Pro", L"Roboto Mono", L"DejaVu Sans Mono", L"Inconsolata", L"Consolas", L"Lucida Console" }; + +const WCHAR* const TextFontPrioList[] = { L"Cascadia Mono", L"Cousine", L"Roboto Mono", L"DejaVu Sans Mono", + L"Inconsolata", L"Consolas", L"Lucida Console" }; + +WCHAR CodeFontPrioListStrgBuf[LARGE_BUFFER] = { 0 }; +WCHAR TextFontPrioListStrgBuf[LARGE_BUFFER] = { 0 }; + +// ---------------------------------------------------------------------------- + static int s_iStatusbarSections[STATUS_SECTOR_COUNT] = SBS_INIT_MINUS; // ---------------------------------------------------------------------------- @@ -1147,12 +1158,12 @@ void LoadSettings() auto* const pPathBuffer = (wchar_t*)AllocMem(PATHLONG_MAX_CCH * sizeof(wchar_t), HEAP_ZERO_MEMORY); bool bDirtyFlag = false; // do we have to save the file on done - + OpenSettingsFile(__func__); // -------------------------------------------------------------------------- - const WCHAR *const IniSecSettings = Constants.Settings_Section; - const WCHAR *const IniSecSettings2 = Constants.Settings2_Section; + const WCHAR* const IniSecSettings = Constants.Settings_Section; + const WCHAR* const IniSecSettings2 = Constants.Settings2_Section; // -------------------------------------------------------------------------- // prerequisites @@ -1168,25 +1179,29 @@ void LoadSettings() if (Globals.CmdLnFlag_ReuseWindow == 0) { Flags.bReuseWindow = IniSectionGetBool(IniSecSettings2, L"ReuseWindow", DefaultFlags.bReuseWindow); - } else { + } + else { Flags.bReuseWindow = (Globals.CmdLnFlag_ReuseWindow == 2); } if (Globals.CmdLnFlag_SingleFileInstance == 0) { Flags.bSingleFileInstance = IniSectionGetBool(IniSecSettings2, L"SingleFileInstance", DefaultFlags.bSingleFileInstance); - } else { + } + else { Flags.bSingleFileInstance = (Globals.CmdLnFlag_SingleFileInstance == 2); } if (Globals.CmdLnFlag_MultiFileArg == 0) { Flags.MultiFileArg = IniSectionGetBool(IniSecSettings2, L"MultiFileArg", DefaultFlags.MultiFileArg); - } else { + } + else { Flags.MultiFileArg = (Globals.CmdLnFlag_MultiFileArg == 2); } if (Globals.CmdLnFlag_ShellUseSystemMRU == 0) { Flags.ShellUseSystemMRU = IniSectionGetBool(IniSecSettings2, L"ShellUseSystemMRU", DefaultFlags.ShellUseSystemMRU); - } else { + } + else { Flags.ShellUseSystemMRU = (Globals.CmdLnFlag_ShellUseSystemMRU == 2); } @@ -1206,19 +1221,19 @@ void LoadSettings() // -------------------------------------------------------------------------- - #if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS) +#if defined(HAVE_DYN_LOAD_LIBS_MUI_LNGS) - Default_PreferredLanguageLocaleName[0] = L'\0'; - GetUserPreferredLanguage(Default_PreferredLanguageLocaleName, LOCALE_NAME_MAX_LENGTH); + Default_PreferredLanguageLocaleName[0] = L'\0'; + GetUserPreferredLanguage(Default_PreferredLanguageLocaleName, LOCALE_NAME_MAX_LENGTH); - IniSectionGetStringNoQuotes(IniSecSettings2, L"PreferredLanguageLocaleName", Default_PreferredLanguageLocaleName, - Settings2.PreferredLanguageLocaleName, COUNTOF(Settings2.PreferredLanguageLocaleName)); - #endif + IniSectionGetStringNoQuotes(IniSecSettings2, L"PreferredLanguageLocaleName", Default_PreferredLanguageLocaleName, + Settings2.PreferredLanguageLocaleName, COUNTOF(Settings2.PreferredLanguageLocaleName)); +#endif // -------------------------------------------------------------------------- IniSectionGetStringNoQuotes(IniSecSettings2, L"DefaultExtension", L"txt", - Settings2.DefaultExtension, COUNTOF(Settings2.DefaultExtension)); + Settings2.DefaultExtension, COUNTOF(Settings2.DefaultExtension)); StrTrim(Settings2.DefaultExtension, L" \t."); IniSectionGetStringNoQuotes(IniSecSettings2, L"DefaultDirectory", L"", pPathBuffer, PATHLONG_MAX_CCH); @@ -1228,9 +1243,9 @@ void LoadSettings() IniSectionGetStringNoQuotes(IniSecSettings2, L"FileDlgFilters", L"", pPathBuffer, XHUGE_BUFFER); StrgReset(Settings2.FileDlgFilters, pPathBuffer); - Settings2.FileCheckInverval = clampul(IniSectionGetInt(IniSecSettings2, L"FileCheckInverval", 0), 0, 86400000<<2); // max: 48h + Settings2.FileCheckInverval = clampul(IniSectionGetInt(IniSecSettings2, L"FileCheckInverval", 0), 0, 86400000 << 2); // max: 48h // handle deprecated old "AutoReloadTimeout" - int const autoReload = IniSectionGetInt(IniSecSettings2, L"AutoReloadTimeout", -1); // deprecated + int const autoReload = IniSectionGetInt(IniSecSettings2, L"AutoReloadTimeout", -1); // deprecated unsigned int const fci = max_u(250, (autoReload > 0) ? max_u(autoReload, Settings2.FileCheckInverval) : Settings2.FileCheckInverval); if ((Settings2.FileCheckInverval > 0) && (fci != Settings2.FileCheckInverval)) { Settings2.FileCheckInverval = fci; @@ -1254,7 +1269,8 @@ void LoadSettings() bDirtyFlag = true; } Defaults.RenderingTechnology = clampi(Defaults.RenderingTechnology, SC_TECHNOLOGY_DEFAULT, SC_TECHNOLOGY_DIRECTWRITEDC); - } else { + } + else { Defaults.RenderingTechnology = SC_TECHNOLOGY_DIRECTWRITE; // new default DirectWrite (D2D) } @@ -1323,13 +1339,13 @@ void LoadSettings() IniSectionGetString(IniSecSettings2, L"ShellAppUserModelID", _W("Rizonesoft." SAPPNAME), Settings2.AppUserModelID, COUNTOF(Settings2.AppUserModelID)); } IniSectionGetString(IniSecSettings2, L"ExtendedWhiteSpaceChars", L"", - Settings2.ExtendedWhiteSpaceChars, COUNTOF(Settings2.ExtendedWhiteSpaceChars)); + Settings2.ExtendedWhiteSpaceChars, COUNTOF(Settings2.ExtendedWhiteSpaceChars)); IniSectionGetString(IniSecSettings2, L"AutoCompleteWordCharSet", L"", Settings2.AutoCompleteWordCharSet, COUNTOF(Settings2.AutoCompleteWordCharSet)); IniSectionGetString(IniSecSettings2, L"AutoCompleteFillUpChars", L"", Settings2.AutoCompleteFillUpChars, COUNTOF(Settings2.AutoCompleteFillUpChars)); - IniSectionGetString(IniSecSettings2, L"LineCommentPostfixStrg", L"", Settings2.LineCommentPostfixStrg, COUNTOF(Settings2.LineCommentPostfixStrg)); + IniSectionGetString(IniSecSettings2, L"LineCommentPostfixStrg", L"", Settings2.LineCommentPostfixStrg, COUNTOF(Settings2.LineCommentPostfixStrg)); StrTrim(Settings2.LineCommentPostfixStrg, L"\"'"); IniSectionGetStringNoQuotes(IniSecSettings2, L"DateTimeFormat", L"", Settings2.DateTimeFormat, COUNTOF(Settings2.DateTimeFormat)); @@ -1365,7 +1381,7 @@ void LoadSettings() IniSectionGetStringNoQuotes(IniSecSettings2, L"HyperlinkShellExURLCmdLnArgs", URLPLACEHLDR, pPathBuffer, PATHLONG_MAX_CCH); StrgReset(Settings2.HyperlinkShellExURLCmdLnArgs, pPathBuffer); - const static WCHAR *const allowedVerbs[7] = { L"edit", L"explore", L"find", L"open", L"print", L"properties", L"runas" }; + const static WCHAR* const allowedVerbs[] = { L"edit", L"explore", L"find", L"open", L"print", L"properties", L"runas" }; Settings2.HyperlinkFileProtocolVerb[0] = L'\0'; IniSectionGetStringNoQuotes(IniSecSettings2, L"HyperlinkFileProtocolVerb", L"", tchKeyName, COUNTOF(tchKeyName)); for (auto allowedVerb : allowedVerbs) { @@ -1375,6 +1391,46 @@ void LoadSettings() } } + for (int i = 0; i < COUNTOF(Settings2.CodeFontPrefPrioList); ++i) { + if (i < COUNTOF(CodeFontPrioList)) + Settings2.CodeFontPrefPrioList[i] = CodeFontPrioList[i]; + else + Settings2.CodeFontPrefPrioList[i] = nullptr; + } + if (IniSectionGetStringNoQuotes(IniSecSettings2, L"CodeFontPrefPrioList", L"", CodeFontPrioListStrgBuf, COUNTOF(CodeFontPrioListStrgBuf))) { + // split string and assign pointer array + WCHAR* p = &CodeFontPrioListStrgBuf[0]; + int i = 0; + while (p && *p && (i < COUNTOF(Settings2.CodeFontPrefPrioList))) { + Settings2.CodeFontPrefPrioList[i] = p; + while (p && *p) { + if (*p == L',') { *p = L'\0'; ++p; break; } + ++p; + } + ++i; + } + } + + for (int i = 0; i < COUNTOF(Settings2.TextFontPrefPrioList); ++i) { + if (i < COUNTOF(TextFontPrioList)) + Settings2.TextFontPrefPrioList[i] = TextFontPrioList[i]; + else + Settings2.TextFontPrefPrioList[i] = nullptr; + } + if (IniSectionGetStringNoQuotes(IniSecSettings2, L"TextFontPrefPrioList", L"", TextFontPrioListStrgBuf, COUNTOF(TextFontPrioListStrgBuf))) { + // split string and assign pointer array + WCHAR* p = &TextFontPrioListStrgBuf[0]; + int i = 0; + while (p && *p && (i < COUNTOF(Settings2.TextFontPrefPrioList))) { + Settings2.TextFontPrefPrioList[i] = p; + while (p && *p) { + if (*p == L',') { *p = L'\0'; ++p; break; } + ++p; + } + ++i; + } + } + #ifdef D_NP3_WIN10_DARK_MODE unsigned int iValue = 0; diff --git a/src/Helpers.c b/src/Helpers.c index 88fb12415..f2fa9d12f 100644 --- a/src/Helpers.c +++ b/src/Helpers.c @@ -717,7 +717,9 @@ static int CALLBACK EnumFontFamExProcFound(CONST LOGFONT *plf, CONST TEXTMETRIC bool IsFontAvailable(LPCWSTR lpszFontName) { - bool fFound = FALSE; + BOOL fFound = FALSE; + if (!lpszFontName) + return fFound; LOGFONT lf = { 0 }; StringCchCopy(lf.lfFaceName, LF_FACESIZE, lpszFontName); diff --git a/src/Notepad3.c b/src/Notepad3.c index d471ec9d2..900091147 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -8495,14 +8495,15 @@ inline static LRESULT _MsgNotifyLean(const SCNotification *const scn, bool* bMod if ((iModType & SC_MULTISTEPUNDOREDO) && !(iModType & SC_LASTSTEPINUNDOREDO)) { return TRUE; // wait for last step in multi-step-undo/redo } + bool const bInUndoRedoStep = (iModType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)); if (iModType & SC_MOD_INSERTCHECK) { - if (!(iModType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO))) { + if (!bInUndoRedoStep) { _HandleInsertCheck(scn); } } if (iModType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) { *bModified = false; // not yet - if (!(iModType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO))) { + if (!bInUndoRedoStep) { if (!_InUndoRedoTransaction() && (_urtoken < URTok_TokenStart)) { _SaveSelectionToBuffer(); bool const bSelEmpty = SciCall_IsSelectionEmpty(); @@ -8521,7 +8522,7 @@ inline static LRESULT _MsgNotifyLean(const SCNotification *const scn, bool* bMod } } } else if (iModType & (SC_MOD_INSERTTEXT | SC_MOD_DELETETEXT)) { - if (!(iModType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO))) { + if (!bInUndoRedoStep) { if (!_InUndoRedoTransaction() && (_urtoken >= URTok_TokenStart)) { _SaveRedoSelection(_urtoken, SciCall_GetModify()); _urtoken = URTok_NoTransaction; @@ -8541,7 +8542,7 @@ inline static LRESULT _MsgNotifyLean(const SCNotification *const scn, bool* bMod if (*bModified) { DWORD const timeout = Settings2.UndoTransactionTimeout; if (timeout != 0UL) { - if (!((iModType & SC_PERFORMED_UNDO) || (iModType & SC_PERFORMED_REDO))) { + if (!bInUndoRedoStep) { _DelaySplitUndoTransaction(max_dw(_MQ_IMMEDIATE, timeout)); } } diff --git a/src/StyleLexers/styleLexStandard.c b/src/StyleLexers/styleLexStandard.c index 2d1c13c0d..6b048e735 100644 --- a/src/StyleLexers/styleLexStandard.c +++ b/src/StyleLexers/styleLexStandard.c @@ -38,7 +38,7 @@ EDITLEXER lexStandard2nd = { SCLEX_NULL, "null", IDS_LEX_STR_63266, L"2nd Common Base", L"", L"", &KeyWords_NULL,{ - /* 0 */ { {STYLE_DEFAULT}, IDS_LEX_2ND_STYLE, L"2nd Default Style", L"font:Consolas", L"" }, + /* 0 */ { {STYLE_DEFAULT}, IDS_LEX_2ND_STYLE, L"2nd Default Style", L"font:$Code", L"" }, /* 1 */ { {STYLE_LINENUMBER}, IDS_LEX_2ND_MARGIN, L"2nd Margins and Line Numbers", L"font:Consolas; size:-2; fore:#008080", L"" }, /* 2 */ { {STYLE_BRACELIGHT}, IDS_LEX_2ND_BRACE, L"2nd Matching Braces (Indicator)", L"fore:#00FF40; alpha:80; alpha2:220; indic_roundbox", L"" }, /* 3 */ { {STYLE_BRACEBAD}, IDS_LEX_2ND_BRACE_FAIL, L"2nd Matching Braces Error (Indicator)", L"fore:#FF0080; alpha:140; alpha2:220; indic_roundbox", L"" }, diff --git a/src/Styles.c b/src/Styles.c index a0aa7f7bb..866150ab3 100644 --- a/src/Styles.c +++ b/src/Styles.c @@ -2938,81 +2938,58 @@ bool Style_GetFileFilterStr(LPWSTR lpszFilter, int cchFilter, LPWSTR lpszDefExt, //============================================================================= -static WCHAR _DefaultCodingFont[LF_FACESIZE] = { L"\0" }; // session static +static WCHAR _DefaultCodingFont[LF_FACESIZE+1] = { L"\0" }; // session static -static inline bool GetDefaultCodeFont(LPWSTR pwchFontName, int cchFont) +static inline void GetDefaultCodeFont(LPWSTR pwchFontName, int cchFont) { - if (StrIsNotEmpty(_DefaultCodingFont)) { - StringCchCopy(pwchFontName, cchFont, _DefaultCodingFont); - return true; + StringCchCopy(pwchFontName, cchFont, _DefaultCodingFont); + + if (StrIsNotEmpty(pwchFontName)) { + return; } - LPCWSTR const FontNamePrioList[] = { - L"Cascadia Code", - L"Cascadia Mono", - L"Cousine", - L"Fira Code", - L"Source Code Pro", - L"Roboto Mono", - L"DejaVu Sans Mono", - L"Inconsolata", - L"Consolas", - L"Lucida Console" - }; - unsigned const countof = COUNTOF(FontNamePrioList); + unsigned const countof = COUNTOF(Settings2.CodeFontPrefPrioList); unsigned i = 0; for ( ; i < countof; ++i) { - LPCWSTR const fontName = FontNamePrioList[i]; + LPCWSTR const fontName = Settings2.CodeFontPrefPrioList[i]; if (IsFontAvailable(fontName)) { StringCchCopy(pwchFontName, cchFont, fontName); break; } } - if (i >= countof) { + if (StrIsEmpty(pwchFontName)) { StringCchCopy(pwchFontName, cchFont, L"Courier New"); // fallback } StringCchCopy(_DefaultCodingFont, COUNTOF(_DefaultCodingFont), pwchFontName); - - return (i < countof); } -static WORD _wDTFSize = 9; -static WCHAR _DefaultTextFont[LF_FACESIZE] = { L"\0" }; // session static +static WCHAR _DefaultTextFont[LF_FACESIZE+1] = { L"\0" }; // session static -static inline unsigned GetDefaultTextFont(LPWSTR pwchFontName, int cchFont) +static inline void GetDefaultTextFont(LPWSTR pwchFontName, int cchFont) { + StringCchCopy(pwchFontName, LF_FACESIZE, _DefaultTextFont); + if (StrIsNotEmpty(_DefaultTextFont)) { - StringCchCopy(pwchFontName, LF_FACESIZE, _DefaultTextFont); - return _wDTFSize; + return; } - LPCWSTR const FontNamePrioList[] = { - L"Cascadia Mono", - L"Cousine", - L"Roboto Mono", - L"DejaVu Sans Mono", - L"Inconsolata", - L"Consolas", - L"Lucida Console" - }; - unsigned const countof = COUNTOF(FontNamePrioList); + unsigned const countof = COUNTOF(Settings2.TextFontPrefPrioList); unsigned i = 0; for (; i < countof; ++i) { - LPCWSTR const fontName = FontNamePrioList[i]; + LPCWSTR const fontName = Settings2.TextFontPrefPrioList[i]; if (IsFontAvailable(fontName)) { StringCchCopy(pwchFontName, cchFont, fontName); break; } } - if (i >= countof) { + if (StrIsEmpty(pwchFontName)) { + WORD _wDTFSize = 9; GetThemedDialogFont(pwchFontName, &_wDTFSize); } - StringCchCopy(_DefaultTextFont, COUNTOF(_DefaultTextFont), pwchFontName); - return _wDTFSize; } //============================================================================= diff --git a/src/TypeDefs.h b/src/TypeDefs.h index aa769ca2f..5deaf2940 100644 --- a/src/TypeDefs.h +++ b/src/TypeDefs.h @@ -798,6 +798,9 @@ typedef struct SETTINGS2_T { WCHAR HyperlinkFileProtocolVerb[MICRO_BUFFER]; + const WCHAR* CodeFontPrefPrioList[MICRO_BUFFER]; + const WCHAR* TextFontPrefPrioList[MICRO_BUFFER]; + } SETTINGS2_T, *PSETTINGS2_T; #define Default_ExitOnESCSkipLevel 2