From dfd419a0c0531cbbf03d34c91be6a93fcb4cdd1e Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 30 Sep 2010 08:03:48 +0000 Subject: [PATCH] Bug 325488: Toggle through quick type hierarchies, by Patrick Hofer. --- .../ui/text/AbstractInformationControl.java | 38 ++++- .../internal/ui/typehierarchy/Messages.java | 11 +- .../typehierarchy/THInformationControl.java | 158 +++++++++++++++--- .../ui/typehierarchy/messages.properties | 11 +- 4 files changed, 192 insertions(+), 26 deletions(-) diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/AbstractInformationControl.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/AbstractInformationControl.java index 3de07c9c760..e3d807c2aa8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/AbstractInformationControl.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/AbstractInformationControl.java @@ -8,11 +8,14 @@ * Contributors: * IBM Corporation - initial API and implementation * Markus Schorn (Wind River Systems) + * Patrick Hofer [bug 325488] *******************************************************************************/ package org.eclipse.cdt.internal.ui.text; +import org.eclipse.core.commands.Command; import org.eclipse.core.runtime.CoreException; import org.eclipse.jface.action.IMenuManager; +import org.eclipse.jface.bindings.TriggerSequence; import org.eclipse.jface.dialogs.Dialog; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.PopupDialog; @@ -52,6 +55,10 @@ import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IEditorPart; +import org.eclipse.ui.IWorkbench; +import org.eclipse.ui.PlatformUI; +import org.eclipse.ui.commands.ICommandService; +import org.eclipse.ui.keys.IBindingService; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.IParent; @@ -129,7 +136,9 @@ public abstract class AbstractInformationControl extends PopupDialog implements * Field for tree style since it must be remembered by the instance. */ private int fTreeStyle; - + private Command fInvokingCommand; + private TriggerSequence fInvokingTriggerSequence; + /** * Creates a tree information control with the given shell as parent. The given * styles are applied to the shell and the tree widget. @@ -138,10 +147,23 @@ public abstract class AbstractInformationControl extends PopupDialog implements * @param shellStyle the additional styles for the shell * @param treeStyle the additional styles for the tree widget * @param invokingCommandId the id of the command that invoked this control or null - * @param showStatusField true iff the control has a status field at the bottom + * @param showStatusField true if the control has a status field at the bottom */ public AbstractInformationControl(Shell parent, int shellStyle, int treeStyle, String invokingCommandId, boolean showStatusField) { super(parent, shellStyle, true, true, true, true, true, null, null); + if (invokingCommandId != null) { + IWorkbench workbench = PlatformUI.getWorkbench(); + ICommandService commandSupport = (ICommandService)workbench.getAdapter(ICommandService.class); + if (commandSupport != null) { + fInvokingCommand = commandSupport.getCommand(invokingCommandId); + if (fInvokingCommand != null && !fInvokingCommand.isDefined()) + fInvokingCommand= null; + else { + IBindingService bindingService = (IBindingService) workbench.getService(IBindingService.class); + fInvokingTriggerSequence = bindingService.getBestActiveBindingFor(invokingCommandId); + } + } + } fTreeStyle= treeStyle; // Title and status text must be set to get the title label created, so force empty values here. if (hasHeader()) @@ -319,6 +341,10 @@ public abstract class AbstractInformationControl extends PopupDialog implements return fFilterText; } + protected void updateStatusFieldText() { + setInfoText(getStatusFieldText()); + } + protected String getStatusFieldText() { return ""; //$NON-NLS-1$ } @@ -617,6 +643,14 @@ public abstract class AbstractInformationControl extends PopupDialog implements getShell().removeFocusListener(listener); } + final protected Command getInvokingCommand() { + return fInvokingCommand; + } + + final protected TriggerSequence getInvokingCommandTriggerSequence() { + return fInvokingTriggerSequence; + } + /* * @see org.eclipse.jface.dialogs.PopupDialog#getDialogSettings() */ diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/Messages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/Messages.java index 1f7d945b790..7af2a32b53c 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/Messages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/Messages.java @@ -29,8 +29,15 @@ public class Messages extends NLS { public static String THHistoryListAction_HistoryList_title; public static String THHistoryListAction_label; public static String THHistoryListAction_Remove; - public static String THInformationControl_regularTitle; - public static String THInformationControl_showDefiningTypesTitle; + public static String THInformationControl_titleHierarchy; + public static String THInformationControl_titleSubHierarchy; + public static String THInformationControl_titleSuperHierarchy; + public static String THInformationControl_titleMemberInHierarchy; + public static String THInformationControl_titleMemberInSubHierarchy; + public static String THInformationControl_titleMemberInSuperHierarchy; + public static String THInformationControl_toggle_typeHierarchy_label; + public static String THInformationControl_toggle_subTypeHierarchy_label; + public static String THInformationControl_toggle_superTypeHierarchy_label; public static String THViewPart_AutomaticOrientation; public static String THViewPart_Cancel; public static String THViewPart_Cancel_tooltip; diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THInformationControl.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THInformationControl.java index 71a98501364..169b505cb59 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THInformationControl.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/THInformationControl.java @@ -1,28 +1,37 @@ /******************************************************************************* - * Copyright (c) 2007, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2007, 2010 Wind River Systems, 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: - * Markus Schorn - initial API and implementation + * Markus Schorn - initial API and implementation + * Patrick Hofer [bug 325488] *******************************************************************************/ package org.eclipse.cdt.internal.ui.typehierarchy; import java.util.Iterator; +import org.eclipse.jface.bindings.Trigger; +import org.eclipse.jface.bindings.TriggerSequence; +import org.eclipse.jface.bindings.keys.KeyStroke; +import org.eclipse.jface.bindings.keys.SWTKeySupport; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.viewers.ViewerSorter; +import org.eclipse.osgi.util.NLS; import org.eclipse.swt.SWT; import org.eclipse.swt.events.DisposeEvent; +import org.eclipse.swt.events.KeyAdapter; +import org.eclipse.swt.events.KeyEvent; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; +import org.eclipse.swt.widgets.Text; import org.eclipse.swt.widgets.Tree; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.progress.IWorkbenchSiteProgressService; @@ -43,28 +52,61 @@ public class THInformationControl extends AbstractInformationControl implements private THLabelProvider fHierarchyLabelProvider; private TreeViewer fHierarchyTreeViewer; private boolean fDisposed= false; - + private KeyAdapter fKeyAdapter; + public THInformationControl(Shell parent, int shellStyle, int treeStyle) { super(parent, shellStyle, treeStyle, ICEditorActionDefinitionIds.OPEN_QUICK_TYPE_HIERARCHY, true); } + private KeyAdapter getKeyAdapter() { + if (fKeyAdapter == null) { + fKeyAdapter= new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + int accelerator = SWTKeySupport.convertEventToUnmodifiedAccelerator(e); + KeyStroke keyStroke = SWTKeySupport.convertAcceleratorToKeyStroke(accelerator); + Trigger[] triggers = getInvokingCommandTriggerSequence().getTriggers(); + if (triggers == null) + return; + + for (Trigger trigger : triggers) { + if (trigger.equals(keyStroke)) { + e.doit= false; + toggleHierarchy(); + return; + } + } + } + }; + } + return fKeyAdapter; + } + @Override protected boolean hasHeader() { return true; } + @Override + protected Text createFilterText(Composite parent) { + Text text= super.createFilterText(parent); + text.addKeyListener(getKeyAdapter()); + return text; + } + @Override protected TreeViewer createTreeViewer(Composite parent, int style) { Display display= getShell().getDisplay(); fModel= new THHierarchyModel(this, display, true); fHierarchyLabelProvider= new THLabelProvider(display, fModel); fHierarchyLabelProvider.setMarkImplementers(false); - fHierarchyTreeViewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); - fHierarchyTreeViewer.setContentProvider(new THContentProvider()); - fHierarchyTreeViewer.setLabelProvider(fHierarchyLabelProvider); - fHierarchyTreeViewer.setSorter(new ViewerSorter()); - fHierarchyTreeViewer.setUseHashlookup(true); - return fHierarchyTreeViewer; + fHierarchyTreeViewer = new TreeViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER); + fHierarchyTreeViewer.setContentProvider(new THContentProvider()); + fHierarchyTreeViewer.setLabelProvider(fHierarchyLabelProvider); + fHierarchyTreeViewer.setSorter(new ViewerSorter()); + fHierarchyTreeViewer.setUseHashlookup(true); + fHierarchyTreeViewer.getTree().addKeyListener(getKeyAdapter()); + return fHierarchyTreeViewer; } protected void onOpenElement(ISelection selection) { @@ -86,17 +128,41 @@ public class THInformationControl extends AbstractInformationControl implements fModel.setInput(splitInput[0], splitInput[1]); fHierarchyLabelProvider.setHideNonImplementers(splitInput[1] != null); fHierarchyTreeViewer.setInput(fModel); - fModel.computeGraph(); - String msgfmt= Messages.THInformationControl_regularTitle; - String obj= splitInput[0].getElementName(); - if (splitInput[1] != null) { - msgfmt= Messages.THInformationControl_showDefiningTypesTitle; - obj= splitInput[1].getElementName(); - } - String title= MessageFormat.format(msgfmt, new Object[] {obj}); - setTitleText(title); + fModel.computeGraph(); + updateTitle(); } - } + } + } + + protected void updateTitle() { + setTitleText(computeTitleText()); + } + + private String computeTitleText() { + final ICElement input = fModel.getInput(); + final ICElement member= fModel.getSelectedMember(); + String elemName= member != null ? member.getElementName() : input.getElementName(); + return NLS.bind(getFormatString(fModel.getHierarchyKind(), member != null), elemName); + } + + private String getFormatString(int hierarchyKind, boolean forMember) { + switch (hierarchyKind) { + case THHierarchyModel.SUB_TYPE_HIERARCHY: + return forMember + ? Messages.THInformationControl_titleMemberInSubHierarchy + : Messages.THInformationControl_titleSubHierarchy; + + case THHierarchyModel.SUPER_TYPE_HIERARCHY: + return forMember + ? Messages.THInformationControl_titleMemberInSuperHierarchy + : Messages.THInformationControl_titleSuperHierarchy; + + case THHierarchyModel.TYPE_HIERARCHY: + default: + return forMember + ? Messages.THInformationControl_titleMemberInHierarchy + : Messages.THInformationControl_titleHierarchy; + } } @Override @@ -164,7 +230,34 @@ public class THInformationControl extends AbstractInformationControl implements public IWorkbenchSiteProgressService getProgressService() { return null; } - + + @Override + protected String getStatusFieldText() { + TriggerSequence sequence = getInvokingCommandTriggerSequence(); + String keyName= ""; //$NON-NLS-1$ + if (sequence != null) + keyName= sequence.format(); + + String message= ""; //$NON-NLS-1$ + switch (fModel.getHierarchyKind()) { + case THHierarchyModel.TYPE_HIERARCHY: + message = Messages.THInformationControl_toggle_superTypeHierarchy_label; + break; + + case THHierarchyModel.SUB_TYPE_HIERARCHY: + message = Messages.THInformationControl_toggle_typeHierarchy_label; + break; + + case THHierarchyModel.SUPER_TYPE_HIERARCHY: + message = Messages.THInformationControl_toggle_subTypeHierarchy_label; + break; + + default: + break; + } + return MessageFormat.format(message, new Object[] {keyName} ); + } + @Override protected void selectFirstMatch() { Tree tree= fHierarchyTreeViewer.getTree(); @@ -175,6 +268,31 @@ public class THInformationControl extends AbstractInformationControl implements fHierarchyTreeViewer.setSelection(StructuredSelection.EMPTY); } + protected void toggleHierarchy() { + fHierarchyTreeViewer.getTree().setRedraw(false); + switch (fModel.getHierarchyKind()) { + case THHierarchyModel.TYPE_HIERARCHY: + fModel.setHierarchyKind(THHierarchyModel.SUPER_TYPE_HIERARCHY); + break; + + case THHierarchyModel.SUB_TYPE_HIERARCHY: + fModel.setHierarchyKind(THHierarchyModel.TYPE_HIERARCHY); + break; + + case THHierarchyModel.SUPER_TYPE_HIERARCHY: + fModel.setHierarchyKind(THHierarchyModel.SUB_TYPE_HIERARCHY); + break; + + default: + break; + } + fHierarchyTreeViewer.refresh(); + fHierarchyTreeViewer.expandAll(); + fHierarchyTreeViewer.getTree().setRedraw(true); + updateStatusFieldText(); + updateTitle(); + } + private THNode findElement(TreeItem[] items) { for (TreeItem item2 : items) { Object item= item2.getData(); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/messages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/messages.properties index f58e83b9efb..b8673ad3590 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/messages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/typehierarchy/messages.properties @@ -54,7 +54,14 @@ OpenTypeHierarchyAction_tooltip=Open Type Hierarchy OpenTypeInHierarchyAction_errorTitle=Open Type in Hierarchy OpenTypeInHierarchyAction_title=Open Type in Hierarchy OpenTypeInHierarchyAction_message=&Choose a type (? = any character, * = any string): -THInformationControl_regularTitle=Type Hierarchy of {0} -THInformationControl_showDefiningTypesTitle=Types defining or implementing {0} +THInformationControl_titleHierarchy=Type hierarchy of ''{0}'' +THInformationControl_titleSubHierarchy=Subtypes of ''{0}'' +THInformationControl_titleSuperHierarchy=Supertypes of ''{0}'' +THInformationControl_titleMemberInHierarchy=Types declaring ''{0}'' +THInformationControl_titleMemberInSubHierarchy=Subtypes declaring ''{0}'' +THInformationControl_titleMemberInSuperHierarchy=Supertypes declaring ''{0}'' +THInformationControl_toggle_typeHierarchy_label=Press ''{0}'' to see the type hierarchy +THInformationControl_toggle_subTypeHierarchy_label=Press ''{0}'' to see the subtype hierarchy +THInformationControl_toggle_superTypeHierarchy_label=Press ''{0}'' to see the supertype hierarchy OpenTypeInHierarchyAction_errorNoDefinition=Could not locate definition of type ''{0}'' OpenTypeInHierarchyAction_upperListLabel=&Matching Types: