blob: 3970092cc977f4801562f6df6693a7ac83eb700e [file] [log] [blame]
/************************************************************************
Copyright (c) 2000, 2003 IBM Corporation and others.
All rights reserved. This program and the accompanying materials
are made available under the terms of the Common Public License v1.0
which accompanies this distribution, and is available at
http://www.eclipse.org/legal/cpl-v10.html
Contributors:
IBM - Initial implementation
************************************************************************/
package org.eclipse.ui.views.navigator;
import java.util.*;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.jface.viewers.*;
import org.eclipse.swt.dnd.*;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.actions.ReadOnlyStateChecker;
import org.eclipse.ui.part.ResourceTransfer;
/**
* Implements drag behaviour when items are dragged out of the
* resource navigator.
*
* @since 2.0
*/
public class NavigatorDragAdapter extends DragSourceAdapter {
private static final String CHECK_MOVE_TITLE = ResourceNavigatorMessages.getString("DragAdapter.title"); //$NON-NLS-1$
private static final String CHECK_DELETE_MESSAGE = ResourceNavigatorMessages.getString("DragAdapter.checkDeleteMessage"); //$NON-NLS-1$
ISelectionProvider selectionProvider;
private TransferData lastDataType;
/**
* Constructs a new drag adapter.
*/
public NavigatorDragAdapter(ISelectionProvider provider) {
selectionProvider = provider;
}
/**
* @see DragSourceListener#dragFinished
*/
public void dragFinished(DragSourceEvent event) {
LocalSelectionTransfer.getInstance().setSelection(null);
if (event.doit == false)
return;
final int typeMask = IResource.FOLDER | IResource.FILE;
if (event.detail == DND.DROP_MOVE) {
//never delete resources when dragging outside Eclipse.
//workaround for bug 30543.
if (lastDataType != null && FileTransfer.getInstance().isSupportedType(lastDataType))
return;
IResource[] resources = getSelectedResources(typeMask);
DragSource dragSource = (DragSource) event.widget;
Control control = dragSource.getControl();
Shell shell = control.getShell();
ReadOnlyStateChecker checker;
if (resources == null || resources.length == 0)
return;
checker = new ReadOnlyStateChecker(shell, CHECK_MOVE_TITLE, CHECK_DELETE_MESSAGE);
resources = checker.checkReadOnlyResources(resources);
//delete the old elements
for (int i = 0; i < resources.length; i++) {
try {
resources[i].delete(IResource.KEEP_HISTORY | IResource.FORCE, null);
} catch (CoreException e) {
e.printStackTrace();
}
}
} else if (event.detail == DND.DROP_TARGET_MOVE) {
IResource[] resources = getSelectedResources(typeMask);
// file moved for us by OS, no need to delete the resources, just
// update the view
if (resources == null)
return;
for (int i = 0; i < resources.length; i++) {
try {
resources[i].refreshLocal(IResource.DEPTH_INFINITE, null);
} catch (CoreException e) {
e.printStackTrace();
}
}
}
}
/**
* @see DragSourceListener#dragSetData
*/
public void dragSetData(DragSourceEvent event) {
final int typeMask = IResource.FILE | IResource.FOLDER;
IResource[] resources = getSelectedResources(typeMask);
if (resources == null || resources.length == 0)
return;
lastDataType = event.dataType;
//use local selection transfer if possible
if (LocalSelectionTransfer.getInstance().isSupportedType(event.dataType)) {
event.data = LocalSelectionTransfer.getInstance().getSelection();
return;
}
//use resource transfer if possible
if (ResourceTransfer.getInstance().isSupportedType(event.dataType)) {
event.data = resources;
return;
}
//resort to a file transfer
if (!FileTransfer.getInstance().isSupportedType(event.dataType))
return;
// Get the path of each file and set as the drag data
final int length = resources.length;
int actualLength = 0;
String[] fileNames = new String[length];
for (int i = 0; i < length; i++) {
IPath location = resources[i].getLocation();
// location may be null. See bug 29491.
if (location != null)
fileNames[actualLength++] = location.toOSString();
}
if (actualLength == 0)
return;
// was one or more of the locations null?
if (actualLength < length) {
String[] tempFileNames = fileNames;
fileNames = new String[actualLength];
for (int i = 0; i < actualLength; i++)
fileNames[i] = tempFileNames[i];
}
event.data = fileNames;
}
/**
* @see DragSourceListener#dragStart
*/
public void dragStart(DragSourceEvent event) {
lastDataType = null;
// Workaround for 1GEUS9V
DragSource dragSource = (DragSource) event.widget;
Control control = dragSource.getControl();
if (control != control.getDisplay().getFocusControl()) {
event.doit = false;
return;
}
IStructuredSelection selection =
(IStructuredSelection) selectionProvider.getSelection();
for (Iterator i = selection.iterator(); i.hasNext();) {
Object next = i.next();
if (!(next instanceof IFile || next instanceof IFolder)) {
event.doit = false;
return;
}
}
if (selection.isEmpty()) {
event.doit = false;
return;
}
LocalSelectionTransfer.getInstance().setSelection(selection);
event.doit = true;
}
private IResource[] getSelectedResources(int resourceTypes) {
List resources = new ArrayList();
IResource[] result = new IResource[0];
ISelection selection = selectionProvider.getSelection();
if (!(selection instanceof IStructuredSelection) || selection.isEmpty()) {
return null;
}
IStructuredSelection structuredSelection = (IStructuredSelection) selection;
if (structuredSelection == null)
return null;
// loop through list and look for matching items
Iterator enum = structuredSelection.iterator();
while (enum.hasNext()) {
Object obj = enum.next();
if (obj instanceof IResource) {
IResource res = (IResource) obj;
if ((res.getType() & resourceTypes) == res.getType()) {
resources.add(res);
}
}
}
result = new IResource[resources.size()];
resources.toArray(result);
return result;
}
}