1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-07 08:15:48 +02:00

Bug 342498 - Pin Call Hierarchy View

This commit is contained in:
Marc-Andre Laperle 2011-11-12 16:40:40 -05:00
parent 8a1269053a
commit 3108f9efdf
12 changed files with 269 additions and 43 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 358 B

View file

@ -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"/>
<view
category="org.eclipse.cdt.ui.views"
class="org.eclipse.cdt.internal.ui.typehierarchy.THViewPart"

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2008 IBM Corporation and others.
* Copyright (c) 2000, 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
@ -26,9 +26,8 @@ import org.eclipse.cdt.internal.ui.CPluginImages;
public class CHHistoryDropDownAction extends Action implements IMenuCreator {
public static class ClearHistoryAction extends Action {
private CHViewPart fView;
private CHViewPart fView;
public ClearHistoryAction(CHViewPart view) {
super(CHMessages.CHHistoryDropDownAction_ClearHistory_label);
fView= view;
@ -36,7 +35,7 @@ public class CHHistoryDropDownAction extends Action implements IMenuCreator {
@Override
public void run() {
fView.setHistoryEntries(new ICElement[0]);
CallHierarchyUI.clearHistory();
fView.setInput(null);
}
}
@ -54,6 +53,7 @@ public class CHHistoryDropDownAction extends Action implements IMenuCreator {
setMenuCreator(this);
}
@Override
public void dispose() {
// action is reused, can be called several times.
if (fMenu != null) {
@ -62,16 +62,18 @@ public class CHHistoryDropDownAction extends Action implements IMenuCreator {
}
}
@Override
public Menu getMenu(Menu parent) {
return null;
}
@Override
public Menu getMenu(Control parent) {
if (fMenu != null) {
fMenu.dispose();
}
fMenu= new Menu(parent);
ICElement[] elements= fHierarchyView.getHistoryEntries();
ICElement[] elements= CallHierarchyUI.getHistoryEntries();
addEntries(fMenu, elements);
new MenuItem(fMenu, SWT.SEPARATOR);
addActionToMenu(fMenu, new CHHistoryListAction(fHierarchyView));

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others.
* Copyright (c) 2000, 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
@ -53,13 +53,16 @@ public class CHHistoryListAction extends Action {
};
IListAdapter<ICElement> adapter= new IListAdapter<ICElement>() {
@Override
public void customButtonPressed(ListDialogField<ICElement> field, int index) {
doCustomButtonPressed();
}
@Override
public void selectionChanged(ListDialogField<ICElement> field) {
doSelectionChanged();
}
@Override
public void doubleClicked(ListDialogField<ICElement> 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());
}
}

View file

@ -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

View file

@ -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

View file

@ -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());
}
}

View file

@ -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<ICElement> fHistoryEntries= new ArrayList<ICElement>(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 <code>true</code> 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 <code>true</code> the view is marked as pinned
*/
void setPinned(boolean pinned) {
fIsPinned= pinned;
}
/**
* Indicates whether the Call Hierarchy view is pinned.
*
* @return <code>true</code> if the view is pinned, <code>false</code> otherwise
*/
boolean isPinned() {
return fIsPinned;
}
}

View file

@ -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<CHViewPart> fLRUCallHierarchyViews= new ArrayList<CHViewPart>();
private static int fViewCount = 0;
private static final int MAX_HISTORY_SIZE = 10;
private static List<ICElement> fHistoryEntries= new ArrayList<ICElement>(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<CHViewPart> 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 <code>null</code> if none found
*/
private static CHViewPart findLRUCallHierarchyViewPart(IWorkbenchPage page) {
boolean viewFoundInPage= false;
for (Iterator<CHViewPart> 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);
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.2 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View file

@ -60,6 +60,11 @@
<td valign="top" headers="name"><strong>Refresh View Contents</strong></td>
<td valign="top" headers="description">Refreshes the view to reflect the current state of the function.</td>
</tr>
<tr>
<td valign="top" headers="command"><div style="text-align:center;"><img src="../images/icon_pin.png" alt="Pin the Call Hierarchy View icon" ></div></td>
<td valign="top" headers="name"><strong>Pin the Call Hierarchy View</strong></td>
<td valign="top" headers="description">Pins the current view and enables the user to open multiple Call Hierarchy views at the same time.</td>
</tr>
<tr>
<td valign="top" headers="command"><div style="text-align:center;"><img src="../images/icon_menu_white.png" alt="Menu icon" ></div></td>
<td valign="top" headers="name"><strong>View Menu</strong></td>