mirror of
https://github.com/rizonesoft/Notepad3.git
synced 2026-06-14 21:09:05 +08:00
+fix: refactored of undo/redo and document modify handler
This commit is contained in:
parent
9fc1752306
commit
29ad342eef
@ -5162,6 +5162,7 @@ void EditSortLines(HWND hwnd, int iSortFlags)
|
||||
}
|
||||
|
||||
BeginWaitCursor(iLineCount > 10000, L" Sorting Lines...");
|
||||
UndoTransActionBegin();
|
||||
|
||||
DocPos iMaxLineLen = Sci_GetRangeMaxLineLength(iLineStart, iLineEnd);
|
||||
char* const pmsz = AllocMem(iMaxLineLen + 1, HEAP_ZERO_MEMORY);
|
||||
@ -5331,6 +5332,7 @@ void EditSortLines(HWND hwnd, int iSortFlags)
|
||||
EditSetSelectionEx(iAnchorPos, iCurPos, -1, -1);
|
||||
}
|
||||
|
||||
EndUndoTransAction();
|
||||
EndWaitCursor();
|
||||
}
|
||||
|
||||
@ -7276,8 +7278,6 @@ void EditMarkAllOccurrences(HWND hwnd, bool bForceClear)
|
||||
|
||||
int const searchFlags = GetMarkAllOccSearchFlags();
|
||||
|
||||
DocChangeTransactionBegin();
|
||||
|
||||
if (Settings.MarkOccurrencesMatchVisible) {
|
||||
|
||||
// get visible lines for update
|
||||
@ -7292,8 +7292,6 @@ void EditMarkAllOccurrences(HWND hwnd, bool bForceClear)
|
||||
} else {
|
||||
EditMarkAll(NULL, searchFlags, 0, Sci_GetDocEndPosition(), false);
|
||||
}
|
||||
|
||||
EndDocChangeTransaction();
|
||||
}
|
||||
|
||||
|
||||
@ -7488,7 +7486,9 @@ bool EditReplaceAll(HWND hwnd, LPEDITFINDREPLACE lpefr, bool bShowInfo)
|
||||
DocPos enlargement = 0;
|
||||
|
||||
BeginWaitCursorUID(true, IDS_MUI_SB_REPLACE_ALL);
|
||||
UndoTransActionBegin();
|
||||
Globals.iReplacedOccurrences = EditReplaceAllInRange(hwnd, lpefr, start, end, &enlargement);
|
||||
EndUndoTransAction();
|
||||
EndWaitCursor();
|
||||
|
||||
WCHAR wchOcc[64] = { L'\0' };
|
||||
|
||||
@ -232,13 +232,19 @@ const WCHAR* const TBBUTTON_DEFAULT_IDS_V2 = L"1 2 4 3 28 0 5 6 0 7 8 9 0 10 11
|
||||
//
|
||||
// Save Needed Flag
|
||||
//
|
||||
static bool s_DocNeedSaving = false; // dirty-flag
|
||||
static bool s_NeedSavingForced = false; // dirty-flag
|
||||
|
||||
static inline void SetSaveNeeded()
|
||||
inline static bool IsSaveNeeded()
|
||||
{
|
||||
AutoSaveStart(!s_DocNeedSaving);
|
||||
s_DocNeedSaving = true;
|
||||
return SciCall_GetModify() || s_NeedSavingForced;
|
||||
}
|
||||
|
||||
static inline void SetSaveNeeded(const bool bSetFlag)
|
||||
{
|
||||
AutoSaveStart(!s_NeedSavingForced);
|
||||
if (bSetFlag) {
|
||||
s_NeedSavingForced = true;
|
||||
}
|
||||
if (IsWindow(Globals.hwndDlgFindReplace)) {
|
||||
PostWMCommand(Globals.hwndDlgFindReplace, IDC_DOC_MODIFIED);
|
||||
}
|
||||
@ -251,14 +257,9 @@ static inline void SetSavePoint()
|
||||
UpdateToolbar();
|
||||
}
|
||||
|
||||
inline static bool IsSaveNeeded()
|
||||
{
|
||||
return SciCall_GetModify() || s_DocNeedSaving;
|
||||
}
|
||||
|
||||
void SetSaveDone()
|
||||
{
|
||||
s_DocNeedSaving = false;
|
||||
s_NeedSavingForced = false;
|
||||
SetSavePoint();
|
||||
}
|
||||
|
||||
@ -408,14 +409,22 @@ static void CopyUndoRedoSelection(void* dst, const void* src)
|
||||
|
||||
static UT_icd UndoRedoSelection_icd = { sizeof(UndoRedoSelection_t), InitUndoRedoSelection, CopyUndoRedoSelection, DelUndoRedoSelection };
|
||||
static UT_array* UndoRedoSelectionUTArray = NULL;
|
||||
static inline bool _InUndoRedoTransaction();
|
||||
static void _SaveRedoSelection(const LONG token);
|
||||
static LONG _SaveUndoSelection();
|
||||
static LONG _UndoRedoActionMap(const LONG token, const UndoRedoSelection_t** selection);
|
||||
// => UndoTransActionBegin();
|
||||
// => EndUndoTransAction();
|
||||
|
||||
static inline void _SplitUndoTransaction() {
|
||||
|
||||
static volatile LONG UndoActionToken = URTok_NoRecording; // needs UndoRedoRecordingStart()
|
||||
|
||||
static inline bool _InUndoRedoTransaction()
|
||||
{
|
||||
return (InterlockedOr(&UndoActionToken, 0L) >= URTok_TokenStart);
|
||||
}
|
||||
|
||||
static inline void _SplitUndoTransaction()
|
||||
{
|
||||
if (!_InUndoRedoTransaction()) {
|
||||
SciCall_BeginUndoAction();
|
||||
/* noop */
|
||||
@ -448,10 +457,12 @@ static __forceinline bool NotifyDocChanged()
|
||||
return (InterlockedOr(&iNotifyChangeStackCounter, 0L) == 0L);
|
||||
}
|
||||
|
||||
void SetNotifyDocChangedEvent(const SciEventMask evm)
|
||||
void SetNotifyDocChangedEvent()
|
||||
{
|
||||
if (NotifyDocChanged()) {
|
||||
SciCall_SetModEventMask(EVM_None);
|
||||
}
|
||||
InterlockedIncrement(&iNotifyChangeStackCounter);
|
||||
SciCall_SetModEventMask(evm);
|
||||
}
|
||||
|
||||
void ResetNotifyDocChangedEvent()
|
||||
@ -1768,7 +1779,7 @@ HWND InitInstance(const HINSTANCE hInstance, LPCWSTR pszCmdLine, int nCmdShow)
|
||||
if (Path_IsExistingFile(s_hpthRelaunchElevatedFile)) {
|
||||
DeleteFileW(Path_Get(s_hpthRelaunchElevatedFile));
|
||||
}
|
||||
SetSaveNeeded();
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
|
||||
if (Path_IsNotEmpty(Paths.CurrentFile)) {
|
||||
@ -3836,11 +3847,11 @@ LRESULT MsgFileChangeNotify(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
if (IsYesOkay(InfoBoxLng(MB_YESNO | MB_ICONWARNING, NULL, IDS_MUI_FILECHANGENOTIFY2))) {
|
||||
FileSave(FSF_SaveAlways);
|
||||
} else {
|
||||
SetSaveNeeded();
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
} else {
|
||||
// FWM_INDICATORSILENT: nothing todo here
|
||||
SetSaveNeeded();
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4817,7 +4828,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
BeginWaitCursorUID(true, IDS_MUI_SB_RECODING_DOC);
|
||||
if (EditSetNewEncoding(Globals.hwndEdit, iNewEncoding, (s_flagSetEncoding != CPI_NONE))) {
|
||||
UpdateMargins(true);
|
||||
SetSaveNeeded();
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
EndWaitCursor();
|
||||
UpdateToolbar();
|
||||
@ -6437,7 +6448,7 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
case IDM_SETPASS:
|
||||
if (GetFileKey(Globals.hwndEdit)) {
|
||||
SetSaveNeeded();
|
||||
SetSaveNeeded(true);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -8226,11 +8237,11 @@ inline static LRESULT _MsgNotifyLean(const SCNotification *const scn, bool* bMod
|
||||
} break;
|
||||
|
||||
case SCN_SAVEPOINTREACHED: {
|
||||
SetSavePoint();
|
||||
SetSaveDone();
|
||||
} break;
|
||||
|
||||
case SCN_SAVEPOINTLEFT: {
|
||||
SetSaveNeeded();
|
||||
SetSaveNeeded(false);
|
||||
} break;
|
||||
|
||||
case SCN_MODIFYATTEMPTRO: {
|
||||
@ -10195,13 +10206,6 @@ void UpdateUI() {
|
||||
|
||||
//=============================================================================
|
||||
|
||||
static volatile LONG UndoActionToken = URTok_NoRecording; // needs UndoRedoRecordingStart()
|
||||
|
||||
static inline bool _InUndoRedoTransaction()
|
||||
{
|
||||
return (InterlockedOr(&UndoActionToken, 0L) >= URTok_TokenStart);
|
||||
}
|
||||
|
||||
LONG BeginUndoActionEx()
|
||||
{
|
||||
if (!_InUndoRedoTransaction()) {
|
||||
@ -10209,22 +10213,22 @@ LONG BeginUndoActionEx()
|
||||
SciCall_BeginUndoAction();
|
||||
return URTok_NoTokenFlag;
|
||||
}
|
||||
return URTok_InTransaction;
|
||||
return InterlockedOr(&UndoActionToken, 0L); // current token
|
||||
}
|
||||
|
||||
void EndLockUndoActionEx(const LONG token)
|
||||
{
|
||||
if (_InUndoRedoTransaction()) {
|
||||
if (InterlockedOr(&UndoActionToken, 0L) == token) {
|
||||
SciCall_EndUndoAction();
|
||||
InterlockedExchange(&UndoActionToken, URTok_NoTransaction);
|
||||
if (token == InterlockedOr(&UndoActionToken, 0L)) {
|
||||
if (token == URTok_NoTokenFlag) {
|
||||
SciCall_EndUndoAction();
|
||||
InterlockedExchange(&UndoActionToken, URTok_NoTransaction);
|
||||
}
|
||||
//else foreign token - okay, child transaction
|
||||
} else {
|
||||
assert("Wrong Transaction" && 0);
|
||||
}
|
||||
}
|
||||
else if (URTok_InTransaction == token) {
|
||||
// okay, was child transaction
|
||||
}
|
||||
else {
|
||||
assert("No Transaction" && 0);
|
||||
}
|
||||
@ -10239,7 +10243,6 @@ void UndoRedoRecordingStart()
|
||||
_UndoRedoActionMap(URTok_NoTransaction, NULL); // clear
|
||||
SciCall_SetUndoCollection(true);
|
||||
SciCall_EmptyUndoBuffer();
|
||||
SetSavePoint();
|
||||
SciCall_SetChangeHistory(SC_CHANGE_HISTORY_ENABLED | Settings.ChangeHistoryMode);
|
||||
UpdateMargins(true);
|
||||
}
|
||||
@ -10347,8 +10350,8 @@ static LONG _SaveUndoSelection()
|
||||
LONG const token = _UndoRedoActionMap(URTok_NoTransaction, &pSel);
|
||||
|
||||
if (token >= 0) {
|
||||
//~SciCall_AddUndoAction(token, UNDO_MAY_COALESCE);
|
||||
SciCall_AddUndoAction((int)token, UNDO_NONE);
|
||||
SciCall_AddUndoAction(token, UNDO_MAY_COALESCE);
|
||||
//SciCall_AddUndoAction((int)token, UNDO_NONE);
|
||||
}
|
||||
|
||||
DelUndoRedoSelection(&sel); // utarray_free()
|
||||
@ -10465,15 +10468,17 @@ const char* const _assert_msg = "Broken UndoRedo-Transaction!";
|
||||
void EndUndoActionSelection(const LONG token)
|
||||
{
|
||||
switch (token) {
|
||||
case URTok_NoTransaction:
|
||||
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 (InterlockedOr(&UndoActionToken, 0L) == token) {
|
||||
if (token == InterlockedOr(&UndoActionToken, 0L)) {
|
||||
_SaveRedoSelection(token);
|
||||
SciCall_EndUndoAction();
|
||||
InterlockedExchange(&UndoActionToken, URTok_NoTransaction);
|
||||
@ -10597,7 +10602,7 @@ void RestoreActionSelection(const LONG token, DoAction doAct)
|
||||
//
|
||||
static LONG _UndoRedoActionMap(const LONG token, const UndoRedoSelection_t** selection)
|
||||
{
|
||||
static ULONG uiTokenCnt = URTok_TokenStart;
|
||||
static ULONG uiTokenCnt = URTok_TokenStart;
|
||||
|
||||
if (UndoRedoSelectionUTArray == NULL) {
|
||||
return URTok_NoRecording;
|
||||
@ -10637,7 +10642,7 @@ static LONG _UndoRedoActionMap(const LONG token, const UndoRedoSelection_t** sel
|
||||
(*selection) = (UndoRedoSelection_t*)utarray_eltptr(UndoRedoSelectionUTArray, utoken);
|
||||
} else {
|
||||
// this is a set request (fill redo pos)
|
||||
assert(false); // not used yet
|
||||
assert("Invalid set request (fill redo pos)!" && 0); // not used yet
|
||||
//~utarray_insert(UndoRedoSelectionUTArray, (void*)(*selection), utoken);
|
||||
}
|
||||
// don't clear map item here (token used in redo/undo again)
|
||||
@ -10788,7 +10793,7 @@ bool FileLoad(const HPATHL hfile_pth, FileLoadFlags fLoadFlags)
|
||||
|
||||
Style_SetDefaultLexer(Globals.hwndEdit);
|
||||
|
||||
SetSavePoint();
|
||||
SetSaveDone();
|
||||
|
||||
UpdateToolbar();
|
||||
UpdateMargins(true);
|
||||
|
||||
@ -193,30 +193,36 @@ LRESULT MsgCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT MsgSysCommand(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
|
||||
LRESULT MsgUahMenuBar(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
LRESULT MsgNonClientAreaPaint(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
|
||||
//LRESULT MsgNonClientAreaPaint(HWND hwnd, UINT umsg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void SetNotifyDocChangedEvent(const SciEventMask evm);
|
||||
void ResetNotifyDocChangedEvent();
|
||||
|
||||
#define DisableNotifyEvents() { int _evm_ = 0; __try { _evm_ = SciCall_GetModEventMask(); SciCall_SetModEventMask(EVM_None);
|
||||
#define EnableNotifyEvents() ;} __finally { SciCall_SetModEventMask(_evm_); } }
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void SetNotifyDocChangedEvent();
|
||||
void ResetNotifyDocChangedEvent();
|
||||
|
||||
// none msg change notify, preserve redo-undo selection stack (only in simple, non complex operations)
|
||||
#define UndoTransActionBegin() { LONG _token_ = 0L; __try { _token_ = BeginUndoActionSelection(); SetNotifyDocChangedEvent();
|
||||
#define EndUndoTransAction() ;} __finally { ResetNotifyDocChangedEvent(); EndUndoActionSelection(_token_); } }
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
LONG BeginUndoActionEx();
|
||||
void EndLockUndoActionEx(const LONG token);
|
||||
|
||||
// lean msg change notify (preferred) - does not preserve redo-undo selection stack
|
||||
#define DocChangeTransactionBegin() { LONG _tok_ = 0L; __try { _tok_ = BeginUndoActionEx(); SetNotifyDocChangedEvent(EVM_None);
|
||||
#define DocChangeTransactionBegin() { LONG _tok_ = 0L; __try { _tok_ = BeginUndoActionEx(); SetNotifyDocChangedEvent();
|
||||
#define EndDocChangeTransaction() ;} __finally { ResetNotifyDocChangedEvent(); EndLockUndoActionEx(_tok_); } }
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// none msg change notify, preserve redo-undo selection stack (only in simple, non complex operations)
|
||||
#define UndoTransActionBegin() { LONG _token_ = 0L; __try { _token_ = BeginUndoActionSelection(); SetNotifyDocChangedEvent(EVM_None);
|
||||
#define EndUndoTransAction() ;} __finally { ResetNotifyDocChangedEvent(); EndUndoActionSelection(_token_); } }
|
||||
// DEBUG:
|
||||
//#define DocChangeTransactionBegin() UndoTransActionBegin()
|
||||
//#define EndDocChangeTransaction() EndUndoTransAction()
|
||||
//#define UndoTransActionBegin() DocChangeTransactionBegin()
|
||||
//#define EndUndoTransAction() EndDocChangeTransaction()
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
@ -700,13 +700,22 @@ 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