mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-11 21:03:05 +08:00
+rfc: refactoring of undo/redo and document modify handler
This commit is contained in:
parent
fbdd90530f
commit
238111dcd2
41
src/Edit.c
41
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)) {
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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); \
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user