From 9b8671d00bf80f9b9ad10da7e301a1dec2885a51 Mon Sep 17 00:00:00 2001 From: Chris Recoskie Date: Fri, 7 Jul 2006 12:39:18 +0000 Subject: [PATCH] fix for 48208 (sticky hover help) --- core/org.eclipse.cdt.ui/plugin.properties | 3 + core/org.eclipse.cdt.ui/plugin.xml | 13 + .../cdt/internal/ui/ICHelpContextIds.java | 4 +- .../cdt/internal/ui/editor/CEditor.java | 364 ++++++++++++++++++ .../ui/editor/CEditorMessages.properties | 2 + .../editor/ICEditorActionDefinitionIds.java | 10 +- .../cdt/internal/ui/text/ICPartitions.java | 9 +- .../c/hover/AbstractCEditorTextHover.java | 34 +- .../eclipse/cdt/ui/PreferenceConstants.java | 20 +- 9 files changed, 446 insertions(+), 13 deletions(-) diff --git a/core/org.eclipse.cdt.ui/plugin.properties b/core/org.eclipse.cdt.ui/plugin.properties index af650c06a56..235d1bed7f0 100644 --- a/core/org.eclipse.cdt.ui/plugin.properties +++ b/core/org.eclipse.cdt.ui/plugin.properties @@ -114,6 +114,9 @@ ActionDefinition.format.description=Format Source Code ActionDefinition.gotoMatchingBracket.name= Go to Matching Bracket ActionDefinition.gotoMatchingBracket.description= Moves the cursor to the matching bracket +ActionDefinition.showTooltip.name= Show Tooltip Description +ActionDefinition.showTooltip.description= Shows the tooltip description for the element at the cursor + CEditor.name=C/C++ Editor CPluginPreferencePage.name=C/C++ diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index be15b0addd1..7fff7589b18 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -919,6 +919,13 @@ contextId="org.eclipse.cdt.ui.cEditorScope" schemeId="org.eclipse.ui.defaultAcceleratorConfiguration" sequence="M1+M2+J"/> + + + @@ -1039,6 +1046,12 @@ categoryId="org.eclipse.cdt.ui.category.source" id="org.eclipse.cdt.ui.edit.text.c.goto.matching.bracket"> + + true if successful, false + * otherwise + */ + private boolean makeTextHoverFocusable(ISourceViewer sourceViewer, + ITextHover textHover) { + Point hoverEventLocation = ((ITextViewerExtension2) sourceViewer) + .getHoverEventLocation(); + int offset = computeOffsetAtLocation(sourceViewer, + hoverEventLocation.x, hoverEventLocation.y); + if (offset == -1) + return false; + + try { + IRegion hoverRegion = textHover.getHoverRegion(sourceViewer, + offset); + if (hoverRegion == null) + return false; + + String hoverInfo = textHover.getHoverInfo(sourceViewer, + hoverRegion); + + IInformationControlCreator controlCreator = null; + if (textHover instanceof IInformationProviderExtension2) + controlCreator = ((IInformationProviderExtension2) textHover) + .getInformationPresenterControlCreator(); + + IInformationProvider informationProvider = new InformationProvider( + hoverRegion, hoverInfo, controlCreator); + + fInformationPresenter.setOffset(offset); + fInformationPresenter + .setAnchor(AbstractInformationControlManager.ANCHOR_BOTTOM); + fInformationPresenter.setMargins(6, 6); // default values from + // AbstractInformationControlManager + String contentType = TextUtilities.getContentType(sourceViewer + .getDocument(), ICPartitions.C_PARTITIONING, offset, + true); + fInformationPresenter.setInformationProvider( + informationProvider, contentType); + fInformationPresenter.showInformation(); + + return true; + + } catch (BadLocationException e) { + return false; + } + } + + /** + * Tries to make an annotation hover focusable (or "sticky"). + * + * @param sourceViewer + * the source viewer to display the hover over + * @param annotationHover + * the hover to make focusable + * @return true if successful, false + * otherwise + */ + private boolean makeAnnotationHoverFocusable( + ISourceViewer sourceViewer, IAnnotationHover annotationHover) { + IVerticalRulerInfo info = getVerticalRuler(); + int line = info.getLineOfLastMouseButtonActivity(); + if (line == -1) + return false; + + try { + + // compute the hover information + Object hoverInfo; + if (annotationHover instanceof IAnnotationHoverExtension) { + IAnnotationHoverExtension extension = (IAnnotationHoverExtension) annotationHover; + ILineRange hoverLineRange = extension.getHoverLineRange( + sourceViewer, line); + if (hoverLineRange == null) + return false; + final int maxVisibleLines = Integer.MAX_VALUE; // allow any + // number of + // lines + // being + // displayed, + // as we + // support + // scrolling + hoverInfo = extension.getHoverInfo(sourceViewer, + hoverLineRange, maxVisibleLines); + } else { + hoverInfo = annotationHover + .getHoverInfo(sourceViewer, line); + } + + // hover region: the beginning of the concerned line to place + // the control right over the line + IDocument document = sourceViewer.getDocument(); + int offset = document.getLineOffset(line); + String contentType = TextUtilities.getContentType(document, + ICPartitions.C_PARTITIONING, offset, true); + + IInformationControlCreator controlCreator = null; + + /* + * XXX: This is a hack to avoid API changes at the end of 3.2, + * and should be fixed for 3.3, see: + * https://bugs.eclipse.org/bugs/show_bug.cgi?id=137967 + */ + if ("org.eclipse.jface.text.source.projection.ProjectionAnnotationHover".equals(annotationHover.getClass().getName())) { //$NON-NLS-1$ + controlCreator = new IInformationControlCreator() { + public IInformationControl createInformationControl( + Shell shell) { + int shellStyle = SWT.RESIZE | SWT.TOOL + | getOrientation(); + int style = SWT.V_SCROLL | SWT.H_SCROLL; + return new SourceViewerInformationControl(shell, + shellStyle, style); + } + }; + + } else { + if (annotationHover instanceof IInformationProviderExtension2) + controlCreator = ((IInformationProviderExtension2) annotationHover) + .getInformationPresenterControlCreator(); + else if (annotationHover instanceof IAnnotationHoverExtension) + controlCreator = ((IAnnotationHoverExtension) annotationHover) + .getHoverControlCreator(); + } + + IInformationProvider informationProvider = new InformationProvider( + new Region(offset, 0), hoverInfo, controlCreator); + + fInformationPresenter.setOffset(offset); + fInformationPresenter + .setAnchor(AbstractInformationControlManager.ANCHOR_RIGHT); + fInformationPresenter.setMargins(4, 0); // AnnotationBarHoverManager + // sets (5,0), minus + // SourceViewer.GAP_SIZE_1 + fInformationPresenter.setInformationProvider( + informationProvider, contentType); + fInformationPresenter.showInformation(); + + return true; + + } catch (BadLocationException e) { + return false; + } + } + + // modified version from TextViewer + private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) { + + StyledText styledText = textViewer.getTextWidget(); + IDocument document = textViewer.getDocument(); + + if (document == null) + return -1; + + try { + int widgetOffset = styledText.getOffsetAtLocation(new Point(x, + y)); + Point p = styledText.getLocationAtOffset(widgetOffset); + if (p.x > x) + widgetOffset--; + + if (textViewer instanceof ITextViewerExtension5) { + ITextViewerExtension5 extension = (ITextViewerExtension5) textViewer; + return extension.widgetOffset2ModelOffset(widgetOffset); + } else { + IRegion visibleRegion = textViewer.getVisibleRegion(); + return widgetOffset + visibleRegion.getOffset(); + } + } catch (IllegalArgumentException e) { + return -1; + } + + } + } + /** * The editor selection changed listener. * @@ -650,6 +989,13 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS fFoldingGroup= new FoldingActionGroup(this, getSourceViewer()); + // Sticky hover support + ResourceAction resAction= new TextOperationAction(CEditorMessages.getResourceBundle(), "ShowToolTip.", this, ISourceViewer.INFORMATION, true); //$NON-NLS-1$ + ResourceAction resAction2= new InformationDispatchAction(CEditorMessages.getResourceBundle(), "ShowToolTip.", (TextOperationAction) resAction); //$NON-NLS-1$ + resAction2.setActionDefinitionId(ICEditorActionDefinitionIds.SHOW_TOOLTIP); + setAction("ShowToolTip", resAction2); //$NON-NLS-1$ + PlatformUI.getWorkbench().getHelpSystem().setHelp(resAction2, ICHelpContextIds.SHOW_TOOLTIP_ACTION); + // Default text editing menu items Action action= new GotoMatchingBracketAction(this); action.setActionDefinitionId(ICEditorActionDefinitionIds.GOTO_MATCHING_BRACKET); @@ -802,7 +1148,25 @@ public class CEditor extends TextEditor implements ISelectionChangedListener, IS */ public void createPartControl(Composite parent) { super.createPartControl(parent); + + // Sticky hover support + IInformationControlCreator informationControlCreator = new IInformationControlCreator() { + public IInformationControl createInformationControl(Shell shell) { + boolean cutDown = false; + int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL); + return new DefaultInformationControl(shell, SWT.RESIZE + | SWT.TOOL, style, new HTMLTextPresenter(cutDown)); + } + }; + fInformationPresenter = new InformationPresenter( + informationControlCreator); + fInformationPresenter.setSizeConstraints(60, 10, true, true); + fInformationPresenter.install(getSourceViewer()); + fInformationPresenter + .setDocumentPartitioning(ICPartitions.C_PARTITIONING); + + ProjectionViewer projectionViewer= (ProjectionViewer) getSourceViewer(); fProjectionSupport= new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors()); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties index 305093b5d00..9686804dbb0 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/CEditorMessages.properties @@ -192,3 +192,5 @@ GotoNextMember.tooltip=Goes to next member GotoPrevMember.description=Goes to previous member GotoPrevMember.label=Go to &previous member GotoPrevMember.tooltip=Goes to previous member. + +ShowToolTip.label=Show T&ooltip Description diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java index 94d9a3785c0..c010aff5f3d 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/ICEditorActionDefinitionIds.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 QNX Software Systems and others. + * Copyright (c) 2000, 2006 QNX Software Systems 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 @@ -7,6 +7,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.internal.ui.editor; @@ -155,4 +156,11 @@ public interface ICEditorActionDefinitionIds extends ITextEditorActionDefinition */ public static final String GOTO_MATCHING_BRACKET= "org.eclipse.cdt.ui.edit.text.c.goto.matching.bracket"; //$NON-NLS-1$ + /** + * Action definition ID of the edit -> show tooltip action + * (value "org.eclipse.cdt.ui.edit.text.c.show.tooltip"). + * + * @since 3.1.1 + */ + public static final String SHOW_TOOLTIP = "org.eclipse.cdt.ui.edit.text.c.show.tooltip"; //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/ICPartitions.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/ICPartitions.java index 4df1ff71843..c437b0c1e1f 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/ICPartitions.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/ICPartitions.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2005 QNX Software Systems and others. + * Copyright (c) 2000, 2006 QNX Software Systems 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 @@ -7,6 +7,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.internal.ui.text; @@ -38,5 +39,11 @@ public interface ICPartitions { * The identifier of the C character partition content type. */ String C_CHARACTER= "c_character"; //$NON-NLS-1$ + + /** + * The identifier of the C partitioning. + */ + String C_PARTITIONING= "___c_partitioning"; //$NON-NLS-1$ + } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/AbstractCEditorTextHover.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/AbstractCEditorTextHover.java index d040ff205d7..7a9d1f91c89 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/AbstractCEditorTextHover.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/AbstractCEditorTextHover.java @@ -7,6 +7,7 @@ * * Contributors: * QNX Software Systems - Initial API and implementation + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.internal.ui.text.c.hover; @@ -22,9 +23,14 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.keys.IBindingService; +import org.eclipse.cdt.ui.CUIPlugin; +import org.eclipse.cdt.ui.PreferenceConstants; import org.eclipse.cdt.ui.text.c.hover.ICEditorTextHover; +import org.eclipse.cdt.internal.ui.editor.ICEditorActionDefinitionIds; import org.eclipse.cdt.internal.ui.text.CWordFinder; import org.eclipse.cdt.internal.ui.text.HTMLTextPresenter; @@ -38,6 +44,15 @@ public abstract class AbstractCEditorTextHover implements ICEditorTextHover, private IEditorPart fEditor; + /* Mapping key to action */ + private IBindingService fBindingService; + + // initialization block, called during constructor call + { + fBindingService = (IBindingService) PlatformUI.getWorkbench() + .getAdapter(IBindingService.class); + } + /* * @see ICEditorTextHover#setEditor(IEditorPart) */ @@ -88,7 +103,7 @@ public abstract class AbstractCEditorTextHover implements ICEditorTextHover, } }; } - + /** * Returns the tool tip affordance string. * @@ -97,9 +112,20 @@ public abstract class AbstractCEditorTextHover implements ICEditorTextHover, * @since 3.0 */ protected String getTooltipAffordanceString() { - //TLETODO [hover] provide affordance string - // @see org.eclipse.jdt.internal.ui.text.java.hover.AbstractJavaEditorTextHover - return null; + + if (fBindingService == null + || !CUIPlugin.getDefault().getPreferenceStore().getBoolean( + PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE)) + return null; + + String keySequence = fBindingService + .getBestActiveBindingFormattedFor(ICEditorActionDefinitionIds.SHOW_TOOLTIP); + if (keySequence == null) + return null; + + return CHoverMessages + .getFormattedString( + "CTextHover.makeStickyHint", keySequence == null ? "" : keySequence); //$NON-NLS-1$ } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java index dac9113b718..4c4e7e66b25 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java @@ -11,14 +11,12 @@ *******************************************************************************/ package org.eclipse.cdt.ui; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.RGB; - +import org.eclipse.cdt.internal.ui.text.ICColorConstants; import org.eclipse.jface.action.Action; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.preference.PreferenceConverter; - -import org.eclipse.cdt.internal.ui.text.ICColorConstants; +import org.eclipse.swt.SWT; +import org.eclipse.swt.graphics.RGB; /** * Preference constants used in the CDT-UI preference store. Clients should only read the @@ -374,6 +372,15 @@ public class PreferenceConstants { return CUIPlugin.getDefault().getPreferenceStore(); } + /** + * A named preference that defines whether the hint to make hover sticky should be shown. + * + * @see JavaUI + * @since 3.1.1 + */ + public static final String EDITOR_SHOW_TEXT_HOVER_AFFORDANCE= "PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE"; //$NON-NLS-1$ + + /** * Initializes the given preference store with the default values. * @@ -395,7 +402,8 @@ public class PreferenceConstants { String mod1Name= Action.findModifierString(SWT.MOD1); // SWT.COMMAND on Mac; SWT.CONTROL elsewhere store.setDefault(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIERS, "org.eclipse.cdt.ui.BestMatchHover;0;org.eclipse.cdt.ui.CSourceHover;" + mod1Name); //$NON-NLS-1$ store.setDefault(PreferenceConstants.EDITOR_TEXT_HOVER_MODIFIER_MASKS, "org.eclipse.cdt.ui.BestMatchHover;0;org.eclipse.cdt.ui.CSourceHover;" + SWT.MOD1); //$NON-NLS-1$ - //store.setDefault(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE, true); + + store.setDefault(PreferenceConstants.EDITOR_SHOW_TEXT_HOVER_AFFORDANCE, true); // folding store.setDefault(PreferenceConstants.EDITOR_FOLDING_ENABLED, false);