diff options
author | Neil <nyamatongwe@gmail.com> | 2025-01-22 21:34:54 +1100 |
---|---|---|
committer | Neil <nyamatongwe@gmail.com> | 2025-01-22 21:34:54 +1100 |
commit | 3de9d37c7b8f4501558d309ada718dc52533e94c (patch) | |
tree | ce87afaff43a86c26c562fefcf0c9a5ea409ef6b /src/EditModel.cxx | |
parent | bac32d7fde0b1d052ac9e926c6b3c96afe39bcfd (diff) | |
download | scintilla-mirror-3de9d37c7b8f4501558d309ada718dc52533e94c.tar.gz |
Bug [#1224]. Remember selection in undo history. SCI_SETSELECTIONUNDOHISTORY.
Diffstat (limited to 'src/EditModel.cxx')
-rw-r--r-- | src/EditModel.cxx | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/src/EditModel.cxx b/src/EditModel.cxx index 13b3da5b0..60848e6dc 100644 --- a/src/EditModel.cxx +++ b/src/EditModel.cxx @@ -58,6 +58,54 @@ using namespace Scintilla::Internal; Caret::Caret() noexcept : active(false), on(false), period(500) {} +SelectionSimple::SelectionSimple(const Selection &sel) { + selType = sel.selType; + if (sel.IsRectangular()) { + // rectangular or thin + // Could be large so don't remember each range, just the rectangular bounds then reconstitute when undone + rangeRectangular = sel.RectangularCopy(); + } else { + ranges = sel.RangesCopy(); + } + mainRange = sel.Main(); +} + +void ModelState::RememberSelectionForUndo(int index, const Selection &sel) { + historyForUndo.indexCurrent = index; + historyForUndo.ssCurrent = SelectionSimple(sel); +} + +void ModelState::ForgetSelectionForUndo() noexcept { + historyForUndo.indexCurrent = -1; +} + +void ModelState::RememberSelectionOntoStack(int index) { + if ((historyForUndo.indexCurrent >= 0) && (index == historyForUndo.indexCurrent + 1)) { + // Don't overwrite initial selection save if most recent action was coalesced + historyForUndo.stack[index] = historyForUndo.ssCurrent; + } +} + +void ModelState::RememberSelectionForRedoOntoStack(int index, const Selection &sel) { + historyForRedo.stack[index] = SelectionSimple(sel); +} + +const SelectionSimple *ModelState::SelectionFromStack(int index, UndoRedo history) const { + const SelectionHistory &sh = history == UndoRedo::undo ? historyForUndo : historyForRedo; + std::map<int, SelectionSimple>::const_iterator it = sh.stack.find(index); + if (it != sh.stack.end()) { + return &it->second; + } + return {}; +} + +void ModelState::TruncateUndo(int index) { + std::map<int, SelectionSimple>::iterator itUndo = historyForUndo.stack.find(index); + historyForUndo.stack.erase(itUndo, historyForUndo.stack.end()); + std::map<int, SelectionSimple>::iterator itRedo = historyForRedo.stack.find(index); + historyForRedo.stack.erase(itRedo, historyForRedo.stack.end()); +} + EditModel::EditModel() : braces{} { inOverstrike = false; xOffset = 0; @@ -131,3 +179,14 @@ InSelection EditModel::LineEndInSelection(Sci::Line lineDoc) const { int EditModel::GetMark(Sci::Line line) const { return pdoc->GetMark(line, FlagSet(changeHistoryOption, ChangeHistoryOption::Markers)); } + +void EditModel::EnsureModelState() { + if (!modelState && rememberingSelectionForUndo) { + if (ViewStateShared vss = pdoc->GetViewState(this)) { + modelState = std::dynamic_pointer_cast<ModelState>(vss); + } else { + modelState = std::make_shared<ModelState>(); + pdoc->SetViewState(this, std::static_pointer_cast<ViewState>(modelState)); + } + } +} |