aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorpschonbac2009-07-03 06:35:32 (EDT)
committersefftinge2009-07-03 06:35:32 (EDT)
commit590495d558865c6a2deeb552a24ce8ade095a757 (patch)
tree1caee4f4f29add23bd9271e09a183cd358e43747
parent4c400e9fe78490ad656e2b894401aba1ffe7381f (diff)
downloadorg.eclipse.xtext-590495d558865c6a2deeb552a24ce8ade095a757.zip
org.eclipse.xtext-590495d558865c6a2deeb552a24ce8ade095a757.tar.gz
org.eclipse.xtext-590495d558865c6a2deeb552a24ce8ade095a757.tar.bz2
bug 282033: [UI Accessibility] Display problem marker info in hover and in status line
https://bugs.eclipse.org/bugs/show_bug.cgi?id=282033
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/XtextUIMessages.java5
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java83
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java11
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/hover/AbstractHover.java106
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/hover/ProblemHover.java59
-rw-r--r--plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/messages.properties2
6 files changed, 266 insertions, 0 deletions
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/XtextUIMessages.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/XtextUIMessages.java
index 22f751c..3fddabc 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/XtextUIMessages.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/XtextUIMessages.java
@@ -68,6 +68,11 @@ public class XtextUIMessages extends NLS {
}
/**
+ * messages for hovers
+ */
+ public static String AbstractHover_MultipleMarkers;
+
+ /**
* messages for tasktag preferences page
*/
public static String TodoTaskPreferencePage_title;
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
index e32487d..41451fa 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextEditor.java
@@ -8,20 +8,32 @@
*******************************************************************************/
package org.eclipse.xtext.ui.core.editor;
+import java.util.Iterator;
+
import org.apache.log4j.Logger;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jface.text.ITextSelection;
+import org.eclipse.jface.text.Position;
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.IAnnotationModelExtension2;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
+import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.ISelectionProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
@@ -30,6 +42,7 @@ import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
import org.eclipse.ui.texteditor.SelectMarkerRulerAction;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
@@ -82,6 +95,8 @@ public class XtextEditor extends TextEditor {
private ValidationJob validationJob;
+ private ISelectionChangedListener selectionChangedListener;
+
private String languageName;
public XtextEditor() {
@@ -269,6 +284,19 @@ public class XtextEditor extends TextEditor {
// TODO Folding stuff
installHighlightingHelper();
+ selectionChangedListener = new ISelectionChangedListener() {
+ public void selectionChanged(final SelectionChangedEvent event) {
+ updateStatusLine();
+ }
+ };
+ final ISelectionProvider selectionProvider = getSelectionProvider();
+ if (selectionProvider instanceof IPostSelectionProvider) {
+ final IPostSelectionProvider postSelectionProvider = (IPostSelectionProvider) selectionProvider;
+ postSelectionProvider.addPostSelectionChangedListener(selectionChangedListener);
+ }
+ else {
+ getSelectionProvider().addSelectionChangedListener(selectionChangedListener);
+ }
}
private void installHighlightingHelper() {
@@ -291,6 +319,16 @@ public class XtextEditor extends TextEditor {
outlinePage = null;
}
uninstallHighlightingHelper();
+ if (selectionChangedListener != null) {
+ final ISelectionProvider selectionProvider = getSelectionProvider();
+ if (selectionProvider instanceof IPostSelectionProvider) {
+ final IPostSelectionProvider postSelectionProvider = (IPostSelectionProvider) selectionProvider;
+ postSelectionProvider.removePostSelectionChangedListener(selectionChangedListener);
+ }
+ else {
+ getSelectionProvider().removeSelectionChangedListener(selectionChangedListener);
+ }
+ }
}
/**
@@ -360,4 +398,49 @@ public class XtextEditor extends TextEditor {
return more;
}
+ protected void updateStatusLine() {
+ final ITextSelection selection = (ITextSelection) getSelectionProvider().getSelection();
+ final Annotation annotation = getAnnotation(selection.getOffset(), selection.getLength());
+ String message = null;
+ if (annotation != null) {
+ updateMarkerViews(annotation);
+ if (isProblemMarkerAnnotation(annotation)) {
+ message = annotation.getText();
+ }
+ }
+ setStatusLineMessage(message);
+ }
+
+ private Annotation getAnnotation(final int offset, final int length) {
+ final IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
+ if (model == null)
+ return null;
+
+ Iterator iterator;
+ if (model instanceof IAnnotationModelExtension2) {
+ iterator = ((IAnnotationModelExtension2) model).getAnnotationIterator(offset, length, true, true);
+ }
+ else {
+ iterator = model.getAnnotationIterator();
+ }
+
+ while (iterator.hasNext()) {
+ final Annotation a = (Annotation) iterator.next();
+ final Position p = model.getPosition(a);
+ if (p != null && p.overlapsWith(offset, length))
+ return a;
+ }
+ return null;
+ }
+
+ private boolean isProblemMarkerAnnotation(final Annotation annotation) {
+ if (!(annotation instanceof MarkerAnnotation))
+ return false;
+ try {
+ return (((MarkerAnnotation) annotation).getMarker().isSubtypeOf(IMarker.PROBLEM));
+ }
+ catch (final CoreException e) {
+ return false;
+ }
+ }
}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
index 2c12ebd..548a99c 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/XtextSourceViewerConfiguration.java
@@ -19,10 +19,12 @@ import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
import org.eclipse.jface.text.presentation.IPresentationReconciler;
import org.eclipse.jface.text.reconciler.IReconciler;
+import org.eclipse.jface.text.source.IAnnotationHover;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.ui.editors.text.TextSourceViewerConfiguration;
import org.eclipse.xtext.ui.core.editor.contentassist.IContentAssistantFactory;
import org.eclipse.xtext.ui.core.editor.formatting.IContentFormatterFactory;
+import org.eclipse.xtext.ui.core.editor.hover.ProblemHover;
import org.eclipse.xtext.ui.core.editor.toggleComments.ISingleLineCommentHelper;
import com.google.inject.Inject;
@@ -54,6 +56,14 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
@Inject
private Provider<XtextPresentationReconciler> presentationReconcilerProvider;
+ /**
+ * @see org.eclipse.ui.editors.text.TextSourceViewerConfiguration#getAnnotationHover(org.eclipse.jface.text.source.ISourceViewer)
+ */
+ @Override
+ public IAnnotationHover getAnnotationHover(ISourceViewer sourceViewer) {
+ return new ProblemHover(sourceViewer);
+ }
+
@Override
public IContentAssistant getContentAssistant(ISourceViewer sourceViewer) {
return contentAssistantFactory.createConfiguredAssistant(this, sourceViewer);
@@ -133,4 +143,5 @@ public class XtextSourceViewerConfiguration extends TextSourceViewerConfiguratio
public Provider<XtextPresentationReconciler> getPresentationReconcilerProvider() {
return presentationReconcilerProvider;
}
+
}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/hover/AbstractHover.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/hover/AbstractHover.java
new file mode 100644
index 0000000..884b7fd
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/hover/AbstractHover.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * Copyright (c) 2008 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.xtext.ui.core.editor.hover;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.BadLocationException;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITextHover;
+import org.eclipse.jface.text.ITextHoverExtension2;
+import org.eclipse.jface.text.ITextViewer;
+import org.eclipse.jface.text.Region;
+import org.eclipse.jface.text.source.IAnnotationHover;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.xtext.ui.core.XtextUIMessages;
+
+/**
+ * @author Patrick Schoenbach - Initial API and implementation
+ */
+
+public abstract class AbstractHover implements IAnnotationHover, ITextHover, ITextHoverExtension2 {
+
+ protected final ISourceViewer sourceViewer;
+
+ public AbstractHover(final ISourceViewer sourceViewer) {
+ if (sourceViewer == null)
+ throw new IllegalArgumentException();
+
+ this.sourceViewer = sourceViewer;
+ }
+
+ public IDocument getDocument() {
+ return sourceViewer.getDocument();
+ }
+
+ public String getHoverInfo(final ISourceViewer sourceViewer, final int lineNumber) {
+ return getHoverInfoInternal(lineNumber, -1);
+ }
+
+ public String getHoverInfo(final ITextViewer textViewer, final IRegion hoverRegion) {
+ return getHoverInfo2(textViewer, hoverRegion);
+ }
+
+ // for TextHover
+ public String getHoverInfo2(final ITextViewer textViewer, final IRegion hoverRegion) {
+ int lineNumber;
+ try {
+ lineNumber = getDocument().getLineOfOffset(hoverRegion.getOffset());
+ }
+ catch (final BadLocationException e) {
+ return null;
+ }
+ return getHoverInfoInternal(lineNumber, hoverRegion.getOffset());
+ }
+
+ public IRegion getHoverRegion(final ITextViewer textViewer, final int offset) {
+ final Point selection = textViewer.getSelectedRange();
+ if (selection.x <= offset && offset < selection.x + selection.y)
+ return new Region(selection.x, selection.y);
+ return new Region(offset, 0);
+ }
+
+ protected String formatInfo(final List<String> messages) {
+ final StringBuffer buffer = new StringBuffer();
+ if (messages.size() > 1) {
+ buffer.append(XtextUIMessages.AbstractHover_MultipleMarkers);
+ final Iterator<String> e = messages.iterator();
+ while (e.hasNext()) {
+ splitInfo("- " + e.next() + "\n", buffer);
+ }
+ }
+ else if (messages.size() == 1) {
+ splitInfo(messages.get(0), buffer);
+ }
+ return buffer.toString();
+ }
+
+ protected abstract String getHoverInfoInternal(final int lineNumber, final int offset);
+
+ private String splitInfo(final String message, final StringBuffer buffer) {
+ String msg = message;
+ String prefix = "";
+ int pos;
+ do {
+ pos = msg.indexOf(" ", 60);
+ if (pos > -1) {
+ buffer.append(prefix + msg.substring(0, pos) + "\n");
+ msg = msg.substring(pos);
+ prefix = " ";
+ }
+ else {
+ buffer.append(prefix + msg);
+ }
+ } while (pos > -1);
+ return buffer.toString();
+ }
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/hover/ProblemHover.java b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/hover/ProblemHover.java
new file mode 100644
index 0000000..5476598
--- /dev/null
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/editor/hover/ProblemHover.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright (c) 2007 Sven Efftinge (http://www.efftinge.de) 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
+ *
+ * Contributors:
+ * committers of openArchitectureWare
+ *******************************************************************************/
+package org.eclipse.xtext.ui.core.editor.hover;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.jface.text.source.Annotation;
+import org.eclipse.jface.text.source.IAnnotationModel;
+import org.eclipse.jface.text.source.ISourceViewer;
+import org.eclipse.ui.texteditor.MarkerAnnotation;
+
+public class ProblemHover extends AbstractHover {
+
+ public ProblemHover(final ISourceViewer sourceViewer) {
+ super(sourceViewer);
+ }
+
+ @Override
+ protected String getHoverInfoInternal(final int lineNumber,
+ final int offset) {
+ final IAnnotationModel model = sourceViewer.getAnnotationModel();
+ final List<String> messages = new ArrayList<String>();
+
+ final Iterator<?> iterator = model.getAnnotationIterator();
+ while (iterator.hasNext()) {
+ final Annotation annotation = (Annotation) iterator.next();
+ if (!(annotation instanceof MarkerAnnotation)) {
+ continue;
+ }
+ final MarkerAnnotation mAnno = (MarkerAnnotation) annotation;
+ final int start = model.getPosition(mAnno).getOffset();
+ final int end = start + model.getPosition(mAnno).getLength();
+
+ if (offset > 0 && !(start <= offset && offset <= end)) {
+ continue;
+ }
+ try {
+ if (lineNumber != sourceViewer.getDocument().getLineOfOffset(
+ start)) {
+ continue;
+ }
+ } catch (final Exception x) {
+ continue;
+ }
+ messages.add(mAnno.getText().trim());
+ }
+ return formatInfo(messages);
+ }
+}
diff --git a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/messages.properties b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/messages.properties
index d78db61..c322f1f 100644
--- a/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/messages.properties
+++ b/plugins/org.eclipse.xtext.ui.core/src/org/eclipse/xtext/ui/core/messages.properties
@@ -11,6 +11,8 @@ XtextOutlineSortingAction.description=Sorts elements in the outline.
XtextOutlineSortingAction.label=Sort
XtextOutlineSortingAction.tooltip=Sort
+AbstractHover_MultipleMarkers=Multiple markers at this line\\n
+
ContentAssistProposal.label=Content assist
ContentAssistProposal.tooltip=Content assist
ContentAssistProposal.description=Provides content assistance