From aaab190763b720e2eed6495d8508b970d09ad39c Mon Sep 17 00:00:00 2001 From: ozone10 Date: Tue, 31 Jan 2023 18:07:26 +0100 Subject: [PATCH] Add show non-printable characters command | Name | Codepoint | Abbreviation | |------------------------------|-----------|--------------| | No-Break Space | U+00A0 | NBSP | | Ogham Space Mark | U+1680 | OSPM | | Mongolian Vowel Separator | U+180E | MVS | | En Quad | U+2000 | NQSP | | Em Quad | U+2001 | MQSP | | En Space | U+2002 | ENSP | | Em Space | U+2003 | EMSP | | Three-Per-Em Space | U+2004 | 3/MSP | | Four-Per-Em Space | U+2005 | 4/MSP | | Six-Per-Em Space | U+2006 | 6/MSP | | Figure Space | U+2007 | FSP | | Punctation Space | U+2008 | PSP | | Thin Space | U+2009 | THSP | | Hair Space | U+200A | HSP | | Zero-Width Space | U+200B | ZWSP | | Zero-Width Non-Joiner | U+200C | ZWNJ | | Zero-Width Joiner | U+200D | ZWJ | | Left-To-Right Mark | U+200E | LRM | | Right-To-Left Mark | U+200F | RLM | | Line Separator | U+2028 | LS | | Paragraph Separator | U+2029 | PS | | Left-To-Right Embedding | U+202A | LRE | | Right-To-Left Embedding | U+202B | RLE | | Pop Directional Formatting | U+202C | PDF | | Left-To-Right Override | U+202D | LRO | | Right-To-Left Override | U+202E | RLO | | Narrow No-Break Space | U+202F | NNBSP | | Medium Mathematical Space | U+205F | MMSP | | Word Joiner | U+2060 | WJ | | Left-To-Right Isolate | U+2066 | LRI | | Right-To-Left Isolate | U+2067 | RLI | | First Strong Isolate | U+2068 | FSI | | Pop Directional Isolate | U+2069 | PDI | | Inhibit Symmetric Swapping | U+206A | ISS | | Activate Symmetric Swapping | U+206B | ASS | | Inhibit Arabic Form Shaping | U+206C | IAFS | | Activate Arabic Form Shaping | U+206D | AAFS | | National Digit Shapes | U+206E | NADS | | Nominal Digit Shapes | U+206F | NODS | | Ideographic Space | U+3000 | IDSP | | Zero-Width No-Break Space | U+FEFF | ZWNBSP | Fix also issue with tooltips in preference dialog, when changing between dark/light mode. Fix #827, fix #4731, fix #8284, close #13020 --- PowerEditor/installer/nativeLang/english.xml | 32 ++++- .../installer/themes/DarkModeDefault.xml | 1 + PowerEditor/src/Notepad_plus.cpp | 37 ++---- PowerEditor/src/Notepad_plus.rc | 11 +- PowerEditor/src/Notepad_plus_Window.cpp | 3 + PowerEditor/src/NppBigSwitch.cpp | 28 ++++ PowerEditor/src/NppCommands.cpp | 100 ++++++++++---- PowerEditor/src/Parameters.cpp | 81 ++++++++++++ PowerEditor/src/Parameters.h | 6 + .../ScintillaComponent/ScintillaEditView.cpp | 47 +++++++ .../ScintillaComponent/ScintillaEditView.h | 94 ++++++++++++- .../WinControls/ColourPicker/WordStyleDlg.cpp | 5 + .../src/WinControls/Preference/preference.rc | 71 +++++----- .../WinControls/Preference/preferenceDlg.cpp | 123 +++++++++++++++--- .../WinControls/Preference/preferenceDlg.h | 24 ++++ .../WinControls/Preference/preference_rc.h | 6 + PowerEditor/src/menuCmdID.h | 2 + PowerEditor/src/resource.h | 3 + PowerEditor/src/stylers.model.xml | 1 + 19 files changed, 564 insertions(+), 111 deletions(-) diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml index 949485657..5655c73bd 100644 --- a/PowerEditor/installer/nativeLang/english.xml +++ b/PowerEditor/installer/nativeLang/english.xml @@ -265,7 +265,7 @@ The comments are here for explanation, it's not necessary to translate them. - + @@ -295,6 +295,7 @@ The comments are here for explanation, it's not necessary to translate them. + @@ -925,6 +926,10 @@ The comments are here for explanation, it's not necessary to translate them. + + + + @@ -1638,6 +1643,31 @@ NOTE: 1. Modifying options here requires re-open currently opened large files to get proper behavior. 2. If "Deactivate Word Wrap globally" is checked and you open a large file, "Word Wrap" will be disabled for all files. You can re-enable it via menu "View->Word Wrap"." /> + + + + diff --git a/PowerEditor/installer/themes/DarkModeDefault.xml b/PowerEditor/installer/themes/DarkModeDefault.xml index 14d64fbf1..8ae515090 100644 --- a/PowerEditor/installer/themes/DarkModeDefault.xml +++ b/PowerEditor/installer/themes/DarkModeDefault.xml @@ -1455,5 +1455,6 @@ License: GPL2 + diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 601d41609..1f4f530ef 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -4707,9 +4707,9 @@ void Notepad_plus::bookmarkNext(bool forwardScan) lineRetry = _pEditView->execute(SCI_GETLINECOUNT); //If not found, try from the end sci_marker = SCI_MARKERPREVIOUS; } - intptr_t nextLine = _pEditView->execute(sci_marker, lineStart, 1 << MARK_BOOKMARK); + intptr_t nextLine = _pEditView->execute(sci_marker, lineStart, static_cast(1 << MARK_BOOKMARK)); if (nextLine < 0) - nextLine = _pEditView->execute(sci_marker, lineRetry, 1 << MARK_BOOKMARK); + nextLine = _pEditView->execute(sci_marker, lineRetry, static_cast(1 << MARK_BOOKMARK)); if (nextLine < 0) return; @@ -4721,32 +4721,17 @@ void Notepad_plus::bookmarkNext(bool forwardScan) void Notepad_plus::staticCheckMenuAndTB() const { // Visibility of invisible characters - bool wsTabShow = _pEditView->isInvisibleCharsShown(); - bool eolShow = _pEditView->isEolVisible(); + const bool wsTabShow = _pEditView->isShownSpaceAndTab(); + const bool eolShow = _pEditView->isShownEol(); + const bool npcShow = _pEditView->isShownNpc(); - bool onlyWS = false; - bool onlyEOL = false; - bool bothWSEOL = false; - if (wsTabShow) - { - if (eolShow) - { - bothWSEOL = true; - } - else - { - onlyWS = true; - } - } - else if (eolShow) - { - onlyEOL = true; - } + const bool allShow = wsTabShow && eolShow && npcShow; - checkMenuItem(IDM_VIEW_TAB_SPACE, onlyWS); - checkMenuItem(IDM_VIEW_EOL, onlyEOL); - checkMenuItem(IDM_VIEW_ALL_CHARACTERS, bothWSEOL); - _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, bothWSEOL); + checkMenuItem(IDM_VIEW_TAB_SPACE, wsTabShow); + checkMenuItem(IDM_VIEW_EOL, eolShow); + checkMenuItem(IDM_VIEW_NPC, npcShow); + checkMenuItem(IDM_VIEW_ALL_CHARACTERS, allShow); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allShow); // Visibility of the indentation guide line bool b = _pEditView->isShownIndentGuide(); diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index 3083ffa08..408c0b877 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -668,12 +668,13 @@ BEGIN MENUITEM SEPARATOR POPUP "Show Symbol" BEGIN - MENUITEM "Show White Space and TAB", IDM_VIEW_TAB_SPACE - MENUITEM "Show End of Line", IDM_VIEW_EOL - MENUITEM "Show All Characters", IDM_VIEW_ALL_CHARACTERS + MENUITEM "Show Space and Tab", IDM_VIEW_TAB_SPACE + MENUITEM "Show End of Line", IDM_VIEW_EOL + MENUITEM "Show Non-Printing Characters", IDM_VIEW_NPC + MENUITEM "Show All Characters", IDM_VIEW_ALL_CHARACTERS MENUITEM SEPARATOR - MENUITEM "Show Indent Guide", IDM_VIEW_INDENT_GUIDE - MENUITEM "Show Wrap Symbol", IDM_VIEW_WRAP_SYMBOL + MENUITEM "Show Indent Guide", IDM_VIEW_INDENT_GUIDE + MENUITEM "Show Wrap Symbol", IDM_VIEW_WRAP_SYMBOL END POPUP "Zoom" BEGIN diff --git a/PowerEditor/src/Notepad_plus_Window.cpp b/PowerEditor/src/Notepad_plus_Window.cpp index f83379427..274494bbb 100644 --- a/PowerEditor/src/Notepad_plus_Window.cpp +++ b/PowerEditor/src/Notepad_plus_Window.cpp @@ -310,6 +310,8 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin ::SendMessage(_hSelf, NPPM_INTERNAL_CRLFFORMCHANGED, 0, 0); + ::SendMessage(_hSelf, NPPM_INTERNAL_NPCFORMCHANGED, 0, 0); + ::SendMessage(_hSelf, NPPM_INTERNAL_ENABLECHANGEHISTORY, 0, 0); // Notify plugins that Notepad++ is ready @@ -393,6 +395,7 @@ void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLin // Make this call later to take effect ::SendMessage(_hSelf, NPPM_INTERNAL_SETWORDCHARS, 0, 0); + ::SendMessage(_hSelf, NPPM_INTERNAL_SETNPC, 0, 0); if (nppParams.doFunctionListExport()) ::SendMessage(_hSelf, NPPM_INTERNAL_EXPORTFUNCLISTANDQUIT, 0, 0); diff --git a/PowerEditor/src/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index 57c869be6..adad274dd 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -1740,6 +1740,14 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa return TRUE; } + case NPPM_INTERNAL_SETNPC: + { + const bool isShown = nppParam.getSVP()._npcShow; + _mainEditView.showNpc(isShown); + _subEditView.showNpc(isShown); + return TRUE; + } + case NPPM_INTERNAL_SETMULTISELCTION: { const NppGUI & nppGUI = nppParam.getNppGUI(); @@ -2913,6 +2921,13 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa _subEditView.setCRLF(); return TRUE; } + + case NPPM_INTERNAL_NPCFORMCHANGED: + { + _mainEditView.setNPC(); + _subEditView.setNPC(); + return TRUE; + } case NPPM_INTERNAL_ENABLECHANGEHISTORY: { @@ -2954,6 +2969,19 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa return TRUE; } + case NPPM_INTERNAL_NPCLAUNCHSTYLECONF: + { + // Launch _configStyleDlg (create or display it) + command(IDM_LANGSTYLE_CONFIG_DLG); + + // go into the section we need + generic_string npcStr = L"Global Styles:"; + npcStr += g_npcStyleName; + _configStyleDlg.goToSection(npcStr.c_str()); + + return TRUE; + } + case NPPM_INTERNAL_LAUNCHPREFERENCES: { // Launch _configStyleDlg (create or display it) diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index b3537d2c5..76e0a9614 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -2299,51 +2299,95 @@ void Notepad_plus::command(int id) case IDM_VIEW_TAB_SPACE: { - bool isChecked = !(::GetMenuState(_mainMenuHandle, IDM_VIEW_TAB_SPACE, MF_BYCOMMAND) == MF_CHECKED); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_EOL, MF_BYCOMMAND | MF_UNCHECKED); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_ALL_CHARACTERS, MF_BYCOMMAND | MF_UNCHECKED); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_TAB_SPACE, MF_BYCOMMAND | (isChecked?MF_CHECKED:MF_UNCHECKED)); - _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, false); - _mainEditView.showEOL(false); + auto setCheckMenuItem = [this](int id, bool check) -> DWORD { + return ::CheckMenuItem(_mainMenuHandle, id, MF_BYCOMMAND | (check ? MF_CHECKED : MF_UNCHECKED)); + }; + + const bool isChecked = !(::GetMenuState(_mainMenuHandle, id, MF_BYCOMMAND) == MF_CHECKED); + setCheckMenuItem(id, isChecked); + _mainEditView.showWSAndTab(isChecked); - _subEditView.showEOL(false); _subEditView.showWSAndTab(isChecked); - ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance()).getSVP(); - svp1._whiteSpaceShow = isChecked; - svp1._eolShow = false; + auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); + svp1._whiteSpaceShow = isChecked; + + const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow; + + setCheckMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allChecked); + break; } + case IDM_VIEW_EOL: { - bool isChecked = !(::GetMenuState(_mainMenuHandle, IDM_VIEW_EOL, MF_BYCOMMAND) == MF_CHECKED); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_TAB_SPACE, MF_BYCOMMAND | MF_UNCHECKED); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_EOL, MF_BYCOMMAND | (isChecked?MF_CHECKED:MF_UNCHECKED)); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_ALL_CHARACTERS, MF_BYCOMMAND | MF_UNCHECKED); - _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, false); + auto setCheckMenuItem = [this](int id, bool check) -> DWORD { + return ::CheckMenuItem(_mainMenuHandle, id, MF_BYCOMMAND | (check ? MF_CHECKED : MF_UNCHECKED)); + }; + + const bool isChecked = !(::GetMenuState(_mainMenuHandle, id, MF_BYCOMMAND) == MF_CHECKED); + setCheckMenuItem(id, isChecked); + _mainEditView.showEOL(isChecked); _subEditView.showEOL(isChecked); - _mainEditView.showWSAndTab(false); - _subEditView.showWSAndTab(false); - ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance()).getSVP(); - svp1._whiteSpaceShow = false; - svp1._eolShow = isChecked; + auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); + svp1._eolShow = isChecked; + + const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow; + + setCheckMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allChecked); + break; } + + case IDM_VIEW_NPC: + { + auto setCheckMenuItem = [this](int id, bool check) -> DWORD { + return ::CheckMenuItem(_mainMenuHandle, id, MF_BYCOMMAND | (check ? MF_CHECKED : MF_UNCHECKED)); + }; + + const bool isChecked = !(::GetMenuState(_mainMenuHandle, id, MF_BYCOMMAND) == MF_CHECKED); + setCheckMenuItem(id, isChecked); + + _mainEditView.showNpc(isChecked); + _subEditView.showNpc(isChecked); + + auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); + svp1._npcShow = isChecked; + + const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow; + + setCheckMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allChecked); + + break; + } + case IDM_VIEW_ALL_CHARACTERS: { - bool isChecked = !(::GetMenuState(_mainMenuHandle, id, MF_BYCOMMAND) == MF_CHECKED); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_EOL, MF_BYCOMMAND | MF_UNCHECKED); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_TAB_SPACE, MF_BYCOMMAND | MF_UNCHECKED); - ::CheckMenuItem(_mainMenuHandle, IDM_VIEW_ALL_CHARACTERS, MF_BYCOMMAND | (isChecked?MF_CHECKED:MF_UNCHECKED)); + auto setCheckMenuItem = [this](int id, bool check) -> DWORD { + return ::CheckMenuItem(_mainMenuHandle, id, MF_BYCOMMAND | (check ? MF_CHECKED : MF_UNCHECKED)); + }; + + const bool isChecked = !(::GetMenuState(_mainMenuHandle, id, MF_BYCOMMAND) == MF_CHECKED); + setCheckMenuItem(id, isChecked); + setCheckMenuItem(IDM_VIEW_TAB_SPACE, isChecked); + setCheckMenuItem(IDM_VIEW_EOL, isChecked); + setCheckMenuItem(IDM_VIEW_NPC, isChecked); + _toolBar.setCheck(id, isChecked); + _mainEditView.showInvisibleChars(isChecked); _subEditView.showInvisibleChars(isChecked); - _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, isChecked); - ScintillaViewParams & svp1 = (ScintillaViewParams &)(NppParameters::getInstance()).getSVP(); - svp1._whiteSpaceShow = isChecked; - svp1._eolShow = isChecked; + auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); + + svp1._whiteSpaceShow = isChecked; + svp1._eolShow = isChecked; + svp1._npcShow = isChecked; + break; } diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 71a998b2a..b2422c38a 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -260,6 +260,7 @@ static const WinMenuKeyDefinition winKeyDefs[] = { VK_NULL, IDM_VIEW_TAB_SPACE, false, false, false, nullptr }, { VK_NULL, IDM_VIEW_EOL, false, false, false, nullptr }, { VK_NULL, IDM_VIEW_ALL_CHARACTERS, false, false, false, nullptr }, + { VK_NULL, IDM_VIEW_NPC, false, false, false, nullptr }, { VK_NULL, IDM_VIEW_INDENT_GUIDE, false, false, false, nullptr }, { VK_NULL, IDM_VIEW_WRAP_SYMBOL, false, false, false, nullptr }, // { VK_NULL, IDM_VIEW_ZOOMIN, false, false, false, nullptr }, @@ -3884,6 +3885,13 @@ bool NppParameters::feedStylerArray(TiXmlNode *node) } } + constexpr auto rgbhex = [](COLORREF bbggrr) -> int { + return + ((bbggrr & 0xFF0000) >> 16) | + ((bbggrr & 0x00FF00)) | + ((bbggrr & 0x0000FF) << 16); + }; + const Style* pStyle = _widgetStyleArray.findByName(TEXT("EOL custom color")); if (!pStyle) { @@ -3895,6 +3903,30 @@ bool NppParameters::feedStylerArray(TiXmlNode *node) _widgetStyleArray.addStyler(0, eolColorkNode); } + const Style* pStyleNpc = _widgetStyleArray.findByName(g_npcStyleName); + if (!pStyleNpc) + { + TiXmlNode* npcColorkNode = globalStyleRoot->InsertEndChild(TiXmlElement(TEXT("WidgetStyle"))); + npcColorkNode->ToElement()->SetAttribute(TEXT("name"), g_npcStyleName); + npcColorkNode->ToElement()->SetAttribute(TEXT("styleID"), TEXT("0")); + + // use color from style White space symbol + const Style* pStyleWS = _widgetStyleArray.findByName(TEXT("White space symbol")); + if (pStyleWS) + { + constexpr size_t bufSize = 7; + wchar_t strColor[bufSize] = { '\0' }; + swprintf(strColor, bufSize, L"%6X", rgbhex(pStyleWS->_fgColor)); + npcColorkNode->ToElement()->SetAttribute(L"fgColor", strColor); + } + else + { + npcColorkNode->ToElement()->SetAttribute(L"fgColor", L"DADADA"); + } + + _widgetStyleArray.addStyler(0, npcColorkNode); + } + return true; } @@ -6027,6 +6059,30 @@ void NppParameters::feedScintillaParam(TiXmlNode *node) { TiXmlElement* element = node->ToElement(); + auto parseYesNoBoolAttribute = [&element](const TCHAR* name, bool defaultValue = false) -> bool { + const TCHAR* nm = element->Attribute(name); + if (nm) + { + if (!lstrcmp(nm, TEXT("yes"))) + return true; + else if (!lstrcmp(nm, TEXT("no"))) + return false; + } + return defaultValue; + }; + + auto parseShowHideBoolAttribute = [&element](const TCHAR* name, bool defaultValue = false) -> bool { + const TCHAR* nm = element->Attribute(name); + if (nm) + { + if (!lstrcmp(nm, TEXT("show"))) + return true; + else if (!lstrcmp(nm, TEXT("hide"))) + return false; + } + return defaultValue; + }; + // Line Number Margin const TCHAR *nm = element->Attribute(TEXT("lineNumberMargin")); if (nm) @@ -6276,6 +6332,18 @@ void NppParameters::feedScintillaParam(TiXmlNode *node) _svp._eolMode = static_cast(val); } + // Unicode non-printable characters visibility State + _svp._npcShow = parseShowHideBoolAttribute(TEXT("npcShow")); + + nm = element->Attribute(TEXT("npcMode"), &val); + if (nm) + { + if (val >= 1 && val <= 2) + _svp._npcMode = static_cast(val); + } + + _svp._npcCustomColor = parseYesNoBoolAttribute(TEXT("npcCustomColor")); + nm = element->Attribute(TEXT("borderWidth"), &val); if (nm) { @@ -6529,6 +6597,16 @@ bool NppParameters::writeScintillaParams() (scintNode->ToElement())->SetAttribute(TEXT("name"), pViewName); } + auto setYesNoBoolAttribute = [&scintNode](const TCHAR* name, bool value) -> void { + const TCHAR* pStr = value ? TEXT("yes") : TEXT("no"); + (scintNode->ToElement())->SetAttribute(name, pStr); + }; + + auto setShowHideBoolAttribute = [&scintNode](const TCHAR* name, bool value) -> void { + const TCHAR* pStr = value ? TEXT("show") : TEXT("hide"); + (scintNode->ToElement())->SetAttribute(name, pStr); + }; + (scintNode->ToElement())->SetAttribute(TEXT("lineNumberMargin"), _svp._lineNumberMarginShow?TEXT("show"):TEXT("hide")); (scintNode->ToElement())->SetAttribute(TEXT("lineNumberDynamicWidth"), _svp._lineNumberMarginDynamicWidth ?TEXT("yes"):TEXT("no")); (scintNode->ToElement())->SetAttribute(TEXT("bookMarkMargin"), _svp._bookMarkMarginShow?TEXT("show"):TEXT("hide")); @@ -6568,6 +6646,9 @@ bool NppParameters::writeScintillaParams() (scintNode->ToElement())->SetAttribute(TEXT("whiteSpaceShow"), _svp._whiteSpaceShow?TEXT("show"):TEXT("hide")); (scintNode->ToElement())->SetAttribute(TEXT("eolShow"), _svp._eolShow?TEXT("show"):TEXT("hide")); (scintNode->ToElement())->SetAttribute(TEXT("eolMode"), _svp._eolMode); + setShowHideBoolAttribute(TEXT("npcShow"), _svp._npcShow); + (scintNode->ToElement())->SetAttribute(TEXT("npcMode"), static_cast(_svp._npcMode)); + setYesNoBoolAttribute(TEXT("npcCustomColor"), _svp._npcCustomColor); (scintNode->ToElement())->SetAttribute(TEXT("borderWidth"), _svp._borderWidth); (scintNode->ToElement())->SetAttribute(TEXT("smoothFont"), _svp._doSmoothFont ? TEXT("yes") : TEXT("no")); (scintNode->ToElement())->SetAttribute(TEXT("paddingLeft"), _svp._paddingLeft); diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index 5d20f3237..c1c1c7e76 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -147,6 +147,8 @@ const TCHAR nppLogNulContentCorruptionIssue[] = TEXT("nppLogNulContentCorruption void cutString(const TCHAR *str2cut, std::vector & patternVect); void cutStringBy(const TCHAR *str2cut, std::vector & patternVect, char byChar, bool allowEmptyStr); +// style names +const wchar_t g_npcStyleName[] = L"Non-printing characters custom color"; struct Position { @@ -943,6 +945,10 @@ struct ScintillaViewParams bool _eolShow = false; enum crlfMode {plainText = 0, roundedRectangleText = 1, plainTextCustomColor = 2, roundedRectangleTextCustomColor = 3}; crlfMode _eolMode = roundedRectangleText; + bool _npcShow = false; + enum npcMode { identity = 0, abbreviation = 1, codepoint = 2 }; + npcMode _npcMode = abbreviation; + bool _npcCustomColor = false; int _borderWidth = 2; bool _virtualSpace = false; diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp index bd3b34dd0..41c237122 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp @@ -1418,6 +1418,39 @@ void ScintillaEditView::setCRLF(long color) redraw(); } +void ScintillaEditView::setNPC(long color) +{ + NppParameters& nppParams = NppParameters::getInstance(); + const ScintillaViewParams& svp = nppParams.getSVP(); + + COLORREF npcCustomColor = liteGrey; + + if (color == -1) + { + StyleArray& stylers = nppParams.getMiscStylerArray(); + Style* pStyle = stylers.findByName(g_npcStyleName); + if (pStyle) + { + npcCustomColor = pStyle->_fgColor; + } + } + else + { + npcCustomColor = color; + } + + const long appearance = svp._npcCustomColor ? SC_REPRESENTATION_BLOB | SC_REPRESENTATION_COLOUR : SC_REPRESENTATION_BLOB; + const long alphaNpcCustomColor = npcCustomColor | 0xFF000000; // add alpha color to make DirectWrite mode work + + for (const auto& invChar : g_nonPrintingChars) + { + execute(SCI_SETREPRESENTATIONCOLOUR, reinterpret_cast(invChar.at(0)), alphaNpcCustomColor); + execute(SCI_SETREPRESENTATIONAPPEARANCE, reinterpret_cast(invChar.at(0)), appearance); + } + + redraw(); +} + void ScintillaEditView::defineDocType(LangType typeDoc) { StyleArray & stylers = NppParameters::getInstance().getMiscStylerArray(); @@ -2010,7 +2043,13 @@ void ScintillaEditView::activateBuffer(BufferID buffer, bool force) runMarkers(true, 0, true, false); + if (isShownNpc()) + { + showNpc(); + } + setCRLF(); + setNPC(); NppParameters& nppParam = NppParameters::getInstance(); const ScintillaViewParams& svp = nppParam.getSVP(); @@ -2784,6 +2823,14 @@ void ScintillaEditView::performGlobalStyles() eolCustomColor = pStyle->_fgColor; } setCRLF(eolCustomColor); + + COLORREF npcCustomColor = liteGrey; + pStyle = stylers.findByName(g_npcStyleName); + if (pStyle) + { + npcCustomColor = pStyle->_fgColor; + } + setNPC(npcCustomColor); } void ScintillaEditView::showIndentGuideLine(bool willBeShowed) diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h index 8cf82a2c1..75e63b027 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h @@ -120,9 +120,53 @@ const int MARK_HIDELINESUNDERLINE = 17; // 20 - 17 reserved for Notepad++ internal used // 16 - 0 are free to use for plugins +const std::vector> g_nonPrintingChars = +{ + {"\xC2\xA0", "NBSP", "U+00A0"}, // U+00A0 : no-break space + {"\xE1\x9A\x80", "OSPM", "U+1680"}, // U+1680 : ogham space mark + {"\xE1\xA0\x8E", "MVS", "U+180E"}, // U+180E : mongolian vowel separator + {"\xE2\x80\x80", "NQSP", "U+2000"}, // U+2000 : en quad + {"\xE2\x80\x81", "MQSP", "U+2001"}, // U+2001 : em quad + {"\xE2\x80\x82", "ENSP", "U+2002"}, // U+2002 : en space + {"\xE2\x80\x83", "EMSP", "U+2003"}, // U+2003 : em space + {"\xE2\x80\x84", "3/MSP", "U+2004"}, // U+2004 : three-per-em space + {"\xE2\x80\x85", "4/MSP", "U+2005"}, // U+2005 : four-per-em space + {"\xE2\x80\x86", "6/MSP", "U+2006"}, // U+2006 : six-per-em space + {"\xE2\x80\x87", "FSP", "U+2007"}, // U+2007 : figure space + {"\xE2\x80\x88", "PSP", "U+2008"}, // U+2008 : punctation space + {"\xE2\x80\x89", "THSP", "U+2009"}, // U+2009 : thin space + {"\xE2\x80\x8A", "HSP", "U+200A"}, // U+200A : hair space + {"\xE2\x80\x8B", "ZWSP", "U+200B"}, // U+200B : zero-width space + {"\xE2\x80\x8C", "ZWNJ", "U+200C"}, // U+200C : zero-width non-joiner + {"\xE2\x80\x8D", "ZWJ", "U+200D"}, // U+200D : zero-width joiner + {"\xE2\x80\x8E", "LRM", "U+200E"}, // U+200E : left-to-right mark + {"\xE2\x80\x8F", "RLM", "U+200F"}, // U+200F : right-to-left mark + {"\xE2\x80\xA8", "LS", "U+2028"}, // U+2028 : line separator + {"\xE2\x80\xA9", "PS", "U+2029"}, // U+2029 : paragraph separator + {"\xE2\x80\xAA", "LRE", "U+202A"}, // U+202A : left-to-right embedding + {"\xE2\x80\xAB", "RLE", "U+202B"}, // U+202B : right-to-left embedding + {"\xE2\x80\xAC", "PDF", "U+202C"}, // U+202C : pop directional formatting + {"\xE2\x80\xAD", "LRO", "U+202D"}, // U+202D : left-to-right override + {"\xE2\x80\xAE", "RLO", "U+202E"}, // U+202E : right-to-left override + {"\xE2\x80\xAF", "NNBSP", "U+202F"}, // U+202F : narrow no-break space + {"\xE2\x81\x9F", "MMSP", "U+205F"}, // U+205F : medium mathematical space + {"\xE2\x81\xA0", "WJ", "U+2060"}, // U+2060 : word joiner + {"\xE2\x81\xA6", "LRI", "U+2066"}, // U+2066 : left-to-right isolate + {"\xE2\x81\xA7", "RLI", "U+2067"}, // U+2067 : right-to-left isolate + {"\xE2\x81\xA8", "FSI", "U+2068"}, // U+2068 : first strong isolate + {"\xE2\x81\xA9", "PDI", "U+2069"}, // U+2069 : pop directional isolate + {"\xE2\x81\xAA", "ISS", "U+206A"}, // U+206A : inhibit symmetric swapping + {"\xE2\x81\xAB", "ASS", "U+206B"}, // U+206B : activate symmetric swapping + {"\xE2\x81\xAC", "IAFS", "U+206C"}, // U+206C : inhibit arabic form shaping + {"\xE2\x81\xAD", "AAFS", "U+206D"}, // U+206D : activate arabic form shaping + {"\xE2\x81\xAE", "NADS", "U+206E"}, // U+206E : national digit shapes + {"\xE2\x81\xAF", "NODS", "U+206F"}, // U+206F : nominal digit shapes + {"\xE3\x80\x80", "IDSP", "U+3000"}, // U+3000 : ideographic space + {"\xEF\xBB\xBF", "ZWNBSP", "U+FEFF"} // U+FEFF : zero-width no-break space +}; int getNbDigits(int aNum, int base); -HMODULE loadSciLexerDll(); +//HMODULE loadSciLexerDll(); TCHAR * int2str(TCHAR *str, int strLen, int number, int base, int nbChiffre, bool isZeroLeading); @@ -351,21 +395,60 @@ public: execute(SCI_SETWHITESPACESIZE, 2, 0); }; + bool isShownSpaceAndTab() { + return (execute(SCI_GETVIEWWS) != 0); + }; + void showEOL(bool willBeShowed = true) { execute(SCI_SETVIEWEOL, willBeShowed); }; - bool isEolVisible() { + bool isShownEol() { return (execute(SCI_GETVIEWEOL) != 0); }; + + void showNpc(bool willBeShowed = true) { + auto& svp = NppParameters::getInstance().getSVP(); + if (willBeShowed) + { + const auto& mode = static_cast(svp._npcMode); + for (const auto& invChar : g_nonPrintingChars) + { + execute(SCI_SETREPRESENTATION, reinterpret_cast(invChar.at(0)), reinterpret_cast(invChar.at(mode))); + } + + if (svp._npcCustomColor) + { + setNPC(); + } + } + else + { + execute(SCI_CLEARALLREPRESENTATIONS); + + // SCI_CLEARALLREPRESENTATIONS will also reset CRLF + if (svp._eolMode != svp.roundedRectangleText) + { + setCRLF(); + } + } + redraw(); + }; + + bool isShownNpc() { + auto& svp = NppParameters::getInstance().getSVP(); + return svp._npcShow; + }; + void showInvisibleChars(bool willBeShowed = true) { + showNpc(willBeShowed); showWSAndTab(willBeShowed); showEOL(willBeShowed); }; - bool isInvisibleCharsShown() { - return (execute(SCI_GETVIEWWS) != 0); - }; + //bool isShownInvisibleChars() { + // return isShownSpaceTab() && isShownEol() && isShownNpc(); + //}; void showIndentGuideLine(bool willBeShowed = true); @@ -574,6 +657,7 @@ public: void restoreDefaultWordChars(); void setWordChars(); void setCRLF(long color = -1); + void setNPC(long color = -1); void mouseWheel(WPARAM wParam, LPARAM lParam) { scintillaNew_Proc(_hSelf, WM_MOUSEWHEEL, wParam, lParam); diff --git a/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp b/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp index 26d129db7..423f7b304 100644 --- a/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp +++ b/PowerEditor/src/WinControls/ColourPicker/WordStyleDlg.cpp @@ -984,6 +984,11 @@ std::pair WordStyleDlg::goToPreferencesSettings() result.first = 1; result.second = IDC_CHECK_WITHCUSTOMCOLOR_CRLF; } + else if (style._styleDesc == g_npcStyleName) + { + result.first = 1; + result.second = IDC_CHECK_NPC_COLOR; + } return result; } diff --git a/PowerEditor/src/WinControls/Preference/preference.rc b/PowerEditor/src/WinControls/Preference/preference.rc index 853c4f5d4..03a7ed566 100644 --- a/PowerEditor/src/WinControls/Preference/preference.rc +++ b/PowerEditor/src/WinControls/Preference/preference.rc @@ -70,36 +70,47 @@ IDD_PREFERENCE_SUB_EDITING DIALOGEX 115, 10, 460, 205 STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD FONT 8, "MS Shell Dlg", 0, 0, 0x1 BEGIN - GROUPBOX "EOL (CRLF)",IDC_GB_STATIC_CRLF,32,6,150,67,BS_CENTER - CONTROL "Default",IDC_RADIO_ROUNDCORNER_CRLF,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP | WS_GROUP,39,18,118,10 - CONTROL "Plain Text",IDC_RADIO_PLEINTEXT_CRLF,"Button",BS_AUTORADIOBUTTON,39,33,117,10 - CONTROL "Custom Color",IDC_CHECK_WITHCUSTOMCOLOR_CRLF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,39,50,100,10 - PUSHBUTTON "...",IDC_BUTTON_LAUNCHSTYLECONF_CRLF,140,48,14,14 - GROUPBOX "Line Wrap",IDC_LW_GB_STATIC,194,6,78,67,BS_CENTER - CONTROL "Default",IDC_RADIO_LWDEF,"Button",BS_AUTORADIOBUTTON | WS_GROUP,203,21,59,10 - CONTROL "Aligned",IDC_RADIO_LWALIGN,"Button",BS_AUTORADIOBUTTON,203,36,60,10 - CONTROL "Indent",IDC_RADIO_LWINDENT,"Button",BS_AUTORADIOBUTTON,203,51,62,10 - GROUPBOX "Current Line Indicator",IDC_CURRENTLINEMARK_STATIC,284,6,156,67,BS_CENTER - CONTROL "None",IDC_RADIO_CLM_NONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,299,15,100,10 - CONTROL "Highlight Background",IDC_RADIO_CLM_HILITE,"Button",BS_AUTORADIOBUTTON,299,30,100,10 - CONTROL "Frame",IDC_RADIO_CLM_FRAME,"Button",BS_AUTORADIOBUTTON,299,45,100,10 - LTEXT "Width :",IDC_CARETLINEFRAME_WIDTH_STATIC,291,60,37,8,0,WS_EX_RIGHT - CONTROL "",IDC_CARETLINEFRAME_WIDTH_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | TBS_TRANSPARENTBKGND | WS_TABSTOP,329,59,57,13 - LTEXT "1",IDC_CARETLINEFRAME_WIDTH_DISPLAY,388,60,12,8 - GROUPBOX "Caret Settings",IDC_CARETSETTING_STATIC,284,77,156,48,BS_CENTER - LTEXT "Width :",IDC_WIDTH_STATIC,311,93,37,8,0,WS_EX_RIGHT - COMBOBOX IDC_WIDTH_COMBO,355,91,40,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP - RTEXT "Blink rate :",IDC_BLINKRATE_STATIC,286,108,60,8 - CONTROL "",IDC_CARETBLINKRATE_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | TBS_TRANSPARENTBKGND | WS_TABSTOP,363,106,57,13 - LTEXT "S",IDC_CARETBLINKRATE_S_STATIC,424,107,12,8 - LTEXT "F",IDC_CARETBLINKRATE_F_STATIC,351,107,12,8,0,WS_EX_RIGHT - CONTROL "Enable smooth font",IDC_CHECK_SMOOTHFONT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,26,103,250,10 - CONTROL "Enable virtual space",IDC_CHECK_VIRTUALSPACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,26,116,250,10 - CONTROL "Make current level folding/unfolding commands toggleable",IDC_CHECK_FOLDINGTOGGLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,26,129,270,10 - CONTROL "Enable Multi-Editing (Ctrl+Mouse click/selection)",IDC_CHECK_MULTISELECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,26,142,270,10 - CONTROL "Enable scrolling beyond last line",IDC_CHECK_SCROLLBEYONDLASTLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,26,155,270,10 - CONTROL "Keep selection when right-click outside of selection",IDC_CHECK_RIGHTCLICKKEEPSSELECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,26,168,270,10 - CONTROL "Disable advanced scrolling feature due to touchpad issue",IDC_CHECK_DISABLEADVANCEDSCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,26,181,270,10 + GROUPBOX "Non-Printing Characters",IDC_GB_STATIC_NPC,11,3,150,59,BS_CENTER + PUSHBUTTON "?",IDC_BUTTON_NPC_NOTE,141,14,16,14,NOT WS_TABSTOP + CONTROL "Abbreviation",IDC_RADIO_NPC_ABBREVIATION,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP | WS_GROUP,17,16,110,10 + CONTROL "Codepoint",IDC_RADIO_NPC_CODEPOINT,"Button",BS_AUTORADIOBUTTON,17,31,110,10 + CONTROL "Custom Color",IDC_CHECK_NPC_COLOR,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,47,110,10 + PUSHBUTTON "...",IDC_BUTTON_NPC_LAUNCHSTYLECONF,141,44,16,14 + + GROUPBOX "Current Line Indicator",IDC_CURRENTLINEMARK_STATIC,11,68,150,74,BS_CENTER + CONTROL "None",IDC_RADIO_CLM_NONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,17,81,100,10 + CONTROL "Highlight Background",IDC_RADIO_CLM_HILITE,"Button",BS_AUTORADIOBUTTON,17,96,100,10 + CONTROL "Frame",IDC_RADIO_CLM_FRAME,"Button",BS_AUTORADIOBUTTON,17,111,100,10 + RTEXT "Width :",IDC_CARETLINEFRAME_WIDTH_STATIC,30,125,37,8 + CONTROL "",IDC_CARETLINEFRAME_WIDTH_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | TBS_TRANSPARENTBKGND | WS_TABSTOP,68,124,57,13 + LTEXT "1",IDC_CARETLINEFRAME_WIDTH_DISPLAY,127,125,12,8 + + GROUPBOX "Caret Settings",IDC_CARETSETTING_STATIC,11,148,150,47,BS_CENTER + RTEXT "Width :",IDC_WIDTH_STATIC,30,164,37,8 + COMBOBOX IDC_WIDTH_COMBO,73,162,40,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP + RTEXT "Blink rate :",IDC_BLINKRATE_STATIC,14,179,53,8 + CONTROL "",IDC_CARETBLINKRATE_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | TBS_TRANSPARENTBKGND | WS_TABSTOP,81,178,57,13 + LTEXT "S",IDC_CARETBLINKRATE_S_STATIC,140,179,12,8 + RTEXT "F",IDC_CARETBLINKRATE_F_STATIC,68,179,12,8 + + GROUPBOX "EOL (CRLF)",IDC_GB_STATIC_CRLF,171,3,130,59,BS_CENTER + CONTROL "Default",IDC_RADIO_ROUNDCORNER_CRLF,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP | WS_GROUP,177,16,100,10 + CONTROL "Plain Text",IDC_RADIO_PLEINTEXT_CRLF,"Button",BS_AUTORADIOBUTTON,177,31,100,10 + CONTROL "Custom Color",IDC_CHECK_WITHCUSTOMCOLOR_CRLF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,177,47,100,10 + PUSHBUTTON "...",IDC_BUTTON_LAUNCHSTYLECONF_CRLF,281,44,16,14 + + GROUPBOX "Line Wrap",IDC_LW_GB_STATIC,311,3,80,59,BS_CENTER + CONTROL "Default",IDC_RADIO_LWDEF,"Button",BS_AUTORADIOBUTTON | WS_GROUP,317,16,68,10 + CONTROL "Aligned",IDC_RADIO_LWALIGN,"Button",BS_AUTORADIOBUTTON,317,31,68,10 + CONTROL "Indent",IDC_RADIO_LWINDENT,"Button",BS_AUTORADIOBUTTON,317,46,68,10 + + CONTROL "Enable smooth font",IDC_CHECK_SMOOTHFONT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,81,270,10 + CONTROL "Enable virtual space",IDC_CHECK_VIRTUALSPACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,96,270,10 + CONTROL "Make current level folding/unfolding commands toggleable",IDC_CHECK_FOLDINGTOGGLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,111,270,10 + CONTROL "Enable Multi-Editing (Ctrl+Mouse click/selection)",IDC_CHECK_MULTISELECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,126,270,10 + CONTROL "Enable scrolling beyond last line",IDC_CHECK_SCROLLBEYONDLASTLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,141,270,10 + CONTROL "Keep selection when right-click outside of selection",IDC_CHECK_RIGHTCLICKKEEPSSELECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,156,270,10 + CONTROL "Disable advanced scrolling feature due to touchpad issue",IDC_CHECK_DISABLEADVANCEDSCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,171,270,10 END diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp index f08b2c31a..909799c30 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp @@ -237,7 +237,19 @@ intptr_t CALLBACK PreferenceDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM { NppDarkMode::autoThemeChildControls(_hSelf); - if (_performanceSubDlg._largeFileRestrictionTip) + if (_editingSubDlg._tip != nullptr) + NppDarkMode::setDarkTooltips(_editingSubDlg._tip, NppDarkMode::ToolTipsType::tooltip); + + for (auto& tip : _editingSubDlg._tips) + { + if (tip != nullptr) + { + NppDarkMode::setDarkTooltips(tip, NppDarkMode::ToolTipsType::tooltip); + } + } + if (_delimiterSubDlg._tip != nullptr) + NppDarkMode::setDarkTooltips(_delimiterSubDlg._tip, NppDarkMode::ToolTipsType::tooltip); + if (_performanceSubDlg._largeFileRestrictionTip != nullptr) NppDarkMode::setDarkTooltips(_performanceSubDlg._largeFileRestrictionTip, NppDarkMode::ToolTipsType::tooltip); return TRUE; @@ -903,9 +915,63 @@ intptr_t CALLBACK EditingSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM generic_string tip2show = pNativeSpeaker->getLocalizedStrFromID("eol-custom-color-tip", TEXT("Go to Style Configurator to change the default EOL custom color (\"EOL custom color\").")); _tip = CreateToolTip(IDC_BUTTON_LAUNCHSTYLECONF_CRLF, _hSelf, _hInst, const_cast(tip2show.c_str()), pNativeSpeaker->isRTL()); - if (_tip) + + const bool isNpcModeAbbrv = svp._npcMode == svp.abbreviation; + ::SendDlgItemMessage(_hSelf, IDC_RADIO_NPC_ABBREVIATION, BM_SETCHECK, isNpcModeAbbrv, 0); + ::SendDlgItemMessage(_hSelf, IDC_RADIO_NPC_CODEPOINT, BM_SETCHECK, !isNpcModeAbbrv, 0); + + ::SendDlgItemMessage(_hSelf, IDC_CHECK_NPC_COLOR, BM_SETCHECK, svp._npcCustomColor, 0); + + generic_string tipNote2Show = pNativeSpeaker->getLocalizedStrFromID("npcNote-tip", + L"Representation of selected \"non-ASCII\" whitespace and non-printing (control) characters.\n\n"\ + L"NOTE:\n"\ + L"Some characters might already have some representation and are thus visible. "\ + L"Line separator and paragraph separator are already represented by abbreviation by default.\n\n"\ + L"Using representation will disable character effects on text.\n\n"\ + L"For the full list of selected whitespace and non-printing characters check User Manual.\n\n"\ + L"Click on this button to open website with User Manual."); + + generic_string tipAb2Show = pNativeSpeaker->getLocalizedStrFromID("npcAbbreviation-tip", + L"Abbreviation : name\n"\ + L"NBSP : no-break space\n"\ + L"ZWSP : zero-width space\n"\ + L"ZWNBSP : zero-width no-break space\n\n"\ + L"For the full list check User Manual.\n"\ + L"Click on \"?\" button on right to open website with User Manual."); + + generic_string tipCp2Show = pNativeSpeaker->getLocalizedStrFromID("npcCodepoint-tip", + L"Codepoint : name\n"\ + L"U+00A0 : no-break space\n"\ + L"U+200B : zero-width space\n"\ + L"U+FEFF : zero-width no-break space\n\n"\ + L"For the full list check User Manual.\n"\ + L"Click on \"?\" button on right to open website with User Manual."); + + generic_string tipNpcCol2show = pNativeSpeaker->getLocalizedStrFromID("npcCustomColor-tip", + L"Go to Style Configurator to change the default custom color for selected whitespace and non-printing characters (\"Non-printing characters custom color\")."); + + _tipNote = CreateToolTip(IDC_BUTTON_NPC_NOTE, _hSelf, _hInst, const_cast(tipNote2Show.c_str()), pNativeSpeaker->isRTL()); + _tipAbb = CreateToolTip(IDC_RADIO_NPC_ABBREVIATION, _hSelf, _hInst, const_cast(tipAb2Show.c_str()), pNativeSpeaker->isRTL()); + _tipCodepoint = CreateToolTip(IDC_RADIO_NPC_CODEPOINT, _hSelf, _hInst, const_cast(tipCp2Show.c_str()), pNativeSpeaker->isRTL()); + _tipNpcColor = CreateToolTip(IDC_BUTTON_NPC_LAUNCHSTYLECONF, _hSelf, _hInst, const_cast(tipNpcCol2show.c_str()), pNativeSpeaker->isRTL()); + + _tips.emplace_back(_tipNote); + _tips.emplace_back(_tipAbb); + _tips.emplace_back(_tipCodepoint); + _tips.emplace_back(_tipNpcColor); + + for (auto& tip : _tips) { - SendMessage(_tip, TTM_ACTIVATE, TRUE, 0); + if (tip != nullptr) + { + ::SendMessage(tip, TTM_SETMAXTIPWIDTH, 0, 260); + } + } + + if (_tipNote != nullptr) + { + // Make tip stay 30 seconds + ::SendMessage(_tipNote, TTM_SETDELAYTIME, TTDT_AUTOPOP, MAKELPARAM((30000), (0))); } initScintParam(); @@ -915,11 +981,6 @@ intptr_t CALLBACK EditingSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM case WM_CTLCOLOREDIT: { - if (_tip) - { - NppDarkMode::setDarkTooltips(_tip, NppDarkMode::ToolTipsType::tooltip); - } - if (NppDarkMode::isEnabled()) { return NppDarkMode::onCtlColorSofter(reinterpret_cast(wParam)); @@ -1058,6 +1119,44 @@ intptr_t CALLBACK EditingSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM return TRUE; } + case IDC_RADIO_NPC_ABBREVIATION: + case IDC_RADIO_NPC_CODEPOINT: + { + if (wParam == IDC_RADIO_NPC_CODEPOINT) + { + svp._npcMode = svp.codepoint; + } + else // if (wParam == IDC_RADIO_NONPRINT_ABBREVIATION) + { + svp._npcMode = svp.abbreviation; + } + + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_SETNPC, 0, 0); + return TRUE; + } + + case IDC_BUTTON_NPC_NOTE: + { + ::ShellExecute(NULL, L"open", L"https://npp-user-manual.org/docs/views/#show-symbol", NULL, NULL, SW_SHOWNORMAL); + return TRUE; + } + + case IDC_CHECK_NPC_COLOR: + { + svp._npcCustomColor = isCheckedOrNot(IDC_CHECK_NPC_COLOR); + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_NPCFORMCHANGED, 0, 0); + return TRUE; + } + + case IDC_BUTTON_NPC_LAUNCHSTYLECONF: + { + HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_NPCLAUNCHSTYLECONF, 0, 0); + return TRUE; + } + case IDC_CHECK_VIRTUALSPACE: svp._virtualSpace = (BST_CHECKED == ::SendDlgItemMessage(_hSelf, IDC_CHECK_VIRTUALSPACE, BM_GETCHECK, 0, 0)); ::SendMessage(::GetParent(_hParent), NPPM_INTERNAL_VIRTUALSPACE, 0, 0); @@ -4601,9 +4700,6 @@ intptr_t CALLBACK DelimiterSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR _tip = CreateToolTip(IDD_WORDCHAR_QUESTION_BUTTON, _hSelf, _hInst, const_cast(tip2show.c_str()), pNativeSpeaker->isRTL()); if (_tip) { - SendMessage(_tip, TTM_ACTIVATE, TRUE, 0); - SendMessage(_tip, TTM_SETMAXTIPWIDTH, 0, 200); - // Make tip stay 30 seconds SendMessage(_tip, TTM_SETDELAYTIME, TTDT_AUTOPOP, MAKELPARAM((30000), (0))); } @@ -4612,11 +4708,6 @@ intptr_t CALLBACK DelimiterSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPAR case WM_CTLCOLOREDIT: { - if (_tip) - { - NppDarkMode::setDarkTooltips(_tip, NppDarkMode::ToolTipsType::tooltip); - } - if (NppDarkMode::isEnabled()) { return NppDarkMode::onCtlColorSofter(reinterpret_cast(wParam)); diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.h b/PowerEditor/src/WinControls/Preference/preferenceDlg.h index cdd70af88..d2fba202b 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.h +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.h @@ -45,11 +45,34 @@ private : class EditingSubDlg : public StaticDialog { +friend class PreferenceDlg; public : EditingSubDlg() = default; + ~EditingSubDlg() { + if (_tip != nullptr) + { + ::DestroyWindow(_tip); + _tip = nullptr; + } + + for (auto& tip : _tips) + { + if (tip != nullptr) + { + ::DestroyWindow(tip); + tip = nullptr; + } + } + }; private : HWND _tip = nullptr; + HWND _tipNote = nullptr; + HWND _tipAbb = nullptr; + HWND _tipCodepoint = nullptr; + HWND _tipNpcColor = nullptr; + + std::vector _tips; intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); void initScintParam(); @@ -213,6 +236,7 @@ private : class DelimiterSubDlg : public StaticDialog { +friend class PreferenceDlg; public : DelimiterSubDlg() = default; ~DelimiterSubDlg() { diff --git a/PowerEditor/src/WinControls/Preference/preference_rc.h b/PowerEditor/src/WinControls/Preference/preference_rc.h index 6322c0915..216d8cdfb 100644 --- a/PowerEditor/src/WinControls/Preference/preference_rc.h +++ b/PowerEditor/src/WinControls/Preference/preference_rc.h @@ -157,6 +157,12 @@ #define IDC_CHECK_WITHCUSTOMCOLOR_CRLF (IDD_PREFERENCE_SUB_EDITING + 50) #define IDC_BUTTON_LAUNCHSTYLECONF_CRLF (IDD_PREFERENCE_SUB_EDITING + 51) + #define IDC_GB_STATIC_NPC (IDD_PREFERENCE_SUB_EDITING + 52) + #define IDC_BUTTON_NPC_NOTE (IDD_PREFERENCE_SUB_EDITING + 53) + #define IDC_RADIO_NPC_ABBREVIATION (IDD_PREFERENCE_SUB_EDITING + 54) + #define IDC_RADIO_NPC_CODEPOINT (IDD_PREFERENCE_SUB_EDITING + 55) + #define IDC_CHECK_NPC_COLOR (IDD_PREFERENCE_SUB_EDITING + 56) + #define IDC_BUTTON_NPC_LAUNCHSTYLECONF (IDD_PREFERENCE_SUB_EDITING + 57) #define IDD_PREFERENCE_SUB_DELIMITER 6250 //(IDD_PREFERENCE_BOX + 250) #define IDC_DELIMITERSETTINGS_GB_STATIC (IDD_PREFERENCE_SUB_DELIMITER + 1) diff --git a/PowerEditor/src/menuCmdID.h b/PowerEditor/src/menuCmdID.h index 70adf5357..32c9ee3f2 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -375,6 +375,8 @@ #define IDM_VIEW_TAB_COLOUR_4 (IDM_VIEW + 114) #define IDM_VIEW_TAB_COLOUR_5 (IDM_VIEW + 115) + #define IDM_VIEW_NPC (IDM_VIEW + 130) + #define IDM_VIEW_GOTO_ANOTHER_VIEW 10001 #define IDM_VIEW_CLONE_TO_ANOTHER_VIEW 10002 #define IDM_VIEW_GOTO_NEW_INSTANCE 10003 diff --git a/PowerEditor/src/resource.h b/PowerEditor/src/resource.h index db94d6829..452af3641 100644 --- a/PowerEditor/src/resource.h +++ b/PowerEditor/src/resource.h @@ -645,6 +645,9 @@ #define NPPM_INTERNAL_CLEANBRACEMATCH (NOTEPADPLUS_USER_INTERNAL + 69) #define NPPM_INTERNAL_WINDOWSSESSIONEXIT (NOTEPADPLUS_USER_INTERNAL + 70) #define NPPM_INTERNAL_RESTOREMONOINSTANCE (NOTEPADPLUS_USER_INTERNAL + 71) + #define NPPM_INTERNAL_SETNPC (NOTEPADPLUS_USER_INTERNAL + 72) + #define NPPM_INTERNAL_NPCFORMCHANGED (NOTEPADPLUS_USER_INTERNAL + 73) + #define NPPM_INTERNAL_NPCLAUNCHSTYLECONF (NOTEPADPLUS_USER_INTERNAL + 74) // See Notepad_plus_msgs.h //#define NOTEPADPLUS_USER (WM_USER + 1000) diff --git a/PowerEditor/src/stylers.model.xml b/PowerEditor/src/stylers.model.xml index 89b032573..3abf553a5 100644 --- a/PowerEditor/src/stylers.model.xml +++ b/PowerEditor/src/stylers.model.xml @@ -1444,5 +1444,6 @@ +