001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.views.navigator;
011:
012: import java.util.Iterator;
013: import java.util.List;
014:
015: import org.eclipse.core.resources.IContainer;
016: import org.eclipse.core.resources.IResource;
017: import org.eclipse.core.runtime.Assert;
018: import org.eclipse.core.runtime.IPath;
019: import org.eclipse.jface.dialogs.MessageDialog;
020: import org.eclipse.jface.viewers.IStructuredSelection;
021: import org.eclipse.swt.SWTError;
022: import org.eclipse.swt.dnd.Clipboard;
023: import org.eclipse.swt.dnd.DND;
024: import org.eclipse.swt.dnd.FileTransfer;
025: import org.eclipse.swt.dnd.TextTransfer;
026: import org.eclipse.swt.dnd.Transfer;
027: import org.eclipse.swt.widgets.Shell;
028: import org.eclipse.ui.PlatformUI;
029: import org.eclipse.ui.actions.SelectionListenerAction;
030: import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
031: import org.eclipse.ui.part.ResourceTransfer;
032:
033: /**
034: * Standard action for copying the currently selected resources to the clipboard.
035: * <p>
036: * This class may be instantiated; it is not intended to be subclassed.
037: * </p>
038: *
039: * @since 2.0
040: */
041: /*package*/class CopyAction extends SelectionListenerAction {
042:
043: /**
044: * The id of this action.
045: */
046: public static final String ID = PlatformUI.PLUGIN_ID
047: + ".CopyAction"; //$NON-NLS-1$
048:
049: /**
050: * The shell in which to show any dialogs.
051: */
052: private Shell shell;
053:
054: /**
055: * System clipboard
056: */
057: private Clipboard clipboard;
058:
059: /**
060: * Associated paste action. May be <code>null</code>
061: */
062: private PasteAction pasteAction;
063:
064: /**
065: * Creates a new action.
066: *
067: * @param shell the shell for any dialogs
068: * @param clipboard a platform clipboard
069: */
070: public CopyAction(Shell shell, Clipboard clipboard) {
071: super (ResourceNavigatorMessages.CopyAction_title);
072: Assert.isNotNull(shell);
073: Assert.isNotNull(clipboard);
074: this .shell = shell;
075: this .clipboard = clipboard;
076: setToolTipText(ResourceNavigatorMessages.CopyAction_toolTip);
077: setId(CopyAction.ID);
078: PlatformUI.getWorkbench().getHelpSystem().setHelp(this ,
079: INavigatorHelpContextIds.COPY_ACTION);
080: }
081:
082: /**
083: * Creates a new action.
084: *
085: * @param shell the shell for any dialogs
086: * @param clipboard a platform clipboard
087: * @param pasteAction a paste action
088: *
089: * @since 2.0
090: */
091: public CopyAction(Shell shell, Clipboard clipboard,
092: PasteAction pasteAction) {
093: this (shell, clipboard);
094: this .pasteAction = pasteAction;
095: }
096:
097: /* (non-Javadoc)
098: * @see org.eclipse.jface.action.Action#run()
099: */
100: public void run() {
101: /**
102: * The <code>CopyAction</code> implementation of this method defined
103: * on <code>IAction</code> copies the selected resources to the
104: * clipboard.
105: */
106: List selectedResources = getSelectedResources();
107: IResource[] resources = (IResource[]) selectedResources
108: .toArray(new IResource[selectedResources.size()]);
109:
110: // Get the file names and a string representation
111: final int length = resources.length;
112: int actualLength = 0;
113: String[] fileNames = new String[length];
114: StringBuffer buf = new StringBuffer();
115: for (int i = 0; i < length; i++) {
116: IPath location = resources[i].getLocation();
117: // location may be null. See bug 29491.
118: if (location != null) {
119: fileNames[actualLength++] = location.toOSString();
120: }
121: if (i > 0) {
122: buf.append("\n"); //$NON-NLS-1$
123: }
124: buf.append(resources[i].getName());
125: }
126: // was one or more of the locations null?
127: if (actualLength < length) {
128: String[] tempFileNames = fileNames;
129: fileNames = new String[actualLength];
130: for (int i = 0; i < actualLength; i++) {
131: fileNames[i] = tempFileNames[i];
132: }
133: }
134: setClipboard(resources, fileNames, buf.toString());
135:
136: // update the enablement of the paste action
137: // workaround since the clipboard does not suppot callbacks
138: if (pasteAction != null
139: && pasteAction.getStructuredSelection() != null) {
140: pasteAction.selectionChanged(pasteAction
141: .getStructuredSelection());
142: }
143: }
144:
145: /**
146: * Set the clipboard contents. Prompt to retry if clipboard is busy.
147: *
148: * @param resources the resources to copy to the clipboard
149: * @param fileNames file names of the resources to copy to the clipboard
150: * @param names string representation of all names
151: */
152: private void setClipboard(IResource[] resources,
153: String[] fileNames, String names) {
154: try {
155: // set the clipboard contents
156: if (fileNames.length > 0) {
157: clipboard.setContents(new Object[] { resources,
158: fileNames, names }, new Transfer[] {
159: ResourceTransfer.getInstance(),
160: FileTransfer.getInstance(),
161: TextTransfer.getInstance() });
162: } else {
163: clipboard.setContents(
164: new Object[] { resources, names },
165: new Transfer[] {
166: ResourceTransfer.getInstance(),
167: TextTransfer.getInstance() });
168: }
169: } catch (SWTError e) {
170: if (e.code != DND.ERROR_CANNOT_SET_CLIPBOARD) {
171: throw e;
172: }
173: if (MessageDialog
174: .openQuestion(
175: shell,
176: ResourceNavigatorMessages.CopyToClipboardProblemDialog_title,
177: ResourceNavigatorMessages.CopyToClipboardProblemDialog_message)) {
178: setClipboard(resources, fileNames, names);
179: }
180: }
181: }
182:
183: /* (non-Javadoc)
184: * @see org.eclipse.ui.actions.BaseSelectionListenerAction#updateSelection(org.eclipse.jface.viewers.IStructuredSelection)
185: */
186: protected boolean updateSelection(IStructuredSelection selection) {
187:
188: /**
189: * The <code>CopyAction</code> implementation of this
190: * <code>SelectionListenerAction</code> method enables this action if
191: * one or more resources of compatible types are selected.
192: */
193:
194: if (!super .updateSelection(selection)) {
195: return false;
196: }
197:
198: if (getSelectedNonResources().size() > 0) {
199: return false;
200: }
201:
202: List selectedResources = getSelectedResources();
203: if (selectedResources.size() == 0) {
204: return false;
205: }
206:
207: boolean projSelected = selectionIsOfType(IResource.PROJECT);
208: boolean fileFoldersSelected = selectionIsOfType(IResource.FILE
209: | IResource.FOLDER);
210: if (!projSelected && !fileFoldersSelected) {
211: return false;
212: }
213:
214: // selection must be homogeneous
215: if (projSelected && fileFoldersSelected) {
216: return false;
217: }
218:
219: // must have a common parent
220: IContainer firstParent = ((IResource) selectedResources.get(0))
221: .getParent();
222: if (firstParent == null) {
223: return false;
224: }
225:
226: Iterator resourcesEnum = selectedResources.iterator();
227: while (resourcesEnum.hasNext()) {
228: IResource currentResource = (IResource) resourcesEnum
229: .next();
230: if (!currentResource.getParent().equals(firstParent)) {
231: return false;
232: }
233: }
234:
235: return true;
236: }
237:
238: }
|