Skip to content

Commit

Permalink
Fix post undo/redo caret position (#915)
Browse files Browse the repository at this point in the history
  • Loading branch information
Jugen authored Mar 18, 2020
1 parent af4c7c5 commit c5a7d66
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,38 @@ public void incoming_change_is_not_merged_after_period_of_user_inactivity() {
}

@Test // After undo, text insertion point jumps to the start of the text area #780
// After undo, text insertion point jumps to the end of the text area #912
public void undo_leaves_correct_insertion_point() {
long periodOfUserInactivity = UndoUtils.DEFAULT_PREVENT_MERGE_DELAY.toMillis() + 300L;

write("abc def ");
sleep(periodOfUserInactivity);

write("xyz");
interact(area::undo);

write('g');
write("abc mno");
interact(() -> {
area.insertText(3," def");
area.appendText(" xyz");
});

sleep(periodOfUserInactivity);
assertTrue(area.getText().endsWith("g"));
assertEquals("abc def mno xyz",area.getText());

interact(area::undo); // removes " xyz"
assertEquals("abc def mno",area.getText());
// ^
assertEquals( area.getCaretPosition(), area.getSelection().getStart() );
assertEquals( 11, area.getSelection().getStart() );

interact(area::undo); // removes " def"
assertEquals("abc mno",area.getText());
// ^
assertEquals( area.getCaretPosition(), area.getSelection().getStart() );
assertEquals( 3, area.getSelection().getStart() );

interact(area::redo); // restore " def"
assertEquals("abc def mno",area.getText());
// ^
assertEquals( area.getCaretPosition(), area.getSelection().getStart() );
assertEquals( 7, area.getSelection().getStart() );

interact(area::undo); // removes " def"
interact(() -> area.insertText(area.getCaretPosition()," ?"));
assertEquals("abc ? mno",area.getText());
}

@Test
Expand Down
23 changes: 21 additions & 2 deletions richtextfx/src/main/java/org/fxmisc/richtext/util/UndoUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,10 @@ public static <PS, SEG, S> UndoManager<List<PlainTextChange>> plainTextUndoManag
* by {@code area.replaceText(change.getPosition(), change.getRemovalEnd(), change.getInserted()}.
*/
public static <PS, SEG, S> Consumer<PlainTextChange> applyPlainTextChange(GenericStyledArea<PS, SEG, S> area) {
return change -> area.replaceText(change.getPosition(), change.getRemovalEnd(), change.getInserted());
return change -> {
area.replaceText(change.getPosition(), change.getRemovalEnd(), change.getInserted());
moveToChange( area, change );
};
}

/**
Expand All @@ -223,7 +226,10 @@ public static <PS, SEG, S> Consumer<PlainTextChange> applyPlainTextChange(Generi
*/
public static <PS, SEG, S> Consumer<RichTextChange<PS, SEG, S>> applyRichTextChange(
GenericStyledArea<PS, SEG, S> area) {
return change -> area.replace(change.getPosition(), change.getRemovalEnd(), change.getInserted());
return change -> {
area.replace(change.getPosition(), change.getRemovalEnd(), change.getInserted());
moveToChange( area, change );
};
}

/**
Expand All @@ -238,6 +244,7 @@ public static <PS, SEG, S> Consumer<List<PlainTextChange>> applyMultiPlainTextCh
builder.replaceTextAbsolutely(c.getPosition(), c.getRemovalEnd(), c.getInserted());
}
builder.commit();
moveToChange( area, changeList.get( changeList.size()-1 ) );
};
}

Expand All @@ -253,7 +260,19 @@ public static <PS, SEG, S> Consumer<List<RichTextChange<PS, SEG, S>>> applyMulti
builder.replaceAbsolutely(c.getPosition(), c.getRemovalEnd(), c.getInserted());
}
builder.commit();
moveToChange( area, changeList.get( changeList.size()-1 ) );
};
}

/*
* Address #912 "After undo/redo, new text is inserted at the end".
* Without breaking PositionTests. (org.fxmisc.richtext.api.caret)
*/
private static void moveToChange( GenericStyledArea area, TextChange chg ) {
int pos = chg.getPosition(), len = chg.getNetLength();
if ( len > 0 ) {
pos = Math.min( pos + Math.abs(len), area.getLength() );
}
area.moveTo( pos );
}
}

0 comments on commit c5a7d66

Please sign in to comment.