From 72d5fa4d498dd24c2219644f0d0bfa29b0cc6a92 Mon Sep 17 00:00:00 2001 From: Jordan Martinez Date: Wed, 21 Jun 2017 19:33:51 -0700 Subject: [PATCH] Allow UndoManager to use developer-defined changes (text, view, etc.) --- .../fxmisc/richtext/GenericStyledArea.java | 27 +++--------- .../fxmisc/richtext/model/UndoActions.java | 2 +- .../org/fxmisc/richtext/util/UndoUtils.java | 43 +++++++++++++++++++ 3 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 richtextfx/src/main/java/org/fxmisc/richtext/util/UndoUtils.java diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java b/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java index e58062e1a..41615d980 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/GenericStyledArea.java @@ -73,14 +73,13 @@ import org.fxmisc.richtext.model.SegmentOps; import org.fxmisc.richtext.model.StyleSpans; import org.fxmisc.richtext.model.StyledDocument; -import org.fxmisc.richtext.model.TextChange; import org.fxmisc.richtext.model.TextEditingArea; import org.fxmisc.richtext.model.TextOps; import org.fxmisc.richtext.model.TwoDimensional; import org.fxmisc.richtext.model.TwoLevelNavigator; import org.fxmisc.richtext.model.UndoActions; +import org.fxmisc.richtext.util.UndoUtils; import org.fxmisc.undo.UndoManager; -import org.fxmisc.undo.UndoManagerFactory; import org.reactfx.EventStream; import org.reactfx.EventStreams; import org.reactfx.Guard; @@ -306,11 +305,9 @@ private static int clamp(int min, int val, int max) { // undo manager private UndoManager undoManager; @Override public UndoManager getUndoManager() { return undoManager; } - @Override public void setUndoManager(UndoManagerFactory undoManagerFactory) { - undoManager.close(); - undoManager = preserveStyle - ? createRichUndoManager(undoManagerFactory) - : createPlainUndoManager(undoManagerFactory); + @Override public void setUndoManager(UndoManager undoManager) { + this.undoManager.close(); + this.undoManager = undoManager; } private final ObjectProperty mouseOverTextDelay = new SimpleObjectProperty<>(null); @@ -618,9 +615,7 @@ public GenericStyledArea( this.applyParagraphStyle = applyParagraphStyle; this.segmentOps = segmentOps; - undoManager = preserveStyle - ? createRichUndoManager(UndoManagerFactory.unlimitedHistoryFactory()) - : createPlainUndoManager(UndoManagerFactory.unlimitedHistoryFactory()); + undoManager = UndoUtils.createUndoManager(this); // allow tab traversal into area setFocusTraversable(true); @@ -1449,18 +1444,6 @@ private PS getParagraphStyleForInsertionAt(int pos) { } } - private UndoManager createPlainUndoManager(UndoManagerFactory factory) { - Consumer apply = change -> replaceText(change.getPosition(), change.getPosition() + change.getRemoved().length(), change.getInserted()); - BiFunction> merge = PlainTextChange::mergeWith; - return factory.create(plainTextChanges(), PlainTextChange::invert, apply, merge, TextChange::isIdentity); - } - - private UndoManager createRichUndoManager(UndoManagerFactory factory) { - Consumer> apply = change -> replace(change.getPosition(), change.getPosition() + change.getRemoved().length(), change.getInserted()); - BiFunction, RichTextChange, Optional>> merge = RichTextChange::mergeWith; - return factory.create(richChanges(), RichTextChange::invert, apply, merge, TextChange::isIdentity); - } - private void suspendVisibleParsWhile(Runnable runnable) { Suspendable.combine(beingUpdated, visibleParagraphs).suspendWhile(runnable); } diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/model/UndoActions.java b/richtextfx/src/main/java/org/fxmisc/richtext/model/UndoActions.java index a45137dad..83f382756 100644 --- a/richtextfx/src/main/java/org/fxmisc/richtext/model/UndoActions.java +++ b/richtextfx/src/main/java/org/fxmisc/richtext/model/UndoActions.java @@ -13,7 +13,7 @@ public interface UndoActions { * Undo manager of this text area. */ UndoManager getUndoManager(); - void setUndoManager(UndoManagerFactory undoManagerFactory); + void setUndoManager(UndoManager undoManager); default void undo() { getUndoManager().undo(); } diff --git a/richtextfx/src/main/java/org/fxmisc/richtext/util/UndoUtils.java b/richtextfx/src/main/java/org/fxmisc/richtext/util/UndoUtils.java new file mode 100644 index 000000000..9c6fe170f --- /dev/null +++ b/richtextfx/src/main/java/org/fxmisc/richtext/util/UndoUtils.java @@ -0,0 +1,43 @@ +package org.fxmisc.richtext.util; + +import org.fxmisc.richtext.GenericStyledArea; +import org.fxmisc.richtext.model.PlainTextChange; +import org.fxmisc.richtext.model.RichTextChange; +import org.fxmisc.richtext.model.TextChange; +import org.fxmisc.undo.UndoManager; +import org.fxmisc.undo.UndoManagerFactory; + +import java.util.function.Consumer; + +public final class UndoUtils { + + private UndoUtils() { + throw new IllegalStateException("UndoUtils cannot be instantiated"); + } + + public static UndoManager createUndoManager(GenericStyledArea area) { + return area.isPreserveStyle() + ? richTextUndoManager(area) + : plainTextUndoManager(area); + } + + public static UndoManager richTextUndoManager(GenericStyledArea area) { + return richTextUndoManager(area, UndoManagerFactory.unlimitedHistoryFactory()); + } + + public static UndoManager richTextUndoManager(GenericStyledArea area, + UndoManagerFactory factory) { + Consumer> apply = change -> area.replace(change.getPosition(), change.getPosition() + change.getRemoved().length(), change.getInserted()); + return factory.create(area.richChanges(), RichTextChange::invert, apply, TextChange::mergeWith, TextChange::isIdentity); + }; + + public static UndoManager plainTextUndoManager(GenericStyledArea area) { + return plainTextUndoManager(area, UndoManagerFactory.unlimitedHistoryFactory()); + } + + public static UndoManager plainTextUndoManager(GenericStyledArea area, + UndoManagerFactory factory) { + Consumer apply = change -> area.replaceText(change.getPosition(), change.getPosition() + change.getRemoved().length(), change.getInserted()); + return factory.create(area.plainTextChanges(), PlainTextChange::invert, apply, TextChange::mergeWith, TextChange::isIdentity); + } +}