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.List;
013:
014: import org.eclipse.core.resources.IContainer;
015: import org.eclipse.core.resources.IFile;
016: import org.eclipse.core.resources.IProject;
017: import org.eclipse.core.resources.IResource;
018: import org.eclipse.core.runtime.Assert;
019: import org.eclipse.jface.viewers.IStructuredSelection;
020: import org.eclipse.swt.dnd.Clipboard;
021: import org.eclipse.swt.dnd.FileTransfer;
022: import org.eclipse.swt.dnd.TransferData;
023: import org.eclipse.swt.widgets.Shell;
024: import org.eclipse.ui.PlatformUI;
025: import org.eclipse.ui.actions.CopyFilesAndFoldersOperation;
026: import org.eclipse.ui.actions.CopyProjectOperation;
027: import org.eclipse.ui.actions.SelectionListenerAction;
028: import org.eclipse.ui.internal.views.navigator.ResourceNavigatorMessages;
029: import org.eclipse.ui.part.ResourceTransfer;
030:
031: /**
032: * Standard action for pasting resources on the clipboard to the selected resource's location.
033: * <p>
034: * This class may be instantiated; it is not intended to be subclassed.
035: * </p>
036: *
037: * @since 2.0
038: */
039: /*package*/class PasteAction extends SelectionListenerAction {
040:
041: /**
042: * The id of this action.
043: */
044: public static final String ID = PlatformUI.PLUGIN_ID
045: + ".PasteAction";//$NON-NLS-1$
046:
047: /**
048: * The shell in which to show any dialogs.
049: */
050: private Shell shell;
051:
052: /**
053: * System clipboard
054: */
055: private Clipboard clipboard;
056:
057: /**
058: * Creates a new action.
059: *
060: * @param shell the shell for any dialogs
061: * @param clipboard the clipboard
062: */
063: public PasteAction(Shell shell, Clipboard clipboard) {
064: super (ResourceNavigatorMessages.PasteAction_title);
065: Assert.isNotNull(shell);
066: Assert.isNotNull(clipboard);
067: this .shell = shell;
068: this .clipboard = clipboard;
069: setToolTipText(ResourceNavigatorMessages.PasteAction_toolTip);
070: setId(PasteAction.ID);
071: PlatformUI.getWorkbench().getHelpSystem().setHelp(this ,
072: INavigatorHelpContextIds.PASTE_ACTION);
073: }
074:
075: /**
076: * Returns the actual target of the paste action. Returns null
077: * if no valid target is selected.
078: *
079: * @return the actual target of the paste action
080: */
081: private IResource getTarget() {
082: List selectedResources = getSelectedResources();
083:
084: for (int i = 0; i < selectedResources.size(); i++) {
085: IResource resource = (IResource) selectedResources.get(i);
086:
087: if (resource instanceof IProject
088: && !((IProject) resource).isOpen()) {
089: return null;
090: }
091: if (resource.getType() == IResource.FILE) {
092: resource = resource.getParent();
093: }
094: if (resource != null) {
095: return resource;
096: }
097: }
098: return null;
099: }
100:
101: /**
102: * Returns whether any of the given resources are linked resources.
103: *
104: * @param resources resource to check for linked type. may be null
105: * @return true=one or more resources are linked. false=none of the
106: * resources are linked
107: */
108: private boolean isLinked(IResource[] resources) {
109: for (int i = 0; i < resources.length; i++) {
110: if (resources[i].isLinked()) {
111: return true;
112: }
113: }
114: return false;
115: }
116:
117: /**
118: * Implementation of method defined on <code>IAction</code>.
119: */
120: public void run() {
121: // try a resource transfer
122: ResourceTransfer resTransfer = ResourceTransfer.getInstance();
123: IResource[] resourceData = (IResource[]) clipboard
124: .getContents(resTransfer);
125:
126: if (resourceData != null && resourceData.length > 0) {
127: if (resourceData[0].getType() == IResource.PROJECT) {
128: // enablement checks for all projects
129: for (int i = 0; i < resourceData.length; i++) {
130: CopyProjectOperation operation = new CopyProjectOperation(
131: this .shell);
132: operation.copyProject((IProject) resourceData[i]);
133: }
134: } else {
135: // enablement should ensure that we always have access to a container
136: IContainer container = getContainer();
137:
138: CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
139: this .shell);
140: operation.copyResources(resourceData, container);
141: }
142: return;
143: }
144:
145: // try a file transfer
146: FileTransfer fileTransfer = FileTransfer.getInstance();
147: String[] fileData = (String[]) clipboard
148: .getContents(fileTransfer);
149:
150: if (fileData != null) {
151: // enablement should ensure that we always have access to a container
152: IContainer container = getContainer();
153:
154: CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(
155: this .shell);
156: operation.copyFiles(fileData, container);
157: }
158: }
159:
160: /**
161: * Returns the container to hold the pasted resources.
162: */
163: private IContainer getContainer() {
164: List selection = getSelectedResources();
165: if (selection.get(0) instanceof IFile) {
166: return ((IFile) selection.get(0)).getParent();
167: } else {
168: return (IContainer) selection.get(0);
169: }
170: }
171:
172: /**
173: * The <code>PasteAction</code> implementation of this
174: * <code>SelectionListenerAction</code> method enables this action if
175: * a resource compatible with what is on the clipboard is selected.
176: *
177: * -Clipboard must have IResource or java.io.File
178: * -Projects can always be pasted if they are open
179: * -Workspace folder may not be copied into itself
180: * -Files and folders may be pasted to a single selected folder in open
181: * project or multiple selected files in the same folder
182: */
183: protected boolean updateSelection(IStructuredSelection selection) {
184: if (!super .updateSelection(selection)) {
185: return false;
186: }
187:
188: final IResource[][] clipboardData = new IResource[1][];
189: shell.getDisplay().syncExec(new Runnable() {
190: public void run() {
191: // clipboard must have resources or files
192: ResourceTransfer resTransfer = ResourceTransfer
193: .getInstance();
194: clipboardData[0] = (IResource[]) clipboard
195: .getContents(resTransfer);
196: }
197: });
198: IResource[] resourceData = clipboardData[0];
199: boolean isProjectRes = resourceData != null
200: && resourceData.length > 0
201: && resourceData[0].getType() == IResource.PROJECT;
202:
203: if (isProjectRes) {
204: for (int i = 0; i < resourceData.length; i++) {
205: // make sure all resource data are open projects
206: // can paste open projects regardless of selection
207: if (resourceData[i].getType() != IResource.PROJECT
208: || ((IProject) resourceData[i]).isOpen() == false) {
209: return false;
210: }
211: }
212: return true;
213: }
214:
215: if (getSelectedNonResources().size() > 0) {
216: return false;
217: }
218:
219: IResource targetResource = getTarget();
220: // targetResource is null if no valid target is selected (e.g., open project)
221: // or selection is empty
222: if (targetResource == null) {
223: return false;
224: }
225:
226: // can paste files and folders to a single selection (file, folder,
227: // open project) or multiple file selection with the same parent
228: List selectedResources = getSelectedResources();
229: if (selectedResources.size() > 1) {
230: for (int i = 0; i < selectedResources.size(); i++) {
231: IResource resource = (IResource) selectedResources
232: .get(i);
233: if (resource.getType() != IResource.FILE) {
234: return false;
235: }
236: if (!targetResource.equals(resource.getParent())) {
237: return false;
238: }
239: }
240: }
241: if (resourceData != null) {
242: // linked resources can only be pasted into projects
243: if (isLinked(resourceData)
244: && targetResource.getType() != IResource.PROJECT
245: && targetResource.getType() != IResource.FOLDER) {
246: return false;
247: }
248:
249: if (targetResource.getType() == IResource.FOLDER) {
250: // don't try to copy folder to self
251: for (int i = 0; i < resourceData.length; i++) {
252: if (targetResource.equals(resourceData[i])) {
253: return false;
254: }
255: }
256: }
257: return true;
258: }
259: TransferData[] transfers = clipboard.getAvailableTypes();
260: FileTransfer fileTransfer = FileTransfer.getInstance();
261: for (int i = 0; i < transfers.length; i++) {
262: if (fileTransfer.isSupportedType(transfers[i])) {
263: return true;
264: }
265: }
266: return false;
267: }
268: }
|