allow to insert a line break through a dedicated method in IDocument
Signed-off-by: Florian Thienel <florian@thienel.org>
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
index 6bad15a..b6df88c 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/dom/Document.java
@@ -350,6 +350,68 @@
return new String(characters);
}
+ @Override
+ public void insertLineBreak(final int offset) throws DocumentValidationException {
+ Assert.isTrue(offset > getStartOffset() && offset <= getEndOffset(), MessageFormat.format("Offset must be in [{0}, {1}]", getStartOffset() + 1, getEndOffset()));
+
+ final INode insertionNode = getNodeForInsertionAt(offset);
+ insertionNode.accept(new INodeVisitor() {
+ @Override
+ public void visit(final IDocument document) {
+ Assert.isTrue(false, "Cannot insert a line break directly into Document.");
+ }
+
+ @Override
+ public void visit(final IDocumentFragment fragment) {
+ Assert.isTrue(false, "DocumentFragment is never a child of Document.");
+ }
+
+ @Override
+ public void visit(final IElement element) {
+ if (!canInsertAt(element, offset, IValidator.PCDATA)) {
+ throw new DocumentValidationException(MessageFormat.format("Cannot insert a line break into a {0} element at offset {1}.", element.getLocalName(), offset));
+ }
+ insertLineBreak(offset, element);
+ }
+
+ @Override
+ public void visit(final IText text) {
+ insertLineBreak(offset, text.getParent());
+ }
+
+ @Override
+ public void visit(final IComment comment) {
+ insertLineBreak(offset, comment.getParent());
+ }
+
+ @Override
+ public void visit(final IProcessingInstruction pi) {
+ // The target is validated to ensure the instruction is valid after the insertion
+ final String charBefore = pi.getText(new ContentRange(offset - 1, offset - 1));
+ final String charAfter = pi.getText(new ContentRange(offset, offset));
+ final String candidate = charBefore + '\n' + charAfter; // TODO '\n' is an implementation detail that we should not have to rely on at this point!
+
+ final IValidationResult result = XML.validateProcessingInstructionData(candidate);
+ if (!result.isOK()) {
+ throw new DocumentValidationException(result.getMessage());
+ }
+
+ insertLineBreak(offset, pi.getParent());
+ }
+
+ private void insertLineBreak(final int offset, final IParent parent) {
+ fireBeforeContentInserted(new ContentChangeEvent(Document.this, parent, new ContentRange(offset, offset), true));
+ getContent().insertLineBreak(offset);
+ fireContentInserted(new ContentChangeEvent(Document.this, parent, new ContentRange(offset, offset), true));
+ }
+
+ @Override
+ public void visit(final IIncludeNode document) {
+ Assert.isTrue(false, "Cannot insert text into an Include.");
+ }
+ });
+ }
+
/**
* Inserts a node at the given offset. There is no check that the insertion is valid.
*
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/DOMController.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/DOMController.java
index 6835ebf..610deb7 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/DOMController.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/DOMController.java
@@ -113,6 +113,11 @@
moveCursor(toOffset(cursor.getOffset() + 1));
}
+ public void insertLineBreak() {
+ document.insertLineBreak(cursor.getOffset());
+ moveCursor(toOffset(cursor.getOffset() + 1));
+ }
+
public void insertElement(final QualifiedName elementName) {
document.insertElement(cursor.getOffset(), elementName);
moveCursor(toOffset(cursor.getOffset() + 1));
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/BoxWidget.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/BoxWidget.java
index 233a724..1a650b0 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/BoxWidget.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/internal/widget/swt/BoxWidget.java
@@ -191,6 +191,8 @@
case SWT.HOME:
moveOrSelect(event.stateMask, toOffset(0));
break;
+ case SWT.CR:
+ controller.insertLineBreak();
default:
if (event.character > 0 && Character.isDefined(event.character)) {
controller.enterChar(event.character);
diff --git a/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IDocument.java b/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IDocument.java
index 376436a..6b72af5 100644
--- a/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IDocument.java
+++ b/org.eclipse.vex.core/src/org/eclipse/vex/core/provisional/dom/IDocument.java
@@ -145,6 +145,8 @@
*/
void insertText(int offset, String text) throws DocumentValidationException;
+ void insertLineBreak(int offset) throws DocumentValidationException;
+
/**
* @return true if a comment can be inserted a the given offset
*/