/*
Copyright 2012 GanttProject Team
This file is part of GanttProject, an opensource project management tool.
GanttProject is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
GanttProject is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GanttProject. If not, see <http://www.gnu.org/licenses/>.
*/
package net.sourceforge.ganttproject.chart.gantt;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
import net.sourceforge.ganttproject.GPLogger;
import net.sourceforge.ganttproject.language.GanttLanguage;
import net.sourceforge.ganttproject.task.ResourceAssignment;
import net.sourceforge.ganttproject.task.Task;
import net.sourceforge.ganttproject.task.TaskContainmentHierarchyFacade;
import net.sourceforge.ganttproject.task.TaskManager;
import net.sourceforge.ganttproject.task.TaskManager.TaskBuilder;
import net.sourceforge.ganttproject.task.dependency.TaskDependency;
import net.sourceforge.ganttproject.task.dependency.TaskDependencyConstraint;
import net.sourceforge.ganttproject.task.dependency.TaskDependencyException;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
/**
* Implements procedures for clipboard operations with tasks.
*
* @author dbarashev (Dmitry Barashev)
*/
public class ClipboardTaskProcessor {
private final TaskManager myTaskManager;
public ClipboardTaskProcessor(TaskManager taskManager) {
myTaskManager = taskManager;
}
public List<Task> pasteAsSibling(Task selectedTask, ClipboardContents clipboardContents) {
Task pasteRoot = myTaskManager.getTaskHierarchy().getContainer(selectedTask);
if (pasteRoot == null) {
pasteRoot = myTaskManager.getRootTask();
selectedTask = null;
}
return pasteAsChild(pasteRoot, selectedTask, clipboardContents);
}
public List<Task> pasteAsChild(Task selectedTask, ClipboardContents clipboardContents) {
return pasteAsChild(selectedTask, null, clipboardContents);
}
private List<Task> pasteAsChild(Task pasteRoot, Task anchor, ClipboardContents clipboardContents) {
List<Task> result = Lists.newArrayListWithExpectedSize(clipboardContents.getTasks().size());
Map<Task, Task> original2copy = Maps.newHashMap();
for (Task task : clipboardContents.getTasks()) {
Task copy = copyAndInsert(task, pasteRoot, anchor, original2copy, clipboardContents);
anchor = copy;
result.add(copy);
}
copyDependencies(clipboardContents, original2copy);
copyAssignments(clipboardContents, original2copy);
return result;
}
private void copyAssignments(ClipboardContents clipboardContents, Map<Task, Task> original2copy) {
for (ResourceAssignment ra : clipboardContents.getAssignments()) {
Task copy = original2copy.get(ra.getTask());
if (copy == null) {
continue;
}
ResourceAssignment newAssignment = copy.getAssignmentCollection().addAssignment(ra.getResource());
newAssignment.setLoad(ra.getLoad());
newAssignment.setRoleForAssignment(ra.getRoleForAssignment());
newAssignment.setCoordinator(ra.isCoordinator());
}
}
private void copyDependencies(ClipboardContents clipboardContents, Map<Task, Task> original2copy) {
for (TaskDependency td : clipboardContents.getIntraDeps()) {
Task dependee = td.getDependee();
Task dependant = td.getDependant();
TaskDependencyConstraint constraint = td.getConstraint();
try {
TaskDependency dep = myTaskManager.getDependencyCollection().createDependency(
original2copy.get(dependant),
original2copy.get(dependee),
myTaskManager.createConstraint(constraint.getType()));
dep.setDifference(td.getDifference());
dep.setHardness(td.getHardness());
} catch (TaskDependencyException e) {
GPLogger.log(e);
}
}
for (TaskDependency td : clipboardContents.getIncomingDeps()) {
Task predecessor = td.getDependee();
Task newSuccessor = original2copy.get(td.getDependant());
if (predecessor == null || newSuccessor == null) {
continue;
}
TaskDependency newDep = myTaskManager.getDependencyCollection().createDependency(
newSuccessor, predecessor, myTaskManager.createConstraint(td.getConstraint().getType()));
newDep.setDifference(td.getDifference());
newDep.setHardness(td.getHardness());
}
for (TaskDependency td : clipboardContents.getOutgoingDeps()) {
Task successor = td.getDependant();
Task newPredecessor = original2copy.get(td.getDependee());
if (newPredecessor == null || successor == null) {
continue;
}
TaskDependency newDep = myTaskManager.getDependencyCollection().createDependency(
successor, newPredecessor, myTaskManager.createConstraint(td.getConstraint().getType()));
newDep.setDifference(td.getDifference());
newDep.setHardness(td.getHardness());
}
}
private Task copyAndInsert(Task task, Task newContainer, Task prevSibling, Map<Task, Task> original2copy, ClipboardContents clipboardContents) {
TaskBuilder builder = myTaskManager.newTaskBuilder()
.withPrototype(task)
.withParent(newContainer)
.withPrevSibling(prevSibling);
if (clipboardContents.isCut()) {
builder = builder.withId(task.getTaskID()).withName(task.getName());
} else {
String newName = MessageFormat.format(myTaskManager.getTaskCopyNamePrefixOption().getValue(), GanttLanguage.getInstance().getText("copy2"), task.getName());
builder = builder.withName(newName);
}
Task result = builder.build();
original2copy.put(task, result);
Task anchor = null;
for (Task child : clipboardContents.getNestedTasks(task)) {
Task copied = copyAndInsert(child, result, anchor, original2copy, clipboardContents);
anchor = copied;
}
return result;
}
public boolean canMove(Task dropTarget, ClipboardContents clipboard) {
TaskContainmentHierarchyFacade hierarchy = myTaskManager.getTaskHierarchy();
for (Task t : clipboard.getTasks()) {
if (!hierarchy.areUnrelated(t, dropTarget)) {
return false;
}
}
return true;
}
}