diff options
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)); + } + } +} |