/* GanttProject is an opensource project management tool. Copyright (C) 2011 GanttProject Team This program 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. This program 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 this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package net.sourceforge.ganttproject.task; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.Iterator; import java.util.List; import com.google.common.base.Supplier; import net.sourceforge.ganttproject.gui.TaskSelectionContext; /** * This class manages the selected tasks. * * @author bbaranne */ public class TaskSelectionManager implements TaskSelectionContext { public interface Listener { void selectionChanged(List<Task> currentSelection); void userInputConsumerChanged(Object newConsumer); } /** * List of the selected tasks. */ private final List<Task> selectedTasks = new ArrayList<Task>(); private final List<Listener> myListeners = new ArrayList<Listener>(); private Object myUserInputConsumer; private final Supplier<TaskManager> myTaskManager; /** * Creates an instance of TaskSelectionManager */ public TaskSelectionManager(Supplier<TaskManager> taskManager) { myTaskManager = taskManager; } public void setUserInputConsumer(Object consumer) { if (consumer != myUserInputConsumer) { fireUserInputConsumerChanged(); } myUserInputConsumer = consumer; } /** * Adds <code>task</code> to the selected tasks. * * @param task * A task to add to the selected tasks. */ public void addTask(Task task) { if (!selectedTasks.contains(task)) { selectedTasks.add(task); fireSelectionChanged(); } } /** * Removes <code>task</code> from the selected tasks; * * @param task * A task to remove from the selected tasks. */ public void removeTask(Task task) { if (selectedTasks.contains(task)) { selectedTasks.remove(task); fireSelectionChanged(); } } private TaskContainmentHierarchyFacade getTaskHierarchy() { return myTaskManager.get().getTaskHierarchy(); } public void setSelectedTasks(List<Task> tasks) { // selection paths in Swing are stored in a hashtable // and thus come to selection listeners in pretty random order. // For correct indent/outdent operations with need // to order them the way they are ordered in the tree. Collections.sort(tasks, new Comparator<Task>() { @Override public int compare(Task o1, Task o2) { return getTaskHierarchy().compareDocumentOrder(o1, o2); } }); clear(); for (Task t : tasks) { addTask(t); } } /** * @param task * The task to test. * @return <code>true</code> if <code>task</code> is selected, * <code>false</code> otherwise. */ public boolean isTaskSelected(Task task) { return selectedTasks.contains(task); } /** @return The selected tasks list. */ @Override public List<Task> getSelectedTasks() { return Collections.unmodifiableList(selectedTasks); } /** @return The earliest start date. */ public Date getEarliestStart() { Date res = null; Iterator<Task> it = selectedTasks.iterator(); while (it.hasNext()) { Task task = it.next(); Date d = task.getStart().getTime(); if (res == null) { res = d; continue; } if (d.before(res)) res = d; } return res; } /** @return The latest end date. */ public Date getLatestEnd() { Date res = null; Iterator<Task> it = selectedTasks.iterator(); while (it.hasNext()) { Task task = it.next(); Date d = task.getEnd().getTime(); if (res == null) { res = d; continue; } if (d.after(res)) res = d; } return res; } /** Clears the selected tasks list. */ public void clear() { selectedTasks.clear(); fireSelectionChanged(); } public void addSelectionListener(Listener listener) { myListeners.add(listener); } public void removeSelectionListener(Listener listener) { myListeners.remove(listener); } public void fireSelectionChanged() { for (int i = 0; i < myListeners.size(); i++) { Listener next = myListeners.get(i); next.selectionChanged(Collections.unmodifiableList(selectedTasks)); } } private void fireUserInputConsumerChanged() { for (int i = 0; i < myListeners.size(); i++) { Listener next = myListeners.get(i); next.userInputConsumerChanged(myUserInputConsumer); } } }