package org.eclipse.xtext.gmf.glue.partialEditing;
import java.util.Collections;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISynchronizable;
import org.eclipse.jface.text.source.AnnotationModel;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.xtext.gmf.glue.edit.part.IXtextEMFReconciler;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.model.XtextDocument;
import org.eclipse.xtext.util.StringInputStream;
/**
*
*/
public class PartialModelEditor {
protected final SourceViewer viewer;
protected final boolean insertLineBreaks;
protected final ISyntheticResourceProvider resourceProvider;
protected EObject semanticElement ;
protected IXtextEMFReconciler modelReconciler ;
//private final Injector xtextInjector ;
/**
* @param viewer
* @param resourceProvider
* @param insertLineBreaks
* @param semanticElement
* @param modelReconciler
*
*/
public PartialModelEditor(SourceViewer viewer,
ISyntheticResourceProvider resourceProvider,
boolean insertLineBreaks,
EObject semanticElement,
IXtextEMFReconciler modelReconciler) {
//this.xtextInjector = xtextInjector ;
this.viewer = viewer;
this.resourceProvider = resourceProvider;
this.insertLineBreaks = insertLineBreaks;
this.semanticElement = semanticElement ;
this.modelReconciler = modelReconciler ;
}
/**
* @param document
* @param prefix
* @param editablePart
* @param suffix
*
*/
public void setModel(XtextDocument document, String prefix, String editablePart, String suffix) {
if (insertLineBreaks) {
String delimiter = document.getLegalLineDelimiters()[0];
prefix = prefix + delimiter;
suffix = delimiter + suffix;
}
String model = prefix + editablePart + suffix;
document.set(model);
XtextResource resource = createResource(model);
document.setInput(resource);
AnnotationModel annotationModel = new AnnotationModel();
if (document instanceof ISynchronizable) {
Object lock= ((ISynchronizable)document).getLockObject();
if (lock == null) {
lock= new Object();
((ISynchronizable)document).setLockObject(lock);
}
((ISynchronizable) annotationModel).setLockObject(lock);
}
viewer.setDocument(document, annotationModel, prefix.length(), editablePart.length());
viewer.getUndoManager().reset();
}
/**
* @param content
* @return XtextResource
*
*/
public XtextResource createResource(String content) {
XtextResource result = resourceProvider.createResource();
try {
result.load(new StringInputStream(content, result.getEncoding()), Collections.emptyMap());
} catch (Exception e) {
throw new RuntimeException(e);
}
return result;
}
/**
* @param prefix
* @param editablePart
* @param suffix
*
*/
public void updateModel(String prefix, String editablePart, String suffix) {
IDocument document= viewer.getDocument();
if (insertLineBreaks) {
String delimiter = document.getLegalLineDelimiters()[0];
prefix = prefix + delimiter;
suffix = delimiter + suffix;
}
String model = prefix + editablePart + suffix;
viewer.setRedraw(false);
viewer.getUndoManager().disconnect();
document.set(model);
viewer.setVisibleRegion(prefix.length(), editablePart.length());
viewer.getUndoManager().connect(viewer);
viewer.setRedraw(true);
}
/**
* @param prefix
*
*/
public void updatePrefix(String prefix) {
try {
IDocument document= viewer.getDocument();
IRegion visibleRegion = viewer.getVisibleRegion();
String editablePart = document.get(visibleRegion.getOffset(), visibleRegion.getLength());
int suffixOffset = visibleRegion.getOffset() + visibleRegion.getLength();
String suffix = "";
if (document.getLength() - suffixOffset > 0) {
suffix = document.get(suffixOffset, document.getLength() - suffixOffset);
if (insertLineBreaks) {
String delimiter = document.getLegalLineDelimiters()[0];
suffix = suffix.substring(delimiter.length());
}
}
updateModel(prefix, editablePart, suffix);
} catch(BadLocationException e) {
throw new RuntimeException(e);
}
}
/**
* @return String
*
*/
public String getEditablePart() {
IDocument doc= viewer.getDocument();
IRegion visible= viewer.getVisibleRegion();
try {
return doc.get(visible.getOffset(), visible.getLength());
} catch (BadLocationException e) {
return ""; //$NON-NLS-1$
}
}
/**
* @return String
*
*/
public String getSerializedModel() {
return viewer.getDocument().get();
}
}