/******************************************************************************* * Copyright © 2004, 2013 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 * *******************************************************************************/ package org.eclipse.edt.ide.ui.internal.packageexplorer; import java.lang.reflect.InvocationTargetException; import java.util.Iterator; import java.util.List; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.edt.ide.core.internal.model.EGLElementTransfer; import org.eclipse.edt.ide.core.model.EGLModelException; import org.eclipse.edt.ide.core.model.IEGLElement; import org.eclipse.edt.ide.core.model.IEGLFile; import org.eclipse.edt.ide.core.model.IPackageFragment; import org.eclipse.edt.ide.core.model.IPackageFragmentRoot; import org.eclipse.edt.ide.ui.EDTUIPlugin; import org.eclipse.edt.ide.ui.internal.EGLLogger; import org.eclipse.edt.ide.ui.internal.UINlsStrings; import org.eclipse.edt.ide.ui.internal.refactoring.ReorgCopyStarter; import org.eclipse.jface.util.Assert; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.swt.dnd.Clipboard; import org.eclipse.swt.dnd.FileTransfer; import org.eclipse.swt.dnd.TransferData; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.ISharedImages; import org.eclipse.ui.actions.CopyFilesAndFoldersOperation; import org.eclipse.ui.actions.CopyProjectOperation; import org.eclipse.ui.actions.SelectionListenerAction; import org.eclipse.ui.part.ResourceTransfer; public class PasteAction extends SelectionListenerAction { /** * The shell in which to show any dialogs. */ private Shell shell; /** * System clipboard */ private Clipboard clipboard; /** * @param text */ public PasteAction(Shell shell, Clipboard clipboard) { super(UINlsStrings.EGLPasteAction_Label); Assert.isNotNull(shell); Assert.isNotNull(clipboard); this.shell = shell; this.clipboard = clipboard; setToolTipText(""); //$NON-NLS-1$ //setId(PasteAction.ID); //WorkbenchHelp.setHelp(this, INavigatorHelpContextIds.PASTE_ACTION); ISharedImages workbenchImages= EDTUIPlugin.getDefault().getWorkbench().getSharedImages(); setDisabledImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE_DISABLED)); setImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE)); setHoverImageDescriptor(workbenchImages.getImageDescriptor(ISharedImages.IMG_TOOL_PASTE)); updateSelection(getStructuredSelection()); } /** * Implementation of method defined on <code>IAction</code>. */ public void run() { // try egl transfer EGLElementTransfer eglTransfer = EGLElementTransfer.getInstance(); IEGLElement[] eglData = (IEGLElement[])clipboard.getContents(eglTransfer); if(eglData != null && eglData.length > 0) { try { //if the source is EGLFile, destination is PackageFragmentRoot, need to conver PackageFragmentRoot to default packageFragment IEGLElement target = getEGLTarget(getStructuredSelection()); if(target instanceof IPackageFragmentRoot) { //let's check the source if (eglData[0] instanceof IEGLFile) { IPackageFragment defaultpkg = ((IPackageFragmentRoot)target).getPackageFragment(""); //$NON-NLS-1$ target = defaultpkg; } } if(!startRefactoring(new IResource[0], eglData, target)) { CopyResourceAndFilesFolderOperation copyOp = new CopyResourceAndFilesFolderOperation(eglData, target, true, shell); try { copyOp.run(null); } catch (CoreException e) { e.printStackTrace(); } } } catch(EGLModelException e) { EGLLogger.log(this, e); } } else if(eglData == null) //try resource { // try a resource transfer ResourceTransfer resTransfer = ResourceTransfer.getInstance(); IResource[] resourceData = (IResource[])clipboard.getContents(resTransfer); if (resourceData != null && resourceData.length > 0) { if (resourceData[0].getType() == IResource.PROJECT) { // enablement checks for all projects for (int i = 0; i < resourceData.length; i++) { CopyProjectOperation operation = new CopyProjectOperation(this.shell); operation.copyProject((IProject) resourceData[i]); } } else { // enablement should ensure that we always have access to a container IContainer container = getContainer(); CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(this.shell); operation.copyResources(resourceData, container); } return; } // try a file transfer FileTransfer fileTransfer = FileTransfer.getInstance(); String[] fileData = (String[])clipboard.getContents(fileTransfer); if (fileData != null) { // enablement should ensure that we always have access to a container IContainer container = getContainer(); CopyFilesAndFoldersOperation operation = new CopyFilesAndFoldersOperation(this.shell); operation.copyFiles(fileData, container); } } } /** * Returns the actual target of the paste action. Returns null * if no valid target is selected. * * @return the actual target of the paste action */ private IEGLElement getEGLTarget(IStructuredSelection selection) { List selectedResources = selection.toList(); //List selectedResources = getSelectedResources(); for(Iterator iter=selectedResources.iterator(); iter.hasNext();) { Object element = iter.next(); if(element instanceof IEGLElement) return (IEGLElement)element; } return null; } /** * The <code>PasteAction</code> implementation of this * <code>SelectionListenerAction</code> method enables this action if * a resource compatible with what is on the clipboard is selected. * * - souce -destination * EGLFile EGLPackageFragment, EGLPackageFramgmentRoot(default package) * EGLPackageFragment EGLPackageFragmentRoot * * -Clipboard must have IResource or java.io.File * -Projects can always be pasted if they are open * -Workspace folder may not be copied into itself * -Files and folders may be pasted to a single selected folder in open * project or multiple selected files in the same folder */ protected boolean updateSelection(IStructuredSelection selection) { if (!super.updateSelection(selection)) return false; if(selection.toList().size() > 1) //you can only paste to one selection return false; EGLElementTransfer eglTransfer = EGLElementTransfer.getInstance(); IEGLElement[] clipboardData = (IEGLElement[])clipboard.getContents(eglTransfer); if(clipboardData != null && clipboardData.length > 0) { IEGLElement eglTgt = getEGLTarget(selection); if(eglTgt == null) return false; int iTgtType = eglTgt.getElementType(); //test the egl paste rule for(int i=0; i<clipboardData.length; i++) { IEGLElement eglelem = clipboardData[i]; int iSrcType = eglelem.getElementType(); if(iSrcType == IEGLElement.EGL_FILE) { if((iTgtType != IEGLElement.PACKAGE_FRAGMENT) && (iTgtType != IEGLElement.PACKAGE_FRAGMENT_ROOT)) return false; } else if(iSrcType == IEGLElement.PACKAGE_FRAGMENT) { if(iTgtType != IEGLElement.PACKAGE_FRAGMENT_ROOT) return false; } else return false; } } else if(clipboardData == null) //try resource return canResourcePaste(selection); return true; } private boolean canResourcePaste(IStructuredSelection selection) { final IResource[][] clipboardData = new IResource[1][]; shell.getDisplay().syncExec(new Runnable() { public void run() { // clipboard must have resources or files ResourceTransfer resTransfer = ResourceTransfer.getInstance(); clipboardData[0] = (IResource[])clipboard.getContents(resTransfer); } }); IResource[] resourceData = clipboardData[0]; boolean isProjectRes = resourceData != null && resourceData.length > 0 && resourceData[0].getType() == IResource.PROJECT; if (isProjectRes) { for (int i = 0; i < resourceData.length; i++) { // make sure all resource data are open projects // can paste open projects regardless of selection if (resourceData[i].getType() != IResource.PROJECT || ((IProject) resourceData[i]).isOpen() == false) return false; } return true; } if (getSelectedNonResources().size() > 0) return false; IResource targetResource = getTarget(); // targetResource is null if no valid target is selected (e.g., open project) // or selection is empty if (targetResource == null) return false; // can paste files and folders to a single selection (file, folder, // open project) or multiple file selection with the same parent List selectedResources = getSelectedResources(); if (selectedResources.size() > 1) { for (int i = 0; i < selectedResources.size(); i++) { IResource resource = (IResource)selectedResources.get(i); if (resource.getType() != IResource.FILE) return false; if (!targetResource.equals(resource.getParent())) return false; } } if (resourceData != null) { // linked resources can only be pasted into projects if (isLinked(resourceData) && targetResource.getType() != IResource.PROJECT) return false; if (targetResource.getType() == IResource.FOLDER) { // don't try to copy folder to self for (int i = 0; i < resourceData.length; i++) { if (targetResource.equals(resourceData[i])) return false; } } return true; } TransferData[] transfers = clipboard.getAvailableTypes(); FileTransfer fileTransfer = FileTransfer.getInstance(); for (int i = 0; i < transfers.length; i++) { if (fileTransfer.isSupportedType(transfers[i])) return true; } return false; } /** * Returns the container to hold the pasted resources. */ private IContainer getContainer() { List selection = getSelectedResources(); if (selection.get(0) instanceof IFile) return ((IFile)selection.get(0)).getParent(); else return (IContainer)selection.get(0); } /** * Returns the actual target of the paste action. Returns null * if no valid target is selected. * * @return the actual target of the paste action */ private IResource getTarget() { List selectedResources = getSelectedResources(); for (int i = 0; i < selectedResources.size(); i++) { IResource resource = (IResource)selectedResources.get(i); if (resource instanceof IProject && !((IProject)resource).isOpen()) return null; if (resource.getType() == IResource.FILE) resource = resource.getParent(); if (resource != null) return resource; } return null; } /** * Returns whether any of the given resources are linked resources. * * @param resources resource to check for linked type. may be null * @return true=one or more resources are linked. false=none of the * resources are linked */ private boolean isLinked(IResource[] resources) { for (int i = 0; i < resources.length; i++) { if (resources[i].isLinked()) return true; } return false; } private boolean startRefactoring(IResource[] resources, IEGLElement[] eglElements, IEGLElement destination) throws EGLModelException{ try { ReorgCopyStarter create = ReorgCopyStarter.create(eglElements, resources, destination); if(create == null) { return false; } create.run(shell); } catch (InterruptedException e) { EGLLogger.log(this, e); } catch (InvocationTargetException e) { EGLLogger.log(this, e); } return true; } }