2009-10-01 18:46:46 +02:00
|
|
|
/*
|
2011-10-28 08:17:54 +02:00
|
|
|
* This file is part of LibrePlan
|
2009-10-01 18:46:46 +02:00
|
|
|
*
|
2010-07-19 09:36:44 +02:00
|
|
|
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
|
2010-07-19 09:47:20 +02:00
|
|
|
* Desenvolvemento Tecnolóxico de Galicia
|
2011-01-19 18:00:09 +01:00
|
|
|
* Copyright (C) 2010-2011 Igalia, S.L.
|
2009-10-01 18:46:46 +02:00
|
|
|
*
|
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
|
* it under the terms of the GNU Affero 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 Affero General Public License for more details.
|
|
|
|
|
*
|
|
|
|
|
* You should have received a copy of the GNU Affero General Public License
|
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2009-04-14 17:51:03 +02:00
|
|
|
package org.zkoss.ganttz;
|
|
|
|
|
|
2009-07-24 17:48:46 +02:00
|
|
|
import java.lang.reflect.Method;
|
2009-07-13 14:01:42 +02:00
|
|
|
import java.util.ArrayList;
|
2009-07-24 17:48:46 +02:00
|
|
|
import java.util.Arrays;
|
2009-07-28 20:17:49 +02:00
|
|
|
import java.util.Collection;
|
2009-07-05 17:15:27 +02:00
|
|
|
import java.util.HashMap;
|
2009-07-10 20:40:20 +02:00
|
|
|
import java.util.HashSet;
|
2009-04-29 17:40:02 +02:00
|
|
|
import java.util.List;
|
2009-07-13 14:01:42 +02:00
|
|
|
import java.util.ListIterator;
|
2009-07-05 17:15:27 +02:00
|
|
|
import java.util.Map;
|
2009-07-10 20:40:20 +02:00
|
|
|
import java.util.Set;
|
2009-04-14 17:51:03 +02:00
|
|
|
|
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
|
|
import org.apache.commons.logging.LogFactory;
|
2009-07-20 15:37:39 +02:00
|
|
|
import org.zkoss.ganttz.LeftTasksTreeRow.ILeftTasksTreeNavigator;
|
2010-02-15 01:20:19 +01:00
|
|
|
import org.zkoss.ganttz.adapters.IDisabilityConfiguration;
|
2009-07-28 20:17:49 +02:00
|
|
|
import org.zkoss.ganttz.data.Position;
|
2009-07-20 18:00:11 +02:00
|
|
|
import org.zkoss.ganttz.data.Task;
|
|
|
|
|
import org.zkoss.ganttz.data.TaskContainer;
|
2010-02-10 12:48:27 +01:00
|
|
|
import org.zkoss.ganttz.data.TaskContainer.IExpandListener;
|
2009-09-30 23:30:52 +02:00
|
|
|
import org.zkoss.ganttz.util.ComponentsFinder;
|
2009-07-10 20:40:19 +02:00
|
|
|
import org.zkoss.ganttz.util.MutableTreeModel;
|
2009-07-05 17:15:31 +02:00
|
|
|
import org.zkoss.zk.ui.Component;
|
|
|
|
|
import org.zkoss.zk.ui.Executions;
|
2009-04-14 17:51:03 +02:00
|
|
|
import org.zkoss.zk.ui.HtmlMacroComponent;
|
2009-07-05 17:15:30 +02:00
|
|
|
import org.zkoss.zk.ui.event.Event;
|
|
|
|
|
import org.zkoss.zk.ui.event.EventListener;
|
|
|
|
|
import org.zkoss.zk.ui.event.OpenEvent;
|
2009-07-05 17:15:26 +02:00
|
|
|
import org.zkoss.zul.Tree;
|
2009-07-05 17:15:27 +02:00
|
|
|
import org.zkoss.zul.TreeModel;
|
2009-07-08 13:03:43 +02:00
|
|
|
import org.zkoss.zul.Treecell;
|
2009-07-05 17:15:26 +02:00
|
|
|
import org.zkoss.zul.Treeitem;
|
|
|
|
|
import org.zkoss.zul.TreeitemRenderer;
|
2009-04-14 17:51:03 +02:00
|
|
|
|
2011-11-15 23:09:35 +01:00
|
|
|
/**
|
|
|
|
|
* Tree element to display tasks structure in the planning Gantt <br />
|
|
|
|
|
*
|
|
|
|
|
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
|
|
|
|
* @author Manuel Rego Casasnovas <mrego@igalia.com>
|
|
|
|
|
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
|
|
|
|
|
*/
|
2009-07-20 15:37:39 +02:00
|
|
|
public class LeftTasksTree extends HtmlMacroComponent {
|
2009-04-14 17:51:03 +02:00
|
|
|
|
2009-07-05 17:15:26 +02:00
|
|
|
private final class TaskBeanRenderer implements TreeitemRenderer {
|
2010-02-10 12:48:27 +01:00
|
|
|
private Map<TaskContainer, IExpandListener> expandListeners = new HashMap<TaskContainer, IExpandListener>();
|
|
|
|
|
|
|
|
|
|
public void render(final Treeitem item, Object data) throws Exception {
|
2009-07-20 18:00:11 +02:00
|
|
|
Task task = (Task) data;
|
|
|
|
|
item.setOpen(isOpened(task));
|
2010-02-10 12:48:27 +01:00
|
|
|
if (task instanceof TaskContainer) {
|
|
|
|
|
final TaskContainer container = (TaskContainer) task;
|
|
|
|
|
IExpandListener expandListener = new IExpandListener() {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void expandStateChanged(boolean isNowExpanded) {
|
|
|
|
|
item.setOpen(isNowExpanded);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
expandListeners.put(container, expandListener);
|
|
|
|
|
container.addExpandListener(expandListener);
|
|
|
|
|
|
|
|
|
|
}
|
2010-02-15 01:20:19 +01:00
|
|
|
LeftTasksTreeRow leftTasksTreeRow = LeftTasksTreeRow.create(
|
2011-11-14 19:18:23 +01:00
|
|
|
disabilityConfiguration, task, new TreeNavigator(
|
|
|
|
|
tasksTreeModel, task), planner);
|
2009-07-20 18:00:11 +02:00
|
|
|
if (task.isContainer()) {
|
|
|
|
|
expandWhenOpened((TaskContainer) task, item);
|
2009-07-05 17:15:30 +02:00
|
|
|
}
|
2010-08-17 16:26:01 +02:00
|
|
|
Component row;
|
|
|
|
|
if (disabilityConfiguration.isTreeEditable()) {
|
|
|
|
|
row = Executions.getCurrent().createComponents(
|
|
|
|
|
"~./ganttz/zul/leftTasksTreeRow.zul", item, null);
|
|
|
|
|
} else {
|
|
|
|
|
row = Executions.getCurrent().createComponents(
|
|
|
|
|
"~./ganttz/zul/leftTasksTreeRowLabels.zul", item, null);
|
|
|
|
|
}
|
2009-07-20 15:37:39 +02:00
|
|
|
leftTasksTreeRow.doAfterCompose(row);
|
2009-07-10 20:40:19 +02:00
|
|
|
List<Object> rowChildren = row.getChildren();
|
2009-09-30 23:30:52 +02:00
|
|
|
List<Treecell> treeCells = ComponentsFinder.findComponentsOfType(
|
2009-07-10 20:40:19 +02:00
|
|
|
Treecell.class, rowChildren);
|
2009-07-20 18:00:11 +02:00
|
|
|
detailsForBeans.put(task, leftTasksTreeRow);
|
2009-07-24 17:48:46 +02:00
|
|
|
deferredFiller.isBeingRendered(task, item);
|
2009-07-05 17:15:26 +02:00
|
|
|
}
|
2009-07-05 17:15:30 +02:00
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private void expandWhenOpened(final TaskContainer taskBean,
|
2009-07-05 17:15:30 +02:00
|
|
|
Treeitem item) {
|
|
|
|
|
item.addEventListener("onOpen", new EventListener() {
|
|
|
|
|
@Override
|
2011-06-06 17:46:26 +02:00
|
|
|
public void onEvent(Event event) {
|
2009-07-05 17:15:30 +02:00
|
|
|
OpenEvent openEvent = (OpenEvent) event;
|
|
|
|
|
taskBean.setExpanded(openEvent.isOpen());
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
public boolean isOpened(Task task) {
|
|
|
|
|
return task.isLeaf() || task.isExpanded();
|
2009-07-05 17:15:26 +02:00
|
|
|
}
|
|
|
|
|
|
2011-06-06 16:08:26 +02:00
|
|
|
private static final class DetailsForBeans {
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private Map<Task, LeftTasksTreeRow> map = new HashMap<Task, LeftTasksTreeRow>();
|
2009-07-10 20:40:20 +02:00
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private Set<Task> focusRequested = new HashSet<Task>();
|
2009-07-10 20:40:20 +02:00
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
public void put(Task task, LeftTasksTreeRow leftTasksTreeRow) {
|
|
|
|
|
map.put(task, leftTasksTreeRow);
|
|
|
|
|
if (focusRequested.contains(task)) {
|
|
|
|
|
focusRequested.remove(task);
|
2009-07-20 15:37:39 +02:00
|
|
|
leftTasksTreeRow.receiveFocus();
|
2009-07-10 20:40:20 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
public void requestFocusFor(Task task) {
|
|
|
|
|
focusRequested.add(task);
|
2009-07-10 20:40:20 +02:00
|
|
|
}
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
public LeftTasksTreeRow get(Task taskbean) {
|
2009-07-10 20:40:20 +02:00
|
|
|
return map.get(taskbean);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private DetailsForBeans detailsForBeans = new DetailsForBeans();
|
2009-07-05 17:15:27 +02:00
|
|
|
|
2009-07-20 15:37:39 +02:00
|
|
|
private final class TreeNavigator implements ILeftTasksTreeNavigator {
|
2009-07-05 17:15:27 +02:00
|
|
|
private final int[] pathToNode;
|
2009-07-20 18:00:11 +02:00
|
|
|
private final Task task;
|
2009-07-05 17:15:27 +02:00
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private TreeNavigator(TreeModel treemodel, Task task) {
|
2009-07-13 14:01:40 +02:00
|
|
|
this.task = task;
|
|
|
|
|
this.pathToNode = tasksTreeModel.getPath(tasksTreeModel.getRoot(),
|
|
|
|
|
task);
|
2009-07-05 17:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2009-07-20 15:37:39 +02:00
|
|
|
public LeftTasksTreeRow getAboveRow() {
|
2009-07-20 18:00:11 +02:00
|
|
|
Task parent = getParent(pathToNode);
|
2009-07-05 17:15:27 +02:00
|
|
|
int lastPosition = pathToNode[pathToNode.length - 1];
|
|
|
|
|
if (lastPosition != 0) {
|
|
|
|
|
return getChild(parent, lastPosition - 1);
|
2009-07-10 20:40:19 +02:00
|
|
|
} else if (tasksTreeModel.getRoot() != parent) {
|
2009-07-13 14:01:42 +02:00
|
|
|
return getDetailFor(parent);
|
2009-07-05 17:15:27 +02:00
|
|
|
}
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private LeftTasksTreeRow getChild(Task parent, int position) {
|
|
|
|
|
Task child = tasksTreeModel.getChild(parent, position);
|
2009-07-13 14:01:42 +02:00
|
|
|
return getDetailFor(child);
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private LeftTasksTreeRow getDetailFor(Task child) {
|
2009-07-10 20:40:19 +02:00
|
|
|
return detailsForBeans.get(child);
|
2009-07-05 17:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
2009-07-20 15:37:39 +02:00
|
|
|
public LeftTasksTreeRow getBelowRow() {
|
2009-07-13 14:01:40 +02:00
|
|
|
if (isExpanded() && hasChildren()) {
|
|
|
|
|
return getChild(task, 0);
|
2009-07-05 17:15:27 +02:00
|
|
|
}
|
2009-07-13 14:01:42 +02:00
|
|
|
for (ChildAndParent childAndParent : group(task, tasksTreeModel
|
|
|
|
|
.getParents(task))) {
|
|
|
|
|
if (childAndParent.childIsNotLast()) {
|
|
|
|
|
return getDetailFor(childAndParent.getNextToChild());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// it's the last one, it has none below
|
2009-07-05 17:15:27 +02:00
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-24 17:48:46 +02:00
|
|
|
public List<ChildAndParent> group(Task origin, List<Task> parents) {
|
2009-07-13 14:01:42 +02:00
|
|
|
ArrayList<ChildAndParent> result = new ArrayList<ChildAndParent>();
|
2009-07-20 18:00:11 +02:00
|
|
|
Task child = origin;
|
|
|
|
|
Task parent;
|
|
|
|
|
ListIterator<Task> listIterator = parents.listIterator();
|
2009-07-13 14:01:42 +02:00
|
|
|
while (listIterator.hasNext()) {
|
|
|
|
|
parent = listIterator.next();
|
2009-07-16 10:40:55 +02:00
|
|
|
result.add(new ChildAndParent(child, parent));
|
2009-07-13 14:01:42 +02:00
|
|
|
child = parent;
|
|
|
|
|
}
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class ChildAndParent {
|
2009-07-20 18:00:11 +02:00
|
|
|
private final Task parent;
|
2009-07-13 14:01:42 +02:00
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private final Task child;
|
2009-07-13 14:01:42 +02:00
|
|
|
|
|
|
|
|
private Integer positionOfChildCached;
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private ChildAndParent(Task child, Task parent) {
|
2009-07-13 14:01:42 +02:00
|
|
|
this.parent = parent;
|
|
|
|
|
this.child = child;
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
public Task getNextToChild() {
|
2009-07-13 14:01:42 +02:00
|
|
|
return tasksTreeModel
|
|
|
|
|
.getChild(parent, getPositionOfChild() + 1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public boolean childIsNotLast() {
|
|
|
|
|
return getPositionOfChild() < numberOfChildrenForParent() - 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int numberOfChildrenForParent() {
|
|
|
|
|
return tasksTreeModel.getChildCount(parent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private int getPositionOfChild() {
|
2009-11-03 20:38:03 +01:00
|
|
|
if (positionOfChildCached != null) {
|
2009-07-13 14:01:42 +02:00
|
|
|
return positionOfChildCached;
|
2009-11-03 20:38:03 +01:00
|
|
|
}
|
2009-07-13 14:01:42 +02:00
|
|
|
int[] path = tasksTreeModel.getPath(parent, child);
|
|
|
|
|
return positionOfChildCached = path[path.length - 1];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-13 14:01:40 +02:00
|
|
|
private boolean hasChildren() {
|
2009-07-16 10:40:55 +02:00
|
|
|
return task.isContainer() && task.getTasks().size() > 0;
|
2009-07-13 14:01:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private boolean isExpanded() {
|
2009-07-16 10:40:55 +02:00
|
|
|
return task.isContainer() && task.isExpanded();
|
2009-07-13 14:01:40 +02:00
|
|
|
}
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private Task getParent(int[] path) {
|
|
|
|
|
Task current = tasksTreeModel.getRoot();
|
2009-07-05 17:15:27 +02:00
|
|
|
for (int i = 0; i < path.length - 1; i++) {
|
2009-07-10 20:40:19 +02:00
|
|
|
current = tasksTreeModel.getChild(current, path[i]);
|
2009-07-05 17:15:27 +02:00
|
|
|
}
|
2009-07-10 20:40:19 +02:00
|
|
|
return current;
|
2009-07-05 17:15:27 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-24 17:48:46 +02:00
|
|
|
/**
|
|
|
|
|
* This class is a workaround for an issue with zk {@link Tree}. Once the
|
2010-01-22 20:50:39 +01:00
|
|
|
* tree is created, adding a node with children is troublesome. Only the top
|
2009-07-24 17:48:46 +02:00
|
|
|
* element is added to the tree, although the element has children. The Tree
|
|
|
|
|
* discards the adding event for the children because the parent says it's
|
|
|
|
|
* not loaded. This is the condition that is not satisfied:<br />
|
|
|
|
|
* <code>if(parent != null &&
|
|
|
|
|
(!(parent instanceof Treeitem) || ((Treeitem)parent).isLoaded())){</code><br />
|
|
|
|
|
* This problem is present in zk 3.6.1 at least.
|
|
|
|
|
* @author Óscar González Fernández <ogonzalez@igalia.com>
|
|
|
|
|
* @see Tree#onTreeDataChange
|
|
|
|
|
*/
|
|
|
|
|
private class DeferredFiller {
|
|
|
|
|
|
|
|
|
|
private Set<Task> pendingToAddChildren = new HashSet<Task>();
|
|
|
|
|
|
|
|
|
|
public void addParentOfPendingToAdd(Task parent) {
|
|
|
|
|
pendingToAddChildren.add(parent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void isBeingRendered(final Task parent, final Treeitem item) {
|
2009-11-03 20:38:03 +01:00
|
|
|
if (!pendingToAddChildren.contains(parent)) {
|
2009-07-24 17:48:46 +02:00
|
|
|
return;
|
2009-11-03 20:38:03 +01:00
|
|
|
}
|
2009-07-24 17:48:46 +02:00
|
|
|
markLoaded(item);
|
2009-07-28 20:17:49 +02:00
|
|
|
fillModel(parent, 0, parent.getTasks(), false);
|
2009-07-24 17:48:46 +02:00
|
|
|
pendingToAddChildren.remove(parent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void markLoaded(Treeitem item) {
|
|
|
|
|
try {
|
|
|
|
|
Method method = getSetLoadedMethod();
|
|
|
|
|
method.invoke(item, true);
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-07-28 20:17:49 +02:00
|
|
|
|
2009-07-24 17:48:46 +02:00
|
|
|
private Method setLoadedMethod = null;
|
|
|
|
|
|
|
|
|
|
private Method getSetLoadedMethod() {
|
2009-11-03 20:38:03 +01:00
|
|
|
if (setLoadedMethod != null) {
|
2009-07-24 17:48:46 +02:00
|
|
|
return setLoadedMethod;
|
2009-11-03 20:38:03 +01:00
|
|
|
}
|
2009-07-24 17:48:46 +02:00
|
|
|
try {
|
|
|
|
|
Method method = Treeitem.class.getDeclaredMethod("setLoaded",
|
|
|
|
|
Boolean.TYPE);
|
|
|
|
|
method.setAccessible(true);
|
|
|
|
|
return setLoadedMethod = method;
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
throw new RuntimeException(e);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-20 15:37:39 +02:00
|
|
|
private static Log LOG = LogFactory.getLog(LeftTasksTree.class);
|
2009-06-15 21:48:54 +02:00
|
|
|
|
2009-07-24 17:48:46 +02:00
|
|
|
private final DeferredFiller deferredFiller = new DeferredFiller();
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private final List<Task> tasks;
|
2009-06-15 21:48:54 +02:00
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
private MutableTreeModel<Task> tasksTreeModel;
|
2009-07-05 17:15:26 +02:00
|
|
|
|
|
|
|
|
private Tree tasksTree;
|
|
|
|
|
|
2009-07-20 15:37:42 +02:00
|
|
|
private CommandContextualized<?> goingDownInLastArrowCommand;
|
|
|
|
|
|
2010-02-15 01:20:19 +01:00
|
|
|
private final IDisabilityConfiguration disabilityConfiguration;
|
|
|
|
|
|
2010-02-17 09:10:02 +01:00
|
|
|
private FilterAndParentExpandedPredicates predicate;
|
|
|
|
|
|
|
|
|
|
private final List<Task> visibleTasks = new ArrayList<Task>();
|
|
|
|
|
|
2011-11-14 19:18:23 +01:00
|
|
|
private Planner planner;
|
|
|
|
|
|
2010-02-15 01:20:19 +01:00
|
|
|
public LeftTasksTree(IDisabilityConfiguration disabilityConfiguration,
|
2011-11-14 19:18:23 +01:00
|
|
|
Planner planner,
|
2010-02-17 09:10:02 +01:00
|
|
|
FilterAndParentExpandedPredicates predicate) {
|
2010-02-15 01:20:19 +01:00
|
|
|
this.disabilityConfiguration = disabilityConfiguration;
|
2011-11-14 19:18:23 +01:00
|
|
|
this.tasks = planner.getTaskList().getAllTasks();
|
2010-02-17 09:10:02 +01:00
|
|
|
this.predicate = predicate;
|
2011-11-14 19:18:23 +01:00
|
|
|
this.planner = planner;
|
2009-04-14 17:51:03 +02:00
|
|
|
}
|
|
|
|
|
|
2009-07-28 20:17:49 +02:00
|
|
|
private void fillModel(Collection<? extends Task> tasks, boolean firstTime) {
|
|
|
|
|
fillModel(this.tasksTreeModel.getRoot(), 0, tasks, firstTime);
|
2009-04-29 17:40:02 +02:00
|
|
|
}
|
|
|
|
|
|
2009-07-28 20:17:49 +02:00
|
|
|
private void fillModel(Task parent, Integer insertionPosition,
|
|
|
|
|
Collection<? extends Task> children, final boolean firstTime) {
|
2010-03-16 08:59:42 +01:00
|
|
|
if (predicate.isFilterContainers()) {
|
|
|
|
|
parent = this.tasksTreeModel.getRoot();
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-28 20:17:49 +02:00
|
|
|
if (firstTime) {
|
|
|
|
|
for (Task node : children) {
|
2010-03-16 08:59:42 +01:00
|
|
|
if (predicate.accpetsFilterPredicateAndContainers(node)) {
|
2010-02-17 09:10:02 +01:00
|
|
|
if (!visibleTasks.contains(node)) {
|
|
|
|
|
this.tasksTreeModel.add(parent, node);
|
|
|
|
|
visibleTasks.add(node);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (visibleTasks.contains(node)) {
|
|
|
|
|
this.tasksTreeModel.remove(node);
|
|
|
|
|
visibleTasks.remove(node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2009-07-24 17:48:46 +02:00
|
|
|
if (node.isContainer()) {
|
2009-07-28 20:17:49 +02:00
|
|
|
fillModel(node, 0, node.getTasks(), firstTime);
|
2009-07-24 17:48:46 +02:00
|
|
|
}
|
2009-07-28 20:17:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
for (Task node : children) {
|
2009-07-24 17:48:46 +02:00
|
|
|
if (node.isContainer()) {
|
2010-03-16 08:59:42 +01:00
|
|
|
if (predicate.accpetsFilterPredicateAndContainers(node)) {
|
2010-02-17 09:10:02 +01:00
|
|
|
if (!visibleTasks.contains(node)) {
|
|
|
|
|
this.deferredFiller.addParentOfPendingToAdd(node);
|
|
|
|
|
}
|
|
|
|
|
}
|
2009-07-24 17:48:46 +02:00
|
|
|
}
|
2009-07-10 20:40:19 +02:00
|
|
|
}
|
2009-07-28 20:17:49 +02:00
|
|
|
// the node must be added after, so the multistepTreeFiller is
|
|
|
|
|
// ready
|
2010-02-17 09:10:02 +01:00
|
|
|
for (Task node : children) {
|
2010-03-16 08:59:42 +01:00
|
|
|
if (predicate.accpetsFilterPredicateAndContainers(node)) {
|
2010-02-17 09:10:02 +01:00
|
|
|
if (!visibleTasks.contains(node)) {
|
|
|
|
|
this.tasksTreeModel.add(parent, insertionPosition,
|
|
|
|
|
Arrays.asList(node));
|
|
|
|
|
visibleTasks.add(node);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (visibleTasks.contains(node)) {
|
|
|
|
|
this.tasksTreeModel.remove(node);
|
|
|
|
|
removeTaskAndAllChildren(visibleTasks, node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (node.isContainer()) {
|
|
|
|
|
fillModel(node, 0, node.getTasks(), firstTime);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (visibleTasks.contains(node)) {
|
|
|
|
|
insertionPosition++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void removeTaskAndAllChildren(List<Task> visibleTasks, Task task) {
|
|
|
|
|
visibleTasks.remove(task);
|
|
|
|
|
|
|
|
|
|
if (task.isContainer()) {
|
|
|
|
|
for (Task node : task.getTasks()) {
|
|
|
|
|
removeTaskAndAllChildren(visibleTasks, node);
|
|
|
|
|
}
|
2009-07-10 20:40:19 +02:00
|
|
|
}
|
2009-07-05 17:15:26 +02:00
|
|
|
}
|
|
|
|
|
|
2009-07-20 18:00:11 +02:00
|
|
|
public void taskRemoved(Task taskRemoved) {
|
2009-07-12 21:31:27 +02:00
|
|
|
tasksTreeModel.remove(taskRemoved);
|
2009-04-29 17:40:02 +02:00
|
|
|
}
|
|
|
|
|
|
2009-06-15 21:48:54 +02:00
|
|
|
@Override
|
|
|
|
|
public void afterCompose() {
|
2009-06-29 11:43:23 +02:00
|
|
|
setClass("listdetails");
|
2009-06-15 21:48:54 +02:00
|
|
|
super.afterCompose();
|
2009-07-05 17:15:26 +02:00
|
|
|
tasksTree = (Tree) getFellow("tasksTree");
|
2009-07-20 18:00:11 +02:00
|
|
|
tasksTreeModel = MutableTreeModel.create(Task.class);
|
2009-07-24 17:48:46 +02:00
|
|
|
fillModel(tasks, true);
|
2009-07-05 17:15:26 +02:00
|
|
|
tasksTree.setModel(tasksTreeModel);
|
|
|
|
|
tasksTree.setTreeitemRenderer(new TaskBeanRenderer());
|
2009-04-14 17:51:03 +02:00
|
|
|
}
|
|
|
|
|
|
2009-07-28 20:17:49 +02:00
|
|
|
void addTask(Position position, Task task) {
|
|
|
|
|
if (position.isAppendToTop()) {
|
|
|
|
|
fillModel(Arrays.asList(task), false);
|
|
|
|
|
detailsForBeans.requestFocusFor(task);
|
|
|
|
|
} else {
|
|
|
|
|
List<Task> toAdd = Arrays.asList(task);
|
|
|
|
|
fillModel(position.getParent(), position.getInsertionPosition(),
|
|
|
|
|
toAdd, false);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void addTasks(Position position, Collection<? extends Task> newTasks) {
|
2009-07-28 20:17:49 +02:00
|
|
|
Task root = tasksTreeModel.getRoot();
|
2009-07-28 20:17:49 +02:00
|
|
|
if (position.isAppendToTop()) {
|
2009-07-28 20:17:49 +02:00
|
|
|
fillModel(root, tasksTreeModel.getChildCount(root), newTasks, false);
|
2009-07-28 20:17:49 +02:00
|
|
|
} else if (position.isAtTop()) {
|
2009-07-28 20:17:49 +02:00
|
|
|
fillModel(root,
|
2009-07-28 20:17:49 +02:00
|
|
|
position.getInsertionPosition(), newTasks, false);
|
|
|
|
|
} else {
|
|
|
|
|
fillModel(position.getParent(), position.getInsertionPosition(),
|
|
|
|
|
newTasks, false);
|
|
|
|
|
}
|
2009-06-30 20:31:08 +02:00
|
|
|
}
|
|
|
|
|
|
2009-07-20 15:37:42 +02:00
|
|
|
public CommandContextualized<?> getGoingDownInLastArrowCommand() {
|
|
|
|
|
return goingDownInLastArrowCommand;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void setGoingDownInLastArrowCommand(
|
|
|
|
|
CommandContextualized<?> goingDownInLastArrowCommand) {
|
|
|
|
|
this.goingDownInLastArrowCommand = goingDownInLastArrowCommand;
|
|
|
|
|
}
|
|
|
|
|
|
2010-02-17 09:10:02 +01:00
|
|
|
public void setPredicate(FilterAndParentExpandedPredicates predicate) {
|
|
|
|
|
this.predicate = predicate;
|
2010-03-16 08:59:42 +01:00
|
|
|
|
|
|
|
|
visibleTasks.clear();
|
|
|
|
|
tasksTreeModel = MutableTreeModel.create(Task.class);
|
|
|
|
|
fillModel(tasks, true);
|
|
|
|
|
tasksTree.setModel(tasksTreeModel);
|
2010-02-17 09:10:02 +01:00
|
|
|
}
|
|
|
|
|
|
2009-07-01 17:42:47 +02:00
|
|
|
}
|