From 119dc5ecd3d8fdb60d30bef76a5a75ef26c5168b Mon Sep 17 00:00:00 2001 From: Don Ho Date: Thu, 30 Nov 2023 15:11:46 +0100 Subject: [PATCH] Make RTL per document & remembered across the sessions Fix #9665, fix #9950, fix #14385 --- PowerEditor/src/Notepad_plus.cpp | 7 +----- PowerEditor/src/NppCommands.cpp | 4 ---- PowerEditor/src/NppIO.cpp | 6 +++++ PowerEditor/src/Parameters.cpp | 7 ++++++ PowerEditor/src/Parameters.h | 2 +- PowerEditor/src/ScintillaComponent/Buffer.cpp | 3 +++ PowerEditor/src/ScintillaComponent/Buffer.h | 5 ++++ .../ScintillaComponent/ScintillaEditView.cpp | 9 +++++++ PowerEditor/src/localization.cpp | 24 ++++++++++++++++--- PowerEditor/src/localization.h | 14 +++++++---- 10 files changed, 62 insertions(+), 19 deletions(-) diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index ac77c24b212a..fd56ac18b7fe 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -864,12 +864,6 @@ LRESULT Notepad_plus::init(HWND hwnd) _mainEditView.getFocus(); - if (_nativeLangSpeaker.isRTL()) - { - _mainEditView.changeTextDirection(true); - _subEditView.changeTextDirection(true); - } - return TRUE; } @@ -6227,6 +6221,7 @@ void Notepad_plus::getCurrentOpenedFiles(Session & session, bool includUntitledD sfi._isMonitoring = buf->isMonitoringOn(); sfi._individualTabColour = docTab[k]->getIndividualTabColour(static_cast(i)); + sfi._isRTL = buf->isRTL(); _invisibleEditView.execute(SCI_SETDOCPOINTER, 0, buf->getDocument()); size_t maxLine = static_cast(_invisibleEditView.execute(SCI_GETLINECOUNT)); diff --git a/PowerEditor/src/NppCommands.cpp b/PowerEditor/src/NppCommands.cpp index 825d49188d29..f605ceda5e36 100644 --- a/PowerEditor/src/NppCommands.cpp +++ b/PowerEditor/src/NppCommands.cpp @@ -3851,16 +3851,12 @@ void Notepad_plus::command(int id) } _pEditView->changeTextDirection(toRTL); - _pNonEditView->changeTextDirection(toRTL); // Wrap then !wrap to fix problem of mirror characters bool isWraped = _pEditView->isWrap(); _pEditView->wrap(!isWraped); _pEditView->wrap(isWraped); - _pNonEditView->wrap(!isWraped); - _pNonEditView->wrap(isWraped); - if (_pDocMap) { _pDocMap->changeTextDirection(toRTL); diff --git a/PowerEditor/src/NppIO.cpp b/PowerEditor/src/NppIO.cpp index 440fd377fae2..ea5089ceae13 100644 --- a/PowerEditor/src/NppIO.cpp +++ b/PowerEditor/src/NppIO.cpp @@ -2212,6 +2212,10 @@ bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode, const wch if (isSnapshotMode && session._mainViewFiles[i]._backupFilePath != TEXT("") && PathFileExists(session._mainViewFiles[i]._backupFilePath.c_str())) buf->setDirty(true); + buf->setRTL(session._mainViewFiles[i]._isRTL); + if (i == 0 && session._activeMainIndex == 0) + _mainEditView.changeTextDirection(buf->isRTL()); + _mainDocTab.setIndividualTabColour(lastOpened, session._mainViewFiles[i]._individualTabColour); //Force in the document so we can add the markers @@ -2340,6 +2344,8 @@ bool Notepad_plus::loadSession(Session & session, bool isSnapshotMode, const wch if (isSnapshotMode && session._subViewFiles[k]._backupFilePath != TEXT("") && PathFileExists(session._subViewFiles[k]._backupFilePath.c_str())) buf->setDirty(true); + buf->setRTL(session._subViewFiles[k]._isRTL); + _subDocTab.setIndividualTabColour(lastOpened, session._subViewFiles[k]._individualTabColour); //Force in the document so we can add the markers diff --git a/PowerEditor/src/Parameters.cpp b/PowerEditor/src/Parameters.cpp index d9f407e34426..b060b2118a4d 100644 --- a/PowerEditor/src/Parameters.cpp +++ b/PowerEditor/src/Parameters.cpp @@ -2425,6 +2425,12 @@ bool NppParameters::getSessionFromXmlTree(TiXmlDocument *pSessionDoc, Session& s sfi._individualTabColour = _wtoi(intStrTabColour); } + const TCHAR* rtlStr = (childNode->ToElement())->Attribute(TEXT("RTL")); + if (rtlStr) + { + sfi._isRTL = _wcsicmp(TEXT("yes"), rtlStr) == 0; + } + for (TiXmlNode *markNode = childNode->FirstChildElement(TEXT("Mark")); markNode; markNode = markNode->NextSibling(TEXT("Mark"))) @@ -3588,6 +3594,7 @@ void NppParameters::writeSession(const Session & session, const TCHAR *fileName) (fileNameNode->ToElement())->SetAttribute(TEXT("originalFileLastModifTimestamp"), static_cast(viewSessionFiles[i]._originalFileLastModifTimestamp.dwLowDateTime)); (fileNameNode->ToElement())->SetAttribute(TEXT("originalFileLastModifTimestampHigh"), static_cast(viewSessionFiles[i]._originalFileLastModifTimestamp.dwHighDateTime)); (fileNameNode->ToElement())->SetAttribute(TEXT("tabColourId"), static_cast(viewSessionFiles[i]._individualTabColour)); + (fileNameNode->ToElement())->SetAttribute(TEXT("RTL"), viewSessionFiles[i]._isRTL ? TEXT("yes") : TEXT("no")); // docMap (fileNameNode->ToElement())->SetAttribute(TEXT("mapFirstVisibleDisplayLine"), _i64tot(static_cast(viewSessionFiles[i]._mapPos._firstVisibleDisplayLine), szInt64, 10)); diff --git a/PowerEditor/src/Parameters.h b/PowerEditor/src/Parameters.h index 7256005736e5..004eb5b32479 100644 --- a/PowerEditor/src/Parameters.h +++ b/PowerEditor/src/Parameters.h @@ -210,7 +210,7 @@ struct sessionFileInfo : public Position bool _isUserReadOnly = false; bool _isMonitoring = false; int _individualTabColour = -1; - + bool _isRTL = false; std::wstring _backupFilePath; FILETIME _originalFileLastModifTimestamp {}; diff --git a/PowerEditor/src/ScintillaComponent/Buffer.cpp b/PowerEditor/src/ScintillaComponent/Buffer.cpp index 266f09391675..c09abe69e89f 100644 --- a/PowerEditor/src/ScintillaComponent/Buffer.cpp +++ b/PowerEditor/src/ScintillaComponent/Buffer.cpp @@ -86,6 +86,9 @@ Buffer::Buffer(FileManager * pManager, BufferID id, Document doc, DocFileStatus // reset after initialization _canNotify = true; + + if (nppParamInst.getNativeLangSpeaker()->isRTL() && nppParamInst.getNativeLangSpeaker()->isEditZoneRTL()) + _isRTL = true; } diff --git a/PowerEditor/src/ScintillaComponent/Buffer.h b/PowerEditor/src/ScintillaComponent/Buffer.h index 4143094e209a..9c7671fbd590 100644 --- a/PowerEditor/src/ScintillaComponent/Buffer.h +++ b/PowerEditor/src/ScintillaComponent/Buffer.h @@ -342,6 +342,9 @@ class Buffer final { return _docColorId; }; + bool isRTL() const { return _isRTL; }; + void setRTL(bool isRTL) { _isRTL = isRTL; }; + private: int indexOfReference(const ScintillaEditView * identifier) const; @@ -420,4 +423,6 @@ class Buffer final { std::mutex _reloadFromDiskRequestGuard; bool _isInaccessible = false; + + bool _isRTL = false; }; diff --git a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp index 541e94cf00cf..8caab546eff3 100644 --- a/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp +++ b/PowerEditor/src/ScintillaComponent/ScintillaEditView.cpp @@ -2228,6 +2228,9 @@ void ScintillaEditView::activateBuffer(BufferID buffer, bool force) int enabledCH = svp._isChangeHistoryEnabled ? (SC_CHANGE_HISTORY_ENABLED | SC_CHANGE_HISTORY_MARKERS) : SC_CHANGE_HISTORY_DISABLED; execute(SCI_SETCHANGEHISTORY, enabledCH); + if (isTextDirectionRTL() != buffer->isRTL()) + changeTextDirection(buffer->isRTL()); + return; //all done } @@ -4214,6 +4217,9 @@ bool ScintillaEditView::isTextDirectionRTL() const void ScintillaEditView::changeTextDirection(bool isRTL) { + if (isTextDirectionRTL() == isRTL) + return; + long exStyle = static_cast(::GetWindowLongPtr(_hSelf, GWL_EXSTYLE)); exStyle = isRTL ? (exStyle | WS_EX_LAYOUTRTL) : (exStyle & (~WS_EX_LAYOUTRTL)); ::SetWindowLongPtr(_hSelf, GWL_EXSTYLE, exStyle); @@ -4246,6 +4252,9 @@ void ScintillaEditView::changeTextDirection(bool isRTL) execute(SCI_ASSIGNCMDKEY, SCK_LEFT + (SCMOD_CTRL << 16), SCI_WORDLEFT); execute(SCI_ASSIGNCMDKEY, SCK_LEFT + ((SCMOD_SHIFT + SCMOD_CTRL) << 16), SCI_WORDLEFTEXTEND); } + + Buffer* buf = getCurrentBuffer(); + buf->setRTL(isRTL); } generic_string ScintillaEditView::getEOLString() const diff --git a/PowerEditor/src/localization.cpp b/PowerEditor/src/localization.cpp index 7c31222dd597..d8560bee0e08 100644 --- a/PowerEditor/src/localization.cpp +++ b/PowerEditor/src/localization.cpp @@ -122,12 +122,30 @@ void NativeLangSpeaker::init(TiXmlDocumentA *nativeLangDocRootA, bool loadIfEngl { TiXmlElementA *element = _nativeLangA->ToElement(); const char *rtl = element->Attribute("RTL"); + if (rtl) + { _isRTL = (strcmp(rtl, "yes") == 0); - else - _isRTL = false; - // get original file name (defined by Notpad++) from the attribute + if (_isRTL) + { + const char* editZoneRtl = element->Attribute("editZoneRTL"); + if (editZoneRtl) + _isEditZoneRTL = !(strcmp(editZoneRtl, "no") == 0); + else + _isEditZoneRTL = true; + } + else + _isEditZoneRTL = false; + } + else + { + _isRTL = false; + _isEditZoneRTL = false; + } + + + // get original file name (defined by Notpad++) from the attribute _fileName = element->Attribute("filename"); if (!loadIfEnglish && _fileName && stricmp("english.xml", _fileName) == 0) diff --git a/PowerEditor/src/localization.h b/PowerEditor/src/localization.h index 62a70fded68f..68105c6ddb14 100644 --- a/PowerEditor/src/localization.h +++ b/PowerEditor/src/localization.h @@ -39,7 +39,6 @@ class MenuPosition { class NativeLangSpeaker { public: - NativeLangSpeaker():_nativeLangA(NULL), _nativeLangEncoding(CP_ACP), _isRTL(false), _fileName(NULL){}; void init(TiXmlDocumentA *nativeLangDocRootA, bool loadIfEnglish = false); void changeConfigLang(HWND hDlg); void changeLangTabContextMenu(HMENU hCM); @@ -66,6 +65,10 @@ class NativeLangSpeaker { return _isRTL; }; + bool isEditZoneRTL() const { + return _isEditZoneRTL; + }; + const char * getFileName() const { return _fileName; }; @@ -92,10 +95,11 @@ class NativeLangSpeaker { int messageBox(const char *msgBoxTagName, HWND hWnd, const TCHAR *message, const TCHAR *title, int msgBoxType, int intInfo = 0, const TCHAR *strInfo = NULL); private: - TiXmlNodeA *_nativeLangA; - int _nativeLangEncoding; - bool _isRTL; - const char *_fileName; + TiXmlNodeA *_nativeLangA = nullptr; + int _nativeLangEncoding = CP_ACP; + bool _isRTL = false; // for Notepad++ GUI + bool _isEditZoneRTL = false; // for Scitilla + const char *_fileName = nullptr; std::map _shortcutMenuEntryNameMap; };