mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Spell correction hover.
This commit is contained in:
parent
eb179298f4
commit
5eb63f4700
14 changed files with 1086 additions and 116 deletions
BIN
core/org.eclipse.cdt.ui/icons/dlcl16/configure_annotations.gif
Normal file
BIN
core/org.eclipse.cdt.ui/icons/dlcl16/configure_annotations.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 357 B |
BIN
core/org.eclipse.cdt.ui/icons/elcl16/configure_annotations.gif
Normal file
BIN
core/org.eclipse.cdt.ui/icons/elcl16/configure_annotations.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 383 B |
|
@ -161,18 +161,24 @@
|
||||||
</extension>
|
</extension>
|
||||||
<extension
|
<extension
|
||||||
point="org.eclipse.cdt.ui.textHovers">
|
point="org.eclipse.cdt.ui.textHovers">
|
||||||
<hover
|
|
||||||
label="%cdocHover"
|
|
||||||
description="%cdocHoverDescription"
|
|
||||||
class="org.eclipse.cdt.internal.ui.text.c.hover.CDocHover"
|
|
||||||
id="org.eclipse.cdt.ui.CDocHover">
|
|
||||||
</hover>
|
|
||||||
<hover
|
<hover
|
||||||
label="%sequentialHover"
|
label="%sequentialHover"
|
||||||
description="%sequentialHoverDescription"
|
description="%sequentialHoverDescription"
|
||||||
class="org.eclipse.cdt.internal.ui.text.c.hover.BestMatchHover"
|
class="org.eclipse.cdt.internal.ui.text.c.hover.BestMatchHover"
|
||||||
id="org.eclipse.cdt.ui.BestMatchHover">
|
id="org.eclipse.cdt.ui.BestMatchHover">
|
||||||
</hover>
|
</hover>
|
||||||
|
<hover
|
||||||
|
label="%problemHover"
|
||||||
|
description="%problemHoverDescription"
|
||||||
|
class="org.eclipse.cdt.internal.ui.text.c.hover.ProblemHover"
|
||||||
|
id="org.eclipse.cdt.ui.ProblemHover">
|
||||||
|
</hover>
|
||||||
|
<hover
|
||||||
|
label="%cdocHover"
|
||||||
|
description="%cdocHoverDescription"
|
||||||
|
class="org.eclipse.cdt.internal.ui.text.c.hover.CDocHover"
|
||||||
|
id="org.eclipse.cdt.ui.CDocHover">
|
||||||
|
</hover>
|
||||||
<hover
|
<hover
|
||||||
label="%sourceHover"
|
label="%sourceHover"
|
||||||
description="%sourceHoverDescription"
|
description="%sourceHoverDescription"
|
||||||
|
@ -185,12 +191,6 @@
|
||||||
class="org.eclipse.cdt.internal.ui.text.c.hover.CMacroExpansionHover"
|
class="org.eclipse.cdt.internal.ui.text.c.hover.CMacroExpansionHover"
|
||||||
id="org.eclipse.cdt.ui.CMacroExpansionHover">
|
id="org.eclipse.cdt.ui.CMacroExpansionHover">
|
||||||
</hover>
|
</hover>
|
||||||
<!--hover
|
|
||||||
label="%problemHover"
|
|
||||||
description="%problemHoverDescription"
|
|
||||||
class="org.eclipse.cdt.internal.ui.text.c.hover.ProblemHover"
|
|
||||||
id="org.eclipse.cdt.ui.ProblemHover">
|
|
||||||
</hover-->
|
|
||||||
<hover
|
<hover
|
||||||
label="%annotationHover"
|
label="%annotationHover"
|
||||||
description="%annotationHoverDescription"
|
description="%annotationHoverDescription"
|
||||||
|
|
|
@ -10,16 +10,21 @@
|
||||||
* QNX Software System
|
* QNX Software System
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui;
|
package org.eclipse.cdt.internal.ui;
|
||||||
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
|
||||||
|
import org.eclipse.core.runtime.FileLocator;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.core.runtime.Path;
|
||||||
import org.eclipse.jface.action.IAction;
|
import org.eclipse.jface.action.IAction;
|
||||||
import org.eclipse.jface.resource.ImageDescriptor;
|
import org.eclipse.jface.resource.ImageDescriptor;
|
||||||
import org.eclipse.jface.resource.ImageRegistry;
|
import org.eclipse.jface.resource.ImageRegistry;
|
||||||
import org.eclipse.swt.graphics.Image;
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.osgi.framework.Bundle;
|
||||||
|
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
|
@ -27,6 +32,7 @@ import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
* Bundle of all images used by the C plugin.
|
* Bundle of all images used by the C plugin.
|
||||||
*/
|
*/
|
||||||
public class CPluginImages {
|
public class CPluginImages {
|
||||||
|
public static final IPath ICONS_PATH= new Path("$nl$/icons"); //$NON-NLS-1$
|
||||||
|
|
||||||
// The plugin registry
|
// The plugin registry
|
||||||
private static ImageRegistry imageRegistry = new ImageRegistry(CUIPlugin.getStandardDisplay());
|
private static ImageRegistry imageRegistry = new ImageRegistry(CUIPlugin.getStandardDisplay());
|
||||||
|
@ -47,6 +53,8 @@ public class CPluginImages {
|
||||||
public static final String T_OBJ= "obj16/"; //$NON-NLS-1$
|
public static final String T_OBJ= "obj16/"; //$NON-NLS-1$
|
||||||
public static final String T_WIZBAN= "wizban/"; //$NON-NLS-1$
|
public static final String T_WIZBAN= "wizban/"; //$NON-NLS-1$
|
||||||
public static final String T_LCL= "lcl16/"; //$NON-NLS-1$
|
public static final String T_LCL= "lcl16/"; //$NON-NLS-1$
|
||||||
|
public static final String T_DLCL= "dlcl16/"; //$NON-NLS-1$
|
||||||
|
public static final String T_ELCL= "elcl16/"; //$NON-NLS-1$
|
||||||
public static final String T_TOOL= "tool16/"; //$NON-NLS-1$
|
public static final String T_TOOL= "tool16/"; //$NON-NLS-1$
|
||||||
public static final String T_VIEW= "view16/"; //$NON-NLS-1$
|
public static final String T_VIEW= "view16/"; //$NON-NLS-1$
|
||||||
public static final String T_OVR= "ovr16/"; //$NON-NLS-1$
|
public static final String T_OVR= "ovr16/"; //$NON-NLS-1$
|
||||||
|
@ -128,7 +136,7 @@ public class CPluginImages {
|
||||||
public static final String IMG_VIEW_BUILD = NAME_PREFIX + "buildconsole.gif"; //$NON-NLS-1$
|
public static final String IMG_VIEW_BUILD = NAME_PREFIX + "buildconsole.gif"; //$NON-NLS-1$
|
||||||
public static final String IMG_VIEW_MENU = NAME_PREFIX + "view_menu.gif"; //$NON-NLS-1$
|
public static final String IMG_VIEW_MENU = NAME_PREFIX + "view_menu.gif"; //$NON-NLS-1$
|
||||||
|
|
||||||
// unknow type
|
// unknown type
|
||||||
public static final String IMG_OBJS_UNKNOWN = NAME_PREFIX + "unknown_obj.gif"; //$NON-NLS-1$
|
public static final String IMG_OBJS_UNKNOWN = NAME_PREFIX + "unknown_obj.gif"; //$NON-NLS-1$
|
||||||
|
|
||||||
public static final ImageDescriptor DESC_BUILD_CONSOLE = createManaged(T_VIEW, IMG_VIEW_BUILD);
|
public static final ImageDescriptor DESC_BUILD_CONSOLE = createManaged(T_VIEW, IMG_VIEW_BUILD);
|
||||||
|
@ -333,6 +341,9 @@ public class CPluginImages {
|
||||||
public static final String IMG_EMPTY = NAME_PREFIX + "tc_empty.gif"; //$NON-NLS-1$
|
public static final String IMG_EMPTY = NAME_PREFIX + "tc_empty.gif"; //$NON-NLS-1$
|
||||||
public static final ImageDescriptor DESC_EMPTY = createManaged(T_OBJ, IMG_EMPTY);
|
public static final ImageDescriptor DESC_EMPTY = createManaged(T_OBJ, IMG_EMPTY);
|
||||||
|
|
||||||
|
public static final ImageDescriptor DESC_DLCL_CONFIGURE_ANNOTATIONS= createUnManaged(T_DLCL, "configure_annotations.gif"); //$NON-NLS-1$
|
||||||
|
public static final ImageDescriptor DESC_ELCL_CONFIGURE_ANNOTATIONS= createUnManaged(T_ELCL, "configure_annotations.gif"); //$NON-NLS-1$
|
||||||
|
|
||||||
public static final String IMG_OBJS_QUICK_ASSIST= NAME_PREFIX + "quickassist_obj.gif"; //$NON-NLS-1$
|
public static final String IMG_OBJS_QUICK_ASSIST= NAME_PREFIX + "quickassist_obj.gif"; //$NON-NLS-1$
|
||||||
public static final ImageDescriptor DESC_OBJS_QUICK_ASSIST = createManaged(T_OBJ, IMG_OBJS_QUICK_ASSIST);
|
public static final ImageDescriptor DESC_OBJS_QUICK_ASSIST = createManaged(T_OBJ, IMG_OBJS_QUICK_ASSIST);
|
||||||
public static final String IMG_CORRECTION_ADD= NAME_PREFIX + "correction_add.gif"; //$NON-NLS-1$
|
public static final String IMG_CORRECTION_ADD= NAME_PREFIX + "correction_add.gif"; //$NON-NLS-1$
|
||||||
|
@ -363,6 +374,27 @@ public class CPluginImages {
|
||||||
return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name));
|
return ImageDescriptor.createFromURL(makeIconFileURL(prefix, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates an image descriptor for the given prefix and name in the JDT UI bundle. The path can
|
||||||
|
* contain variables like $NL$.
|
||||||
|
* If no image could be found, <code>useMissingImageDescriptor</code> decides if either
|
||||||
|
* the 'missing image descriptor' is returned or <code>null</code>.
|
||||||
|
* or <code>null</code>.
|
||||||
|
*/
|
||||||
|
private static ImageDescriptor create(String prefix, String name, boolean useMissingImageDescriptor) {
|
||||||
|
IPath path= ICONS_PATH.append(prefix).append(name);
|
||||||
|
return createImageDescriptor(CUIPlugin.getDefault().getBundle(), path, useMissingImageDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates an image descriptor for the given prefix and name in the JDT UI bundle. The path can
|
||||||
|
* contain variables like $NL$.
|
||||||
|
* If no image could be found, the 'missing image descriptor' is returned.
|
||||||
|
*/
|
||||||
|
private static ImageDescriptor createUnManaged(String prefix, String name) {
|
||||||
|
return create(prefix, name, true);
|
||||||
|
}
|
||||||
|
|
||||||
private static URL makeIconFileURL(String prefix, String name) {
|
private static URL makeIconFileURL(String prefix, String name) {
|
||||||
StringBuffer buffer= new StringBuffer(prefix);
|
StringBuffer buffer= new StringBuffer(prefix);
|
||||||
buffer.append(name);
|
buffer.append(name);
|
||||||
|
@ -374,6 +406,24 @@ public class CPluginImages {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates an image descriptor for the given path in a bundle. The path can contain variables
|
||||||
|
* like $NL$.
|
||||||
|
* If no image could be found, <code>useMissingImageDescriptor</code> decides if either
|
||||||
|
* the 'missing image descriptor' is returned or <code>null</code>.
|
||||||
|
* Added for 3.1.1.
|
||||||
|
*/
|
||||||
|
public static ImageDescriptor createImageDescriptor(Bundle bundle, IPath path, boolean useMissingImageDescriptor) {
|
||||||
|
URL url= FileLocator.find(bundle, path, null);
|
||||||
|
if (url != null) {
|
||||||
|
return ImageDescriptor.createFromURL(url);
|
||||||
|
}
|
||||||
|
if (useMissingImageDescriptor) {
|
||||||
|
return ImageDescriptor.getMissingImageDescriptor();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the three image descriptors for enabled, disabled, and hovered to an action. The actions
|
* Sets the three image descriptors for enabled, disabled, and hovered to an action. The actions
|
||||||
* are retrieved from the *tool16 folders.
|
* are retrieved from the *tool16 folders.
|
||||||
|
|
|
@ -7,64 +7,44 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.editor;
|
package org.eclipse.cdt.internal.ui.editor;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IMarker;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
import org.eclipse.jface.text.source.Annotation;
|
import org.eclipse.jface.text.source.Annotation;
|
||||||
import org.eclipse.jface.text.source.IAnnotationModel;
|
import org.eclipse.ui.texteditor.MarkerAnnotation;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filters problems based on their types.
|
* Filters problems based on their types.
|
||||||
*/
|
*/
|
||||||
public class CAnnotationIterator implements Iterator<Annotation> {
|
public class CAnnotationIterator implements Iterator<Annotation> {
|
||||||
|
|
||||||
private Iterator<Annotation> fIterator;
|
private Iterator<Annotation> fIterator;
|
||||||
private Annotation fNext;
|
private Annotation fNext;
|
||||||
private boolean fSkipIrrelevants;
|
|
||||||
private boolean fReturnAllAnnotations;
|
private boolean fReturnAllAnnotations;
|
||||||
|
|
||||||
/**
|
|
||||||
* Equivalent to <code>CAnnotationIterator(model, skipIrrelevants, false)</code>.
|
|
||||||
*/
|
|
||||||
public CAnnotationIterator(IAnnotationModel model, boolean skipIrrelevants) {
|
|
||||||
this(model, skipIrrelevants, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new CAnnotationIterator.
|
* Returns a new CAnnotationIterator.
|
||||||
* @param model the annotation model
|
* @param parent the parent iterator to iterate over annotations
|
||||||
* @param skipIrrelevants whether to skip irrelevant annotations
|
* @param returnAllAnnotations whether to return all annotations or just problem annotations
|
||||||
* @param returnAllAnnotations Whether to return non IJavaAnnotations as well
|
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked") // using api without generics
|
public CAnnotationIterator(Iterator<Annotation> parent, boolean returnAllAnnotations) {
|
||||||
public CAnnotationIterator(IAnnotationModel model, boolean skipIrrelevants, boolean returnAllAnnotations) {
|
|
||||||
fReturnAllAnnotations= returnAllAnnotations;
|
fReturnAllAnnotations= returnAllAnnotations;
|
||||||
if (model != null)
|
fIterator= parent;
|
||||||
fIterator= model.getAnnotationIterator();
|
|
||||||
else
|
|
||||||
fIterator= Collections.EMPTY_LIST.iterator();
|
|
||||||
fSkipIrrelevants= skipIrrelevants;
|
|
||||||
skip();
|
skip();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void skip() {
|
private void skip() {
|
||||||
while (fIterator.hasNext()) {
|
while (fIterator.hasNext()) {
|
||||||
Annotation next= fIterator.next();
|
Annotation next= fIterator.next();
|
||||||
if (next instanceof ICAnnotation) {
|
|
||||||
if (fSkipIrrelevants) {
|
if (next.isMarkedDeleted())
|
||||||
if (!next.isMarkedDeleted()) {
|
continue;
|
||||||
fNext= next;
|
|
||||||
return;
|
if (fReturnAllAnnotations || next instanceof ICAnnotation || isProblemMarkerAnnotation(next)) {
|
||||||
}
|
|
||||||
} else {
|
|
||||||
fNext= next;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (fReturnAllAnnotations) {
|
|
||||||
fNext= next;
|
fNext= next;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -72,6 +52,16 @@ public class CAnnotationIterator implements Iterator<Annotation> {
|
||||||
fNext= null;
|
fNext= null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isProblemMarkerAnnotation(Annotation annotation) {
|
||||||
|
if (!(annotation instanceof MarkerAnnotation))
|
||||||
|
return false;
|
||||||
|
try {
|
||||||
|
return(((MarkerAnnotation)annotation).getMarker().isSubtypeOf(IMarker.PROBLEM));
|
||||||
|
} catch (CoreException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see Iterator#hasNext()
|
* @see Iterator#hasNext()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.editor;
|
package org.eclipse.cdt.internal.ui.editor;
|
||||||
|
|
||||||
|
|
||||||
import java.text.CharacterIterator;
|
import java.text.CharacterIterator;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -90,6 +89,7 @@ import org.eclipse.jface.text.link.LinkedModeUI.IExitPolicy;
|
||||||
import org.eclipse.jface.text.source.Annotation;
|
import org.eclipse.jface.text.source.Annotation;
|
||||||
import org.eclipse.jface.text.source.IAnnotationModel;
|
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||||
import org.eclipse.jface.text.source.IAnnotationModelExtension;
|
import org.eclipse.jface.text.source.IAnnotationModelExtension;
|
||||||
|
import org.eclipse.jface.text.source.IAnnotationModelExtension2;
|
||||||
import org.eclipse.jface.text.source.ICharacterPairMatcher;
|
import org.eclipse.jface.text.source.ICharacterPairMatcher;
|
||||||
import org.eclipse.jface.text.source.IOverviewRuler;
|
import org.eclipse.jface.text.source.IOverviewRuler;
|
||||||
import org.eclipse.jface.text.source.ISourceViewer;
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
|
@ -222,7 +222,6 @@ import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.ISelectionListenerWithAST;
|
import org.eclipse.cdt.internal.ui.viewsupport.ISelectionListenerWithAST;
|
||||||
import org.eclipse.cdt.internal.ui.viewsupport.SelectionListenerWithASTManager;
|
import org.eclipse.cdt.internal.ui.viewsupport.SelectionListenerWithASTManager;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* C/C++ source editor.
|
* C/C++ source editor.
|
||||||
*/
|
*/
|
||||||
|
@ -402,7 +401,6 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ExitPolicy implements IExitPolicy {
|
private class ExitPolicy implements IExitPolicy {
|
||||||
|
|
||||||
final char fExitCharacter;
|
final char fExitCharacter;
|
||||||
final char fEscapeCharacter;
|
final char fEscapeCharacter;
|
||||||
final Stack<BracketLevel> fStack;
|
final Stack<BracketLevel> fStack;
|
||||||
|
@ -484,7 +482,6 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
||||||
* @see org.eclipse.jface.text.IPositionUpdater#update(org.eclipse.jface.text.DocumentEvent)
|
* @see org.eclipse.jface.text.IPositionUpdater#update(org.eclipse.jface.text.DocumentEvent)
|
||||||
*/
|
*/
|
||||||
public void update(DocumentEvent event) {
|
public void update(DocumentEvent event) {
|
||||||
|
|
||||||
int eventOffset = event.getOffset();
|
int eventOffset = event.getOffset();
|
||||||
int eventOldLength = event.getLength();
|
int eventOldLength = event.getLength();
|
||||||
int eventNewLength = event.getText() == null ? 0 : event.getText().length();
|
int eventNewLength = event.getText() == null ? 0 : event.getText().length();
|
||||||
|
@ -504,11 +501,11 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
||||||
int length = position.getLength();
|
int length = position.getLength();
|
||||||
int end = offset + length;
|
int end = offset + length;
|
||||||
|
|
||||||
if (offset >= eventOffset + eventOldLength)
|
if (offset >= eventOffset + eventOldLength) {
|
||||||
// position comes
|
// position comes
|
||||||
// after change - shift
|
// after change - shift
|
||||||
position.setOffset(offset + deltaLength);
|
position.setOffset(offset + deltaLength);
|
||||||
else if (end <= eventOffset) {
|
} else if (end <= eventOffset) {
|
||||||
// position comes way before change -
|
// position comes way before change -
|
||||||
// leave alone
|
// leave alone
|
||||||
} else if (offset <= eventOffset && end >= eventOffset + eventOldLength) {
|
} else if (offset <= eventOffset && end >= eventOffset + eventOldLength) {
|
||||||
|
@ -2455,8 +2452,20 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IC
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
private Annotation getAnnotation(int offset, int length) {
|
private Annotation getAnnotation(int offset, int length) {
|
||||||
IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
|
IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
|
||||||
Iterator<Annotation> e = new CAnnotationIterator(model, true, true);
|
if (model == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Iterator parent;
|
||||||
|
if (model instanceof IAnnotationModelExtension2) {
|
||||||
|
parent= ((IAnnotationModelExtension2)model).getAnnotationIterator(offset, length, true, true);
|
||||||
|
} else {
|
||||||
|
parent= model.getAnnotationIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Iterator<Annotation> e= new CAnnotationIterator(parent, false);
|
||||||
while (e.hasNext()) {
|
while (e.hasNext()) {
|
||||||
Annotation a = e.next();
|
Annotation a = e.next();
|
||||||
if (!isNavigationTarget(a))
|
if (!isNavigationTarget(a))
|
||||||
|
|
|
@ -26,6 +26,7 @@ import org.eclipse.jface.text.ITextViewerExtension5;
|
||||||
import org.eclipse.jface.text.Position;
|
import org.eclipse.jface.text.Position;
|
||||||
import org.eclipse.jface.text.source.Annotation;
|
import org.eclipse.jface.text.source.Annotation;
|
||||||
import org.eclipse.jface.text.source.IAnnotationModel;
|
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.ISourceViewer;
|
||||||
import org.eclipse.jface.text.source.SourceViewerConfiguration;
|
import org.eclipse.jface.text.source.SourceViewerConfiguration;
|
||||||
import org.eclipse.jface.util.PropertyChangeEvent;
|
import org.eclipse.jface.util.PropertyChangeEvent;
|
||||||
|
@ -268,8 +269,20 @@ public class AsmTextEditor extends TextEditor implements ISelectionChangedListen
|
||||||
* @return the found annotation or <code>null</code>
|
* @return the found annotation or <code>null</code>
|
||||||
*/
|
*/
|
||||||
private Annotation getAnnotation(int offset, int length) {
|
private Annotation getAnnotation(int offset, int length) {
|
||||||
IAnnotationModel model = getDocumentProvider().getAnnotationModel(getEditorInput());
|
IAnnotationModel model= getDocumentProvider().getAnnotationModel(getEditorInput());
|
||||||
Iterator<Annotation> e = new CAnnotationIterator(model, true, true);
|
if (model == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Iterator parent;
|
||||||
|
if (model instanceof IAnnotationModelExtension2) {
|
||||||
|
parent= ((IAnnotationModelExtension2)model).getAnnotationIterator(offset, length, true, true);
|
||||||
|
} else {
|
||||||
|
parent= model.getAnnotationIterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Iterator<Annotation> e= new CAnnotationIterator(parent, false);
|
||||||
while (e.hasNext()) {
|
while (e.hasNext()) {
|
||||||
Annotation a = e.next();
|
Annotation a = e.next();
|
||||||
if (!isNavigationTarget(a))
|
if (!isNavigationTarget(a))
|
||||||
|
|
|
@ -6,30 +6,83 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|
||||||
package org.eclipse.cdt.internal.ui.text.c.hover;
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
|
import org.eclipse.core.filebuffers.FileBuffers;
|
||||||
|
import org.eclipse.core.filebuffers.ITextFileBufferManager;
|
||||||
|
import org.eclipse.core.filebuffers.LocationKind;
|
||||||
|
import org.eclipse.core.runtime.Assert;
|
||||||
|
import org.eclipse.core.runtime.CoreException;
|
||||||
|
import org.eclipse.core.runtime.IPath;
|
||||||
|
import org.eclipse.jface.action.Action;
|
||||||
|
import org.eclipse.jface.action.ToolBarManager;
|
||||||
import org.eclipse.jface.preference.IPreferenceStore;
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
|
import org.eclipse.jface.resource.JFaceResources;
|
||||||
|
import org.eclipse.jface.text.AbstractInformationControl;
|
||||||
|
import org.eclipse.jface.text.AbstractReusableInformationControlCreator;
|
||||||
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
import org.eclipse.jface.text.IInformationControl;
|
||||||
|
import org.eclipse.jface.text.IInformationControlCreator;
|
||||||
|
import org.eclipse.jface.text.IInformationControlExtension2;
|
||||||
|
import org.eclipse.jface.text.IInformationControlExtension4;
|
||||||
import org.eclipse.jface.text.IRegion;
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.IRewriteTarget;
|
||||||
import org.eclipse.jface.text.ITextViewer;
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.jface.text.ITextViewerExtension;
|
||||||
import org.eclipse.jface.text.Position;
|
import org.eclipse.jface.text.Position;
|
||||||
|
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||||
|
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension;
|
||||||
|
import org.eclipse.jface.text.contentassist.ICompletionProposalExtension2;
|
||||||
import org.eclipse.jface.text.source.Annotation;
|
import org.eclipse.jface.text.source.Annotation;
|
||||||
import org.eclipse.jface.text.source.IAnnotationModel;
|
import org.eclipse.jface.text.source.IAnnotationModel;
|
||||||
import org.eclipse.ui.IEditorPart;
|
import org.eclipse.jface.text.source.IAnnotationModelExtension2;
|
||||||
|
import org.eclipse.jface.text.source.ISourceViewer;
|
||||||
|
import org.eclipse.swt.SWT;
|
||||||
|
import org.eclipse.swt.custom.ScrolledComposite;
|
||||||
|
import org.eclipse.swt.custom.StyledText;
|
||||||
|
import org.eclipse.swt.events.FocusEvent;
|
||||||
|
import org.eclipse.swt.events.FocusListener;
|
||||||
|
import org.eclipse.swt.events.KeyEvent;
|
||||||
|
import org.eclipse.swt.events.KeyListener;
|
||||||
|
import org.eclipse.swt.events.MouseEvent;
|
||||||
|
import org.eclipse.swt.events.MouseListener;
|
||||||
|
import org.eclipse.swt.events.PaintEvent;
|
||||||
|
import org.eclipse.swt.events.PaintListener;
|
||||||
|
import org.eclipse.swt.events.SelectionAdapter;
|
||||||
|
import org.eclipse.swt.events.SelectionEvent;
|
||||||
|
import org.eclipse.swt.graphics.Color;
|
||||||
|
import org.eclipse.swt.graphics.Font;
|
||||||
|
import org.eclipse.swt.graphics.Image;
|
||||||
|
import org.eclipse.swt.graphics.Point;
|
||||||
|
import org.eclipse.swt.graphics.Rectangle;
|
||||||
|
import org.eclipse.swt.layout.GridData;
|
||||||
|
import org.eclipse.swt.layout.GridLayout;
|
||||||
|
import org.eclipse.swt.widgets.Canvas;
|
||||||
|
import org.eclipse.swt.widgets.Composite;
|
||||||
|
import org.eclipse.swt.widgets.Control;
|
||||||
|
import org.eclipse.swt.widgets.Label;
|
||||||
|
import org.eclipse.swt.widgets.Link;
|
||||||
|
import org.eclipse.swt.widgets.ScrollBar;
|
||||||
|
import org.eclipse.swt.widgets.Shell;
|
||||||
|
import org.eclipse.ui.IEditorInput;
|
||||||
|
import org.eclipse.ui.IStorageEditorInput;
|
||||||
|
import org.eclipse.ui.PlatformUI;
|
||||||
|
import org.eclipse.ui.dialogs.PreferencesUtil;
|
||||||
import org.eclipse.ui.editors.text.EditorsUI;
|
import org.eclipse.ui.editors.text.EditorsUI;
|
||||||
import org.eclipse.ui.texteditor.AnnotationPreference;
|
import org.eclipse.ui.texteditor.AnnotationPreference;
|
||||||
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
|
import org.eclipse.ui.texteditor.DefaultMarkerAnnotationAccess;
|
||||||
import org.eclipse.ui.texteditor.IDocumentProvider;
|
|
||||||
|
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.CPluginImages;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CAnnotationIterator;
|
import org.eclipse.cdt.internal.ui.editor.CAnnotationIterator;
|
||||||
import org.eclipse.cdt.internal.ui.editor.CEditor;
|
|
||||||
import org.eclipse.cdt.internal.ui.text.HTMLPrinter;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AbstractAnnotationHover
|
* AbstractAnnotationHover
|
||||||
|
@ -37,42 +90,585 @@ import org.eclipse.cdt.internal.ui.text.HTMLPrinter;
|
||||||
*/
|
*/
|
||||||
public class AbstractAnnotationHover extends AbstractCEditorTextHover {
|
public class AbstractAnnotationHover extends AbstractCEditorTextHover {
|
||||||
|
|
||||||
private IPreferenceStore fStore= CUIPlugin.getDefault().getCombinedPreferenceStore();
|
/**
|
||||||
private DefaultMarkerAnnotationAccess fAnnotationAccess= new DefaultMarkerAnnotationAccess();
|
* An annotation info contains information about an {@link Annotation}
|
||||||
private boolean fAllAnnotations;
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
protected static class AnnotationInfo {
|
||||||
|
public final Annotation annotation;
|
||||||
|
public final Position position;
|
||||||
|
public final ITextViewer viewer;
|
||||||
|
|
||||||
|
public AnnotationInfo(Annotation annotation, Position position, ITextViewer textViewer) {
|
||||||
|
this.annotation= annotation;
|
||||||
|
this.position= position;
|
||||||
|
this.viewer= textViewer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create completion proposals which can resolve the given annotation at
|
||||||
|
* the given position. Returns an empty array if no such proposals exist.
|
||||||
|
*
|
||||||
|
* @return the proposals or an empty array
|
||||||
|
*/
|
||||||
|
public ICompletionProposal[] getCompletionProposals() {
|
||||||
|
return new ICompletionProposal[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds actions to the given toolbar.
|
||||||
|
*
|
||||||
|
* @param manager the toolbar manager to add actions to
|
||||||
|
* @param infoControl the information control
|
||||||
|
*/
|
||||||
|
public void fillToolBar(ToolBarManager manager, IInformationControl infoControl) {
|
||||||
|
ConfigureAnnotationsAction configureAnnotationsAction= new ConfigureAnnotationsAction(annotation, infoControl);
|
||||||
|
manager.add(configureAnnotationsAction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The annotation information control shows informations about a given
|
||||||
|
* {@link AbstractAnnotationHover.AnnotationInfo}. It can also show a toolbar
|
||||||
|
* and a list of {@link ICompletionProposal}s.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
private static class AnnotationInformationControl extends AbstractInformationControl implements IInformationControlExtension2 {
|
||||||
|
private final DefaultMarkerAnnotationAccess fMarkerAnnotationAccess;
|
||||||
|
private Control fFocusControl;
|
||||||
|
private AnnotationInfo fInput;
|
||||||
|
private Composite fParent;
|
||||||
|
|
||||||
|
public AnnotationInformationControl(Shell parentShell, String statusFieldText) {
|
||||||
|
super(parentShell, statusFieldText);
|
||||||
|
|
||||||
|
fMarkerAnnotationAccess= new DefaultMarkerAnnotationAccess();
|
||||||
|
create();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AnnotationInformationControl(Shell parentShell, ToolBarManager toolBarManager) {
|
||||||
|
super(parentShell, toolBarManager);
|
||||||
|
|
||||||
|
fMarkerAnnotationAccess= new DefaultMarkerAnnotationAccess();
|
||||||
|
create();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.IInformationControl#setInformation(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setInformation(String information) {
|
||||||
|
//replaced by IInformationControlExtension2#setInput
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.IInformationControlExtension2#setInput(java.lang.Object)
|
||||||
|
*/
|
||||||
|
public void setInput(Object input) {
|
||||||
|
Assert.isLegal(input instanceof AnnotationInfo);
|
||||||
|
fInput= (AnnotationInfo)input;
|
||||||
|
disposeDeferredCreatedContent();
|
||||||
|
deferredCreateContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.IInformationControlExtension#hasContents()
|
||||||
|
*/
|
||||||
|
public boolean hasContents() {
|
||||||
|
return fInput != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private AnnotationInfo getAnnotationInfo() {
|
||||||
|
return fInput;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractAnnotationHover.AbstractInformationControl#setFocus()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setFocus() {
|
||||||
|
super.setFocus();
|
||||||
|
if (fFocusControl != null)
|
||||||
|
fFocusControl.setFocus();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.AbstractInformationControl#setVisible(boolean)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public final void setVisible(boolean visible) {
|
||||||
|
if (!visible)
|
||||||
|
disposeDeferredCreatedContent();
|
||||||
|
super.setVisible(visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void disposeDeferredCreatedContent() {
|
||||||
|
Control[] children= fParent.getChildren();
|
||||||
|
for (int i= 0; i < children.length; i++) {
|
||||||
|
children[i].dispose();
|
||||||
|
}
|
||||||
|
ToolBarManager toolBarManager= getToolBarManager();
|
||||||
|
if (toolBarManager != null)
|
||||||
|
toolBarManager.removeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.AbstractInformationControl#createContent(org.eclipse.swt.widgets.Composite)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void createContent(Composite parent) {
|
||||||
|
fParent= parent;
|
||||||
|
GridLayout layout= new GridLayout(1, false);
|
||||||
|
layout.verticalSpacing= 0;
|
||||||
|
layout.marginWidth= 0;
|
||||||
|
layout.marginHeight= 0;
|
||||||
|
fParent.setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.AbstractInformationControl#computeSizeHint()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Point computeSizeHint() {
|
||||||
|
Point preferedSize= getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true);
|
||||||
|
|
||||||
|
Point constrains= getSizeConstraints();
|
||||||
|
if (constrains == null)
|
||||||
|
return preferedSize;
|
||||||
|
|
||||||
|
Point constrainedSize= getShell().computeSize(constrains.x, SWT.DEFAULT, true);
|
||||||
|
|
||||||
|
int width= Math.min(preferedSize.x, constrainedSize.x);
|
||||||
|
int height= Math.max(preferedSize.y, constrainedSize.y);
|
||||||
|
|
||||||
|
return new Point(width, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fills the toolbar actions, if a toolbar is available. This
|
||||||
|
* is called after the input has been set.
|
||||||
|
*/
|
||||||
|
protected void fillToolbar() {
|
||||||
|
ToolBarManager toolBarManager= getToolBarManager();
|
||||||
|
if (toolBarManager == null)
|
||||||
|
return;
|
||||||
|
fInput.fillToolBar(toolBarManager, this);
|
||||||
|
toolBarManager.update(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create content of the hover. This is called after
|
||||||
|
* the input has been set.
|
||||||
|
*/
|
||||||
|
protected void deferredCreateContent() {
|
||||||
|
fillToolbar();
|
||||||
|
|
||||||
|
createAnnotationInformation(fParent, getAnnotationInfo().annotation);
|
||||||
|
setColorAndFont(fParent, fParent.getForeground(), fParent.getBackground(), JFaceResources.getDialogFont());
|
||||||
|
|
||||||
|
ICompletionProposal[] proposals= getAnnotationInfo().getCompletionProposals();
|
||||||
|
if (proposals.length > 0)
|
||||||
|
createCompletionProposalsControl(fParent, proposals);
|
||||||
|
|
||||||
|
fParent.layout(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setColorAndFont(Control control, Color foreground, Color background, Font font) {
|
||||||
|
control.setForeground(foreground);
|
||||||
|
control.setBackground(background);
|
||||||
|
control.setFont(font);
|
||||||
|
|
||||||
|
if (control instanceof Composite) {
|
||||||
|
Control[] children= ((Composite) control).getChildren();
|
||||||
|
for (int i= 0; i < children.length; i++) {
|
||||||
|
setColorAndFont(children[i], foreground, background, font);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createAnnotationInformation(Composite parent, final Annotation annotation) {
|
||||||
|
Composite composite= new Composite(parent, SWT.NONE);
|
||||||
|
composite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
|
||||||
|
GridLayout layout= new GridLayout(2, false);
|
||||||
|
layout.marginHeight= 2;
|
||||||
|
layout.marginWidth= 2;
|
||||||
|
layout.horizontalSpacing= 0;
|
||||||
|
composite.setLayout(layout);
|
||||||
|
|
||||||
|
final Canvas canvas= new Canvas(composite, SWT.NO_FOCUS);
|
||||||
|
GridData gridData= new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false);
|
||||||
|
gridData.widthHint= 17;
|
||||||
|
gridData.heightHint= 16;
|
||||||
|
canvas.setLayoutData(gridData);
|
||||||
|
canvas.addPaintListener(new PaintListener() {
|
||||||
|
public void paintControl(PaintEvent e) {
|
||||||
|
e.gc.setFont(null);
|
||||||
|
fMarkerAnnotationAccess.paint(annotation, e.gc, canvas, new Rectangle(0, 0, 16, 16));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
StyledText text= new StyledText(composite, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY);
|
||||||
|
GridData data= new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
text.setLayoutData(data);
|
||||||
|
text.setText(annotation.getText());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createCompletionProposalsControl(Composite parent, ICompletionProposal[] proposals) {
|
||||||
|
Composite composite= new Composite(parent, SWT.NONE);
|
||||||
|
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
|
GridLayout layout2= new GridLayout(1, false);
|
||||||
|
layout2.marginHeight= 0;
|
||||||
|
layout2.marginWidth= 0;
|
||||||
|
layout2.verticalSpacing= 2;
|
||||||
|
composite.setLayout(layout2);
|
||||||
|
|
||||||
|
Label separator= new Label(composite, SWT.SEPARATOR | SWT.HORIZONTAL);
|
||||||
|
GridData gridData= new GridData(SWT.FILL, SWT.CENTER, true, false);
|
||||||
|
separator.setLayoutData(gridData);
|
||||||
|
|
||||||
|
Label quickFixLabel= new Label(composite, SWT.NONE);
|
||||||
|
GridData layoutData= new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
|
||||||
|
layoutData.horizontalIndent= 4;
|
||||||
|
quickFixLabel.setLayoutData(layoutData);
|
||||||
|
String text;
|
||||||
|
if (proposals.length == 1) {
|
||||||
|
text= CHoverMessages.AbstractAnnotationHover_message_singleQuickFix;
|
||||||
|
} else {
|
||||||
|
text= MessageFormat.format(CHoverMessages.AbstractAnnotationHover_message_multipleQuickFix, String.valueOf(proposals.length));
|
||||||
|
}
|
||||||
|
quickFixLabel.setText(text);
|
||||||
|
|
||||||
|
setColorAndFont(composite, parent.getForeground(), parent.getBackground(), JFaceResources.getDialogFont());
|
||||||
|
createCompletionProposalsList(composite, proposals);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createCompletionProposalsList(Composite parent, ICompletionProposal[] proposals) {
|
||||||
|
final ScrolledComposite scrolledComposite= new ScrolledComposite(parent, SWT.V_SCROLL | SWT.H_SCROLL);
|
||||||
|
GridData gridData= new GridData(SWT.FILL, SWT.FILL, true, true);
|
||||||
|
scrolledComposite.setLayoutData(gridData);
|
||||||
|
scrolledComposite.setExpandVertical(false);
|
||||||
|
scrolledComposite.setExpandHorizontal(false);
|
||||||
|
|
||||||
|
Composite composite= new Composite(scrolledComposite, SWT.NONE);
|
||||||
|
composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
|
||||||
|
GridLayout layout= new GridLayout(3, false);
|
||||||
|
layout.verticalSpacing= 2;
|
||||||
|
composite.setLayout(layout);
|
||||||
|
|
||||||
|
final Link[] links= new Link[proposals.length];
|
||||||
|
for (int i= 0; i < proposals.length; i++) {
|
||||||
|
Label indent= new Label(composite, SWT.NONE);
|
||||||
|
GridData gridData1= new GridData(SWT.BEGINNING, SWT.CENTER, false, false);
|
||||||
|
gridData1.widthHint= 0;
|
||||||
|
indent.setLayoutData(gridData1);
|
||||||
|
|
||||||
|
links[i]= createCompletionProposalLink(composite, proposals[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
scrolledComposite.setContent(composite);
|
||||||
|
setColorAndFont(scrolledComposite, parent.getForeground(), parent.getBackground(), JFaceResources.getDialogFont());
|
||||||
|
|
||||||
|
Point contentSize= composite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
||||||
|
composite.setSize(contentSize);
|
||||||
|
|
||||||
|
Point constraints= getSizeConstraints();
|
||||||
|
if (constraints != null && contentSize.x < constraints.x) {
|
||||||
|
ScrollBar horizontalBar= scrolledComposite.getHorizontalBar();
|
||||||
|
|
||||||
|
int scrollBarHeight;
|
||||||
|
if (horizontalBar == null) {
|
||||||
|
Point scrollSize= scrolledComposite.computeSize(SWT.DEFAULT, SWT.DEFAULT);
|
||||||
|
scrollBarHeight= scrollSize.y - contentSize.y;
|
||||||
|
} else {
|
||||||
|
scrollBarHeight= horizontalBar.getSize().y;
|
||||||
|
}
|
||||||
|
gridData.heightHint= contentSize.y - scrollBarHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
fFocusControl= links[0];
|
||||||
|
for (int i= 0; i < links.length; i++) {
|
||||||
|
final int index= i;
|
||||||
|
final Link link= links[index];
|
||||||
|
link.addKeyListener(new KeyListener() {
|
||||||
|
public void keyPressed(KeyEvent e) {
|
||||||
|
switch (e.keyCode) {
|
||||||
|
case SWT.ARROW_DOWN:
|
||||||
|
if (index + 1 < links.length) {
|
||||||
|
links[index + 1].setFocus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case SWT.ARROW_UP:
|
||||||
|
if (index > 0) {
|
||||||
|
links[index - 1].setFocus();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void keyReleased(KeyEvent e) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
link.addFocusListener(new FocusListener() {
|
||||||
|
public void focusGained(FocusEvent e) {
|
||||||
|
int currentPosition= scrolledComposite.getOrigin().y;
|
||||||
|
int hight= scrolledComposite.getSize().y;
|
||||||
|
int linkPosition= link.getLocation().y;
|
||||||
|
|
||||||
|
if (linkPosition < currentPosition) {
|
||||||
|
if (linkPosition < 10)
|
||||||
|
linkPosition= 0;
|
||||||
|
|
||||||
|
scrolledComposite.setOrigin(0, linkPosition);
|
||||||
|
} else if (linkPosition + 20 > currentPosition + hight) {
|
||||||
|
scrolledComposite.setOrigin(0, linkPosition - hight + link.getSize().y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void focusLost(FocusEvent e) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Link createCompletionProposalLink(Composite parent, final ICompletionProposal proposal) {
|
||||||
|
Label proposalImage= new Label(parent, SWT.NONE);
|
||||||
|
proposalImage.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
|
||||||
|
Image image= proposal.getImage();
|
||||||
|
if (image != null) {
|
||||||
|
proposalImage.setImage(image);
|
||||||
|
|
||||||
|
proposalImage.addMouseListener(new MouseListener() {
|
||||||
|
|
||||||
|
public void mouseDoubleClick(MouseEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseDown(MouseEvent e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void mouseUp(MouseEvent e) {
|
||||||
|
if (e.button == 1) {
|
||||||
|
apply(proposal, fInput.viewer, fInput.position.offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Link proposalLink= new Link(parent, SWT.WRAP);
|
||||||
|
proposalLink.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
|
||||||
|
proposalLink.setText("<a>" + proposal.getDisplayString() + "</a>"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
proposalLink.addSelectionListener(new SelectionAdapter() {
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void widgetSelected(SelectionEvent e) {
|
||||||
|
apply(proposal, fInput.viewer, fInput.position.offset);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return proposalLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void apply(ICompletionProposal p, ITextViewer viewer, int offset) {
|
||||||
|
//Focus needs to be in the text viewer, otherwise linked mode does not work
|
||||||
|
dispose();
|
||||||
|
|
||||||
|
IRewriteTarget target= null;
|
||||||
|
try {
|
||||||
|
IDocument document= viewer.getDocument();
|
||||||
|
|
||||||
|
if (viewer instanceof ITextViewerExtension) {
|
||||||
|
ITextViewerExtension extension= (ITextViewerExtension) viewer;
|
||||||
|
target= extension.getRewriteTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target != null)
|
||||||
|
target.beginCompoundChange();
|
||||||
|
|
||||||
|
if (p instanceof ICompletionProposalExtension2) {
|
||||||
|
ICompletionProposalExtension2 e= (ICompletionProposalExtension2) p;
|
||||||
|
e.apply(viewer, (char) 0, SWT.NONE, offset);
|
||||||
|
} else if (p instanceof ICompletionProposalExtension) {
|
||||||
|
ICompletionProposalExtension e= (ICompletionProposalExtension) p;
|
||||||
|
e.apply(document, (char) 0, offset);
|
||||||
|
} else {
|
||||||
|
p.apply(document);
|
||||||
|
}
|
||||||
|
|
||||||
|
Point selection= p.getSelection(document);
|
||||||
|
if (selection != null) {
|
||||||
|
viewer.setSelectedRange(selection.x, selection.y);
|
||||||
|
viewer.revealRange(selection.x, selection.y);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
if (target != null)
|
||||||
|
target.endCompoundChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Presenter control creator.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
private static final class PresenterControlCreator extends AbstractReusableInformationControlCreator {
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#doCreateInformationControl(org.eclipse.swt.widgets.Shell)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IInformationControl doCreateInformationControl(Shell parent) {
|
||||||
|
return new AnnotationInformationControl(parent, new ToolBarManager(SWT.FLAT));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hover control creator.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
private static final class HoverControlCreator extends AbstractReusableInformationControlCreator {
|
||||||
|
private final IInformationControlCreator fPresenterControlCreator;
|
||||||
|
|
||||||
|
public HoverControlCreator(IInformationControlCreator presenterControlCreator) {
|
||||||
|
fPresenterControlCreator= presenterControlCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#doCreateInformationControl(org.eclipse.swt.widgets.Shell)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IInformationControl doCreateInformationControl(Shell parent) {
|
||||||
|
return new AnnotationInformationControl(parent, EditorsUI.getTooltipAffordanceString()) {
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IInformationControlCreator getInformationPresenterControlCreator() {
|
||||||
|
return fPresenterControlCreator;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractReusableInformationControlCreator#canReuse(org.eclipse.jface.text.IInformationControl)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean canReuse(IInformationControl control) {
|
||||||
|
if (!super.canReuse(control))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (control instanceof IInformationControlExtension4)
|
||||||
|
((IInformationControlExtension4) control).setStatusText(EditorsUI.getTooltipAffordanceString());
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action to configure the annotation preferences.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
private static final class ConfigureAnnotationsAction extends Action {
|
||||||
|
|
||||||
|
private final Annotation fAnnotation;
|
||||||
|
private final IInformationControl fInfoControl;
|
||||||
|
|
||||||
|
public ConfigureAnnotationsAction(Annotation annotation, IInformationControl infoControl) {
|
||||||
|
super();
|
||||||
|
fAnnotation= annotation;
|
||||||
|
fInfoControl= infoControl;
|
||||||
|
setImageDescriptor(CPluginImages.DESC_ELCL_CONFIGURE_ANNOTATIONS);
|
||||||
|
setDisabledImageDescriptor(CPluginImages.DESC_DLCL_CONFIGURE_ANNOTATIONS);
|
||||||
|
setToolTipText(CHoverMessages.AbstractAnnotationHover_action_configureAnnotationPreferences);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.action.Action#run()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
Shell shell= PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
|
||||||
|
|
||||||
|
Object data= null;
|
||||||
|
AnnotationPreference preference= getAnnotationPreference(fAnnotation);
|
||||||
|
if (preference != null)
|
||||||
|
data= preference.getPreferenceLabel();
|
||||||
|
|
||||||
|
fInfoControl.dispose(); //FIXME: should have protocol to hide, rather than dispose
|
||||||
|
PreferencesUtil.createPreferenceDialogOn(shell, "org.eclipse.ui.editors.preferencePages.Annotations", null, data).open(); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final IPreferenceStore fStore= CUIPlugin.getDefault().getCombinedPreferenceStore();
|
||||||
|
private final DefaultMarkerAnnotationAccess fAnnotationAccess= new DefaultMarkerAnnotationAccess();
|
||||||
|
private final boolean fAllAnnotations;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The hover control creator.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
private IInformationControlCreator fHoverControlCreator;
|
||||||
|
/**
|
||||||
|
* The presentation control creator.
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
private IInformationControlCreator fPresenterControlCreator;
|
||||||
|
|
||||||
public AbstractAnnotationHover(boolean allAnnotations) {
|
public AbstractAnnotationHover(boolean allAnnotations) {
|
||||||
fAllAnnotations= allAnnotations;
|
fAllAnnotations= allAnnotations;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Formats a message as HTML text.
|
* @see org.eclipse.jface.text.ITextHover#getHoverInfo(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
|
||||||
*/
|
|
||||||
private String formatMessage(String message) {
|
|
||||||
StringBuffer buffer= new StringBuffer();
|
|
||||||
HTMLPrinter.addPageProlog(buffer);
|
|
||||||
HTMLPrinter.addParagraph(buffer, HTMLPrinter.convertToHTMLContent(message));
|
|
||||||
HTMLPrinter.addPageEpilog(buffer);
|
|
||||||
return buffer.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* @see ITextHover#getHoverInfo(ITextViewer, IRegion)
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
if (getEditor() == null)
|
/*
|
||||||
|
* @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover#getHoverInfo2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
|
||||||
|
IPath path;
|
||||||
|
IAnnotationModel model;
|
||||||
|
if (textViewer instanceof ISourceViewer) {
|
||||||
|
path= null;
|
||||||
|
model= ((ISourceViewer)textViewer).getAnnotationModel();
|
||||||
|
} else {
|
||||||
|
// Get annotation model from file buffer manager
|
||||||
|
path= getEditorInputPath();
|
||||||
|
model= getAnnotationModel(path);
|
||||||
|
}
|
||||||
|
if (model == null)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
IDocumentProvider provider= CUIPlugin.getDefault().getDocumentProvider();
|
try {
|
||||||
IAnnotationModel model= provider.getAnnotationModel(getEditor().getEditorInput());
|
@SuppressWarnings("unchecked")
|
||||||
|
Iterator parent;
|
||||||
|
if (model instanceof IAnnotationModelExtension2)
|
||||||
|
parent= ((IAnnotationModelExtension2) model).getAnnotationIterator(hoverRegion.getOffset(), hoverRegion.getLength(), true, true);
|
||||||
|
else
|
||||||
|
parent= model.getAnnotationIterator();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Iterator<Annotation> e= new CAnnotationIterator(parent, fAllAnnotations);
|
||||||
|
|
||||||
if (model != null) {
|
|
||||||
Iterator<Annotation> e= new CAnnotationIterator(model, true, fAllAnnotations);
|
|
||||||
int layer= -1;
|
int layer= -1;
|
||||||
String message= null;
|
Annotation annotation= null;
|
||||||
|
Position position= null;
|
||||||
while (e.hasNext()) {
|
while (e.hasNext()) {
|
||||||
Annotation a= e.next();
|
Annotation a= e.next();
|
||||||
|
|
||||||
|
@ -87,27 +683,95 @@ public class AbstractAnnotationHover extends AbstractCEditorTextHover {
|
||||||
if (l > layer && p != null && p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) {
|
if (l > layer && p != null && p.overlapsWith(hoverRegion.getOffset(), hoverRegion.getLength())) {
|
||||||
String msg= a.getText();
|
String msg= a.getText();
|
||||||
if (msg != null && msg.trim().length() > 0) {
|
if (msg != null && msg.trim().length() > 0) {
|
||||||
message= msg;
|
|
||||||
layer= l;
|
layer= l;
|
||||||
|
annotation= a;
|
||||||
|
position= p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (layer > -1)
|
if (layer > -1)
|
||||||
return formatMessage(message);
|
return createAnnotationInfo(annotation, position, textViewer);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
if (path != null) {
|
||||||
|
ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
|
||||||
|
manager.disconnect(path, LocationKind.NORMALIZE, null);
|
||||||
|
}
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CUIPlugin.log(e.getStatus());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected AnnotationInfo createAnnotationInfo(Annotation annotation, Position position, ITextViewer textViewer) {
|
||||||
|
return new AnnotationInfo(annotation, position, textViewer);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see IJavaEditorTextHover#setEditor(IEditorPart)
|
* @see ITextHoverExtension#getHoverControlCreator()
|
||||||
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void setEditor(IEditorPart editor) {
|
public IInformationControlCreator getHoverControlCreator() {
|
||||||
if (editor instanceof CEditor)
|
if (fHoverControlCreator == null)
|
||||||
super.setEditor(editor);
|
fHoverControlCreator= new HoverControlCreator(getInformationPresenterControlCreator());
|
||||||
else
|
return fHoverControlCreator;
|
||||||
super.setEditor(null);
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.ITextHoverExtension2#getInformationPresenterControlCreator()
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public IInformationControlCreator getInformationPresenterControlCreator() {
|
||||||
|
if (fPresenterControlCreator == null)
|
||||||
|
fPresenterControlCreator= new PresenterControlCreator();
|
||||||
|
return fPresenterControlCreator;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPath getEditorInputPath() {
|
||||||
|
if (getEditor() == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
IEditorInput input= getEditor().getEditorInput();
|
||||||
|
if (input instanceof IStorageEditorInput) {
|
||||||
|
try {
|
||||||
|
return ((IStorageEditorInput)input).getStorage().getFullPath();
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CUIPlugin.log(e.getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IAnnotationModel getAnnotationModel(IPath path) {
|
||||||
|
if (path == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
ITextFileBufferManager manager= FileBuffers.getTextFileBufferManager();
|
||||||
|
try {
|
||||||
|
manager.connect(path, LocationKind.NORMALIZE, null);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CUIPlugin.log(e.getStatus());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
IAnnotationModel model= null;
|
||||||
|
try {
|
||||||
|
model= manager.getTextFileBuffer(path, LocationKind.NORMALIZE).getAnnotationModel();
|
||||||
|
return model;
|
||||||
|
} finally {
|
||||||
|
if (model == null) {
|
||||||
|
try {
|
||||||
|
manager.disconnect(path, LocationKind.NORMALIZE, null);
|
||||||
|
} catch (CoreException e) {
|
||||||
|
CUIPlugin.log(e.getStatus());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -116,11 +780,9 @@ public class AbstractAnnotationHover extends AbstractCEditorTextHover {
|
||||||
* @param annotation the annotation
|
* @param annotation the annotation
|
||||||
* @return the annotation preference or <code>null</code> if none
|
* @return the annotation preference or <code>null</code> if none
|
||||||
*/
|
*/
|
||||||
private AnnotationPreference getAnnotationPreference(Annotation annotation) {
|
private static AnnotationPreference getAnnotationPreference(Annotation annotation) {
|
||||||
|
|
||||||
if (annotation.isMarkedDeleted())
|
if (annotation.isMarkedDeleted())
|
||||||
return null;
|
return null;
|
||||||
return EditorsUI.getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
|
return EditorsUI.getAnnotationPreferenceLookup().getAnnotationPreference(annotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* QNX Software Systems - Initial API and implementation
|
* QNX Software Systems - Initial API and implementation
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text.c.hover;
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
|
@ -21,6 +22,10 @@ public final class CHoverMessages extends NLS {
|
||||||
// Do not instantiate
|
// Do not instantiate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String AbstractAnnotationHover_action_configureAnnotationPreferences;
|
||||||
|
public static String AbstractAnnotationHover_message_singleQuickFix;
|
||||||
|
public static String AbstractAnnotationHover_message_multipleQuickFix;
|
||||||
|
|
||||||
public static String CMacroExpansionControl_statusText;
|
public static String CMacroExpansionControl_statusText;
|
||||||
|
|
||||||
public static String CMacroExpansionControl_title_expansion;
|
public static String CMacroExpansionControl_title_expansion;
|
||||||
|
|
|
@ -8,8 +8,13 @@
|
||||||
# Contributors:
|
# Contributors:
|
||||||
# IBM Corporation - initial API and implementation
|
# IBM Corporation - initial API and implementation
|
||||||
# Anton Leherbauer (Wind River Systems)
|
# Anton Leherbauer (Wind River Systems)
|
||||||
|
# Sergey Prigogin (Google)
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
AbstractAnnotationHover_action_configureAnnotationPreferences= Configure Annotation Preferences
|
||||||
|
AbstractAnnotationHover_message_singleQuickFix= 1 quick fix available:
|
||||||
|
AbstractAnnotationHover_message_multipleQuickFix= {0} quick fixes available:
|
||||||
|
|
||||||
CMacroExpansionControl_statusText=Press {0} or {1} to step through macro expansion
|
CMacroExpansionControl_statusText=Press {0} or {1} to step through macro expansion
|
||||||
CMacroExpansionControl_title_expansion=Expansion \#{0} of {1}
|
CMacroExpansionControl_title_expansion=Expansion \#{0} of {1}
|
||||||
CMacroExpansionControl_title_fullyExpanded=Fully Expanded
|
CMacroExpansionControl_title_fullyExpanded=Fully Expanded
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.text.c.hover;
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
|
@ -25,13 +26,11 @@ import org.eclipse.ui.IPartListener;
|
||||||
import org.eclipse.ui.IWorkbenchPart;
|
import org.eclipse.ui.IWorkbenchPart;
|
||||||
import org.eclipse.ui.IWorkbenchWindow;
|
import org.eclipse.ui.IWorkbenchWindow;
|
||||||
|
|
||||||
import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides information for the current word under the cursor based on the documentation hover.
|
* Provides information for the current word under the cursor based on the documentation hover
|
||||||
|
* and spelling correction hover.
|
||||||
*
|
*
|
||||||
* @see CDocHover
|
* @see CTypeHover
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
public class CInformationProvider implements IInformationProvider, IInformationProviderExtension2 {
|
public class CInformationProvider implements IInformationProvider, IInformationProviderExtension2 {
|
||||||
|
@ -70,23 +69,21 @@ public class CInformationProvider implements IInformationProvider, IInformationP
|
||||||
protected IEditorPart fEditor;
|
protected IEditorPart fEditor;
|
||||||
protected IPartListener fPartListener;
|
protected IPartListener fPartListener;
|
||||||
|
|
||||||
protected ICEditorTextHover fImplementation;
|
protected CTypeHover fImplementation;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default presentation control creator.
|
* The default presentation control creator.
|
||||||
*/
|
*/
|
||||||
private IInformationControlCreator fPresenterControlCreator;
|
private IInformationControlCreator fPresenterControlCreator;
|
||||||
|
|
||||||
|
|
||||||
public CInformationProvider(IEditorPart editor) {
|
public CInformationProvider(IEditorPart editor) {
|
||||||
|
|
||||||
fEditor= editor;
|
fEditor= editor;
|
||||||
|
|
||||||
if (fEditor != null) {
|
if (fEditor != null) {
|
||||||
fPartListener= new EditorWatcher();
|
fPartListener= new EditorWatcher();
|
||||||
IWorkbenchWindow window= fEditor.getSite().getWorkbenchWindow();
|
IWorkbenchWindow window= fEditor.getSite().getWorkbenchWindow();
|
||||||
window.getPartService().addPartListener(fPartListener);
|
window.getPartService().addPartListener(fPartListener);
|
||||||
fImplementation= new CDocHover();
|
fImplementation= new CTypeHover();
|
||||||
fImplementation.setEditor(fEditor);
|
fImplementation.setEditor(fEditor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -104,7 +101,6 @@ public class CInformationProvider implements IInformationProvider, IInformationP
|
||||||
/*
|
/*
|
||||||
* @see IInformationProvider#getInformation(ITextViewer, IRegion)
|
* @see IInformationProvider#getInformation(ITextViewer, IRegion)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public String getInformation(ITextViewer textViewer, IRegion subject) {
|
public String getInformation(ITextViewer textViewer, IRegion subject) {
|
||||||
if (fImplementation != null) {
|
if (fImplementation != null) {
|
||||||
String s= fImplementation.getHoverInfo(textViewer, subject);
|
String s= fImplementation.getHoverInfo(textViewer, subject);
|
||||||
|
@ -115,6 +111,15 @@ public class CInformationProvider implements IInformationProvider, IInformationP
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.information.IInformationProviderExtension#getInformation2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
|
||||||
|
*/
|
||||||
|
public Object getInformation2(ITextViewer textViewer, IRegion subject) {
|
||||||
|
if (fImplementation == null)
|
||||||
|
return null;
|
||||||
|
return fImplementation.getHoverInfo2(textViewer, subject);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @see IInformationProviderExtension2#getInformationPresenterControlCreator()
|
* @see IInformationProviderExtension2#getInformationPresenterControlCreator()
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2008 IBM Corporation 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:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
|
import org.eclipse.jface.text.IInformationControlCreator;
|
||||||
|
import org.eclipse.jface.text.IRegion;
|
||||||
|
import org.eclipse.jface.text.ITextHoverExtension;
|
||||||
|
import org.eclipse.jface.text.ITextHoverExtension2;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
|
||||||
|
import org.eclipse.ui.IEditorPart;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Aggregator of problem and doc hovers.
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
public class CTypeHover implements ICEditorTextHover, ITextHoverExtension, ITextHoverExtension2 {
|
||||||
|
private AbstractCEditorTextHover fProblemHover;
|
||||||
|
private AbstractCEditorTextHover fCDocHover;
|
||||||
|
|
||||||
|
private AbstractCEditorTextHover fCurrentHover;
|
||||||
|
|
||||||
|
public CTypeHover() {
|
||||||
|
fProblemHover= new ProblemHover();
|
||||||
|
fCDocHover= new CDocHover();
|
||||||
|
fCurrentHover= null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see ICEditorTextHover#setEditor(IEditorPart)
|
||||||
|
*/
|
||||||
|
public void setEditor(IEditorPart editor) {
|
||||||
|
fProblemHover.setEditor(editor);
|
||||||
|
fCDocHover.setEditor(editor);
|
||||||
|
fCurrentHover= null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see ITextHover#getHoverRegion(ITextViewer, int)
|
||||||
|
*/
|
||||||
|
public IRegion getHoverRegion(ITextViewer textViewer, int offset) {
|
||||||
|
return fCDocHover.getHoverRegion(textViewer, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see ITextHover#getHoverInfo(ITextViewer, IRegion)
|
||||||
|
*/
|
||||||
|
public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) {
|
||||||
|
return String.valueOf(getHoverInfo2(textViewer, hoverRegion));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.ITextHoverExtension2#getHoverInfo2(org.eclipse.jface.text.ITextViewer, org.eclipse.jface.text.IRegion)
|
||||||
|
*/
|
||||||
|
public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) {
|
||||||
|
Object hoverInfo= fProblemHover.getHoverInfo2(textViewer, hoverRegion);
|
||||||
|
if (hoverInfo != null) {
|
||||||
|
fCurrentHover= fProblemHover;
|
||||||
|
return hoverInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
fCurrentHover= fCDocHover;
|
||||||
|
return fCDocHover.getHoverInfo2(textViewer, hoverRegion);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.ITextHoverExtension#getHoverControlCreator()
|
||||||
|
*/
|
||||||
|
public IInformationControlCreator getHoverControlCreator() {
|
||||||
|
return fCurrentHover == null ? null : fCurrentHover.getHoverControlCreator();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.jface.text.information.IInformationProviderExtension2#getInformationPresenterControlCreator()
|
||||||
|
*/
|
||||||
|
public IInformationControlCreator getInformationPresenterControlCreator() {
|
||||||
|
return fCurrentHover == null ? null : fCurrentHover.getInformationPresenterControlCreator();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2000, 2008 IBM Corporation 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:
|
||||||
|
* IBM Corporation - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.text.c.hover;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.core.resources.IMarker;
|
||||||
|
import org.eclipse.jface.text.ITextViewer;
|
||||||
|
import org.eclipse.jface.text.Position;
|
||||||
|
import org.eclipse.jface.text.contentassist.ICompletionProposal;
|
||||||
|
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.IEditorInput;
|
||||||
|
import org.eclipse.ui.texteditor.MarkerAnnotation;
|
||||||
|
import org.eclipse.ui.texteditor.spelling.SpellingAnnotation;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.model.CModelException;
|
||||||
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.text.ICCompletionProposal;
|
||||||
|
import org.eclipse.cdt.ui.text.IProblemLocation;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.ui.editor.ICAnnotation;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProposalComparator;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.correction.CCorrectionProcessor;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.correction.CorrectionContext;
|
||||||
|
import org.eclipse.cdt.internal.ui.text.correction.ProblemLocation;
|
||||||
|
import org.eclipse.cdt.internal.ui.util.EditorUtility;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This annotation hover shows the description of the
|
||||||
|
* selected java annotation.
|
||||||
|
*
|
||||||
|
* XXX: Currently this problem hover only works for spelling problems.
|
||||||
|
* see: https://bugs.eclipse.org/bugs/show_bug.cgi?id=62081
|
||||||
|
*
|
||||||
|
* @since 5.0
|
||||||
|
*/
|
||||||
|
public class ProblemHover extends AbstractAnnotationHover {
|
||||||
|
|
||||||
|
protected static class ProblemInfo extends AnnotationInfo {
|
||||||
|
private static final ICompletionProposal[] NO_PROPOSALS= new ICompletionProposal[0];
|
||||||
|
|
||||||
|
public ProblemInfo(Annotation annotation, Position position, ITextViewer textViewer) {
|
||||||
|
super(annotation, position, textViewer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @see org.eclipse.cdt.internal.ui.text.java.hover.AbstractAnnotationHover.AnnotationInfo#getCompletionProposals()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public ICompletionProposal[] getCompletionProposals() {
|
||||||
|
if (annotation instanceof ICAnnotation) {
|
||||||
|
return getCAnnotationFixes((ICAnnotation) annotation);
|
||||||
|
} else if (annotation instanceof MarkerAnnotation) {
|
||||||
|
return getMarkerAnnotationFixes((MarkerAnnotation) annotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NO_PROPOSALS;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICompletionProposal[] getCAnnotationFixes(ICAnnotation cAnnotation) {
|
||||||
|
ProblemLocation location= new ProblemLocation(position.getOffset(), position.getLength(), cAnnotation);
|
||||||
|
ITranslationUnit tu= cAnnotation.getTranslationUnit();
|
||||||
|
|
||||||
|
ISourceViewer sourceViewer= null;
|
||||||
|
if (viewer instanceof ISourceViewer)
|
||||||
|
sourceViewer= (ISourceViewer) viewer;
|
||||||
|
|
||||||
|
CorrectionContext context= new CorrectionContext(tu, sourceViewer, location.getOffset(), location.getLength());
|
||||||
|
if (!SpellingAnnotation.TYPE.equals(cAnnotation.getType()))
|
||||||
|
return NO_PROPOSALS;
|
||||||
|
|
||||||
|
List<ICCompletionProposal> proposals= new ArrayList<ICCompletionProposal>();
|
||||||
|
CCorrectionProcessor.collectCorrections(context, new IProblemLocation[] { location }, proposals);
|
||||||
|
Collections.sort(proposals, new CCompletionProposalComparator());
|
||||||
|
|
||||||
|
return proposals.toArray(new ICompletionProposal[proposals.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ICompletionProposal[] getMarkerAnnotationFixes(MarkerAnnotation markerAnnotation) {
|
||||||
|
if (markerAnnotation.isQuickFixableStateSet() && !markerAnnotation.isQuickFixable())
|
||||||
|
return NO_PROPOSALS;
|
||||||
|
|
||||||
|
IMarker marker= markerAnnotation.getMarker();
|
||||||
|
|
||||||
|
IEditorInput input = null;
|
||||||
|
try {
|
||||||
|
input = EditorUtility.getEditorInput(marker.getResource());
|
||||||
|
} catch (CModelException e) {
|
||||||
|
}
|
||||||
|
if (input == null)
|
||||||
|
return NO_PROPOSALS;
|
||||||
|
|
||||||
|
ITranslationUnit tu= getTranslationUnit(input);
|
||||||
|
if (tu == null)
|
||||||
|
return NO_PROPOSALS;
|
||||||
|
|
||||||
|
IAnnotationModel model= CUIPlugin.getDefault().getDocumentProvider().getAnnotationModel(input);
|
||||||
|
if (model == null)
|
||||||
|
return NO_PROPOSALS;
|
||||||
|
|
||||||
|
ISourceViewer sourceViewer= null;
|
||||||
|
if (viewer instanceof ISourceViewer)
|
||||||
|
sourceViewer= (ISourceViewer) viewer;
|
||||||
|
|
||||||
|
CorrectionContext context= new CorrectionContext(tu, sourceViewer, position.getOffset(), position.getLength());
|
||||||
|
|
||||||
|
List<ICCompletionProposal> proposals= new ArrayList<ICCompletionProposal>();
|
||||||
|
CCorrectionProcessor.collectProposals(context, model, new Annotation[] { markerAnnotation }, true, false, proposals);
|
||||||
|
|
||||||
|
return proposals.toArray(new ICompletionProposal[proposals.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ITranslationUnit getTranslationUnit(IEditorInput input) {
|
||||||
|
return CUIPlugin.getDefault().getWorkingCopyManager().getWorkingCopy(input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProblemHover() {
|
||||||
|
super(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AnnotationInfo createAnnotationInfo(Annotation annotation, Position position, ITextViewer textViewer) {
|
||||||
|
return new ProblemInfo(annotation, position, textViewer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
* Anton Leherbauer (Wind River Systems)
|
* Anton Leherbauer (Wind River Systems)
|
||||||
* Jeff Johnston (Red Hat Inc.)
|
* Jeff Johnston (Red Hat Inc.)
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui;
|
package org.eclipse.cdt.ui;
|
||||||
|
|
||||||
|
@ -760,7 +761,7 @@ public class CUIPlugin extends AbstractUIPlugin {
|
||||||
fCEditorTextHoverDescriptors[first]= hoverDescriptor;
|
fCEditorTextHoverDescriptors[first]= hoverDescriptor;
|
||||||
|
|
||||||
// update annotation hover index if needed
|
// update annotation hover index if needed
|
||||||
if (annotationHoverIndex > first && annotationHoverIndex < problemHoverIndex)
|
if (annotationHoverIndex >= first && annotationHoverIndex < problemHoverIndex)
|
||||||
annotationHoverIndex++;
|
annotationHoverIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue