From 57eb344aaa99938b93f3ecf4625031f7f82a7991 Mon Sep 17 00:00:00 2001 From: Sergey Prigogin Date: Fri, 14 May 2010 07:52:37 +0000 Subject: [PATCH] Copy from Call Hierarchy view. Bug 305471. --- .../internal/ui/callhierarchy/CHMessages.java | 7 +- .../ui/callhierarchy/CHMessages.properties | 6 +- .../internal/ui/callhierarchy/CHViewPart.java | 19 ++- .../CopyCallHierarchyAction.java | 133 ++++++++++++++++++ .../cdt/internal/ui/util/SelectionUtil.java | 33 +++++ .../src/org/eclipse/cdt/ui/CUIPlugin.java | 4 +- 6 files changed, 196 insertions(+), 6 deletions(-) create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CopyCallHierarchyAction.java create mode 100644 core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/SelectionUtil.java 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 e471674a2b2..638fd639b48 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, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 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 @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.ui.callhierarchy; @@ -54,6 +55,10 @@ public class CHMessages extends NLS { public static String OpenElementInCallHierarchyAction_message; public static String OpenElementInCallHierarchyAction_title; public static String OpenElementInCallHierarchyAction_upperListLabel; + public static String CopyCallHierarchyAction_label; + public static String CopyCallHierarchyAction_problem; + public static String CopyCallHierarchyAction_clipboard_busy; + static { // initialize resource bundle NLS.initializeMessages(BUNDLE_NAME, CHMessages.class); 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 f544a8079e9..28adf7feca7 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, 2007 Wind River Systems, Inc. and others. +# Copyright (c) 2006, 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 @@ -7,6 +7,7 @@ # # Contributors: # Markus Schorn (Wind River Systems) +# Sergey Prigogin (Google) ############################################################################### CHViewPart_emptyPageMessage=To display the call hierarchy, select a function or method and select the 'Open Call Hierarchy' menu option. CHViewPart_ShowCallers_label=Show Callers @@ -48,3 +49,6 @@ 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}'' +CopyCallHierarchyAction_label=Copy E&xpanded Hierarchy +CopyCallHierarchyAction_problem=Problem Copying Hierarchy to Clipboard +CopyCallHierarchyAction_clipboard_busy=There was a problem when accessing the system clipboard. Retry? 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 90ea0265827..a7c6c96eafc 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 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 @@ -7,6 +7,7 @@ * * Contributors: * Markus Schorn - initial API and implementation + * Sergey Prigogin (Google) *******************************************************************************/ package org.eclipse.cdt.internal.ui.callhierarchy; @@ -33,6 +34,7 @@ import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerComparator; import org.eclipse.jface.viewers.ViewerFilter; import org.eclipse.swt.SWT; +import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTarget; import org.eclipse.swt.dnd.Transfer; @@ -55,6 +57,7 @@ import org.eclipse.ui.PlatformUI; import org.eclipse.ui.actions.ActionFactory; import org.eclipse.ui.contexts.IContextActivation; import org.eclipse.ui.contexts.IContextService; +import org.eclipse.ui.navigator.ICommonMenuConstants; import org.eclipse.ui.part.PageBook; import org.eclipse.ui.part.ViewPart; @@ -101,6 +104,8 @@ public class CHViewPart extends ViewPart { private ArrayList fHistoryEntries= new ArrayList(MAX_HISTORY_SIZE); + private Clipboard fClipboard; + // widgets private PageBook fPagebook; private Composite fViewerPage; @@ -128,13 +133,13 @@ public class CHViewPart extends ViewPart { private Action fHistoryAction; private Action fShowReference; private Action fOpenElement; + private CopyCallHierarchyAction fCopyAction; // action groups private OpenViewActionGroup fOpenViewActionGroup; private SelectionSearchGroup fSelectionSearchGroup; private CRefactoringActionGroup fRefactoringActionGroup; private IContextActivation fContextActivation; - @Override public void setFocus() { @@ -202,6 +207,8 @@ public class CHViewPart extends ViewPart { getSite().setSelectionProvider(new AdaptingSelectionProvider(ICElement.class, fTreeViewer)); + fClipboard = new Clipboard(parent.getDisplay()); + initDragAndDrop(); createActions(); createContextMenu(); @@ -444,7 +451,7 @@ public class CHViewPart extends ViewPart { }; fOpenElement.setToolTipText(CHMessages.CHViewPart_Open_tooltip); fOpenElement.setActionDefinitionId(ICEditorActionDefinitionIds.OPEN_DECL); - + fShowFilesInLabelsAction= new Action(CHMessages.CHViewPart_ShowFiles_label, IAction.AS_CHECK_BOX) { @Override public void run() { @@ -470,6 +477,8 @@ public class CHViewPart extends ViewPart { fPreviousAction.setToolTipText(CHMessages.CHViewPart_PreviousReference_tooltip); CPluginImages.setImageDescriptors(fPreviousAction, CPluginImages.T_LCL, CPluginImages.IMG_SHOW_PREV); + fCopyAction= new CopyCallHierarchyAction(this, fClipboard, fTreeViewer); + fRefreshAction = new Action(CHMessages.CHViewPart_Refresh_label) { @Override public void run() { @@ -711,6 +720,10 @@ public class CHViewPart extends ViewPart { fOpenViewActionGroup.fillContextMenu(menu); } + if (fCopyAction.canActionBeAdded()) { + menu.appendToGroup(ICommonMenuConstants.GROUP_EDIT, fCopyAction); + } + if (SelectionSearchGroup.canActionBeAdded(selection)){ fSelectionSearchGroup.fillContextMenu(menu); } diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CopyCallHierarchyAction.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CopyCallHierarchyAction.java new file mode 100644 index 00000000000..95582375a01 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/callhierarchy/CopyCallHierarchyAction.java @@ -0,0 +1,133 @@ +/******************************************************************************* + * Copyright (c) 2000, 2010 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: + * Jesper Kamstrup Linnet (eclipse@kamstrup-linnet.dk) - initial API and implementation + * Sergey Prigogin (Google) + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.callhierarchy; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringReader; +import java.io.StringWriter; + +import org.eclipse.osgi.util.TextProcessor; + +import org.eclipse.swt.SWTError; +import org.eclipse.swt.dnd.Clipboard; +import org.eclipse.swt.dnd.DND; +import org.eclipse.swt.dnd.TextTransfer; +import org.eclipse.swt.dnd.Transfer; +import org.eclipse.swt.widgets.TreeItem; + +import org.eclipse.core.runtime.Assert; + +import org.eclipse.jface.action.Action; +import org.eclipse.jface.dialogs.MessageDialog; +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.ISelectionProvider; + +import org.eclipse.cdt.internal.ui.util.SelectionUtil; +import org.eclipse.cdt.internal.ui.viewsupport.ExtendedTreeViewer; + +class CopyCallHierarchyAction extends Action { + private static final char INDENTATION= '\t'; + + private CHViewPart fView; + private ExtendedTreeViewer fViewer; + private final Clipboard fClipboard; + + public CopyCallHierarchyAction(CHViewPart view, Clipboard clipboard, ExtendedTreeViewer viewer) { + super(CHMessages.CopyCallHierarchyAction_label); + Assert.isNotNull(clipboard); +// PlatformUI.getWorkbench().getHelpSystem().setHelp(this, ICHelpContextIds.CALL_HIERARCHY_COPY_ACTION); + fView= view; + fClipboard= clipboard; + fViewer= viewer; + } + + public boolean canActionBeAdded() { + Object element= SelectionUtil.getSingleElement(getSelection()); + return element != null; + } + + private ISelection getSelection() { + ISelectionProvider provider= fView.getSite().getSelectionProvider(); + + if (provider != null) { + return provider.getSelection(); + } + + return null; + } + + /* + * @see IAction#run() + */ + @Override + public void run() { + StringBuffer buf= new StringBuffer(); + addCalls(fViewer.getTree().getSelection()[0], 0, buf); + + TextTransfer plainTextTransfer= TextTransfer.getInstance(); + try { + fClipboard.setContents( + new String[] { convertLineTerminators(buf.toString()) }, + new Transfer[] { plainTextTransfer }); + } catch (SWTError e) { + if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) + throw e; + if (MessageDialog.openQuestion(fView.getViewSite().getShell(), CHMessages.CopyCallHierarchyAction_problem, CHMessages.CopyCallHierarchyAction_clipboard_busy)) + run(); + } + } + + /** + * Adds the specified {@link TreeItem}'s text to the StringBuffer. + * + * @param item the tree item + * @param indent the indent size + * @param buf the string buffer + */ + private void addCalls(TreeItem item, int indent, StringBuffer buf) { + for (int i= 0; i < indent; i++) { + buf.append(INDENTATION); + } + + buf.append(TextProcessor.deprocess(item.getText())); + buf.append('\n'); + + if (item.getExpanded()) { + TreeItem[] items= item.getItems(); + for (int i= 0; i < items.length; i++) { + addCalls(items[i], indent + 1, buf); + } + } + } + + static String convertLineTerminators(String in) { + StringWriter stringWriter= new StringWriter(); + PrintWriter printWriter= new PrintWriter(stringWriter); + StringReader stringReader= new StringReader(in); + BufferedReader bufferedReader= new BufferedReader(stringReader); + try { + String line= bufferedReader.readLine(); + while (line != null) { + printWriter.print(line); + line= bufferedReader.readLine(); + if (line != null && line.length() != 0) + printWriter.println(); + + } + } catch (IOException e) { + return in; // return the call hierarchy unfiltered + } + return stringWriter.toString(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/SelectionUtil.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/SelectionUtil.java new file mode 100644 index 00000000000..c491dc53e48 --- /dev/null +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/SelectionUtil.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2000, 2008 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 + * Sergey Prigogin (Google) + *******************************************************************************/ +package org.eclipse.cdt.internal.ui.util; + +import org.eclipse.jface.viewers.ISelection; +import org.eclipse.jface.viewers.IStructuredSelection; + +public class SelectionUtil { + /** + * Returns the selected element if the selection consists of a single element only. + * + * @param s the selection + * @return the selected first element or null + */ + public static Object getSingleElement(ISelection s) { + if (!(s instanceof IStructuredSelection)) + return null; + IStructuredSelection selection= (IStructuredSelection) s; + if (selection.size() != 1) + return null; + + return selection.getFirstElement(); + } +} diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java index 754dbe00461..91a488fdb56 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/CUIPlugin.java @@ -56,6 +56,7 @@ import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.editors.text.EditorsUI; import org.eclipse.ui.editors.text.templates.ContributionContextTypeRegistry; import org.eclipse.ui.editors.text.templates.ContributionTemplateStore; +import org.eclipse.ui.navigator.ICommonMenuConstants; import org.eclipse.ui.plugin.AbstractUIPlugin; import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.eclipse.ui.texteditor.ChainedPreferenceStore; @@ -723,11 +724,12 @@ public class CUIPlugin extends AbstractUIPlugin { public static void createStandardGroups(IMenuManager menu) { if (!menu.isEmpty()) return; - + menu.add(new Separator(IContextMenuConstants.GROUP_NEW)); menu.add(new GroupMarker(IContextMenuConstants.GROUP_GOTO)); menu.add(new Separator(IContextMenuConstants.GROUP_OPEN)); menu.add(new GroupMarker(IContextMenuConstants.GROUP_SHOW)); + menu.add(new Separator(ICommonMenuConstants.GROUP_EDIT)); menu.add(new Separator(IContextMenuConstants.GROUP_REORGANIZE)); menu.add(new Separator(IContextMenuConstants.GROUP_GENERATE)); menu.add(new Separator(IContextMenuConstants.GROUP_SEARCH));