Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'deprecated/org.eclipse.papyrus.infra.gmfdiag.xtext.glue/src/org/eclipse/papyrus/infra/gmfdiag/xtext/glue/partialEditing/HighlightingReconciler.java')
-rw-r--r--deprecated/org.eclipse.papyrus.infra.gmfdiag.xtext.glue/src/org/eclipse/papyrus/infra/gmfdiag/xtext/glue/partialEditing/HighlightingReconciler.java291
1 files changed, 291 insertions, 0 deletions
diff --git a/deprecated/org.eclipse.papyrus.infra.gmfdiag.xtext.glue/src/org/eclipse/papyrus/infra/gmfdiag/xtext/glue/partialEditing/HighlightingReconciler.java b/deprecated/org.eclipse.papyrus.infra.gmfdiag.xtext.glue/src/org/eclipse/papyrus/infra/gmfdiag/xtext/glue/partialEditing/HighlightingReconciler.java
new file mode 100644
index 00000000000..bce3698527e
--- /dev/null
+++ b/deprecated/org.eclipse.papyrus.infra.gmfdiag.xtext.glue/src/org/eclipse/papyrus/infra/gmfdiag/xtext/glue/partialEditing/HighlightingReconciler.java
@@ -0,0 +1,291 @@
+/*******************************************************************************
+ * Copyright (c) 2010 itemis AG (http://www.itemis.eu) and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+package org.eclipse.papyrus.infra.gmfdiag.xtext.glue.partialEditing;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.ITextInputListener;
+import org.eclipse.jface.text.TextAttribute;
+import org.eclipse.jface.text.TextPresentation;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.xtext.resource.XtextResource;
+import org.eclipse.xtext.ui.editor.XtextSourceViewer;
+import org.eclipse.xtext.ui.editor.model.IXtextDocument;
+import org.eclipse.xtext.ui.editor.model.IXtextModelListener;
+import org.eclipse.xtext.ui.editor.model.XtextDocument;
+import org.eclipse.xtext.ui.editor.syntaxcoloring.AttributedPosition;
+import org.eclipse.xtext.ui.editor.syntaxcoloring.HighlightingPresenter;
+import org.eclipse.xtext.ui.editor.syntaxcoloring.IHighlightedPositionAcceptor;
+import org.eclipse.xtext.ui.editor.syntaxcoloring.ISemanticHighlightingCalculator;
+import org.eclipse.xtext.ui.editor.syntaxcoloring.ITextAttributeProvider;
+import org.eclipse.xtext.ui.editor.syntaxcoloring.MergingHighlightedPositionAcceptor;
+import org.eclipse.xtext.util.concurrent.IUnitOfWork;
+
+import com.google.inject.Inject;
+
+/**
+ * @author Sebastian Zarnekow - Initial contribution and API
+ */
+public class HighlightingReconciler implements ITextInputListener, IXtextModelListener, IHighlightedPositionAcceptor {
+
+ @Inject(optional=true)
+ private ISemanticHighlightingCalculator calculator;
+
+ @Inject
+ private ITextAttributeProvider attributeProvider;
+
+ /** The source viewer this highlighting reconciler is installed on */
+ private XtextSourceViewer sourceViewer;
+ /** The highlighting presenter */
+ private HighlightingPresenter presenter;
+
+ /** Background job's added highlighted positions */
+ private final List<AttributedPosition> addedPositions = new ArrayList<AttributedPosition>();
+ /** Background job's removed highlighted positions */
+ private List<AttributedPosition> removedPositions = new ArrayList<AttributedPosition>();
+ /** Number of removed positions */
+ private int removedPositionCount;
+
+ /**
+ * Reconcile operation lock.
+ *
+ * @since 3.2
+ */
+ private final Object fReconcileLock = new Object();
+ /**
+ * <code>true</code> if any thread is executing <code>reconcile</code>, <code>false</code> otherwise.
+ *
+ * @since 3.2
+ */
+ private boolean reconciling = false;
+
+ /**
+ * Start reconciling positions.
+ */
+ private void startReconcilingPositions() {
+ presenter.addAllPositions(removedPositions);
+ removedPositionCount = removedPositions.size();
+ }
+
+ /**
+ * Reconcile positions based on the AST subtrees
+ *
+ * @param subtrees
+ * the AST subtrees
+ */
+ private void reconcilePositions(XtextResource resource) {
+ // for (int i= 0, n= subtrees.length; i < n; i++)
+ // subtrees[i].accept(fCollector);
+ MergingHighlightedPositionAcceptor acceptor = new MergingHighlightedPositionAcceptor(calculator);
+ acceptor.provideHighlightingFor(resource, this);
+// calculator.provideHighlightingFor(resource, this);
+ List<AttributedPosition> oldPositions = removedPositions;
+ List<AttributedPosition> newPositions = new ArrayList<AttributedPosition>(removedPositionCount);
+ for (int i = 0, n = oldPositions.size(); i < n; i++) {
+ AttributedPosition current = oldPositions.get(i);
+ if (current != null)
+ newPositions.add(current);
+ }
+ removedPositions = newPositions;
+ }
+
+ /**
+ * Add a position with the given range and highlighting if it does not exist already.
+ * @param offset The range offset
+ * @param length The range length
+ * @param highlighting The highlighting
+ */
+ public void addPosition(int offset, int length, String... ids) {
+ TextAttribute highlighting = ids.length == 1 ?
+ attributeProvider.getAttribute(ids[0])
+ : attributeProvider.getMergedAttributes(ids);
+ boolean isExisting= false;
+ // TODO: use binary search
+ for (int i= 0, n= removedPositions.size(); i < n; i++) {
+ AttributedPosition position= removedPositions.get(i);
+ if (position == null)
+ continue;
+ if (position.isEqual(offset, length, highlighting)) {
+ isExisting= true;
+ removedPositions.set(i, null);
+ removedPositionCount--;
+ break;
+ }
+ }
+
+ if (!isExisting) {
+ AttributedPosition position= presenter.createHighlightedPosition(offset, length, highlighting);
+ addedPositions.add(position);
+ }
+ }
+
+ /**
+ * Update the presentation.
+ *
+ * @param textPresentation
+ * the text presentation
+ * @param addedPositions
+ * the added positions
+ * @param removedPositions
+ * the removed positions
+ */
+ private void updatePresentation(TextPresentation textPresentation, List<AttributedPosition> addedPositions,
+ List<AttributedPosition> removedPositions) {
+ Runnable runnable = presenter.createUpdateRunnable(textPresentation, addedPositions, removedPositions);
+ if (runnable == null)
+ return;
+
+ Display display = getDisplay();
+ display.asyncExec(runnable);
+ }
+
+ private Display getDisplay() {
+ return this.sourceViewer.getControl().getDisplay();
+ }
+
+ /**
+ * Stop reconciling positions.
+ */
+ private void stopReconcilingPositions() {
+ removedPositions.clear();
+ removedPositionCount = 0;
+ addedPositions.clear();
+ }
+
+ /**
+ * Install this reconciler on the given editor and presenter.
+ *
+ * @param editor
+ * the editor
+ * @param sourceViewer
+ * the source viewer
+ * @param presenter
+ * the highlighting presenter
+ */
+ public void install(XtextSourceViewer sourceViewer, HighlightingPresenter presenter) {
+ this.presenter = presenter;
+ this.sourceViewer = sourceViewer;
+ if (calculator != null) {
+ ((IXtextDocument) sourceViewer.getDocument()).addModelListener(this);
+ sourceViewer.addTextInputListener(this);
+ }
+ refresh();
+ }
+
+ /**
+ * Uninstall this reconciler from the editor
+ */
+ public void uninstall() {
+ if (presenter != null)
+ presenter.setCanceled(true);
+
+ if (sourceViewer.getDocument() != null) {
+ if (calculator != null) {
+ XtextDocument document = (XtextDocument) sourceViewer.getDocument();
+ document.removeModelListener(this);
+ sourceViewer.removeTextInputListener(this);
+ }
+ }
+
+ sourceViewer = null;
+ presenter = null;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentAboutToBeChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
+ */
+ public void inputDocumentAboutToBeChanged(IDocument oldInput, IDocument newInput) {
+ if (oldInput != null)
+ ((IXtextDocument) oldInput).removeModelListener(this);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.ITextInputListener#inputDocumentChanged(org.eclipse.jface.text.IDocument, org.eclipse.jface.text.IDocument)
+ */
+ public void inputDocumentChanged(IDocument oldInput, IDocument newInput) {
+ if (newInput != null) {
+ refresh();
+ ((IXtextDocument) newInput).addModelListener(this);
+ }
+ }
+
+ /**
+ * Refreshes the highlighting.
+ */
+ public void refresh() {
+ if (calculator != null) {
+ ((XtextDocument) sourceViewer.getDocument()).readOnly(new IUnitOfWork.Void<XtextResource>() {
+ @Override
+ public void process(XtextResource state) throws Exception {
+ modelChanged(state);
+ }
+ });
+ } else {
+ Display display = getDisplay();
+ display.asyncExec(presenter.createSimpleUpdateRunnable());
+ }
+ }
+
+ public void modelChanged(XtextResource resource) {
+ // ensure at most one thread can be reconciling at any time
+ synchronized (fReconcileLock) {
+ if (reconciling)
+ return;
+ reconciling = true;
+ }
+ final HighlightingPresenter highlightingPresenter = presenter;
+ try {
+ if (highlightingPresenter == null)
+ return;
+
+ highlightingPresenter.setCanceled(false);
+
+ if (highlightingPresenter.isCanceled())
+ return;
+
+ startReconcilingPositions();
+
+ if (!highlightingPresenter.isCanceled()) {
+ reconcilePositions(resource);
+ }
+
+ final TextPresentation[] textPresentation = new TextPresentation[1];
+ if (!highlightingPresenter.isCanceled()) {
+ textPresentation[0] = highlightingPresenter.createPresentation(addedPositions, removedPositions);
+ }
+
+ if (!highlightingPresenter.isCanceled())
+ updatePresentation(textPresentation[0], addedPositions, removedPositions);
+
+ stopReconcilingPositions();
+ }
+ finally {
+ synchronized (fReconcileLock) {
+ reconciling = false;
+ }
+ }
+ }
+
+ /**
+ * @param calculator
+ *
+ */
+ public void setCalculator(ISemanticHighlightingCalculator calculator) {
+ this.calculator = calculator;
+ }
+
+ /**
+ * @return ISemanticHighlightingCalculator
+ *
+ */
+ public ISemanticHighlightingCalculator getCalculator() {
+ return calculator;
+ }
+}

Back to the top