ItEr48S15CUFiltradoNaPlanificacionItEr47S17: Filter working for planning view.

This commit is contained in:
Manuel Rego Casasnovas 2010-02-17 09:10:02 +01:00 committed by Javier Moran Rua
parent 005ae9a94b
commit af7d653319
12 changed files with 313 additions and 73 deletions

View file

@ -0,0 +1,80 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
*
* 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/>.
*/
package org.zkoss.ganttz;
import org.zkoss.ganttz.data.Position;
import org.zkoss.ganttz.data.Task;
import org.zkoss.ganttz.data.TaskContainer;
import org.zkoss.ganttz.extensions.IContext;
/**
* A predicate over {@link Task} elements checking if it is visible. A
* {@link Task} should visible if it fulfill a filter and its parent (if any) is
* expanded.
*
* @author Manuel Rego Casasnovas <mrego@igalia.com>
*/
public abstract class FilterAndParentExpandedPredicates implements IPredicate {
private final IContext<?> context;
public FilterAndParentExpandedPredicates(IContext<?> context) {
this.context = context;
}
@Override
public boolean accepts(Object object) {
return accepts((Task) object);
}
private boolean accepts(Task task) {
return accpetsFilterPredicate(task)
&& getParentExpandedPredicate().accepts(task);
}
public abstract boolean accpetsFilterPredicate(Task task);
private IPredicate getParentExpandedPredicate() {
return new IPredicate() {
@Override
public boolean accepts(Object object) {
return accepts((Task) object);
}
private boolean accepts(Task task) {
Position position = context.getMapper().findPositionFor(task);
if (position.isAtTop()) {
return true;
} else {
for (TaskContainer taskContainer : position.getAncestors()) {
if (!taskContainer.isExpanded()) {
return false;
}
}
return true;
}
}
};
}
}

View file

@ -45,14 +45,16 @@ public class GanttPanel extends XulElement implements AfterCompose {
FunctionalityExposedForExtensions<?> context,
List<? extends CommandOnTaskContextualized<?>> commandsOnTasksContextualized,
CommandOnTaskContextualized<?> doubleClickCommand,
IDisabilityConfiguration disabilityConfiguration) {
IDisabilityConfiguration disabilityConfiguration,
FilterAndParentExpandedPredicates predicate) {
this.diagramGraph = context.getDiagramGraph();
timeTrackerComponent = timeTrackerForGanttPanel(context
.getTimeTracker());
appendChild(timeTrackerComponent);
dependencyList = new DependencyList(context);
tasksLists = TaskList.createFor(context, doubleClickCommand,
commandsOnTasksContextualized, disabilityConfiguration);
commandsOnTasksContextualized, disabilityConfiguration,
predicate);
appendChild(tasksLists);
appendChild(dependencyList);
}

View file

@ -42,6 +42,8 @@ public class LeftPane extends HtmlMacroComponent {
private final IDisabilityConfiguration disabilityConfiguration;
private FilterAndParentExpandedPredicates predicate;
public void setGoingDownInLastArrowCommand(
CommandContextualized<?> goingDownInLastArrowCommand) {
this.leftTasksTree
@ -49,16 +51,18 @@ public class LeftPane extends HtmlMacroComponent {
}
public LeftPane(IDisabilityConfiguration disabilityConfiguration,
List<Task> topLevelTasks) {
List<Task> topLevelTasks,
FilterAndParentExpandedPredicates predicate) {
this.topLevelTasks = topLevelTasks;
this.disabilityConfiguration = disabilityConfiguration;
this.predicate = predicate;
}
@Override
public void afterCompose() {
super.afterCompose();
leftTasksTree = new LeftTasksTree(disabilityConfiguration,
topLevelTasks);
topLevelTasks, predicate);
getContainer().appendChild(leftTasksTree);
leftTasksTree.afterCompose();
}
@ -80,4 +84,9 @@ public class LeftPane extends HtmlMacroComponent {
leftTasksTree.addTasks(position, newTasks);
}
public void setPredicate(FilterAndParentExpandedPredicates predicate) {
this.predicate = predicate;
leftTasksTree.setPredicate(predicate);
}
}

View file

@ -318,10 +318,16 @@ public class LeftTasksTree extends HtmlMacroComponent {
private final IDisabilityConfiguration disabilityConfiguration;
private FilterAndParentExpandedPredicates predicate;
private final List<Task> visibleTasks = new ArrayList<Task>();
public LeftTasksTree(IDisabilityConfiguration disabilityConfiguration,
List<Task> tasks) {
List<Task> tasks,
FilterAndParentExpandedPredicates predicate) {
this.disabilityConfiguration = disabilityConfiguration;
this.tasks = tasks;
this.predicate = predicate;
}
private void fillModel(Collection<? extends Task> tasks, boolean firstTime) {
@ -331,8 +337,19 @@ public class LeftTasksTree extends HtmlMacroComponent {
private void fillModel(Task parent, Integer insertionPosition,
Collection<? extends Task> children, final boolean firstTime) {
if (firstTime) {
this.tasksTreeModel.add(parent, insertionPosition, children);
for (Task node : children) {
if (predicate.accpetsFilterPredicate(node)) {
if (!visibleTasks.contains(node)) {
this.tasksTreeModel.add(parent, node);
visibleTasks.add(node);
}
} else {
if (visibleTasks.contains(node)) {
this.tasksTreeModel.remove(node);
visibleTasks.remove(node);
}
}
if (node.isContainer()) {
fillModel(node, 0, node.getTasks(), firstTime);
}
@ -341,12 +358,48 @@ public class LeftTasksTree extends HtmlMacroComponent {
} else {
for (Task node : children) {
if (node.isContainer()) {
this.deferredFiller.addParentOfPendingToAdd(node);
if (predicate.accpetsFilterPredicate(node)) {
if (!visibleTasks.contains(node)) {
this.deferredFiller.addParentOfPendingToAdd(node);
}
}
}
}
// the node must be added after, so the multistepTreeFiller is
// ready
this.tasksTreeModel.add(parent, insertionPosition, children);
for (Task node : children) {
if (predicate.accpetsFilterPredicate(node)) {
if (!visibleTasks.contains(node)) {
// this.tasksTreeModel.add(parent, 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);
}
}
}
@ -398,4 +451,9 @@ public class LeftTasksTree extends HtmlMacroComponent {
this.goingDownInLastArrowCommand = goingDownInLastArrowCommand;
}
public void setPredicate(FilterAndParentExpandedPredicates predicate) {
this.predicate = predicate;
fillModel(tasks, false);
}
}

View file

@ -338,10 +338,24 @@ public class Planner extends HtmlMacroComponent {
private void setupComponents() {
insertGlobalCommands();
this.leftPane = new LeftPane(disabilityConfiguration, this.diagramGraph
.getTopLevelTasks());
.getTopLevelTasks(),
new FilterAndParentExpandedPredicates(context) {
@Override
public boolean accpetsFilterPredicate(Task task) {
return true;
}
});
this.ganttPanel = new GanttPanel(this.context,
commandsOnTasksContextualized, doubleClickCommand,
disabilityConfiguration);
disabilityConfiguration,
new FilterAndParentExpandedPredicates(
context) {
@Override
public boolean accpetsFilterPredicate(Task task) {
return true;
}
});
Button button = (Button) getFellow("btnPrint");
button.setDisabled(!context.isPrintEnabled());
}
@ -510,4 +524,20 @@ public class Planner extends HtmlMacroComponent {
listZoomLevels.invalidate();
}
}
public IContext<?> getContext() {
return context;
}
public void setTaskListPredicate(FilterAndParentExpandedPredicates predicate) {
leftPane.setPredicate(predicate);
getTaskList().setPredicate(predicate);
getDependencyList().redrawDependencies();
// TODO Call invalidate() should not be needed in the future if we
// change Task and TaskContainer DSPs in order to use the UUID component
// in a div tag that wraps the component
ganttPanel.invalidate();
}
}

View file

@ -527,4 +527,9 @@ public class TaskComponent extends Div implements AfterCompose {
return task.isSubcontracted();
}
@Override
public String toString() {
return task.toString();
}
}

View file

@ -53,25 +53,22 @@ public class TaskContainerComponent extends TaskComponent implements
private transient IExpandListener expandListener;
public TaskContainerComponent(TaskContainer taskContainer, TaskList taskList) {
public TaskContainerComponent(final TaskContainer taskContainer,
final TaskList taskList) {
super(taskContainer, taskList.getDisabilityConfiguration());
if (!taskContainer.isContainer()) {
throw new IllegalArgumentException();
}
this.taskList = taskList;
this.expandListener = new IExpandListener() {
@Override
public void expandStateChanged(boolean isNowExpanded) {
if (isNowExpanded) {
open();
} else {
close();
}
taskList.reload(true);
updateClass();
}
};
taskContainer.addExpandListener(expandListener);
this.taskList = taskList;
for (Task task : taskContainer.getTasks()) {
getCurrentComponents().add(createChild(task));
}
@ -118,16 +115,6 @@ public class TaskContainerComponent extends TaskComponent implements
}
}
public void open() {
open(true);
}
public void open(boolean recolocate) {
Component previous = this;
List<TaskComponent> toAdd = getCurrentComponents();
addAllAt(previous, toAdd, recolocate);
}
private void addAllAt(Component previous, List<TaskComponent> toAdd,
boolean recolate) {
for (TaskComponent subtaskComponent : toAdd) {
@ -175,17 +162,6 @@ public class TaskContainerComponent extends TaskComponent implements
+ (getTaskContainer().isExpanded() ? "expanded" : "closed");
}
private void close() {
for (TaskComponent subtaskComponent : getCurrentComponents()) {
if (subtaskComponent instanceof TaskContainerComponent) {
TaskContainerComponent container = (TaskContainerComponent) subtaskComponent;
container.close();
}
taskList.hideTaskComponent(subtaskComponent);
taskList.redrawDependencies();
}
}
public void insert(Position position, Collection<? extends Task> newTasks) {
if (position.getParent().equals(getTask())) {
add(position.getInsertionPosition(), newTasks);

View file

@ -32,11 +32,11 @@ import org.zkoss.ganttz.data.Dependency;
import org.zkoss.ganttz.data.DependencyType;
import org.zkoss.ganttz.data.Position;
import org.zkoss.ganttz.data.Task;
import org.zkoss.ganttz.data.TaskContainer;
import org.zkoss.ganttz.timetracker.TimeTracker;
import org.zkoss.ganttz.timetracker.TimeTrackerComponent;
import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.ComponentsFinder;
import org.zkoss.ganttz.util.MenuBuilder;
import org.zkoss.ganttz.util.MenuBuilder.ItemAction;
import org.zkoss.zk.au.out.AuInvoke;
@ -67,39 +67,42 @@ public class TaskList extends XulElement implements AfterCompose {
private final IDisabilityConfiguration disabilityConfiguration;
private FilterAndParentExpandedPredicates predicate;
private List<Task> visibleTasks = new ArrayList<Task>();
private Map<Task, TaskComponent> taskComponentByTask;
public TaskList(
FunctionalityExposedForExtensions<?> context,
CommandOnTaskContextualized<?> doubleClickCommand,
List<Task> tasks,
List<? extends CommandOnTaskContextualized<?>> commandsOnTasksContextualized,
IDisabilityConfiguration disabilityConfiguration) {
IDisabilityConfiguration disabilityConfiguration,
FilterAndParentExpandedPredicates predicate) {
this.context = context;
this.doubleClickCommand = doubleClickCommand;
this.originalTasks = tasks;
this.commandsOnTasksContextualized = commandsOnTasksContextualized;
this.disabilityConfiguration = disabilityConfiguration;
this.predicate = predicate;
}
public static TaskList createFor(
FunctionalityExposedForExtensions<?> context,
CommandOnTaskContextualized<?> doubleClickCommand,
List<? extends CommandOnTaskContextualized<?>> commandsOnTasksContextualized,
IDisabilityConfiguration disabilityConfiguration) {
IDisabilityConfiguration disabilityConfiguration,
FilterAndParentExpandedPredicates predicate) {
TaskList result = new TaskList(context, doubleClickCommand, context
.getDiagramGraph().getTopLevelTasks(),
commandsOnTasksContextualized, disabilityConfiguration);
commandsOnTasksContextualized, disabilityConfiguration,
predicate);
return result;
}
public List<DependencyComponent> asDependencyComponents(
Collection<? extends Dependency> dependencies) {
List<? extends Object> children = getChildren();
List<TaskComponent> taskComponents = ComponentsFinder.findComponentsOfType(
TaskComponent.class, children);
Map<Task, TaskComponent> taskComponentByTask = new HashMap<Task, TaskComponent>();
for (TaskComponent taskComponent : taskComponents) {
taskComponent.publishTaskComponents(taskComponentByTask);
}
List<DependencyComponent> result = new ArrayList<DependencyComponent>();
for (Dependency dependency : dependencies) {
result.add(new DependencyComponent(taskComponentByTask
@ -118,7 +121,6 @@ public class TaskList extends XulElement implements AfterCompose {
final boolean isFirst = getFirstTopTaskComponent() == null
|| getFirstTopTaskComponent().equals(beforeThis);
insertBefore(taskComponent, beforeThis);
addContextMenu(taskComponent);
addListenerForTaskComponentEditForm(taskComponent);
taskComponent.afterCompose();
@ -130,13 +132,6 @@ public class TaskList extends XulElement implements AfterCompose {
adjustZoomColumnsHeight();
getGanttPanel().getDependencyList().redrawDependencies();
}
if (taskComponent instanceof TaskContainerComponent) {
TaskContainerComponent container = (TaskContainerComponent) taskComponent;
if (container.isExpanded()) {
container.open(relocate);
}
}
}
public synchronized void addTaskComponent(
@ -155,7 +150,10 @@ public class TaskList extends XulElement implements AfterCompose {
public void addTasks(Position position, Collection<? extends Task> newTasks) {
if (position.isAppendToTop()) {
for (Task t : newTasks) {
addTaskComponent(TaskComponent.asTaskComponent(t, this), true);
TaskComponent taskComponent = TaskComponent.asTaskComponent(t,
this);
addTaskComponent(taskComponent, true);
taskComponent.publishTaskComponents(taskComponentByTask);
}
} else if (position.isAtTop()) {
final int insertionPosition = position.getInsertionPosition();
@ -166,6 +164,7 @@ public class TaskList extends XulElement implements AfterCompose {
for (Task t : newTasks) {
TaskComponent toAdd = TaskComponent.asTaskComponent(t, this);
addTaskComponent(beforeThis, toAdd, true);
toAdd.publishTaskComponents(taskComponentByTask);
beforeThis = toAdd.getNextSibling();
}
} else {
@ -262,9 +261,15 @@ public class TaskList extends XulElement implements AfterCompose {
@Override
public void afterCompose() {
List<TaskComponent> taskComponents = new ArrayList<TaskComponent>();
for (Task task : originalTasks) {
addTaskComponent(TaskComponent.asTaskComponent(task, this), false);
TaskComponent taskComponent = TaskComponent.asTaskComponent(task,
this);
addTaskComponent(taskComponent, false);
taskComponents.add(taskComponent);
visibleTasks.add(task);
}
if (zoomLevelChangedListener == null) {
zoomLevelChangedListener = new IZoomLevelChangedListener() {
@Override
@ -277,6 +282,11 @@ public class TaskList extends XulElement implements AfterCompose {
};
getTimeTracker().addZoomListener(zoomLevelChangedListener);
}
taskComponentByTask = new HashMap<Task, TaskComponent>();
for (TaskComponent taskComponent : taskComponents) {
taskComponent.publishTaskComponents(taskComponentByTask);
}
}
private Map<TaskComponent, Menupopup> contextMenus = new HashMap<TaskComponent, Menupopup>();
@ -344,4 +354,62 @@ public class TaskList extends XulElement implements AfterCompose {
public IDisabilityConfiguration getDisabilityConfiguration() {
return disabilityConfiguration;
}
public void reload(boolean relocate) {
ArrayList<Task> tasksPendingToAdd = new ArrayList<Task>();
reload(originalTasks, tasksPendingToAdd, relocate);
addPendingTasks(tasksPendingToAdd, null, relocate);
}
private void reload(List<Task> tasks, List<Task> tasksPendingToAdd,
boolean relocate) {
for (Task task : tasks) {
if (visibleTasks.contains(task)) {
addPendingTasks(tasksPendingToAdd, find(task), relocate);
}
if (predicate.accepts(task)) {
if (!visibleTasks.contains(task)) {
tasksPendingToAdd.add(task);
}
} else {
if (visibleTasks.contains(task)) {
TaskComponent taskComponent = find(task);
hideTaskComponent(taskComponent);
visibleTasks.remove(task);
task.setVisible(false);
}
}
if (task instanceof TaskContainer) {
reload(task.getTasks(), tasksPendingToAdd, relocate);
}
}
}
private void addPendingTasks(List<Task> tasksPendingToAdd,
TaskComponent insertBefore, boolean relocate) {
if (tasksPendingToAdd.isEmpty()) {
return;
}
for (Task taskToAdd : tasksPendingToAdd) {
TaskComponent taskComponent = taskComponentByTask.get(taskToAdd);
if (taskComponent == null) {
taskComponent = TaskComponent.asTaskComponent(taskToAdd, this);
taskComponent.publishTaskComponents(taskComponentByTask);
}
addTaskComponent(insertBefore, taskComponent, relocate);
visibleTasks.add(taskToAdd);
taskToAdd.setVisible(true);
}
tasksPendingToAdd.clear();
}
public void setPredicate(FilterAndParentExpandedPredicates predicate) {
this.predicate = predicate;
reload(false);
}
}

View file

@ -51,7 +51,7 @@ public class Milestone extends Task {
}
@Override
protected void setVisible(boolean visible) {
public void setVisible(boolean visible) {
super.setVisible(visible);
if (!this.expanded) {
return;

View file

@ -110,7 +110,7 @@ public abstract class Task implements ITaskFundamentalProperties {
return visible;
}
protected void setVisible(boolean visible) {
public void setVisible(boolean visible) {
boolean previousValue = this.visible;
this.visible = visible;
visibilityProperties.firePropertyChange("visible", previousValue,
@ -315,4 +315,10 @@ public abstract class Task implements ITaskFundamentalProperties {
}
public abstract boolean canBeExplicitlyMoved();
@Override
public String toString() {
return fundamentalProperties.getName();
}
}

View file

@ -150,7 +150,7 @@ public class TaskContainer extends Task {
}
@Override
protected void setVisible(boolean visible) {
public void setVisible(boolean visible) {
super.setVisible(visible);
if (!this.expanded) {
return;
@ -163,9 +163,6 @@ public class TaskContainer extends Task {
public void setExpanded(boolean expanded) {
boolean valueChanged = expanded != this.expanded;
this.expanded = expanded;
for (Task task : tasks) {
task.setVisible(this.expanded);
}
if (valueChanged) {
expandListeners
.fireEvent(new IListenerNotification<IExpandListener>() {

View file

@ -43,8 +43,11 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.zkoss.ganttz.FilterAndParentExpandedPredicates;
import org.zkoss.ganttz.Planner;
import org.zkoss.ganttz.data.Task;
import org.zkoss.ganttz.extensions.ICommand;
import org.zkoss.ganttz.extensions.IContext;
import org.zkoss.ganttz.resourceload.ScriptsRequiredByResourceLoadPanel;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
@ -54,7 +57,6 @@ import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.util.Composer;
import org.zkoss.zul.Constraint;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Messagebox;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Vbox;
@ -194,13 +196,20 @@ public class OrderPlanningController implements Composer {
name);
}
private void filterByPredicate(OrderElementPredicate predicate) {
// TODO
try {
Messagebox.show("TODO");
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
private void filterByPredicate(final OrderElementPredicate predicate) {
final IContext<?> context = planner.getContext();
planner.setTaskListPredicate(new FilterAndParentExpandedPredicates(context) {
@Override
public boolean accpetsFilterPredicate(Task task) {
if (predicate == null) {
return true;
}
TaskElement taskElement = (TaskElement) context.getMapper()
.findAssociatedDomainObject(task);
return predicate.accepts(taskElement.getOrderElement());
}
});
}
public Constraint checkConstraintFinishDate() {