From 0cad36d636aaa517f8fd50bdc171f6fa01181a38 Mon Sep 17 00:00:00 2001 From: ozone10 Date: Mon, 6 Mar 2023 19:03:20 +0100 Subject: [PATCH] Add hide/show ability of Control Characters (C0 & C1) and Unicode EOL Fix #8111, close #13324 --- PowerEditor/installer/nativeLang/english.xml | 5 +- .../nativeLang/english_customizable.xml | 5 +- PowerEditor/src/Notepad_plus.cpp | 10 +- PowerEditor/src/Notepad_plus.rc | 13 +- PowerEditor/src/NppBigSwitch.cpp | 32 +++-- PowerEditor/src/NppCommands.cpp | 77 +++++----- PowerEditor/src/Parameters.cpp | 21 ++- PowerEditor/src/Parameters.h | 2 + .../src/ScintillaComponent/FindReplaceDlg.cpp | 2 +- .../ScintillaComponent/ScintillaEditView.cpp | 109 ++++++++++++-- .../ScintillaComponent/ScintillaEditView.h | 136 ++++++++++++++---- .../src/WinControls/Preference/preference.rc | 53 +++---- .../WinControls/Preference/preferenceDlg.cpp | 31 ++-- .../WinControls/Preference/preferenceDlg.h | 3 +- .../WinControls/Preference/preference_rc.h | 1 + PowerEditor/src/menuCmdID.h | 1 + 16 files changed, 355 insertions(+), 146 deletions(-) diff --git a/PowerEditor/installer/nativeLang/english.xml b/PowerEditor/installer/nativeLang/english.xml index 21d83cbfc..d426a22fe 100644 --- a/PowerEditor/installer/nativeLang/english.xml +++ b/PowerEditor/installer/nativeLang/english.xml @@ -296,6 +296,7 @@ The comments are here for explanation, it's not necessary to translate them. + @@ -956,6 +957,7 @@ The comments are here for explanation, it's not necessary to translate them. + @@ -1683,8 +1685,6 @@ NOTE: + diff --git a/PowerEditor/installer/nativeLang/english_customizable.xml b/PowerEditor/installer/nativeLang/english_customizable.xml index b3babdae0..c7144d967 100644 --- a/PowerEditor/installer/nativeLang/english_customizable.xml +++ b/PowerEditor/installer/nativeLang/english_customizable.xml @@ -296,6 +296,7 @@ The comments are here for explanation, it's not necessary to translate them. + @@ -951,6 +952,7 @@ The comments are here for explanation, it's not necessary to translate them. + @@ -1672,8 +1674,6 @@ NOTE: + diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index d01d7e715..5806a6007 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -4738,12 +4738,14 @@ void Notepad_plus::staticCheckMenuAndTB() const const bool wsTabShow = _pEditView->isShownSpaceAndTab(); const bool eolShow = _pEditView->isShownEol(); const bool npcShow = _pEditView->isShownNpc(); + const bool ccUniEolShow = _pEditView->isShownCcUniEol(); - const bool allShow = wsTabShow && eolShow && npcShow; + const bool allShow = wsTabShow && eolShow && npcShow && ccUniEolShow; checkMenuItem(IDM_VIEW_TAB_SPACE, wsTabShow); checkMenuItem(IDM_VIEW_EOL, eolShow); checkMenuItem(IDM_VIEW_NPC, npcShow); + checkMenuItem(IDM_VIEW_NPC_CCUNIEOL, ccUniEolShow); checkMenuItem(IDM_VIEW_ALL_CHARACTERS, allShow); _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allShow); @@ -6340,6 +6342,12 @@ void Notepad_plus::notifyBufferChanged(Buffer * buffer, int mask) setDisplayFormat(buffer->getEolFormat()); enableConvertMenuItems(buffer->getEolFormat()); } + + if (mask & (BufferChangeUnicode)) + { + _mainEditView.maintainStateForNpc(); + _subEditView.maintainStateForNpc(); + } } void Notepad_plus::notifyBufferActivated(BufferID bufid, int view) diff --git a/PowerEditor/src/Notepad_plus.rc b/PowerEditor/src/Notepad_plus.rc index 6c9a23671..c4bc1feae 100644 --- a/PowerEditor/src/Notepad_plus.rc +++ b/PowerEditor/src/Notepad_plus.rc @@ -668,13 +668,14 @@ BEGIN MENUITEM SEPARATOR POPUP "Show Symbol" BEGIN - 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 "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 Control Characters && Unicode EOL", IDM_VIEW_NPC_CCUNIEOL + 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/NppBigSwitch.cpp b/PowerEditor/src/NppBigSwitch.cpp index 178d51794..7edb2babb 100644 --- a/PowerEditor/src/NppBigSwitch.cpp +++ b/PowerEditor/src/NppBigSwitch.cpp @@ -1759,10 +1759,23 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa case NPPM_INTERNAL_SETNPC: { - const bool isShown = nppParam.getSVP()._npcShow; - _mainEditView.showNpc(isShown); - _subEditView.showNpc(isShown); - _findReplaceDlg.updateFinderScintillaForNpc(); + const auto& svp = nppParam.getSVP(); + const bool isFromIncCcUniEolCtrl = wParam == IDC_CHECK_NPC_INCLUDECCUNIEOL; + if (isFromIncCcUniEolCtrl || svp._npcIncludeCcUniEol) + { + const bool isShown = svp._ccUniEolShow; + _mainEditView.showCcUniEol(isShown); + _subEditView.showCcUniEol(isShown); + } + + if (!isFromIncCcUniEolCtrl) + { + const bool isShown = svp._npcShow; + _mainEditView.showNpc(isShown); + _subEditView.showNpc(isShown); + _findReplaceDlg.updateFinderScintillaForNpc(); + } + return TRUE; } @@ -2945,14 +2958,15 @@ LRESULT Notepad_plus::process(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa case NPPM_INTERNAL_NPCFORMCHANGED: { - NppParameters& nppParam = NppParameters::getInstance(); - const bool isShown = nppParam.getSVP()._npcShow; - if (isShown) + _mainEditView.setNpcAndCcUniEOL(); + _subEditView.setNpcAndCcUniEOL(); + + const auto& svp = NppParameters::getInstance().getSVP(); + if (svp._npcShow) { - _mainEditView.setNPC(); - _subEditView.setNPC(); _findReplaceDlg.updateFinderScintillaForNpc(true); } + return TRUE; } diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 09a63fb0b..7a9c331c9 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -2317,12 +2317,8 @@ void Notepad_plus::command(int id) case IDM_VIEW_TAB_SPACE: { - 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); + checkMenuItem(id, isChecked); _mainEditView.showWSAndTab(isChecked); _subEditView.showWSAndTab(isChecked); @@ -2330,9 +2326,9 @@ void Notepad_plus::command(int id) auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); svp1._whiteSpaceShow = isChecked; - const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow; + const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow && svp1._ccUniEolShow; - setCheckMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); + checkMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allChecked); break; @@ -2340,12 +2336,8 @@ void Notepad_plus::command(int id) case IDM_VIEW_EOL: { - 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); + checkMenuItem(id, isChecked); _mainEditView.showEOL(isChecked); _subEditView.showEOL(isChecked); @@ -2353,9 +2345,9 @@ void Notepad_plus::command(int id) auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); svp1._eolShow = isChecked; - const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow; + const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow && svp1._ccUniEolShow; - setCheckMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); + checkMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allChecked); break; @@ -2363,22 +2355,19 @@ void Notepad_plus::command(int id) 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); + checkMenuItem(id, isChecked); auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); svp1._npcShow = isChecked; - const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow; + // setNpcAndCcUniEOL() in showNpc() uses svp1._npcShow + _mainEditView.showNpc(isChecked); + _subEditView.showNpc(isChecked); + + const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow && svp1._ccUniEolShow; - setCheckMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); + checkMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allChecked); _findReplaceDlg.updateFinderScintillaForNpc(); @@ -2386,27 +2375,45 @@ void Notepad_plus::command(int id) break; } - case IDM_VIEW_ALL_CHARACTERS: + case IDM_VIEW_NPC_CCUNIEOL: { - 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); + checkMenuItem(id, isChecked); + + auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); + svp1._ccUniEolShow = isChecked; + + // setNpcAndCcUniEOL() in showCcUniEol() uses svp1._ccUniEolShow + _mainEditView.showCcUniEol(isChecked); + _subEditView.showCcUniEol(isChecked); + const bool allChecked = svp1._whiteSpaceShow && svp1._eolShow && svp1._npcShow && svp1._ccUniEolShow; + + checkMenuItem(IDM_VIEW_ALL_CHARACTERS, allChecked); + _toolBar.setCheck(IDM_VIEW_ALL_CHARACTERS, allChecked); + + break; + } + + case IDM_VIEW_ALL_CHARACTERS: + { 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); + checkMenuItem(id, isChecked); + checkMenuItem(IDM_VIEW_TAB_SPACE, isChecked); + checkMenuItem(IDM_VIEW_EOL, isChecked); + checkMenuItem(IDM_VIEW_NPC, isChecked); + checkMenuItem(IDM_VIEW_NPC_CCUNIEOL, isChecked); _toolBar.setCheck(id, isChecked); - _mainEditView.showInvisibleChars(isChecked); - _subEditView.showInvisibleChars(isChecked); - auto& svp1 = const_cast(NppParameters::getInstance().getSVP()); svp1._whiteSpaceShow = isChecked; svp1._eolShow = isChecked; svp1._npcShow = isChecked; + svp1._ccUniEolShow = isChecked; + + _mainEditView.showInvisibleChars(isChecked); + _subEditView.showInvisibleChars(isChecked); _findReplaceDlg.updateFinderScintillaForNpc(); diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index 12e043994..b6126d48a 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -261,6 +261,7 @@ static const WinMenuKeyDefinition winKeyDefs[] = { 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_NPC_CCUNIEOL, 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 }, @@ -5923,18 +5924,6 @@ void NppParameters::feedGUIParameters(TiXmlNode *node) } else if (!lstrcmp(nm, TEXT("DarkMode"))) { - auto parseYesNoBoolAttribute = [&element](const TCHAR* name, bool defaultValue = false)->bool { - const TCHAR* val = element->Attribute(name); - if (val) - { - if (!lstrcmp(val, TEXT("yes"))) - return true; - else if (!lstrcmp(val, TEXT("no"))) - return false; - } - return defaultValue; - }; - _nppGUI._darkmode._isEnabled = parseYesNoBoolAttribute(TEXT("enable")); //_nppGUI._darkmode._isEnabledPlugin = parseYesNoBoolAttribute(TEXT("enablePlugin", true)); @@ -6359,7 +6348,7 @@ void NppParameters::feedScintillaParam(TiXmlNode *node) _svp._eolMode = static_cast(val); } - // Unicode non-printable characters visibility State + // Unicode control and ws characters visibility state _svp._npcShow = parseShowHideBoolAttribute(TEXT("npcShow"), true); nm = element->Attribute(TEXT("npcMode"), &val); @@ -6370,6 +6359,10 @@ void NppParameters::feedScintillaParam(TiXmlNode *node) } _svp._npcCustomColor = parseYesNoBoolAttribute(TEXT("npcCustomColor")); + _svp._npcIncludeCcUniEol = parseYesNoBoolAttribute(TEXT("npcIncludeCcUniEOL")); + + // C0, C1 control and Unicode EOL visibility state + _svp._ccUniEolShow = parseYesNoBoolAttribute(TEXT("ccShow"), true); nm = element->Attribute(TEXT("borderWidth"), &val); if (nm) @@ -6676,6 +6669,8 @@ bool NppParameters::writeScintillaParams() setShowHideBoolAttribute(TEXT("npcShow"), _svp._npcShow); (scintNode->ToElement())->SetAttribute(TEXT("npcMode"), static_cast(_svp._npcMode)); setYesNoBoolAttribute(TEXT("npcCustomColor"), _svp._npcCustomColor); + setYesNoBoolAttribute(TEXT("npcIncludeCcUniEOL"), _svp._npcIncludeCcUniEol); + setYesNoBoolAttribute(TEXT("ccShow"), _svp._ccUniEolShow); (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 51eb42bc8..75798709f 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -953,6 +953,8 @@ struct ScintillaViewParams enum npcMode { identity = 0, abbreviation = 1, codepoint = 2 }; npcMode _npcMode = abbreviation; bool _npcCustomColor = false; + bool _npcIncludeCcUniEol = false; + bool _ccUniEolShow = true; int _borderWidth = 2; bool _virtualSpace = false; diff --git a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp index 7f08ed77a..5a7b9e04b 100644 --- a/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp +++ b/PowerEditor/src/ScintillaComponent/FindReplaceDlg.cpp @@ -4958,7 +4958,7 @@ void Finder::setFinderStyleForNpc(bool onlyColor) } else if (isShown) { - _scintView.setNPC(); + _scintView.setNpcAndCcUniEOL(); } } diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp index 50629caae..5340a4e45 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp @@ -1424,7 +1424,7 @@ void ScintillaEditView::setCRLF(long color) redraw(); } -void ScintillaEditView::setNPC(long color) +void ScintillaEditView::setNpcAndCcUniEOL(long color) { NppParameters& nppParams = NppParameters::getInstance(); const ScintillaViewParams& svp = nppParams.getSVP(); @@ -1448,10 +1448,22 @@ void ScintillaEditView::setNPC(long 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) + if (svp._npcShow) { - execute(SCI_SETREPRESENTATIONCOLOUR, reinterpret_cast(invChar.at(0)), alphaNpcCustomColor); - execute(SCI_SETREPRESENTATIONAPPEARANCE, reinterpret_cast(invChar.at(0)), appearance); + for (const auto& invChar : g_nonPrintingChars) + { + execute(SCI_SETREPRESENTATIONCOLOUR, reinterpret_cast(invChar.at(0)), alphaNpcCustomColor); + execute(SCI_SETREPRESENTATIONAPPEARANCE, reinterpret_cast(invChar.at(0)), appearance); + } + } + + if (svp._ccUniEolShow && svp._npcIncludeCcUniEol) + { + for (const auto& invChar : g_ccUniEolChars) + { + execute(SCI_SETREPRESENTATIONCOLOUR, reinterpret_cast(invChar.at(0)), alphaNpcCustomColor); + execute(SCI_SETREPRESENTATIONAPPEARANCE, reinterpret_cast(invChar.at(0)), appearance); + } } redraw(); @@ -2047,6 +2059,8 @@ void ScintillaEditView::activateBuffer(BufferID buffer, bool force) restyleBuffer(); } + maintainStateForNpc(); + // Everything should be updated, but the language bufferUpdated(_currentBuffer, (BufferChangeMask & ~BufferChangeLanguage)); @@ -2058,13 +2072,7 @@ 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(); @@ -2845,7 +2853,86 @@ void ScintillaEditView::performGlobalStyles() { npcCustomColor = pStyle->_fgColor; } - setNPC(npcCustomColor); + setNpcAndCcUniEOL(npcCustomColor); +} + +void ScintillaEditView::showNpc(bool willBeShowed, bool isSearchResult) +{ + 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) + { + setNpcAndCcUniEOL(); + } + } + else + { + execute(SCI_CLEARALLREPRESENTATIONS); + + // SCI_CLEARALLREPRESENTATIONS will also reset CRLF and CcUniEOL + if (!isSearchResult && svp._eolMode != svp.roundedRectangleText) + { + setCRLF(); + } + + showCcUniEol(svp._ccUniEolShow); + } + + // in some case npc representation is not redrawn correctly on first line + // therefore use of showEOL(isShownEol()) instead of redraw() + showEOL(isShownEol()); +} + +void ScintillaEditView::showCcUniEol(bool willBeShowed, bool isSearchResult) +{ + auto& svp = NppParameters::getInstance().getSVP(); + + if (willBeShowed) + { + const auto& mode = static_cast(svp._npcIncludeCcUniEol ? svp._npcMode : ScintillaViewParams::npcMode::abbreviation); + for (const auto& invChar : g_ccUniEolChars) + { + execute(SCI_SETREPRESENTATION, reinterpret_cast(invChar.at(0)), reinterpret_cast(invChar.at(mode))); + } + + if (svp._npcIncludeCcUniEol && svp._npcCustomColor) + { + setNpcAndCcUniEOL(); + } + } + else + { + execute(SCI_CLEARALLREPRESENTATIONS); + + for (const auto& invChar : g_ccUniEolChars) + { + execute(SCI_SETREPRESENTATION, reinterpret_cast(invChar.at(0)), reinterpret_cast(g_ZWSP)); + execute(SCI_SETREPRESENTATIONAPPEARANCE, reinterpret_cast(invChar.at(0)), SC_REPRESENTATION_PLAIN); + } + + // SCI_CLEARALLREPRESENTATIONS will also reset CRLF and NPC + if (!isSearchResult && svp._eolMode != svp.roundedRectangleText) + { + setCRLF(); + } + + if (svp._npcShow) + { + showNpc(); + } + } + + // in some case C0, C1 and Unicode EOL representations are not redrawn correctly on first line + // therefore use of showEOL(isShownEol()) instead of redraw() + showEOL(isShownEol()); } void ScintillaEditView::showIndentGuideLine(bool willBeShowed) diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h index e19fea716..79641c842 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.h +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.h @@ -118,11 +118,86 @@ const int MARK_HIDELINESEND = 18; // 20 - 18 reserved for Notepad++ internal used // 17 - 0 are free to use for plugins +constexpr char g_ZWSP[] = "\xE2\x80\x8B"; + +const std::vector> g_ccUniEolChars = +{ + // C0 + {"\x00", "NUL", "U+0000"}, // U+0000 : Null + {"\x01", "SOH", "U+0001"}, // U+0001 : Start of Heading + {"\x02", "STX", "U+0002"}, // U+0002 : Start of Text + {"\x03", "ETX", "U+0003"}, // U+0003 : End of Text + {"\x04", "EOT", "U+0004"}, // U+0004 : End of Transmission + {"\x05", "ENQ", "U+0005"}, // U+0005 : Enquiry + {"\x06", "ACK", "U+0006"}, // U+0006 : Acknowledge + {"\a", "BEL", "U+0007"}, // U+0007 : Bell + {"\b", "BS", "U+0008"}, // U+0008 : Backspace + {"\v", "VT", "U+000B"}, // U+000B : Line Tabulation + {"\f", "FF", "U+000C"}, // U+000C : Form Feed + {"\x0E", "SO", "U+000E"}, // U+000E : Shift Out + {"\x0F", "SI", "U+000F"}, // U+000F : Shift In + {"\x10", "DLE", "U+0010"}, // U+0010 : Data Link Escape + {"\x11", "DC1", "U+0011"}, // U+0011 : Device Control One + {"\x12", "DC2", "U+0012"}, // U+0012 : Device Control Two + {"\x13", "DC3", "U+0013"}, // U+0013 : Device Control Three + {"\x14", "DC4", "U+0014"}, // U+0014 : Device Control Four + {"\x15", "NAK", "U+0015"}, // U+0015 : Negative Acknowledge + {"\x16", "SYN", "U+0016"}, // U+0016 : Synchronous Idle + {"\x17", "ETB", "U+0017"}, // U+0017 : End of Transmission Block + {"\x18", "CAN", "U+0018"}, // U+0018 : Cancel + {"\x19", "EM", "U+0019"}, // U+0019 : End of Medium + {"\x1A", "SUB", "U+001A"}, // U+001A : Substitute + {"\x1B", "ESC", "U+001B"}, // U+001B : Escape + {"\x1C", "FS", "U+001C"}, // U+001C : Information Separator Four + {"\x1D", "GS", "U+001D"}, // U+001D : Information Separator Three + {"\x1E", "RS", "U+001E"}, // U+001E : Information Separator Two + {"\x1F", "US", "U+001F"}, // U+001F : Information Separator One + {"\x7F", "DEL", "U+007F"}, // U+007F : Delete + // C1 + {"\xC2\x80", "PAD", "U+0080"}, // U+0080 : Padding Character + {"\xC2\x81", "HOP", "U+0081"}, // U+0081 : High Octet Preset + {"\xC2\x82", "BPH", "U+0082"}, // U+0082 : Break Permitted Here + {"\xC2\x83", "NBH", "U+0083"}, // U+0083 : No Break Here + {"\xC2\x84", "IND", "U+0084"}, // U+0084 : Index + //{"\xC2\x85", "NEL", "U+0085"}, // U+0085 : Next Line + {"\xC2\x86", "SSA", "U+0086"}, // U+0086 : Start of Selected Area + {"\xC2\x87", "ESA", "U+0087"}, // U+0087 : End of Selected Area + {"\xC2\x88", "HTS", "U+0088"}, // U+0088 : Character (Horizontal) Tabulation Set + {"\xC2\x89", "HTJ", "U+0089"}, // U+0089 : Character (Horizontal) Tabulation With Justification + {"\xC2\x8A", "LTS", "U+008A"}, // U+008A : Line (Vertical) Tabulation Set + {"\xC2\x8B", "PLD", "U+008B"}, // U+008B : Partial Line Forward (Down) + {"\xC2\x8C", "PLU", "U+008C"}, // U+008C : Partial Line Backward (Up) + {"\xC2\x8D", "RI", "U+008D"}, // U+008D : Reverse Line Feed (Index) + {"\xC2\x8E", "SS2", "U+008E"}, // U+008E : Single-Shift Two + {"\xC2\x8F", "SS3", "U+008F"}, // U+008F : Single-Shift Three + {"\xC2\x90", "DCS", "U+0090"}, // U+0090 : Device Control String + {"\xC2\x91", "PU1", "U+0091"}, // U+0091 : Private Use One + {"\xC2\x92", "PU2", "U+0092"}, // U+0092 : Private Use Two + {"\xC2\x93", "STS", "U+0093"}, // U+0093 : Set Transmit State + {"\xC2\x94", "CCH", "U+0094"}, // U+0094 : Cancel Character + {"\xC2\x95", "MW", "U+0095"}, // U+0095 : Message Waiting + {"\xC2\x96", "SPA", "U+0096"}, // U+0096 : Start of Protected Area + {"\xC2\x97", "EPA", "U+0097"}, // U+0097 : End of Protected Area + {"\xC2\x98", "SOS", "U+0098"}, // U+0098 : Start of String + {"\xC2\x99", "SGCI", "U+0099"}, // U+0099 : Single Graphic Character Introducer + {"\xC2\x9A", "SCI", "U+009A"}, // U+009A : Single Character Introducer + {"\xC2\x9B", "CSI", "U+009B"}, // U+009B : Control Sequence Introducer + {"\xC2\x9C", "ST", "U+009C"}, // U+009C : String Terminator + {"\xC2\x9D", "OSC", "U+009D"}, // U+009D : Operating System Command + {"\xC2\x9E", "PM", "U+009E"}, // U+009E : Private Message + {"\xC2\x9F", "APC", "U+009F"}, // U+009F : Application Program Command + // Unicode EOL + {"\xC2\x85", "NEL", "U+0085"}, // U+0085 : Next Line + {"\xE2\x80\xA8", "LS", "U+2028"}, // U+2028 : Line Separator + {"\xE2\x80\xA9", "PS", "U+2029"} // U+2029 : Paragraph Separator +}; + const std::vector> g_nonPrintingChars = { - {"\xC2\x85", "NEL", "U+0085"}, // U+0085 : next line {"\xC2\xA0", "NBSP", "U+00A0"}, // U+00A0 : no-break space + {"\xC2\xAD", "SHY", "U+00AD"}, // U+00AD : soft hyphen {"\xD8\x9C", "ALM", "U+061C"}, // U+061C : arabic letter mark + {"\xDC\x8F", "SAM", "U+070F"}, // U+070F : syriac abbreviation mark {"\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 @@ -141,8 +216,6 @@ const std::vector> g_nonPrintingChars = {"\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 @@ -151,6 +224,10 @@ const std::vector> g_nonPrintingChars = {"\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\xA1", "(FA)", "U+2061"}, // U+2061 : function application + {"\xE2\x81\xA2", "(IT)", "U+2062"}, // U+2062 : invisible times + {"\xE2\x81\xA3", "(IS)", "U+2063"}, // U+2063 : invisible separator + {"\xE2\x81\xA4", "(IP)", "U+2064"}, // U+2064 : invisible plus {"\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 @@ -162,7 +239,10 @@ const std::vector> g_nonPrintingChars = {"\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 + {"\xEF\xBB\xBF", "ZWNBSP", "U+FEFF"}, // U+FEFF : zero-width no-break space + {"\xEF\xBF\xB9", "IAA", "U+FFF9"}, // U+FFF9 : interlinear annotation anchor + {"\xEF\xBF\xBA", "IAS", "U+FFFA"}, // U+FFFA : interlinear annotation separator + {"\xEF\xBF\xBB", "IAT", "U+FFFB"} // U+FFFB : interlinear annotation terminator }; int getNbDigits(int aNum, int base); @@ -407,41 +487,37 @@ public: return (execute(SCI_GETVIEWEOL) != 0); }; - void showNpc(bool willBeShowed = true, bool isSearchResult = false) { + void showNpc(bool willBeShowed = true, bool isSearchResult = false); + + bool isShownNpc() { auto& svp = NppParameters::getInstance().getSVP(); - if (willBeShowed) + return svp._npcShow; + }; + + void maintainStateForNpc() { + const auto& svp = NppParameters::getInstance().getSVP(); + const bool isShownNpc = svp._npcShow; + const bool isNpcIncCcUniEol = svp._npcIncludeCcUniEol; + const bool isShownCcUniEol = svp._ccUniEolShow; + + if (isShownNpc || isNpcIncCcUniEol) { - 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(); - } + showNpc(isShownNpc); } - else - { - execute(SCI_CLEARALLREPRESENTATIONS); - // SCI_CLEARALLREPRESENTATIONS will also reset CRLF - if (!isSearchResult && svp._eolMode != svp.roundedRectangleText) - { - setCRLF(); - } - } - redraw(); - }; + showCcUniEol(isShownCcUniEol); + } - bool isShownNpc() { + void showCcUniEol(bool willBeShowed = true, bool isSearchResult = false); + + bool isShownCcUniEol() { auto& svp = NppParameters::getInstance().getSVP(); - return svp._npcShow; + return svp._ccUniEolShow; }; void showInvisibleChars(bool willBeShowed = true) { showNpc(willBeShowed); + showCcUniEol(willBeShowed); showWSAndTab(willBeShowed); showEOL(willBeShowed); }; @@ -658,7 +734,7 @@ public: void restoreDefaultWordChars(); void setWordChars(); void setCRLF(long color = -1); - void setNPC(long color = -1); + void setNpcAndCcUniEOL(long color = -1); void mouseWheel(WPARAM wParam, LPARAM lParam) { scintillaNew_Proc(_hSelf, WM_MOUSEWHEEL, wParam, lParam); diff --git a/PowerEditor/src/WinControls/Preference/preference.rc b/PowerEditor/src/WinControls/Preference/preference.rc index 29bf904e3..07550ce32 100644 --- a/PowerEditor/src/WinControls/Preference/preference.rc +++ b/PowerEditor/src/WinControls/Preference/preference.rc @@ -70,20 +70,19 @@ 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 "Non-Printing Characters",IDC_GB_STATIC_NPC,11,3,150,59,BS_CENTER + GROUPBOX "Non-Printing Characters",IDC_GB_STATIC_NPC,11,3,150,74,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 + CONTROL "Apply to C0, C1 && Unicode EOL",IDC_CHECK_NPC_INCLUDECCUNIEOL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,62,140,10 - 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 "EOL (CRLF)",IDC_GB_STATIC_CRLF,11,83,150,59,BS_CENTER + CONTROL "Default",IDC_RADIO_ROUNDCORNER_CRLF,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP | WS_GROUP,17,96,100,10 + CONTROL "Plain Text",IDC_RADIO_PLEINTEXT_CRLF,"Button",BS_AUTORADIOBUTTON,17,111,100,10 + CONTROL "Custom Color",IDC_CHECK_WITHCUSTOMCOLOR_CRLF,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17,127,100,10 + PUSHBUTTON "...",IDC_BUTTON_LAUNCHSTYLECONF_CRLF,141,124,16,14 GROUPBOX "Caret Settings",IDC_CARETSETTING_STATIC,11,148,150,47,BS_CENTER RTEXT "Width :",IDC_WIDTH_STATIC,30,164,37,8 @@ -93,24 +92,26 @@ BEGIN 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 + GROUPBOX "Current Line Indicator",IDC_CURRENTLINEMARK_STATIC,171,3,150,74,BS_CENTER + CONTROL "None",IDC_RADIO_CLM_NONE,"Button",BS_AUTORADIOBUTTON | WS_GROUP,177,16,100,10 + CONTROL "Highlight Background",IDC_RADIO_CLM_HILITE,"Button",BS_AUTORADIOBUTTON,177,31,100,10 + CONTROL "Frame",IDC_RADIO_CLM_FRAME,"Button",BS_AUTORADIOBUTTON,177,46,100,10 + RTEXT "Width :",IDC_CARETLINEFRAME_WIDTH_STATIC,190,60,37,8 + CONTROL "",IDC_CARETLINEFRAME_WIDTH_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | TBS_TRANSPARENTBKGND | WS_TABSTOP,228,59,57,13 + LTEXT "1",IDC_CARETLINEFRAME_WIDTH_DISPLAY,287,60,12,8 + + GROUPBOX "Line Wrap",IDC_LW_GB_STATIC,331,3,80,59,BS_CENTER + CONTROL "Default",IDC_RADIO_LWDEF,"Button",BS_AUTORADIOBUTTON | WS_GROUP,337,16,68,10 + CONTROL "Aligned",IDC_RADIO_LWALIGN,"Button",BS_AUTORADIOBUTTON,337,31,68,10 + CONTROL "Indent",IDC_RADIO_LWINDENT,"Button",BS_AUTORADIOBUTTON,337,46,68,10 + + CONTROL "Enable smooth font",IDC_CHECK_SMOOTHFONT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,88,270,10 + CONTROL "Enable virtual space",IDC_CHECK_VIRTUALSPACE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,103,270,10 + CONTROL "Make current level folding/unfolding commands toggleable",IDC_CHECK_FOLDINGTOGGLE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,118,270,10 + CONTROL "Enable Multi-Editing (Ctrl+Mouse click/selection)",IDC_CHECK_MULTISELECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,133,270,10 + CONTROL "Enable scrolling beyond last line",IDC_CHECK_SCROLLBEYONDLASTLINE,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,148,270,10 + CONTROL "Keep selection when right-click outside of selection",IDC_CHECK_RIGHTCLICKKEEPSSELECTION,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,163,270,10 + CONTROL "Disable advanced scrolling feature due to touchpad issue",IDC_CHECK_DISABLEADVANCEDSCROLL,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,173,178,270,10 END diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp index 6f1ea28c6..4f8801a13 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.cpp @@ -919,16 +919,15 @@ intptr_t CALLBACK EditingSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM _tip = CreateToolTip(IDC_BUTTON_LAUNCHSTYLECONF_CRLF, _hSelf, _hInst, const_cast(tip2show.c_str()), pNativeSpeaker->isRTL()); 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); + setChecked(IDC_RADIO_NPC_ABBREVIATION, isNpcModeAbbrv); + setChecked(IDC_RADIO_NPC_CODEPOINT, !isNpcModeAbbrv); - ::SendDlgItemMessage(_hSelf, IDC_CHECK_NPC_COLOR, BM_SETCHECK, svp._npcCustomColor, 0); + setChecked(IDC_CHECK_NPC_COLOR, svp._npcCustomColor); + setChecked(IDC_CHECK_NPC_INCLUDECCUNIEOL, svp._npcIncludeCcUniEol); 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."); @@ -952,15 +951,20 @@ intptr_t CALLBACK EditingSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM 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\")."); + generic_string tipNpcInc2show = pNativeSpeaker->getLocalizedStrFromID("npcIncludeCcUniEol-tip", + L"Apply non-printing characters appearance settings to C0, C1 control and Unicode EOL (next line, line separator and paragraph separator) characters."); + _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()); + _tipNpcInclude = CreateToolTip(IDC_CHECK_NPC_INCLUDECCUNIEOL, _hSelf, _hInst, const_cast(tipNpcInc2show.c_str()), pNativeSpeaker->isRTL()); - _tips.emplace_back(_tipNote); - _tips.emplace_back(_tipAbb); - _tips.emplace_back(_tipCodepoint); - _tips.emplace_back(_tipNpcColor); + _tips.push_back(_tipNote); + _tips.push_back(_tipAbb); + _tips.push_back(_tipCodepoint); + _tips.push_back(_tipNpcColor); + _tips.push_back(_tipNpcInclude); for (auto& tip : _tips) { @@ -1142,6 +1146,15 @@ intptr_t CALLBACK EditingSubDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM return TRUE; } + case IDC_CHECK_NPC_INCLUDECCUNIEOL: + { + svp._npcIncludeCcUniEol = isCheckedOrNot(IDC_CHECK_NPC_INCLUDECCUNIEOL); + + const HWND grandParent = ::GetParent(_hParent); + ::SendMessage(grandParent, NPPM_INTERNAL_SETNPC, IDC_CHECK_NPC_INCLUDECCUNIEOL, 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); diff --git a/PowerEditor/src/WinControls/Preference/preferenceDlg.h b/PowerEditor/src/WinControls/Preference/preferenceDlg.h index 21f3b9430..a5aa95dfe 100644 --- a/PowerEditor/src/WinControls/Preference/preferenceDlg.h +++ b/PowerEditor/src/WinControls/Preference/preferenceDlg.h @@ -70,10 +70,11 @@ private : HWND _tipAbb = nullptr; HWND _tipCodepoint = nullptr; HWND _tipNpcColor = nullptr; + HWND _tipNpcInclude = nullptr; std::vector _tips; - intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam); + intptr_t CALLBACK run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam) override; void initScintParam(); void changeLineHiliteMode(bool enableSlider); }; diff --git a/PowerEditor/src/WinControls/Preference/preference_rc.h b/PowerEditor/src/WinControls/Preference/preference_rc.h index 2a4a4c42b..ce5a56607 100644 --- a/PowerEditor/src/WinControls/Preference/preference_rc.h +++ b/PowerEditor/src/WinControls/Preference/preference_rc.h @@ -163,6 +163,7 @@ #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 IDC_CHECK_NPC_INCLUDECCUNIEOL (IDD_PREFERENCE_SUB_EDITING + 58) #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 feba291e0..6a3d91848 100644 --- a/PowerEditor/src/menuCmdID.h +++ b/PowerEditor/src/menuCmdID.h @@ -376,6 +376,7 @@ #define IDM_VIEW_TAB_COLOUR_5 (IDM_VIEW + 115) #define IDM_VIEW_NPC (IDM_VIEW + 130) + #define IDM_VIEW_NPC_CCUNIEOL (IDM_VIEW + 131) #define IDM_VIEW_GOTO_ANOTHER_VIEW 10001 #define IDM_VIEW_CLONE_TO_ANOTHER_VIEW 10002