diff --git a/src/Edit.c b/src/Edit.c index ef33dc3f5..64e9519b9 100644 --- a/src/Edit.c +++ b/src/Edit.c @@ -417,7 +417,7 @@ void EditSetNewText(HWND hwnd, const char* lpstrText, DocPosU lenText, bool bCle UndoRedoReset(); } - //DocChangeTransactionBegin(); + //UndoTransActionBegin(); SciCall_Cancel(); if (SciCall_GetReadOnly()) { @@ -434,7 +434,7 @@ void EditSetNewText(HWND hwnd, const char* lpstrText, DocPosU lenText, bool bCle Sci_GotoPosChooseCaret(0); - //EndDocChangeTransaction(); + //EndUndoTransAction(); s_bFreezeAppTitle = false; } @@ -3346,7 +3346,7 @@ void EditIndentBlock(HWND hwnd, int cmd, bool bFormatIndentation, bool bForceAll return; } - DocChangeTransactionBegin() + UndoTransActionBegin() if (bForceAll) { SciCall_SelectAll(); @@ -3417,7 +3417,7 @@ void EditIndentBlock(HWND hwnd, int cmd, bool bFormatIndentation, bool bForceAll Sci_ScrollChooseCaret(); } - EndDocChangeTransaction(); + EndUndoTransAction(); } @@ -4122,7 +4122,7 @@ void EditStripFirstCharacter(HWND hwnd) DocLn const iLineStart = SciCall_LineFromPosition(iSelStart); DocLn const iLineEnd = SciCall_LineFromPosition(iSelEnd); - DocChangeTransactionBegin(); + UndoTransActionBegin(); if (SciCall_IsSelectionRectangle()) { const DocPos selAnchorMainPos = SciCall_GetRectangularSelectionAnchor(); @@ -4176,7 +4176,7 @@ void EditStripFirstCharacter(HWND hwnd) } } - EndDocChangeTransaction(); + EndUndoTransAction(); } @@ -4197,7 +4197,7 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan DocLn const iLineStart = SciCall_LineFromPosition(iSelStart); DocLn const iLineEnd = SciCall_LineFromPosition(iSelEnd); - DocChangeTransactionBegin(); + UndoTransActionBegin(); if (Sci_IsMultiOrRectangleSelection() && !bIgnoreSelection) { if (SciCall_IsSelectionEmpty()) { @@ -4290,7 +4290,7 @@ void EditStripLastCharacter(HWND hwnd, bool bIgnoreSelection, bool bTrailingBlan } } - EndDocChangeTransaction(); + EndUndoTransAction(); } @@ -4319,7 +4319,7 @@ void EditCompressBlanks() const DocPos vSpcAnchorMainPos = SciCall_GetRectangularSelectionAnchorVirtualSpace(); const DocPos vSpcCaretMainPos = SciCall_GetRectangularSelectionCaretVirtualSpace(); - DocChangeTransactionBegin(); + UndoTransActionBegin(); DocPos iMaxLineLen = Sci_GetRangeMaxLineLength(iLineStart, iLineEnd); char* lineBuffer = AllocMem(iMaxLineLen + 1, HEAP_ZERO_MEMORY); @@ -4372,7 +4372,7 @@ void EditCompressBlanks() SciCall_SetRectangularSelectionCaretVirtualSpace(vSpcCaretMainPos); } - EndDocChangeTransaction(); + EndUndoTransAction(); } else if (Sci_IsMultiSelection()) { // @@@ not implemented @@ -4435,7 +4435,7 @@ void EditCompressBlanks() if (bModified) { - DocChangeTransactionBegin(); + UndoTransActionBegin(); if (!SciCall_IsSelectionEmpty()) { SciCall_TargetFromSelection(); @@ -4458,7 +4458,7 @@ void EditCompressBlanks() EditSetSelectionEx(iNewPos, iNewPos, -1, -1); } - EndDocChangeTransaction(); + EndUndoTransAction(); } } FreeMem(pszOut); @@ -4493,7 +4493,7 @@ void EditRemoveBlankLines(HWND hwnd, bool bMerge, bool bRemoveWhiteSpace) --iEndLine; } - DocChangeTransactionBegin(); + UndoTransActionBegin(); for (DocLn iLine = iBegLine; iLine <= iEndLine; ) { DocLn nBlanks = 0; @@ -4538,8 +4538,7 @@ void EditRemoveBlankLines(HWND hwnd, bool bMerge, bool bRemoveWhiteSpace) } } - EndDocChangeTransaction(); - + EndUndoTransAction(); } @@ -4694,7 +4693,7 @@ void EditFocusMarkedLinesCmd(HWND hwnd, bool bCopy, bool bDelete) if (bDelete) { - DocChangeTransactionBegin(); + UndoTransActionBegin(); line = 0; while (line >= 0) { @@ -4712,7 +4711,7 @@ void EditFocusMarkedLinesCmd(HWND hwnd, bool bCopy, bool bDelete) } } - EndDocChangeTransaction(); + EndUndoTransAction(); } SciCall_GotoLine(min_ln(curLn, Sci_GetLastDocLineNumber())); @@ -7332,9 +7331,9 @@ void EditSelectionMultiSelectAllEx(HWND hwnd, CLPCEDITFINDREPLACE edFndRpl) LPCWSTR wchFind = _EditGetFindStrg(hwnd, &efr, false); if (StrIsNotEmpty(wchFind)) { - DocChangeTransactionBegin(); + UndoTransActionBegin(); EditMarkAll(wchFind, efr.fuFlags, 0, Sci_GetDocEndPosition(), true); - EndDocChangeTransaction(); + EndUndoTransAction(); } ReleaseEFR(&efr); } @@ -7559,7 +7558,7 @@ void EditClearAllOccurrenceMarkers(HWND hwnd) UNREFERENCED_PARAMETER(hwnd); Globals.iMarkOccurrencesCount = Globals.iMarkOccurrencesCount = 0; - LimitNotifyEvents(EVM_None); + LimitNotifyEvents(); SciCall_SetIndicatorCurrent(INDIC_NP3_MARK_OCCURANCE); SciCall_IndicatorClearRange(0, Sci_GetDocEndPosition()); @@ -7671,7 +7670,7 @@ void EditMarkAll(LPCWSTR wchFind, int sFlags, DocPos rangeStart, DocPos rangeEnd DocPos iFindLength = 0; - LimitNotifyEvents(EVM_None); + LimitNotifyEvents(); if (StrIsEmpty(wchFind)) { diff --git a/src/Notepad3.c b/src/Notepad3.c index 12ce9a894..12928095f 100644 --- a/src/Notepad3.c +++ b/src/Notepad3.c @@ -416,20 +416,19 @@ static LONG _UndoRedoActionMap(const LONG token, const UndoRedoSelection_t** se // => EndUndoTransAction(); -static volatile LONG UndoActionToken = URTok_NoRecording; // needs UndoRedoRecordingStart() +static volatile int UndoRedoActionStackCount = 0; -static inline bool _InUndoRedoTransaction() +__forceinline bool _InUndoRedoTransaction() { - return (InterlockedOr(&UndoActionToken, 0L) >= URTok_TokenStart); + return (UndoRedoActionStackCount > 0); } static inline void _SplitUndoTransaction() { - - if (!_InUndoRedoTransaction()) { - SciCall_BeginUndoAction(); - /* noop */ + if (_InUndoRedoTransaction()) { SciCall_EndUndoAction(); + /* noop */ + SciCall_BeginUndoAction(); } } @@ -452,28 +451,23 @@ static __forceinline bool IsEventSignaled() { // ---------------------------------------------------------------------------- -static volatile LONG iNotifyChangeStackCounter = 0L; -static __forceinline bool NotifyDocChanged() +__forceinline bool NotifyDocChanged() { - return (InterlockedOr(&iNotifyChangeStackCounter, 0L) == 0L); + return ((SciCall_GetModEventMask() & EVM_Default) == EVM_Default); } -void DisableDocChangeNotification() +int DisableDocChangeNotification() { - if (NotifyDocChanged()) { - SciCall_SetModEventMask(EVM_None); - } - InterlockedIncrement(&iNotifyChangeStackCounter); + int const currentMask = SciCall_GetModEventMask(); + SciCall_SetModEventMask(EVM_None); + return currentMask; } -void EnableDocChangeNotification() +void EnableDocChangeNotification(const int evm) { - if (!NotifyDocChanged()) { - InterlockedDecrement(&iNotifyChangeStackCounter); - } + SciCall_SetModEventMask(evm); if (NotifyDocChanged()) { - SciCall_SetModEventMask(EVM_Default); EditUpdateVisibleIndicators(); UpdateStatusbar(false); } @@ -2651,8 +2645,6 @@ LRESULT MsgCreate(HWND hwnd, WPARAM wParam,LPARAM lParam) SciCall_SetZoom(g_IniWinInfo.zoom ? g_IniWinInfo.zoom : 100); - EnableDocChangeNotification(); - return 0LL; } @@ -10208,6 +10200,7 @@ void UpdateUI() { //============================================================================= +#if 0 LONG BeginUndoActionEx() { if (!_InUndoRedoTransaction()) { @@ -10237,6 +10230,7 @@ void EndUndoActionEx(const LONG token) assert("No Transaction" && 0); } } +#endif //============================================================================= // @@ -10454,16 +10448,12 @@ static void _SaveRedoSelection(const LONG token) // LONG BeginUndoActionSelection() { - if (_InUndoRedoTransaction()) { - return URTok_InTransaction; - } - LONG const token = _SaveUndoSelection(); - if (token >= URTok_TokenStart) { - InterlockedExchange(&UndoActionToken, token); + SciCall_BeginUndoAction(); + ++UndoRedoActionStackCount; + if (1 == UndoRedoActionStackCount) { DisableDocChangeNotification(); - SciCall_BeginUndoAction(); } - return token; + return _SaveUndoSelection(); } @@ -10475,26 +10465,18 @@ const char* const _assert_msg = "Broken UndoRedo-Transaction!"; // void EndUndoActionSelection(const LONG token) { - switch (token) { - case URTok_InTransaction: - // nothing to do (child transaction) - break; - case URTok_NoTransaction: - assert(_assert_msg && InterlockedOr(&UndoActionToken, 0L) == URTok_NoTransaction); - break; - case URTok_NoRecording: - assert(_assert_msg && InterlockedOr(&UndoActionToken, 0L) == URTok_NoRecording); - break; - default: - if (token == InterlockedOr(&UndoActionToken, 0L)) { - _SaveRedoSelection(token); - SciCall_EndUndoAction(); - InterlockedExchange(&UndoActionToken, URTok_NoTransaction); - EnableDocChangeNotification(); + if (token >= URTok_TokenStart) { + --UndoRedoActionStackCount; + SciCall_EndUndoAction(); + if (0 == UndoRedoActionStackCount) { + EnableDocChangeNotification(EVM_Default); } - else { assert(_assert_msg && 0); } - break; + _SaveRedoSelection(token); } + else { + assert(_assert_msg && 0); + } + assert(_assert_msg && (UndoRedoActionStackCount >= 0)); } //============================================================================= @@ -10512,7 +10494,7 @@ static void _RestoreActionSelection(const LONG token, DoAction doAct) if ((_UndoRedoActionMap(token, &pSel) >= URTok_TokenStart) && (pSel != NULL)) { - LimitNotifyEvents(EVM_None); + LimitNotifyEvents(); DocPos* pPosAnchor = (DocPos*)((UNDO == doAct) ? utarray_front(pSel->anchorPos_undo) : utarray_front(pSel->anchorPos_redo)); DocPos* pPosCur = (DocPos*)((UNDO == doAct) ? utarray_front(pSel->curPos_undo) : utarray_front(pSel->curPos_redo)); @@ -10727,22 +10709,15 @@ static LONG _UndoRedoActionMap(const LONG token, const UndoRedoSelection_t** sel ULONG utoken = (token >= URTok_TokenStart) ? (ULONG)token : 0UL; if (selection == NULL) { // reset / clear - LONG const curToken = InterlockedOr(&UndoActionToken, 0L); - if (curToken == URTok_NoTokenFlag) { - EndUndoActionEx(curToken); - InterlockedExchange(&UndoActionToken, URTok_InTransaction); - } - else if (curToken >= URTok_TokenStart) { - EndUndoActionSelection(curToken); - } - else { - InterlockedExchange(&UndoActionToken, URTok_NoTransaction); + while (UndoRedoActionStackCount > 0) { + SciCall_EndUndoAction(); + --UndoRedoActionStackCount; } utarray_clear(UndoRedoSelectionUTArray); //~utarray_free(UndoRedoSelectionUTArray); //~utarray_init(UndoRedoSelectionUTArray, &UndoRedoSelection_icd); uiTokenCnt = URTok_TokenStart; - return InterlockedOr(&UndoActionToken, 0L); + return URTok_NoTransaction; } if (!SciCall_GetUndoCollection()) { @@ -11120,9 +11095,9 @@ bool FileLoad(const HPATHL hfile_pth, const FileLoadFlags fLoadFlags) if (bCheckEOL && !Style_MaybeBinaryFile(Globals.hwndEdit, Paths.CurrentFile)) { if (WarnLineEndingDlg(Globals.hwndMain, &fioStatus)) { - DocChangeTransactionBegin(); + UndoTransActionBegin(); SciCall_ConvertEOLs(fioStatus.iEOLMode); - EndDocChangeTransaction(); + EndUndoTransAction(); Globals.bDocHasInconsistentEOLs = false; } SciCall_SetEOLMode(fioStatus.iEOLMode); diff --git a/src/Notepad3.h b/src/Notepad3.h index ac788121e..09e413184 100644 --- a/src/Notepad3.h +++ b/src/Notepad3.h @@ -197,34 +197,20 @@ LRESULT MsgUahMenuBar(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam); // ---------------------------------------------------------------------------- -#define LimitNotifyEvents(EVM) { int _evm_ = 0; __try { _evm_ = SciCall_GetModEventMask(); SciCall_SetModEventMask(EVM); -#define RestoreNotifyEvents() ;} __finally { SciCall_SetModEventMask(_evm_); } } +int DisableDocChangeNotification(); +void EnableDocChangeNotification(const int evm); -void DisableDocChangeNotification(); -void EnableDocChangeNotification(); +#define LimitNotifyEvents() { int _evm_ = 0; __try { _evm_ = DisableDocChangeNotification(); +#define RestoreNotifyEvents() ;} __finally { EnableDocChangeNotification(_evm_); } } // ---------------------------------------------------------------------------- -// none msg change notify, preserve redo-undo selection stack (only in simple, non complex operations) +// none msg change notify, preserve redo-undo selection stack #define UndoTransActionBegin() { LONG _token_ = 0L; __try { _token_ = BeginUndoActionSelection(); #define EndUndoTransAction() ;} __finally { EndUndoActionSelection(_token_); } } // ---------------------------------------------------------------------------- -LONG BeginUndoActionEx(); -void EndUndoActionEx(const LONG token); -// lean msg change notify (preferred) - does not preserve redo-undo selection stack -#define DocChangeTransactionBegin() { LONG _tok_ = 0L; __try { _tok_ = BeginUndoActionEx(); -#define EndDocChangeTransaction() ;} __finally { EndUndoActionEx(_tok_); } } - -// DEBUG: -//#define DocChangeTransactionBegin() UndoTransActionBegin() -//#define EndDocChangeTransaction() EndUndoTransAction() -//#define UndoTransActionBegin() DocChangeTransactionBegin() -//#define EndUndoTransAction() EndDocChangeTransaction() - -// ---------------------------------------------------------------------------- - #define BeginWaitCursor(cond, text) { \ if (cond) { \ SciCall_SetCursor(SC_CURSORWAIT); \ diff --git a/src/SciCall.h b/src/SciCall.h index 7534aa917..ff2060728 100644 --- a/src/SciCall.h +++ b/src/SciCall.h @@ -700,22 +700,13 @@ DeclareSciCallV1(SetAdditionalCaretsVisible, SETADDITIONALCARETSVISIBLE, bool, f // Undo/Redo Stack // DeclareSciCallV0(EmptyUndoBuffer, EMPTYUNDOBUFFER); -//DeclareSciCallV0(BeginUndoAction, BEGINUNDOACTION); +DeclareSciCallV0(BeginUndoAction, BEGINUNDOACTION); DeclareSciCallV2(AddUndoAction, ADDUNDOACTION, int, token, int, flags); -//DeclareSciCallV0(EndUndoAction, ENDUNDOACTION); +DeclareSciCallV0(EndUndoAction, ENDUNDOACTION); DeclareSciCallR0(GetUndoCollection, GETUNDOCOLLECTION, bool); DeclareSciCallV1(SetUndoCollection, SETUNDOCOLLECTION, bool, bCollectUndo); -inline void SciCall_BeginUndoAction() -{ - SciCall(SCI_BEGINUNDOACTION, 0, 0); -} -inline void SciCall_EndUndoAction() -{ - SciCall(SCI_ENDUNDOACTION, 0, 0); -} - //============================================================================= // // IME