Александр Ильин писал(а):
Евгений Темиргалеев писал(а):
Ещё для отчёту: если открутиться назад на несколько undo, то операция, хоть и notRecorded, но redo-хвост затирает...
Интересное замечание! Я думаю, это следует поправить в ББ.
Вот исправленная реализация Windows.StdSequencer.Do:
Код:
PROCEDURE (s: StdSequencer) Do (st: Stores.Store; IN name: Stores.OpName; op: Stores.Operation);
VAR e: OpElem;
BEGIN
ASSERT(st # NIL, 20); ASSERT(op # NIL, 21);
IF s.trapEra # Kernel.trapCount THEN Reset(s) END;
Do(s, st, op);
IF s.noUndo THEN (* cannot undo: unbalanced BeginModification pending *)
s.lastSt := NIL; s.lastOp := NIL
ELSIF (s.entryLevel = 0) (* don't record when called from within op.Do *)
& AffectsDoc(s, st) THEN (* don't record when Do affected child window only *)
s.lastSt := st; s.lastOp := op;
IF s.notRecordedLevel = 0 THEN
s.redo := NIL (* clear redo stack *)
END;
IF s.script # NIL THEN
Prepend(s.script, st, name, op)
ELSE
IF (s.invisibleLevel = 0) & (s.transparentLevel = 0) & (s.notRecordedLevel = 0) THEN INC(s.modLevel) END;
IF s.notRecordedLevel = 0 THEN
NEW(e); e.st := st; e.op := op; e.name := name;
e.invisible := s.invisibleLevel > 0; e.transparent := s.transparentLevel > 0;
Push(s.undo, e)
END
END
END
END Do;
Что изменилось:
1. добавлен IF s.notRecordedLevel = 0 перед строкой с комментарием "clear redo stack". Это, собственно, исправляет очистку стека redo действиями типа notRecorded;
2. действие последнего IF s.notRecordedLevel = 0 раньше распространялось только на Push(s.undo, e), но если не делать Push, то нет смысла и во всём блоке кода, начиная с NEW(e), поэтому область действия условия расширена, чтобы лишний объект не создавался и не инициализировался.
Евгений Темиргалеев писал(а):
Думаю, это хороший пример копания в кишках. Когда оттуда что-то тянешь, оно может показаться одним, а по сути будет совсем другим... И именно это не повод править ББ "глобально" (кто и как правит локально, для себя, дело личное).
Наверное, всё же не очень хороший, так как "по сути совсем другим" ничего не оказалось. Просто нашлась мелкая недоработка.
Напомню, что константа Windows.notRecorded и переменная Windows.StdSequencer.notRecordedLevel - не мои нововведения, а существующий и работающий механизм стандартного ББ 1.5.