From 3108f9efdf3a43479280e6e6b02d107517eed28f Mon Sep 17 00:00:00 2001 From: Marc-Andre Laperle Date: Sat, 12 Nov 2011 16:40:40 -0500 Subject: [PATCH] Bug 342498 - Pin Call Hierarchy View --- .../icons/dlcl16/pin_view.gif | Bin 0 -> 223 bytes .../icons/elcl16/pin_view.gif | Bin 0 -> 358 bytes core/org.eclipse.cdt.ui/plugin.xml | 3 +- .../CHHistoryDropDownAction.java | 12 +- .../ui/callhierarchy/CHHistoryListAction.java | 9 +- .../internal/ui/callhierarchy/CHMessages.java | 4 +- .../ui/callhierarchy/CHMessages.properties | 4 +- .../ui/callhierarchy/CHPinAction.java | 41 ++++++ .../internal/ui/callhierarchy/CHViewPart.java | 117 +++++++++++++----- .../ui/callhierarchy/CallHierarchyUI.java | 117 +++++++++++++++++- .../images/view_call_hierarchy.png | Bin 7335 -> 4375 bytes .../reference/cdt_u_call_hierarchy_view.htm | 5 + 12 files changed, 269 insertions(+), 43 deletions(-) create mode 100644 core/org.eclipse.cdt.ui/icons/dlcl16/pin_view.gif create mode 100644 core/org.eclipse.cdt.ui/icons/elcl16/pin_view.gif create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHPinAction.java diff --git a/core/org.eclipse.cdt.ui/icons/dlcl16/pin_view.gif b/core/org.eclipse.cdt.ui/icons/dlcl16/pin_view.gif new file mode 100644 index 0000000000000000000000000000000000000000..61615d57dbe934e7ce52eb115791d40e36e7a1d6 GIT binary patch literal 223 zcmV<503iQINk%w1VGsZi0K@+kaO`TP6){r&s={DF^%d4qnQs-m&EthBqY zyS%l+!NLFk{{R30A^8LW0015UEC2ui01yBW000GCpeK%GX`U$Bttr`QTi1H;rOEWF z>l}CE9fc$EkW4Na4F@Oc3<81#f}z1=FiaX@%LP=IF2Z4a0FV#a4uN8zupx$anoy|Q Z7xlSi&$l!za}|PvgK0a5EHfq{06TA~c$feH literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/icons/elcl16/pin_view.gif b/core/org.eclipse.cdt.ui/icons/elcl16/pin_view.gif new file mode 100644 index 0000000000000000000000000000000000000000..ec50b70fab124687826aaef03ff536a3cefc4122 GIT binary patch literal 358 zcmZ?wbhEHb6krfwxXQrLF?F4|QS8K7D<{laVNkNmrEHa3`D(X{)po5%>{<@T&OW#5 z)RWbxo*cdZC3eoamMynhw%$7X>;K2!|G)nE|Ksof*T4S1`~Cm@@BbhF{Qval|JT3&fBgIZ{ont&3m42? zw1A<=j3H5vAxNEJs-5ZVh@x$twOa!hpK6@HJa5&i>8n>x-@dVL|F(|*|Nk>!1ByRc z7#SEW7<53AAU`p%H9O2H@X(R!_gL~;)mtchL&W8mO^)%0ni?AlY{WKS&0$O4*)qxV zXwk`xF#U)b5f%bMTpY~TssR#@hZtGO&5`sRW@@m y;gwcZkyDkEP*pW`(c)E;->^|$P+rr8nO9vyU19G&1tu4UBS()N@$+zGum%8MtEM~v literal 0 HcmV?d00001 diff --git a/core/org.eclipse.cdt.ui/plugin.xml b/core/org.eclipse.cdt.ui/plugin.xml index b6fcfa05921..9a712d3953f 100644 --- a/core/org.eclipse.cdt.ui/plugin.xml +++ b/core/org.eclipse.cdt.ui/plugin.xml @@ -285,7 +285,8 @@ class="org.eclipse.cdt.internal.ui.callhierarchy.CHViewPart" icon="icons/view16/call_hierarchy.gif" id="org.eclipse.cdt.ui.callHierarchy" - name="%callHierarchy.name"/> + name="%callHierarchy.name" + allowMultiple="true"/> adapter= new IListAdapter() { + @Override public void customButtonPressed(ListDialogField field, int index) { doCustomButtonPressed(); } + @Override public void selectionChanged(ListDialogField field) { doSelectionChanged(); } + @Override public void doubleClicked(ListDialogField field) { doDoubleClicked(); } @@ -171,10 +174,10 @@ public class CHHistoryListAction extends Action { */ @Override public void run() { - ICElement[] historyEntries= fView.getHistoryEntries(); + ICElement[] historyEntries= CallHierarchyUI.getHistoryEntries(); HistoryListDialog dialog= new HistoryListDialog(fView.getSite().getShell(), historyEntries); if (dialog.open() == Window.OK) { - fView.setHistoryEntries(dialog.getRemaining()); + CallHierarchyUI.setHistoryEntries(dialog.getRemaining()); fView.setInput(dialog.getResult()); } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.java index 127fcd48c6f..620ceba59e8 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2011 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 @@ -55,6 +55,8 @@ public class CHMessages extends NLS { public static String OpenElementInCallHierarchyAction_message; public static String OpenElementInCallHierarchyAction_title; public static String OpenElementInCallHierarchyAction_upperListLabel; + public static String CHPinAction_label; + public static String CHPinAction_tooltip; static { // initialize resource bundle diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.properties index 2e8321e562a..0d8f98b6daa 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.properties +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHMessages.properties @@ -1,5 +1,5 @@ ############################################################################### -# Copyright (c) 2006, 2010 Wind River Systems, Inc. and others. +# Copyright (c) 2006, 2011 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 @@ -50,3 +50,5 @@ OpenElementInCallHierarchyAction_title=Open Element in Call Hierarchy OpenElementInCallHierarchyAction_upperListLabel=&Matching Elements: OpenElementInCallHierarchyAction_message=&Choose an element (? = any character, * = any string): OpenElementInCallHierarchyAction_errorNoDefinition=Could not locate definition of element ''{0}'' +CHPinAction_label=Pi&n Call Hierarchy View +CHPinAction_tooltip=Pin the Call Hierarchy View diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHPinAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHPinAction.java new file mode 100644 index 00000000000..3b770e66d62 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHPinAction.java @@ -0,0 +1,41 @@ +/******************************************************************************* + * Copyright (c) 2011, 2011 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 + * Marc-Andre Laperle - Adapted to CDT from JDT + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.callhierarchy; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.action.IAction; + +import org.eclipse.cdt.internal.ui.CPluginImages; + +public class CHPinAction extends Action { + private CHViewPart fView= null; + + /** + * Constructs a 'Pin Call Hierarchy view' action. + * + * @param view the Call Hierarchy view + */ + public CHPinAction(CHViewPart view) { + super(CHMessages.CHPinAction_label, IAction.AS_CHECK_BOX); + setToolTipText(CHMessages.CHPinAction_tooltip); + CPluginImages.setImageDescriptors(this, CPluginImages.T_LCL, "pin_view.gif"); //$NON-NLS-1$ + fView= view; + } + + /* + * @see org.eclipse.jface.action.Action#run() + */ + @Override + public void run() { + fView.setPinned(isChecked()); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHViewPart.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHViewPart.java index dc1a0895479..9fd2f0163d2 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHViewPart.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CHViewPart.java @@ -11,8 +11,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.callhierarchy; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Iterator; import org.eclipse.jface.action.Action; @@ -47,8 +45,11 @@ import org.eclipse.swt.widgets.Menu; import org.eclipse.swt.widgets.TreeItem; import org.eclipse.ui.IActionBars; import org.eclipse.ui.IMemento; +import org.eclipse.ui.IPartListener2; +import org.eclipse.ui.IViewReference; import org.eclipse.ui.IViewSite; import org.eclipse.ui.IWorkbenchPage; +import org.eclipse.ui.IWorkbenchPartReference; import org.eclipse.ui.IWorkbenchPartSite; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PartInitException; @@ -91,7 +92,6 @@ import org.eclipse.cdt.internal.ui.viewsupport.WorkingSetFilterUI; * The view part for the include browser. */ public class CHViewPart extends ViewPart { - private static final int MAX_HISTORY_SIZE = 10; private static final String TRUE = String.valueOf(true); private static final String KEY_WORKING_SET_FILTER = "workingSetFilter"; //$NON-NLS-1$ private static final String KEY_FILTER_VARIABLES = "variableFilter"; //$NON-NLS-1$ @@ -101,8 +101,6 @@ public class CHViewPart extends ViewPart { private boolean fShowsMessage; private CHNode fNavigationNode; private int fNavigationDetail; - - private ArrayList fHistoryEntries= new ArrayList(MAX_HISTORY_SIZE); // widgets private PageBook fPagebook; @@ -131,6 +129,7 @@ public class CHViewPart extends ViewPart { private Action fHistoryAction; private Action fShowReference; private Action fOpenElement; + private Action fPinViewAction; private CopyTreeAction fCopyAction; // action groups @@ -138,6 +137,8 @@ public class CHViewPart extends ViewPart { private SelectionSearchGroup fSelectionSearchGroup; private CRefactoringActionGroup fRefactoringActionGroup; private IContextActivation fContextActivation; + private boolean fIsPinned = false; + private IPartListener2 fPartListener; @Override public void setFocus() { @@ -171,7 +172,7 @@ public class CHViewPart extends ViewPart { fTreeViewer.setInput(input); fPagebook.showPage(fViewerPage); updateDescription(); - updateHistory(input); + CallHierarchyUI.updateHistory(input); updateActionEnablement(); } @@ -218,8 +219,48 @@ public class CHViewPart extends ViewPart { } PlatformUI.getWorkbench().getHelpSystem().setHelp(fPagebook, ICHelpContextIds.CALL_HIERARCHY_VIEW); + addPartListener(); } + private void addPartListener() { + fPartListener= new IPartListener2() { + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partActivated(org.eclipse.ui.IWorkbenchPartReference) + */ + @Override + public void partActivated(IWorkbenchPartReference partRef) { + if (isThisView(partRef)) + CallHierarchyUI.callHierarchyViewActivated(CHViewPart.this); + } + + @Override + public void partBroughtToTop(IWorkbenchPartReference partRef) { } + + /* (non-Javadoc) + * @see org.eclipse.ui.IPartListener2#partClosed(org.eclipse.ui.IWorkbenchPartReference) + */ + @Override + public void partClosed(IWorkbenchPartReference partRef) { + if (isThisView(partRef)) { + CallHierarchyUI.callHierarchyViewClosed(CHViewPart.this); + } + } + + @Override + public void partDeactivated(IWorkbenchPartReference partRef) {} + @Override + public void partOpened(IWorkbenchPartReference partRef) { } + @Override + public void partHidden(IWorkbenchPartReference partRef) { } + @Override + public void partVisible(IWorkbenchPartReference partRef) { } + @Override + public void partInputChanged(IWorkbenchPartReference partRef) { } + }; + getViewSite().getPage().addPartListener(fPartListener); + + } + @Override public void dispose() { if (fContextActivation != null) { @@ -245,6 +286,10 @@ public class CHViewPart extends ViewPart { fWorkingSetFilterUI.dispose(); fWorkingSetFilterUI= null; } + if (fPartListener != null) { + getViewSite().getPage().removePartListener(fPartListener); + fPartListener= null; + } super.dispose(); } @@ -276,6 +321,19 @@ public class CHViewPart extends ViewPart { super.init(site, memento); } + /** + * Tells whether the given part reference references this view. + * + * @param partRef the workbench part reference + * @return true if the given part reference references this view + */ + private boolean isThisView(IWorkbenchPartReference partRef) { + if (!CUIPlugin.ID_CALL_HIERARCHY.equals(partRef.getId())) + return false; + String partRefSecondaryId = ((IViewReference)partRef).getSecondaryId(); + String thisSecondaryId = getViewSite().getSecondaryId(); + return thisSecondaryId == null && partRefSecondaryId == null || thisSecondaryId != null && thisSecondaryId.equals(partRefSecondaryId); + } @Override public void saveState(IMemento memento) { @@ -291,7 +349,8 @@ public class CHViewPart extends ViewPart { MenuManager manager = new MenuManager(); manager.setRemoveAllWhenShown(true); manager.addMenuListener(new IMenuListener() { - public void menuAboutToShow(IMenuManager m) { + @Override + public void menuAboutToShow(IMenuManager m) { onContextMenuAboutToShow(m); } }); @@ -315,6 +374,7 @@ public class CHViewPart extends ViewPart { fTreeViewer.setLabelProvider(new DecoratingCLabelProvider(fLabelProvider)); fTreeViewer.setAutoExpandLevel(2); fTreeViewer.addOpenListener(new IOpenListener() { + @Override public void open(OpenEvent event) { onShowSelectedReference(event.getSelection()); } @@ -484,6 +544,7 @@ public class CHViewPart extends ViewPart { fHistoryAction = new CHHistoryDropDownAction(this); fCopyAction= new CopyCallHierarchyAction(this, fTreeViewer); + fPinViewAction= new CHPinAction(this); // setup action bar // global action hooks @@ -509,6 +570,7 @@ public class CHViewPart extends ViewPart { tm.add(fMakesReferenceToAction); tm.add(fHistoryAction); tm.add(fRefreshAction); + tm.add(fPinViewAction); // local menu IMenuManager mm = actionBars.getMenuManager(); @@ -608,16 +670,6 @@ public class CHViewPart extends ViewPart { fTreeViewer.refresh(); } - private void updateHistory(ICElement input) { - if (input != null) { - fHistoryEntries.remove(input); - fHistoryEntries.add(0, input); - if (fHistoryEntries.size() > MAX_HISTORY_SIZE) { - fHistoryEntries.remove(MAX_HISTORY_SIZE-1); - } - } - } - private void updateSorter() { if (fReferencedByAction.isChecked()) { fTreeViewer.setComparator(fSorterAlphaNumeric); @@ -662,7 +714,7 @@ public class CHViewPart extends ViewPart { } private void updateActionEnablement() { - fHistoryAction.setEnabled(!fHistoryEntries.isEmpty()); + fHistoryAction.setEnabled(CallHierarchyUI.getHistoryEntries().length > 0); fNextAction.setEnabled(!fShowsMessage); fPreviousAction.setEnabled(!fShowsMessage); fRefreshAction.setEnabled(!fShowsMessage); @@ -782,16 +834,7 @@ public class CHViewPart extends ViewPart { public Control getPageBook() { return fPagebook; } - - public ICElement[] getHistoryEntries() { - return fHistoryEntries.toArray(new ICElement[fHistoryEntries.size()]); - } - - public void setHistoryEntries(ICElement[] remaining) { - fHistoryEntries.clear(); - fHistoryEntries.addAll(Arrays.asList(remaining)); - } - + public ICElement getInput() { Object input= fTreeViewer.getInput(); if (input instanceof ICElement) { @@ -809,4 +852,22 @@ public class CHViewPart extends ViewPart { super(CHMessages.CHViewPart_CopyCallHierarchy_label, view, viewer); } } + + /** + * Marks the view as pinned. + * + * @param pinned if true the view is marked as pinned + */ + void setPinned(boolean pinned) { + fIsPinned= pinned; + } + + /** + * Indicates whether the Call Hierarchy view is pinned. + * + * @return true if the view is pinned, false otherwise + */ + boolean isPinned() { + return fIsPinned; + } } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java index 3aba5d15132..e0093cf82ac 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CallHierarchyUI.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2010 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2011 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 @@ -10,6 +10,11 @@ *******************************************************************************/ package org.eclipse.cdt.internal.ui.callhierarchy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; @@ -18,6 +23,7 @@ import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jface.text.ITextSelection; import org.eclipse.swt.widgets.Display; import org.eclipse.ui.IEditorInput; +import org.eclipse.ui.IViewReference; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.texteditor.ITextEditor; @@ -57,6 +63,15 @@ public class CallHierarchyUI { private static final ICElement[] NO_ELEMENTS = {}; private static boolean sIsJUnitTest= false; + /** + * List of the Call Hierarchy views in LRU order, where the most recently used view is at index 0. + */ + private static List fLRUCallHierarchyViews= new ArrayList(); + private static int fViewCount = 0; + + private static final int MAX_HISTORY_SIZE = 10; + private static List fHistoryEntries= new ArrayList(MAX_HISTORY_SIZE); + public static void setIsJUnitTest(boolean val) { sIsJUnitTest= val; } @@ -87,9 +102,19 @@ public class CallHierarchyUI { private static CHViewPart internalOpen(IWorkbenchWindow window, ICElement input) { IWorkbenchPage page= window.getActivePage(); try { - CHViewPart result= (CHViewPart) page.showView(CUIPlugin.ID_CALL_HIERARCHY); - result.setInput(input); - return result; + CHViewPart viewPart = findLRUCallHierarchyViewPart(page); //find the first view which is not pinned + String secondaryId = null; + if (viewPart == null) { + if (page.findViewReference(CUIPlugin.ID_CALL_HIERARCHY) != null) { //all the current views are pinned, open a new instance + secondaryId = String.valueOf(++fViewCount); + } + } else { + secondaryId = viewPart.getViewSite().getSecondaryId(); + } + + viewPart = (CHViewPart) page.showView(CUIPlugin.ID_CALL_HIERARCHY, secondaryId, IWorkbenchPage.VIEW_ACTIVATE); + viewPart.setInput(input); + return viewPart; } catch (CoreException e) { ExceptionHandler.handle(e, window.getShell(), CHMessages.OpenCallHierarchyAction_label, null); } @@ -331,4 +356,88 @@ public class CallHierarchyUI { } return false; } + + + /** + * Adds the activated view part to the head of the list. + * + * @param view the Call Hierarchy view part + */ + static void callHierarchyViewActivated(CHViewPart view) { + fLRUCallHierarchyViews.remove(view); + fLRUCallHierarchyViews.add(0, view); + } + + /** + * Removes the closed view part from the list. + * + * @param view the closed view part + */ + static void callHierarchyViewClosed(CHViewPart view) { + fLRUCallHierarchyViews.remove(view); + } + + /** + * Clears the history and updates all the open views. + */ + static void clearHistory() { + setHistoryEntries(new ICElement[0]); + for (Iterator iter= fLRUCallHierarchyViews.iterator(); iter.hasNext();) { + CHViewPart part= iter.next(); + part.setInput(null); + } + } + + /** + * Finds the first Call Hierarchy view part instance that is not pinned. + * + * @param page the active page + * @return the Call Hierarchy view part to open or null if none found + */ + private static CHViewPart findLRUCallHierarchyViewPart(IWorkbenchPage page) { + boolean viewFoundInPage= false; + for (Iterator iter= fLRUCallHierarchyViews.iterator(); iter.hasNext();) { + CHViewPart view= iter.next(); + if (page.equals(view.getSite().getPage())) { + if (!view.isPinned()) { + return view; + } + viewFoundInPage= true; + } + } + if (!viewFoundInPage) { + // find unresolved views + IViewReference[] viewReferences= page.getViewReferences(); + for (int i= 0; i < viewReferences.length; i++) { + IViewReference curr= viewReferences[i]; + if (CUIPlugin.ID_CALL_HIERARCHY.equals(curr.getId()) && page.equals(curr.getPage())) { + CHViewPart view= (CHViewPart)curr.getView(true); + if (view != null && !view.isPinned()) { + return view; + } + } + } + } + return null; + } + + static public ICElement[] getHistoryEntries() { + return fHistoryEntries.toArray(new ICElement[fHistoryEntries.size()]); + } + + static public void setHistoryEntries(ICElement[] remaining) { + fHistoryEntries.clear(); + fHistoryEntries.addAll(Arrays.asList(remaining)); + } + + static public void updateHistory(ICElement input) { + if (input != null) { + fHistoryEntries.remove(input); + fHistoryEntries.add(0, input); + if (fHistoryEntries.size() > MAX_HISTORY_SIZE) { + fHistoryEntries.remove(MAX_HISTORY_SIZE-1); + } + } + } + } diff --git a/doc/org.eclipse.cdt.doc.user/images/view_call_hierarchy.png b/doc/org.eclipse.cdt.doc.user/images/view_call_hierarchy.png index 6485a3bdccb5454a2211377b5837130acf10cf85..5e7d19ae6821860ad1d4679e0eb998d5b1dfebfb 100644 GIT binary patch literal 4375 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 RfNlT)002ovPDHLkV1jB2>~jDB literal 7335 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 View Contents Refreshes the view to reflect the current state of the function. + +
Pin the Call Hierarchy View icon
+ Pin the Call Hierarchy View + Pins the current view and enables the user to open multiple Call Hierarchy views at the same time. +
Menu icon
View Menu