diff options
author | Mickael Istria | 2017-05-18 12:47:18 +0000 |
---|---|---|
committer | Mickael Istria | 2017-09-06 20:32:56 +0000 |
commit | 55c3acdef4f74ecddae3e3f6c89fdb691c2c64ad (patch) | |
tree | 42a38a3a5f0fc5c634a8797b753f4f380566569f /org.eclipse.ui.genericeditor/src/org | |
parent | b3ee795c0b366f5254afb46c633640b78bb06a0a (diff) | |
download | eclipse.platform.text-55c3acdef4f74ecddae3e3f6c89fdb691c2c64ad.tar.gz eclipse.platform.text-55c3acdef4f74ecddae3e3f6c89fdb691c2c64ad.tar.xz eclipse.platform.text-55c3acdef4f74ecddae3e3f6c89fdb691c2c64ad.zip |
Bug 513321 - Aggregate mutliple hover sources
Change-Id: I3cc1fe523f1db9f55095e587ea05a88b1f89dfaa
Signed-off-by: Mickael Istria <mistria@redhat.com>
Diffstat (limited to 'org.eclipse.ui.genericeditor/src/org')
10 files changed, 428 insertions, 117 deletions
diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeTextHover.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeTextHover.java deleted file mode 100644 index 89944fb780b..00000000000 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/CompositeTextHover.java +++ /dev/null @@ -1,90 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2016-2017 Red Hat Inc. 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: - * - Mickael Istria (Red Hat Inc.) - *******************************************************************************/ -package org.eclipse.ui.internal.genericeditor; - -import java.util.List; - -import org.eclipse.core.runtime.Assert; -import org.eclipse.jface.text.IInformationControlCreator; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextHover; -import org.eclipse.jface.text.ITextHoverExtension; -import org.eclipse.jface.text.ITextHoverExtension2; -import org.eclipse.jface.text.ITextViewer; - -/** - * A text hover that delegates its operations to children - * provided in constructor and returns the first interesting result. - * - * @since 1.0 - */ -public class CompositeTextHover implements ITextHover, ITextHoverExtension, ITextHoverExtension2 { - - private List<ITextHover> hoversToConsider; - private ITextHover currentHover = null; - - public CompositeTextHover(List<ITextHover> hoversToConsider) { - Assert.isNotNull(hoversToConsider); - this.hoversToConsider = hoversToConsider; - } - - @Override - public Object getHoverInfo2(ITextViewer textViewer, IRegion hoverRegion) { - for (ITextHover hover : this.hoversToConsider) { - Object res = null; - if (hover instanceof ITextHoverExtension2) { - res = ((ITextHoverExtension2)hover).getHoverInfo2(textViewer, hoverRegion); - } else { - res = hover.getHoverInfo(textViewer, hoverRegion); - } - if (res != null) { - currentHover = hover; - return res; - } - } - return null; - } - - @Override - public IInformationControlCreator getHoverControlCreator() { - ITextHover hover = this.currentHover; - if (hover != null) { - if (hover instanceof ITextHoverExtension) { - return ((ITextHoverExtension)hover).getHoverControlCreator(); - } - } - return null; - } - - @Override - public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { - for (ITextHover hover : this.hoversToConsider) { - String res = hover.getHoverInfo(textViewer, hoverRegion); - if (res != null) { - currentHover = hover; - return res; - } - } - return null; - } - - @Override - public IRegion getHoverRegion(ITextViewer textViewer, int offset) { - for (ITextHover hover : this.hoversToConsider) { - IRegion res = hover.getHoverRegion(textViewer, offset); - if (res != null) { - return res; - } - } - return null; - } - -} diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java index ab43608f518..4e0461fe0b1 100644 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/ExtensionBasedTextViewerConfiguration.java @@ -42,6 +42,7 @@ import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IPropertyListener; import org.eclipse.ui.editors.text.TextSourceViewerConfiguration; import org.eclipse.ui.internal.editors.text.EditorsPlugin; +import org.eclipse.ui.internal.genericeditor.hover.CompositeTextHover; import org.eclipse.ui.internal.genericeditor.markers.MarkerResoltionQuickAssistProcessor; import org.eclipse.ui.texteditor.ITextEditor; import org.eclipse.ui.texteditor.spelling.SpellingCorrectionProcessor; @@ -99,8 +100,14 @@ public final class ExtensionBasedTextViewerConfiguration extends TextSourceViewe @Override public ITextHover getTextHover(ISourceViewer sourceViewer, String contentType) { - TextHoverRegistry registry= GenericEditorPlugin.getDefault().getHoverRegistry(); - return registry.getAvailableHover(sourceViewer, getContentTypes()); + List<ITextHover> hovers = GenericEditorPlugin.getDefault().getHoverRegistry().getAvailableHovers(sourceViewer, getContentTypes()); + if (hovers == null || hovers.isEmpty()) { + return null; + } else if (hovers.size() == 1) { + return hovers.get(0); + } else { + return new CompositeTextHover(hovers); + } } @Override diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorPlugin.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorPlugin.java index 8bdf7a4cf52..cbceac42bcc 100644 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorPlugin.java +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/GenericEditorPlugin.java @@ -14,6 +14,7 @@ package org.eclipse.ui.internal.genericeditor; import org.eclipse.jface.text.ITextHover; import org.eclipse.jface.text.contentassist.IContentAssistProcessor; import org.eclipse.jface.text.presentation.IPresentationReconciler; +import org.eclipse.ui.internal.genericeditor.hover.TextHoverRegistry; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.osgi.framework.BundleContext; diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeInformationControl.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeInformationControl.java new file mode 100644 index 00000000000..a63088f2fb4 --- /dev/null +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeInformationControl.java @@ -0,0 +1,156 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat Inc. 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: + * - Mickael Istria (Red Hat Inc.) + *******************************************************************************/ +package org.eclipse.ui.internal.genericeditor.hover; + +import java.util.Arrays; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; +import org.eclipse.jface.text.AbstractInformationControl; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IInformationControlExtension; +import org.eclipse.jface.text.IInformationControlExtension2; +import org.eclipse.jface.text.IInformationControlExtension5; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Control; +import org.eclipse.swt.widgets.Shell; +import org.eclipse.ui.internal.genericeditor.GenericEditorPlugin; + +public class CompositeInformationControl extends AbstractInformationControl implements IInformationControlExtension2 { + + final LinkedHashMap<ITextHover, IInformationControlCreator> creators; + LinkedHashMap<ITextHover, IInformationControl> controls; + + public CompositeInformationControl(Shell parentShell, LinkedHashMap<ITextHover, IInformationControlCreator> creators) { + super(parentShell, true); // TODO check best constructor + Assert.isLegal(creators.size() > 1, "Do not compose a unique hover"); //$NON-NLS-1$ + this.creators = creators; + create(); + } + + @Override + public boolean hasContents() { + for (IInformationControl control : controls.values()) { + if (control instanceof IInformationControlExtension) { + if (((IInformationControlExtension)control).hasContents()) { + return true; + } + } else { + return true; + } + } + return false; + } + + @Override + public void setInput(Object input) { + @SuppressWarnings("unchecked") + Map<ITextHover, Object> inputs = (Map<ITextHover, Object>)input; + for (Entry<ITextHover, Object> entry : inputs.entrySet()) { + IInformationControl informationControl = controls.get(entry.getKey()); + if (informationControl != null) { + if (informationControl instanceof IInformationControlExtension2) { + ((IInformationControlExtension2)informationControl).setInput(entry.getValue()); + } else { + informationControl.setInformation(entry.getValue().toString()); + } + } + } + } + + @Override + public void createContent(Composite parent) { + this.controls = new LinkedHashMap<>(); // TODO maybe use canReuse or canReplace + GridLayout layout = new GridLayout(1, false); + parent.setLayout(layout); + boolean firstControl = true; + for (Entry<ITextHover, IInformationControlCreator> hoverControlCreator : this.creators.entrySet()) { + IInformationControl informationControl = hoverControlCreator.getValue().createInformationControl(parent.getShell()); + if (informationControl instanceof AbstractInformationControl) { + List<Control> children = Arrays.asList(((AbstractInformationControl)informationControl).getShell().getChildren()); + children.remove(parent); + if (children.size() == 0 ) { + continue; + } + for (Control control : children) { + control.setParent(parent); + control.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); + } + if (!firstControl) { + ((GridData)children.get(0).getLayoutData()).verticalIndent = 15; + } + controls.put(hoverControlCreator.getKey(), informationControl); + firstControl = false; + } else { + GenericEditorPlugin.getDefault().getLog().log(new Status(IStatus.WARNING, GenericEditorPlugin.BUNDLE_ID, + "Only text hovers producing an AbstractInformationControl can be aggregated; got a " + informationControl.getClass().getSimpleName())); //$NON-NLS-1$ + informationControl.dispose(); + } + } + } + + @Override + public void dispose() { + controls.values().forEach(IInformationControl::dispose); + controls.clear(); + super.dispose(); + } + + @Override + public IInformationControlCreator getInformationPresenterControlCreator() { + if (controls.isEmpty()) { + return null; + } else if (controls.size() == 1) { + IInformationControl control = controls.values().iterator().next(); + if (control instanceof IInformationControlExtension5) { + return ((IInformationControlExtension5)control).getInformationPresenterControlCreator(); + } + } else { + LinkedHashMap<ITextHover, IInformationControlCreator> presenterCreators = new LinkedHashMap<>(); + boolean allNull = true; + for (Entry<ITextHover, IInformationControl> hover : this.controls.entrySet()) { + IInformationControlCreator creator = null; + if (hover.getValue() instanceof IInformationControlExtension5) + creator = ((IInformationControlExtension5)hover.getValue()).getInformationPresenterControlCreator(); + if (creator == null) { + creator = this.creators.get(hover.getKey()); + } else { + allNull = false; + } + if (creator != null) { + presenterCreators.put(hover.getKey(), creator); + } + } + if (allNull) { + return null; + } + return new CompositeInformationControlCreator(presenterCreators); + } + return null; + } + + @Override + public Point computeSizeHint() { + return getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true); + } + +} diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeInformationControlCreator.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeInformationControlCreator.java new file mode 100644 index 00000000000..ddeee67056c --- /dev/null +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeInformationControlCreator.java @@ -0,0 +1,120 @@ +/******************************************************************************* + * Copyright (c) 2017 Red Hat Inc. 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: + * - Mickael Istria (Red Hat Inc.) + *******************************************************************************/ +package org.eclipse.ui.internal.genericeditor.hover; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map.Entry; + +import org.eclipse.jface.text.AbstractReusableInformationControlCreator; +import org.eclipse.jface.text.DefaultInformationControl; +import org.eclipse.jface.text.IInformationControl; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IInformationControlCreatorExtension; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextHoverExtension; +import org.eclipse.swt.widgets.Shell; + +public class CompositeInformationControlCreator + implements IInformationControlCreator, IInformationControlCreatorExtension { + + private final LinkedHashMap<ITextHover, IInformationControlCreator> creators; + + public CompositeInformationControlCreator(List<ITextHover> hovers) { + this.creators = new LinkedHashMap<>(); + for (ITextHover hover : hovers) { + creators.put(hover, getInformationControlCreator(hover)); + } + } + + public CompositeInformationControlCreator(LinkedHashMap<ITextHover, IInformationControlCreator> creators) { + this.creators = creators; + } + + private static IInformationControlCreator getInformationControlCreator(ITextHover hover) { + IInformationControlCreator controlCreator = null; + if (hover instanceof ITextHoverExtension) { + controlCreator = ((ITextHoverExtension)hover).getHoverControlCreator(); + } + if (controlCreator == null) { + controlCreator = new AbstractReusableInformationControlCreator() { + @Override + protected IInformationControl doCreateInformationControl(Shell parent) { + return new DefaultInformationControl(parent, true); + } + }; + } + return controlCreator; + } + + + @Override + public boolean canReuse(IInformationControl control) { + if (control.getClass() != CompositeInformationControl.class) { + return false; + } + CompositeInformationControl other = (CompositeInformationControl)control; + if (!other.creators.equals(this.creators)) { + return false; + } + Iterator<Entry<ITextHover, IInformationControlCreator>> thisIterator = this.creators.entrySet().iterator(); + Iterator<Entry<ITextHover, IInformationControl>> otherIterator = other.controls.entrySet().iterator(); + do { + Entry<ITextHover, IInformationControlCreator> thisEntry = thisIterator.next(); + Entry<ITextHover, IInformationControl> otherEntry = otherIterator.next(); + if (!thisEntry.getKey().equals(otherEntry.getKey())) { + return false; + } + if (!(thisEntry.getValue() instanceof IInformationControlCreatorExtension)) { + return false; + } + if (!((IInformationControlCreatorExtension)thisEntry.getValue()).canReuse(otherEntry.getValue())) { + return false; + } + } while (thisIterator.hasNext()); + return true; + } + + @Override + public boolean canReplace(IInformationControlCreator creator) { + if (creator.getClass() != this.getClass()) { + return false; + } + CompositeInformationControlCreator other = (CompositeInformationControlCreator)creator; + if (other.creators.size() != this.creators.size()) { + return false; + } + Iterator<Entry<ITextHover, IInformationControlCreator>> thisIterator = this.creators.entrySet().iterator(); + Iterator<Entry<ITextHover, IInformationControlCreator>> otherIterator = other.creators.entrySet().iterator(); + do { + Entry<ITextHover, IInformationControlCreator> thisEntry = thisIterator.next(); + Entry<ITextHover, IInformationControlCreator> otherEntry = otherIterator.next(); + if (!thisEntry.getKey().equals(otherEntry.getKey())) { + return false; + } + if (!(thisEntry.getValue() instanceof IInformationControlCreatorExtension)) { + return false; + } + if (!((IInformationControlCreatorExtension)thisEntry.getValue()).canReplace(otherEntry.getValue())) { + return false; + } + } while (thisIterator.hasNext()); + return true; + } + + + @Override + public IInformationControl createInformationControl(Shell parent) { + return new CompositeInformationControl(parent, this.creators); + } + +} diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeTextHover.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeTextHover.java new file mode 100644 index 00000000000..82e2cb271a9 --- /dev/null +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/CompositeTextHover.java @@ -0,0 +1,113 @@ +/******************************************************************************* + * Copyright (c) 2016-2017 Red Hat Inc. 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: + * - Mickael Istria (Red Hat Inc.) + *******************************************************************************/ +package org.eclipse.ui.internal.genericeditor.hover; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; + +import org.eclipse.core.runtime.Assert; +import org.eclipse.jface.text.IInformationControlCreator; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextHover; +import org.eclipse.jface.text.ITextHoverExtension; +import org.eclipse.jface.text.ITextHoverExtension2; +import org.eclipse.jface.text.ITextViewer; +import org.eclipse.jface.text.Region; + +/** + * A text hover that delegates its operations to children + * provided in constructor and returns the first interesting result. + * + * @since 1.0 + */ +public class CompositeTextHover implements ITextHover, ITextHoverExtension, ITextHoverExtension2 { + + private final List<ITextHover> allHovers; + private LinkedHashMap<ITextHover, IRegion> regions = null; + private LinkedHashMap<ITextHover, Object> currentHovers = null; + + public CompositeTextHover(List<ITextHover> hoversToConsider) { + Assert.isNotNull(hoversToConsider); + Assert.isLegal(hoversToConsider.size() > 1, "Do not compose a single hover."); //$NON-NLS-1$ + this.allHovers = Collections.unmodifiableList(hoversToConsider); + } + + @Override + public Object getHoverInfo2(ITextViewer textViewer, IRegion requestRegion) { + this.currentHovers = new LinkedHashMap<>(); + for (ITextHover hover : this.allHovers) { + IRegion currentRegion = this.regions.get(hover); + if (currentRegion == null) { + continue; + } + Object res = hover instanceof ITextHoverExtension2 ? + ((ITextHoverExtension2)hover).getHoverInfo2(textViewer, currentRegion) : + hover.getHoverInfo(textViewer, currentRegion); + if (res != null) { + this.currentHovers.put(hover, res); + } + } + if (this.currentHovers.isEmpty()) { + return null; + } else if (this.currentHovers.size() == 1) { + return this.currentHovers.values().iterator().next(); + } else { + return this.currentHovers; + } + } + + @Override + public IInformationControlCreator getHoverControlCreator() { + if (this.currentHovers == null || this.currentHovers.isEmpty()) { + return null; + } else if (currentHovers.size() == 1) { + ITextHover hover = this.currentHovers.keySet().iterator().next(); + return hover instanceof ITextHoverExtension ? + ((ITextHoverExtension)hover).getHoverControlCreator(): + null; + } else { + return new CompositeInformationControlCreator(new ArrayList<>(this.currentHovers.keySet())); + } + } + + @Override + public String getHoverInfo(ITextViewer textViewer, IRegion hoverRegion) { + return this.allHovers.stream() + .map(hover -> hover.getHoverInfo(textViewer, this.regions.get(hover))) + .filter(Objects::nonNull) + .collect(Collectors.joining("\n")); //$NON-NLS-1$ + } + + @Override + public IRegion getHoverRegion(ITextViewer textViewer, int offset) { + this.regions = new LinkedHashMap<>(); + IRegion res = null; + for (ITextHover hover : this.allHovers) { + IRegion region = hover.getHoverRegion(textViewer, offset); + if (region != null) { + this.regions.put(hover, region); + if (res == null) { + res = region; + } else { + int startOffset = Math.max(res.getOffset(), region.getOffset()); + int endOffset = Math.min(res.getOffset() + res.getLength(), region.getOffset() + region.getLength()); + res = new Region(startOffset, endOffset - startOffset); + } + } + } + return res; + } + +} diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/OrderedExtensionComparator.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/OrderedExtensionComparator.java index 0ae0bbaca75..9cf32222951 100644 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/OrderedExtensionComparator.java +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/OrderedExtensionComparator.java @@ -8,7 +8,7 @@ * Contributors: * Mickael Istria (Red Hat Inc.) - initial implementation *******************************************************************************/ -package org.eclipse.ui.internal.genericeditor; +package org.eclipse.ui.internal.genericeditor.hover; import java.util.Collection; import java.util.Comparator; @@ -17,12 +17,12 @@ import java.util.function.Function; import java.util.stream.Collectors; import org.eclipse.core.runtime.Assert; -import org.eclipse.ui.internal.genericeditor.TextHoverRegistry.TextHoverExtension; +import org.eclipse.ui.internal.genericeditor.hover.TextHoverRegistry.TextHoverExtension; /** * A comparator that allows to sort elements according to their relative * placement (isBefore and isAfter) - * + *TODO: generalizing to any kind of extension supporting isBefore and isAfter */ class OrderedExtensionComparator implements Comparator<TextHoverExtension> { diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/TextHoverRegistry.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/TextHoverRegistry.java index 374c066eccc..f68bbf74deb 100644 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/TextHoverRegistry.java +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/hover/TextHoverRegistry.java @@ -8,7 +8,7 @@ * Contributors: * - Mickael Istria (Red Hat Inc.) *******************************************************************************/ -package org.eclipse.ui.internal.genericeditor; +package org.eclipse.ui.internal.genericeditor.hover; import java.util.HashMap; import java.util.HashSet; @@ -30,6 +30,8 @@ import org.eclipse.core.runtime.content.IContentType; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.text.ITextHover; import org.eclipse.jface.text.source.ISourceViewer; +import org.eclipse.ui.internal.genericeditor.GenericContentTypeRelatedExtension; +import org.eclipse.ui.internal.genericeditor.GenericEditorPlugin; /** * Text hover registry that manages the detectors @@ -90,19 +92,15 @@ public final class TextHoverRegistry { }, EXTENSION_POINT_ID); } - public ITextHover getAvailableHover(ISourceViewer sourceViewer, Set<IContentType> contentTypes) { + public List<ITextHover> getAvailableHovers(ISourceViewer sourceViewer, Set<IContentType> contentTypes) { if (this.outOfSync) { sync(); } - List<ITextHover> hoversToConsider = this.extensions.stream() + return this.extensions.stream() .filter(ext -> contentTypes.contains(ext.targetContentType)) // don't sort in the stream as the initial structure is already sorted by isAfter/isBefore .map(GenericContentTypeRelatedExtension<ITextHover>::createDelegate) .collect(Collectors.toList()); - if (!hoversToConsider.isEmpty()) { - return new CompositeTextHover(hoversToConsider); - } - return null; } private void sync() { diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/markers/MarkerHoverControlCreator.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/markers/MarkerHoverControlCreator.java index 8d81994f070..55e9d0bf663 100644 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/markers/MarkerHoverControlCreator.java +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/markers/MarkerHoverControlCreator.java @@ -17,19 +17,29 @@ import org.eclipse.swt.widgets.Shell; public class MarkerHoverControlCreator implements IInformationControlCreator, IInformationControlCreatorExtension { + private final boolean showAffordanceString; + + public MarkerHoverControlCreator() { + this(true); + } + + public MarkerHoverControlCreator(boolean showAffordanceString) { + this.showAffordanceString = showAffordanceString; + } + @Override public boolean canReuse(IInformationControl control) { - return false; + return control instanceof MarkerInformationControl; } @Override public boolean canReplace(IInformationControlCreator creator) { - return false; + return creator instanceof MarkerHoverControlCreator; } @Override public IInformationControl createInformationControl(Shell parent) { - return new MarkerInformationControl(parent,this); + return new MarkerInformationControl(parent, showAffordanceString); } } diff --git a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/markers/MarkerInformationControl.java b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/markers/MarkerInformationControl.java index 98bf713d93b..db93b4a9669 100644 --- a/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/markers/MarkerInformationControl.java +++ b/org.eclipse.ui.genericeditor/src/org/eclipse/ui/internal/genericeditor/markers/MarkerInformationControl.java @@ -11,6 +11,7 @@ package org.eclipse.ui.internal.genericeditor.markers; import java.util.Collection; +import java.util.LinkedHashMap; import java.util.List; import org.eclipse.core.resources.IMarker; @@ -19,7 +20,6 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.text.AbstractInformationControl; -import org.eclipse.jface.text.AbstractReusableInformationControlCreator; import org.eclipse.jface.text.IInformationControl; import org.eclipse.jface.text.IInformationControlCreator; import org.eclipse.jface.text.IInformationControlExtension; @@ -46,11 +46,10 @@ import org.eclipse.ui.ide.IDE.SharedImages; public class MarkerInformationControl extends AbstractInformationControl implements IInformationControl, IInformationControlExtension, IInformationControlExtension2 { - private IInformationControlCreator creator; + private final LinkedHashMap<IMarker, Composite> composites = new LinkedHashMap<>(); - public MarkerInformationControl(Shell parentShell, IInformationControlCreator creator) { - super(parentShell, EditorsUI.getTooltipAffordanceString()); - this.creator = creator; + public MarkerInformationControl(Shell parentShell, boolean showAffordanceString) { + super(parentShell, showAffordanceString ? EditorsUI.getTooltipAffordanceString() : null); create(); } @@ -84,9 +83,11 @@ public class MarkerInformationControl extends AbstractInformationControl impleme @SuppressWarnings("unchecked") @Override public void setInput(Object input) { + this.composites.values().forEach(Composite::dispose); this.markers = (List<IMarker>)input; for (IMarker marker : this.markers) { Composite markerComposite = new Composite(parent, SWT.NONE); + this.composites.put(marker, markerComposite); GridLayout gridLayout = new GridLayout(1, false); gridLayout.verticalSpacing = 0; markerComposite.setLayout(gridLayout); @@ -135,17 +136,12 @@ public class MarkerInformationControl extends AbstractInformationControl impleme }); } } - parent.pack(true); + parent.layout(true); } @Override public IInformationControlCreator getInformationPresenterControlCreator() { - return new AbstractReusableInformationControlCreator() { - @Override - protected IInformationControl doCreateInformationControl(Shell parent) { - return creator.createInformationControl(parent); - } - }; + return new MarkerHoverControlCreator(false); } @Override |