/******************************************************************************* * Copyright (c) 2014-2015 Red Hat 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Mickael Istria (Red Hat Inc.) *******************************************************************************/ package org.eclipse.ui.internal.navigator.workingsets; import java.util.ArrayList; import java.util.List; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.Adapters; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.jface.util.LocalSelectionTransfer; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.TreePath; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTargetEvent; import org.eclipse.swt.dnd.TransferData; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.IWorkingSetManager; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.navigator.CommonDropAdapter; import org.eclipse.ui.navigator.CommonDropAdapterAssistant; /** * Allow dragging projects between working sets in the Project Explorer. * * @since 3.4.800 */ public class ProjectInWorkingSetDropAdapterAssistant extends CommonDropAdapterAssistant { @Override public IStatus validateDrop(Object target, int operation, TransferData transferType) { // We don't currently support COPY or LINK if (operation != DND.DROP_MOVE) { return Status.CANCEL_STATUS; } IWorkingSet targetWorkingSet = Adapters.adapt(target, IWorkingSet.class); if (targetWorkingSet == null) { return Status.CANCEL_STATUS; } if (!LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) { return Status.CANCEL_STATUS; } // Verify that we have at least one project not already in the target ISelection sel = LocalSelectionTransfer.getTransfer().getSelection(); if (!sel.isEmpty() && sel instanceof IStructuredSelection) { for (Object item : ((IStructuredSelection) sel).toArray()) { IProject project = Adapters.adapt(item, IProject.class); if (project != null && !workingSetContains(targetWorkingSet, project)) { return Status.OK_STATUS; } } } return Status.CANCEL_STATUS; } @Override public IStatus handleDrop(CommonDropAdapter dropAdapter, DropTargetEvent dropTargetEvent, Object target) { IWorkingSetManager workingSetManager = PlatformUI.getWorkbench().getWorkingSetManager(); IWorkingSet targetWorkingSet = Adapters.adapt(target, IWorkingSet.class); ISelection sel = LocalSelectionTransfer.getTransfer().getSelection(); if (sel instanceof ITreeSelection) { for (TreePath path : ((ITreeSelection) sel).getPaths()) { IProject project = Adapters.adapt(path.getLastSegment(), IProject.class); if (project != null) { if (!workingSetContains(targetWorkingSet, project)) { workingSetManager.addToWorkingSets(project, new IWorkingSet[] { targetWorkingSet }); } // Check if our top-level element is a working set so that // we can perform a move IWorkingSet sourceWorkingSet = Adapters.adapt(path.getFirstSegment(), IWorkingSet.class); if (sourceWorkingSet != null) { removeFromWorkingSet(project, sourceWorkingSet); } } } } else if (sel instanceof IStructuredSelection) { for (Object item : ((IStructuredSelection) sel).toArray()) { IProject project = Adapters.adapt(item, IProject.class); if (project != null && !workingSetContains(targetWorkingSet, project)) { workingSetManager.addToWorkingSets(project, new IWorkingSet[] { targetWorkingSet }); } } } return Status.OK_STATUS; } /** * Remove the given project from the provided working set * * @param project * the project to remove * @param workingSet * the working set */ private void removeFromWorkingSet(IProject project, IWorkingSet workingSet) { IAdaptable[] srcElements = workingSet.getElements(); List<IAdaptable> newSrcElements = new ArrayList<IAdaptable>(); for (IAdaptable srcElement : srcElements) { if (!project.equals(Adapters.adapt(srcElement, IProject.class))) { newSrcElements.add(srcElement); } } IAdaptable[] adaptedNewSrcElements = workingSet .adaptElements(newSrcElements.toArray(new IAdaptable[newSrcElements.size()])); workingSet.setElements(adaptedNewSrcElements); } /** * Verify if the working set contains the given project * * @param workingSet * the working set to check * @param project * the project to check * @return true if the provided project is contained in the working set, * false otherwise */ private boolean workingSetContains(IWorkingSet workingSet, IProject project) { for (IAdaptable element : workingSet.getElements()) { if (project.equals(Adapters.adapt(element, IProject.class))) { return true; } } return false; } }