blob: a37e7e0287459800702672f8a409be237ad39351 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2008 Tasktop Technologies 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:
* Tasktop Technologies - initial API and implementation
* Jevgeni Holodkov - improvements
*******************************************************************************/
package org.eclipse.mylyn.internal.tasks.ui.views;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerDropAdapter;
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory;
import org.eclipse.mylyn.internal.tasks.core.LocalTask;
import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.TaskCategory;
import org.eclipse.mylyn.internal.tasks.core.UncategorizedTaskContainer;
import org.eclipse.mylyn.internal.tasks.core.UnmatchedTaskContainer;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.util.AbstractRetrieveTitleFromUrlJob;
import org.eclipse.mylyn.internal.tasks.ui.util.PlatformUtil;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.internal.tasks.ui.views.TaskScheduleContentProvider.Unscheduled;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITaskContainer;
import org.eclipse.mylyn.tasks.ui.TasksUiUtil;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.TransferData;
import org.eclipse.ui.PlatformUI;
/**
* @author Mik Kersten
* @author Rob Elves (added URL based task creation support)
* @author Jevgeni Holodkov
*/
public class TaskListDropAdapter extends ViewerDropAdapter {
private boolean fileTransfer;
private boolean localTransfer;
public TaskListDropAdapter(Viewer viewer) {
super(viewer);
setFeedbackEnabled(true);
}
@Override
public void dragOver(DropTargetEvent event) {
// support dragging from sources only supporting DROP_LINK
if (event.detail == DND.DROP_NONE && (event.operations & DND.DROP_LINK) == DND.DROP_LINK) {
event.detail = DND.DROP_LINK;
}
super.dragOver(event);
}
@Override
public boolean performDrop(final Object data) {
List<ITask> tasksToMove = new ArrayList<ITask>();
if (localTransfer) {
ISelection selection = LocalSelectionTransfer.getTransfer().getSelection();
if (selection instanceof IStructuredSelection) {
for (Iterator<?> it = ((IStructuredSelection) selection).iterator(); it.hasNext();) {
Object item = it.next();
if (item instanceof ITask) {
tasksToMove.add((ITask) item);
}
}
}
} else if (fileTransfer) {
// TODO implement dropping of files
} else if (data instanceof String) {
String text = (String) data;
AbstractTask task = createTaskFromUrl(text);
if (task == null) {
task = TasksUiInternal.createNewLocalTask(text);
}
if (task != null) {
tasksToMove.add(task);
final ITask newTask = task;
PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() {
public void run() {
TasksUiUtil.openTask(newTask);
}
});
}
}
Object currentTarget = getCurrentTarget();
if (currentTarget instanceof LocalTask && areAllLocalTasks(tasksToMove) && getCurrentLocation() == LOCATION_ON) {
for (ITask task : tasksToMove) {
if (!((AbstractTask) task).contains(((LocalTask) currentTarget).getHandleIdentifier())) {
TasksUiInternal.getTaskList().addTask(task, (LocalTask) currentTarget);
}
}
} else {
for (ITask task : tasksToMove) {
if (currentTarget instanceof UncategorizedTaskContainer) {
TasksUiInternal.getTaskList().addTask(task, (UncategorizedTaskContainer) currentTarget);
} else if (currentTarget instanceof TaskCategory) {
TasksUiInternal.getTaskList().addTask(task, (TaskCategory) currentTarget);
} else if (currentTarget instanceof UnmatchedTaskContainer) {
if (((UnmatchedTaskContainer) currentTarget).getRepositoryUrl().equals(task.getRepositoryUrl())) {
TasksUiInternal.getTaskList().addTask(task, (AbstractTaskCategory) currentTarget);
}
} else if (currentTarget instanceof ITask) {
ITask targetTask = (ITask) currentTarget;
AbstractTaskCategory targetCategory = null;
// TODO: TaskCategory only used what about AbstractTaskCategory descendants?
ITaskContainer container = TaskCategory.getParentTaskCategory(targetTask);
if (container instanceof TaskCategory || container instanceof UncategorizedTaskContainer) {
targetCategory = (AbstractTaskCategory) container;
} else if (container instanceof UnmatchedTaskContainer) {
if (((UnmatchedTaskContainer) container).getRepositoryUrl().equals(task.getRepositoryUrl())) {
targetCategory = (AbstractTaskCategory) container;
}
}
if (targetCategory != null) {
TasksUiInternal.getTaskList().addTask(task, targetCategory);
}
} else if (currentTarget instanceof ScheduledTaskContainer) {
ScheduledTaskContainer container = (ScheduledTaskContainer) currentTarget;
if (container instanceof Unscheduled) {
TasksUiPlugin.getTaskActivityManager().setScheduledFor((AbstractTask) task, null);
} else {
TasksUiPlugin.getTaskActivityManager().setScheduledFor((AbstractTask) task,
container.getDateRange());
}
} else if (currentTarget == null) {
TasksUiInternal.getTaskList().addTask(task, TasksUiPlugin.getTaskList().getDefaultCategory());
}
}
}
if (tasksToMove.size() == 1) {
getViewer().setSelection(new StructuredSelection(tasksToMove.get(0)));
}
return true;
}
private boolean areAllLocalTasks(List<ITask> tasksToMove) {
for (ITask task : tasksToMove) {
if (!(task instanceof LocalTask)) {
return false;
}
}
return true;
}
/**
* @param data
* string containing url and title separated by <quote>\n</quote>
*/
private AbstractTask createTaskFromUrl(String data) {
if (!data.startsWith("http://") && !data.startsWith("https://")) { //$NON-NLS-1$ //$NON-NLS-2$
return null;
}
String[] urlTransfer = data.split("\n"); //$NON-NLS-1$
if (urlTransfer.length > 0) {
String url = urlTransfer[0];
AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager()
.getConnectorForRepositoryTaskUrl(url);
if (connector != null) {
// attempt to find task in task list
String repositoryUrl = connector.getRepositoryUrlFromTaskUrl(url);
String taskId = connector.getTaskIdFromTaskUrl(url);
AbstractTask task = TasksUiInternal.getTask(repositoryUrl, taskId, url);
if (task != null) {
return task;
}
if (repositoryUrl != null && taskId != null) {
// attempt to open task in background
// TODO: consider attaching a listener to OpenRepsitoryTaskJob to move task to drop target
TasksUiInternal.openRepositoryTask(connector.getConnectorKind(), repositoryUrl, taskId);
}
} else {
// create local task, using title of web page as a summary
final String summary = Messages.TaskListDropAdapter__retrieving_from_URL_;
final LocalTask newTask = TasksUiInternal.createNewLocalTask(summary);
newTask.setUrl(url);
AbstractRetrieveTitleFromUrlJob job = new AbstractRetrieveTitleFromUrlJob(url) {
@Override
protected void titleRetrieved(final String pageTitle) {
// make sure summary was not changed in the mean time
if (newTask.getSummary().equals(summary)) {
newTask.setSummary(pageTitle);
TasksUiInternal.getTaskList().notifyElementChanged(newTask);
}
}
};
job.schedule();
return newTask;
}
}
return null;
}
@Override
public boolean validateDrop(Object targetObject, int operation, TransferData transferType) {
fileTransfer = false;
localTransfer = false;
if (FileTransfer.getInstance().isSupportedType(transferType)) {
fileTransfer = true;
// TODO handle all files
return false;
} else if (LocalSelectionTransfer.getTransfer().isSupportedType(transferType)) {
localTransfer = true;
if (getCurrentTarget() instanceof UncategorizedTaskContainer || getCurrentTarget() instanceof TaskCategory
|| getCurrentTarget() instanceof UnmatchedTaskContainer
|| getCurrentTarget() instanceof ScheduledTaskContainer) {
return true;
} else if (getCurrentTarget() instanceof ITaskContainer
&& (getCurrentLocation() == ViewerDropAdapter.LOCATION_AFTER || getCurrentLocation() == ViewerDropAdapter.LOCATION_BEFORE)) {
return true;
} else if (getCurrentTarget() instanceof LocalTask && getCurrentLocation() == ViewerDropAdapter.LOCATION_ON) {
return true;
} else {
return false;
}
} else if (PlatformUtil.getUrlTransfer().isSupportedType(transferType)) {
return true;
}
return TextTransfer.getInstance().isSupportedType(transferType);
}
}