Skip to content

Commit

Permalink
Merge pull request #528 from JordanMartinez/extractUndo
Browse files Browse the repository at this point in the history
Allow UndoManager to use developer-defined changes (text, view, etc.)
  • Loading branch information
JordanMartinez authored Jun 22, 2017
2 parents 25662f1 + 72d5fa4 commit ce3bf9b
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<Duration> mouseOverTextDelay = new SimpleObjectProperty<>(null);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -1449,18 +1444,6 @@ private PS getParagraphStyleForInsertionAt(int pos) {
}
}

private UndoManager createPlainUndoManager(UndoManagerFactory factory) {
Consumer<PlainTextChange> apply = change -> replaceText(change.getPosition(), change.getPosition() + change.getRemoved().length(), change.getInserted());
BiFunction<PlainTextChange, PlainTextChange, Optional<PlainTextChange>> merge = PlainTextChange::mergeWith;
return factory.create(plainTextChanges(), PlainTextChange::invert, apply, merge, TextChange::isIdentity);
}

private UndoManager createRichUndoManager(UndoManagerFactory factory) {
Consumer<RichTextChange<PS, SEG, S>> apply = change -> replace(change.getPosition(), change.getPosition() + change.getRemoved().length(), change.getInserted());
BiFunction<RichTextChange<PS, SEG, S>, RichTextChange<PS, SEG, S>, Optional<RichTextChange<PS, SEG, S>>> merge = RichTextChange<PS, SEG, S>::mergeWith;
return factory.create(richChanges(), RichTextChange::invert, apply, merge, TextChange::isIdentity);
}

private void suspendVisibleParsWhile(Runnable runnable) {
Suspendable.combine(beingUpdated, visibleParagraphs).suspendWhile(runnable);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(); }

Expand Down
43 changes: 43 additions & 0 deletions richtextfx/src/main/java/org/fxmisc/richtext/util/UndoUtils.java
Original file line number Diff line number Diff line change
@@ -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 <PS, SEG, S> UndoManager createUndoManager(GenericStyledArea<PS, SEG, S> area) {
return area.isPreserveStyle()
? richTextUndoManager(area)
: plainTextUndoManager(area);
}

public static <PS, SEG, S> UndoManager richTextUndoManager(GenericStyledArea<PS, SEG, S> area) {
return richTextUndoManager(area, UndoManagerFactory.unlimitedHistoryFactory());
}

public static <PS, SEG, S> UndoManager richTextUndoManager(GenericStyledArea<PS, SEG, S> area,
UndoManagerFactory factory) {
Consumer<RichTextChange<PS, SEG, S>> 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 <PS, SEG, S> UndoManager plainTextUndoManager(GenericStyledArea<PS, SEG, S> area) {
return plainTextUndoManager(area, UndoManagerFactory.unlimitedHistoryFactory());
}

public static <PS, SEG, S> UndoManager plainTextUndoManager(GenericStyledArea<PS, SEG, S> area,
UndoManagerFactory factory) {
Consumer<PlainTextChange> 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);
}
}

0 comments on commit ce3bf9b

Please sign in to comment.