ItEr55S11RFAspectosGraficosRecursoLimitantesItEr54S12: Created basic LimitingResources controller and components structure

This commit is contained in:
Lorenzo Tilve 2010-04-26 09:45:13 +02:00 committed by Javier Moran Rua
parent 813b77c04f
commit db2600c111
16 changed files with 1337 additions and 0 deletions

View file

@ -0,0 +1,136 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galic
* ia
*
* 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.limitingresources;
import java.util.ArrayList;
import java.util.List;
import org.joda.time.LocalDate;
import org.zkoss.ganttz.IDatesMapper;
import org.zkoss.ganttz.data.resourceload.LoadPeriod;
import org.zkoss.ganttz.data.resourceload.LoadTimeLine;
import org.zkoss.ganttz.timetracker.TimeTracker;
import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.zul.Div;
import org.zkoss.zul.impl.XulElement;
/**
* This class wraps ResourceLoad data inside an specific HTML Div component.
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
public class LimitingResourcesComponent extends XulElement {
public static LimitingResourcesComponent create(TimeTracker timeTracker,
LoadTimeLine loadLine) {
return new LimitingResourcesComponent(timeTracker, loadLine);
}
private final LoadTimeLine loadLine;
private final TimeTracker timeTracker;
private transient IZoomLevelChangedListener zoomChangedListener;
private LimitingResourcesComponent(final TimeTracker timeTracker,
final LoadTimeLine loadLine) {
this.loadLine = loadLine;
this.timeTracker = timeTracker;
createChildren(loadLine, timeTracker.getMapper());
zoomChangedListener = new IZoomLevelChangedListener() {
@Override
public void zoomLevelChanged(ZoomLevel detailLevel) {
getChildren().clear();
createChildren(loadLine, timeTracker.getMapper());
invalidate();
}
};
this.timeTracker.addZoomListener(zoomChangedListener);
}
private void createChildren(LoadTimeLine loadLine, IDatesMapper mapper) {
List<Div> divs = createDivsForPeriods(mapper, loadLine.getLoadPeriods());
for (Div div : divs) {
appendChild(div);
}
}
public String getResourceLoadName() {
return loadLine.getConceptName();
}
public String getResourceLoadType() {
return loadLine.getType();
}
private static List<Div> createDivsForPeriods(IDatesMapper datesMapper,
List<LoadPeriod> loadPeriods) {
List<Div> result = new ArrayList<Div>();
for (LoadPeriod loadPeriod : loadPeriods) {
result.add(createDivForPeriod(datesMapper, loadPeriod));
}
return result;
}
private static Div createDivForPeriod(IDatesMapper datesMapper,
LoadPeriod loadPeriod) {
Div result = new Div();
result.setClass(String.format("taskassignmentinterval %s", loadPeriod
.getLoadLevel().getCategory()));
String load = "Load: " + loadPeriod.getLoadLevel().getPercentage()
+ "% , ";
if (loadPeriod.getLoadLevel().getPercentage() == Integer.MAX_VALUE) {
load = "";
}
result.setTooltiptext(load
+ "total work hours: " + loadPeriod.getTotalResourceWorkHours()
+ " , " + "assigned hours: " + loadPeriod.getAssignedHours());
result.setLeft(forCSS(getStartPixels(datesMapper, loadPeriod)));
result.setWidth(forCSS(getWidthPixels(datesMapper, loadPeriod)));
return result;
}
private static int getWidthPixels(IDatesMapper datesMapper,
LoadPeriod loadPeriod) {
LocalDate start = loadPeriod.getStart();
LocalDate end = loadPeriod.getEnd();
return datesMapper
.toPixels(toMilliseconds(end) - toMilliseconds(start));
}
private static long toMilliseconds(LocalDate localDate) {
return localDate.toDateMidnight().getMillis();
}
private static String forCSS(int pixels) {
return String.format("%dpx", pixels);
}
private static int getStartPixels(IDatesMapper datesMapper,
LoadPeriod loadPeriod) {
return datesMapper.toPixels(loadPeriod.getStart().toDateMidnight()
.toDate());
}
}

View file

@ -0,0 +1,197 @@
/*
* 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.limitingresources;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.zkoss.ganttz.data.resourceload.LoadTimeLine;
import org.zkoss.ganttz.util.MutableTreeModel;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlMacroComponent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zul.Div;
import org.zkoss.zul.Label;
import org.zkoss.zul.Popup;
import org.zkoss.zul.Treecell;
import org.zkoss.zul.Treechildren;
import org.zkoss.zul.Treeitem;
import org.zkoss.zul.TreeitemRenderer;
import org.zkoss.zul.Treerow;
import org.zkoss.zul.api.Tree;
public class LimitingResourcesLeftPane extends HtmlMacroComponent {
private MutableTreeModel<LoadTimeLine> modelForTree;
private final LimitingResourcesList limitingResourcesList;
public LimitingResourcesLeftPane(MutableTreeModel<LoadTimeLine> modelForTree,
LimitingResourcesList resourceLoadList) {
this.limitingResourcesList = resourceLoadList;
this.modelForTree = modelForTree;
}
@Override
public void afterCompose() {
super.afterCompose();
getContainerTree().setModel(modelForTree);
getContainerTree().setTreeitemRenderer(getRendererForTree());
}
private TreeitemRenderer getRendererForTree() {
return new TreeitemRenderer() {
@Override
public void render(Treeitem item, Object data)
throws Exception {
LoadTimeLine line = (LoadTimeLine) data;
item.setOpen(false);
item.setValue(line);
Treerow row = new Treerow();
Treecell cell = new Treecell();
Component component = createComponent(line);
item.appendChild(row);
row.appendChild(cell);
cell.appendChild(component);
collapse(line);
addExpandedListener(item, line);
}
private void addExpandedListener(final Treeitem item,
final LoadTimeLine line) {
item.addEventListener("onOpen", new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
OpenEvent openEvent = (OpenEvent) event;
if (openEvent.isOpen()) {
List<LoadTimeLine> closed = calculatedClosedItems(item);
expand(line, closed);
} else {
collapse(line);
}
}
});
}
private Component createComponent(LoadTimeLine line) {
return isTopLevel(line) ? createFirstLevel(line)
: createSecondLevel(line);
}
private boolean isTopLevel(LoadTimeLine line) {
int[] path = modelForTree.getPath(modelForTree.getRoot(), line);
return path.length == 0;
}
};
}
private void collapse(LoadTimeLine line) {
limitingResourcesList.collapse(line);
}
private void expand(LoadTimeLine line, List<LoadTimeLine> closed) {
limitingResourcesList.expand(line, closed);
}
private List<LoadTimeLine> calculatedClosedItems(Treeitem item) {
List<LoadTimeLine> result = new ArrayList<LoadTimeLine>();
Treechildren treeChildren = item.getTreechildren();
if (treeChildren != null) {
List<Treeitem> myTreeItems = (List<Treeitem>) treeChildren
.getChildren();
Iterator<Treeitem> iterator = myTreeItems.iterator();
while (iterator.hasNext()) {
Treeitem child = (Treeitem) iterator.next();
if (!child.isOpen()) {
result.addAll(getLineChildrenBy(child));
} else {
result.addAll(calculatedClosedItems(child));
}
}
}
return result;
}
private List<LoadTimeLine> getLineChildrenBy(Treeitem item) {
List<LoadTimeLine> result = new ArrayList<LoadTimeLine>();
LoadTimeLine line = getLineByTreeitem(item);
if (line != null) {
result.addAll(line.getAllChildren());
}
return result;
}
private LoadTimeLine getLineByTreeitem(Treeitem child) {
LoadTimeLine line = null;
try {
line = (LoadTimeLine) child.getValue();
} catch (Exception e) {
return null;
}
return line;
}
private Tree getContainerTree() {
return (Tree) getFellow("loadsTree");
}
private Component createFirstLevel(LoadTimeLine principal) {
Div result = createLabelWithName(principal);
result.setSclass("firstlevel");
return result;
}
private Component createSecondLevel(LoadTimeLine loadTimeLine) {
Div result = createLabelWithName(loadTimeLine);
result.setSclass("secondlevel");
return result;
}
private Div createLabelWithName(LoadTimeLine principal) {
Div result = new Div();
Label label = new Label();
final String conceptName = principal.getConceptName();
label.setValue(conceptName);
limitValue(result, label, 40);
result.appendChild(label);
return result;
}
private static void limitValue(Div parent, Label label, int maxLength) {
String originalValue = label.getValue();
if (originalValue == null || originalValue.length() <= maxLength) {
return;
}
label.setValue(originalValue.substring(0, maxLength - 3) + "...");
label.setTooltip(createPopup(parent, originalValue));
}
private static Popup createPopup(Div parent, String originalValue) {
Popup result = new Popup();
result.appendChild(new Label(originalValue));
parent.appendChild(result);
return result;
}
}

View file

@ -0,0 +1,134 @@
/*
* 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.limitingresources;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.zkoss.ganttz.data.resourceload.LoadTimeLine;
import org.zkoss.ganttz.timetracker.TimeTracker;
import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.MutableTreeModel;
import org.zkoss.zk.au.out.AuInvoke;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlMacroComponent;
import org.zkoss.zk.ui.ext.AfterCompose;
/**
* Component to include a list of ResourceLoads inside the ResourcesLoadPanel.
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
public class LimitingResourcesList extends HtmlMacroComponent implements
AfterCompose {
private final IZoomLevelChangedListener zoomListener;
private Map<LoadTimeLine, LimitingResourcesComponent> fromTimeLineToComponent = new HashMap<LoadTimeLine, LimitingResourcesComponent>();
private final MutableTreeModel<LoadTimeLine> timelinesTree;
public LimitingResourcesList(TimeTracker timeTracker,
MutableTreeModel<LoadTimeLine> timelinesTree) {
this.timelinesTree = timelinesTree;
zoomListener = adjustTimeTrackerSizeListener();
timeTracker.addZoomListener(zoomListener);
LoadTimeLine current = timelinesTree.getRoot();
List<LoadTimeLine> toInsert = new ArrayList<LoadTimeLine>();
fill(timelinesTree, current, toInsert);
insertAsComponents(timeTracker, toInsert);
}
private void fill(MutableTreeModel<LoadTimeLine> timelinesTree,
LoadTimeLine current, List<LoadTimeLine> result) {
final int length = timelinesTree.getChildCount(current);
for (int i = 0; i < length; i++) {
LoadTimeLine child = timelinesTree.getChild(current, i);
result.add(child);
fill(timelinesTree, child, result);
}
}
private IZoomLevelChangedListener adjustTimeTrackerSizeListener() {
return new IZoomLevelChangedListener() {
@Override
public void zoomLevelChanged(ZoomLevel detailLevel) {
response(null, new AuInvoke(LimitingResourcesList.this,
"adjustTimeTrackerSize"));
response(null, new AuInvoke(LimitingResourcesList.this,
"adjustResourceLoadRows"));
}
};
}
private void insertAsComponents(TimeTracker timetracker,
List<LoadTimeLine> children) {
for (LoadTimeLine loadTimeLine : children) {
LimitingResourcesComponent component = LimitingResourcesComponent
.create(
timetracker, loadTimeLine);
appendChild(component);
fromTimeLineToComponent.put(loadTimeLine, component);
}
}
public void collapse(LoadTimeLine line) {
for (LoadTimeLine l : line.getAllChildren()) {
getComponentFor(l).detach();
}
}
private LimitingResourcesComponent getComponentFor(LoadTimeLine l) {
LimitingResourcesComponent resourceLoadComponent = fromTimeLineToComponent
.get(l);
return resourceLoadComponent;
}
public void expand(LoadTimeLine line, List<LoadTimeLine> closed) {
LimitingResourcesComponent parentComponent = getComponentFor(line);
Component nextSibling = parentComponent.getNextSibling();
List<LoadTimeLine> childrenToOpen = getChildrenReverseOrderFor(line);
childrenToOpen.removeAll(closed);
for (LoadTimeLine loadTimeLine : childrenToOpen) {
LimitingResourcesComponent child = getComponentFor(loadTimeLine);
insertBefore(child, nextSibling);
nextSibling = child;
}
}
private List<LoadTimeLine> getChildrenReverseOrderFor(LoadTimeLine line) {
List<LoadTimeLine> childrenOf = line.getAllChildren();
Collections.reverse(childrenOf);
return childrenOf;
}
@Override
public void afterCompose() {
super.afterCompose();
}
}

View file

@ -0,0 +1,259 @@
/*
* 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.limitingresources;
import static org.zkoss.ganttz.i18n.I18nHelper._;
import java.util.List;
import org.apache.commons.lang.StringUtils;
import org.zkoss.ganttz.data.resourceload.LoadTimeLine;
import org.zkoss.ganttz.resourceload.ScriptsRequiredByResourceLoadPanel;
import org.zkoss.ganttz.timetracker.TimeTracker;
import org.zkoss.ganttz.timetracker.TimeTrackerComponent;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.ComponentsFinder;
import org.zkoss.ganttz.util.MutableTreeModel;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
import org.zkoss.ganttz.util.script.IScriptsRegister;
import org.zkoss.zk.au.out.AuInvoke;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlMacroComponent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Button;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Separator;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.api.Listbox;
public class LimitingResourcesPanel extends HtmlMacroComponent {
public interface IToolbarCommand {
public void doAction();
public String getLabel();
public String getImage();
}
private TimeTrackerComponent timeTrackerComponent;
private LimitingResourcesLeftPane leftPane;
private LimitingResourcesList limitingResourcesList;
private List<LoadTimeLine> groups;
private MutableTreeModel<LoadTimeLine> treeModel;
private TimeTracker timeTracker;
// private WeakReferencedListeners<IFilterChangedListener> zoomListeners =
// WeakReferencedListeners.create();
private Listbox listZoomLevels;
private static final String filterResources = _("Filter by resources");
private static final String filterCriterions = _("Filter by criterions");
private boolean filterbyResources = true;
public LimitingResourcesPanel(List<LoadTimeLine> groups,
TimeTracker timeTracker) {
init(groups, timeTracker);
}
public void init(List<LoadTimeLine> groups, TimeTracker timeTracker) {
this.groups = groups;
this.timeTracker = timeTracker;
treeModel = createModelForTree();
timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker);
limitingResourcesList = new LimitingResourcesList(timeTracker,
treeModel);
leftPane = new LimitingResourcesLeftPane(treeModel,
limitingResourcesList);
registerNeededScripts();
}
public ListModel getFilters() {
String[] filters = new String[] { filterResources, filterCriterions };
return new SimpleListModel(filters);
}
public void setFilter(String filterby) {
if (filterby.equals(filterResources)) {
this.filterbyResources = true;
} else {
this.filterbyResources = false;
}
}
public boolean getFilter() {
return filterbyResources;
}
// public void onApplyFilter() {
// zoomListeners
// .fireEvent(new IListenerNotification<IFilterChangedListener>() {
// @Override
// public void doNotify(IFilterChangedListener listener) {
// listener.filterChanged(getFilter());
// }
// });
// }
//
// public void addFilterListener(IFilterChangedListener listener) {
// zoomListeners.addListener(listener);
// }
public ListModel getZoomLevels() {
return new SimpleListModel(ZoomLevel.values());
}
public void setZoomLevel(final ZoomLevel zoomLevel) {
timeTracker.setZoomLevel(zoomLevel);
}
public void zoomIncrease() {
timeTracker.zoomIncrease();
}
public void zoomDecrease() {
timeTracker.zoomDecrease();
}
public void add(final IToolbarCommand... commands) {
Component toolbar = getToolbar();
Separator separator = getSeparator();
for (IToolbarCommand c : commands) {
toolbar.insertBefore(asButton(c), separator);
}
}
private Button asButton(final IToolbarCommand c) {
Button result = new Button();
result.addEventListener(Events.ON_CLICK, new EventListener() {
@Override
public void onEvent(Event event) throws Exception {
c.doAction();
}
});
if (!StringUtils.isEmpty(c.getImage())) {
result.setImage(c.getImage());
result.setTooltiptext(c.getLabel());
} else {
result.setLabel(c.getLabel());
}
return result;
}
@SuppressWarnings("unchecked")
private Separator getSeparator() {
List<Component> children = getToolbar().getChildren();
Separator separator = ComponentsFinder.findComponentsOfType(
Separator.class, children).get(0);
return separator;
}
private Component getToolbar() {
Component toolbar = getFellow("toolbar");
return toolbar;
}
private void registerNeededScripts() {
getScriptsRegister().register(ScriptsRequiredByResourceLoadPanel.class);
}
private IScriptsRegister getScriptsRegister() {
return OnZKDesktopRegistry.getLocatorFor(IScriptsRegister.class)
.retrieve();
}
private MutableTreeModel<LoadTimeLine> createModelForTree() {
MutableTreeModel<LoadTimeLine> result = MutableTreeModel
.create(LoadTimeLine.class);
for (LoadTimeLine loadTimeLine : this.groups) {
result.addToRoot(loadTimeLine);
result = addNodes(result, loadTimeLine);
}
return result;
}
private MutableTreeModel<LoadTimeLine> addNodes(
MutableTreeModel<LoadTimeLine> tree, LoadTimeLine parent) {
if (!parent.getChildren().isEmpty()) {
tree.add(parent, parent.getChildren());
for (LoadTimeLine loadTimeLine : parent.getChildren()) {
tree = addNodes(tree, loadTimeLine);
}
}
return tree;
}
private TimeTrackerComponent timeTrackerForResourcesLoadPanel(
TimeTracker timeTracker) {
return new TimeTrackerComponent(timeTracker) {
@Override
protected void scrollHorizontalPercentage(int pixelsDisplacement) {
response("", new AuInvoke(limitingResourcesList,
"adjustScrollHorizontalPosition", pixelsDisplacement
+ ""));
}
};
}
@Override
public void afterCompose() {
super.afterCompose();
leftPane.afterCompose();
getFellow("insertionPointRightPanel").appendChild(timeTrackerComponent);
getFellow("insertionPointRightPanel").appendChild(limitingResourcesList);
TimeTrackerComponent timeTrackerHeader = createTimeTrackerHeader();
getFellow("insertionPointTimetracker").appendChild(timeTrackerHeader);
timeTrackerHeader.afterCompose();
timeTrackerComponent.afterCompose();
listZoomLevels = (Listbox) getFellow("listZoomLevels");
listZoomLevels.setSelectedIndex(timeTracker.getDetailLevel().ordinal());
}
public void clearComponents() {
getFellow("insertionPointLeftPanel").getChildren().clear();
getFellow("insertionPointRightPanel").getChildren().clear();
getFellow("insertionPointTimetracker").getChildren().clear();
}
private TimeTrackerComponent createTimeTrackerHeader() {
return new TimeTrackerComponent(
timeTracker) {
@Override
protected void scrollHorizontalPercentage(int pixelsDisplacement) {
}
};
}
}

View file

@ -48,6 +48,29 @@
<macro-uri>~./ganttz/resourceload/leftPane.zul</macro-uri>
</component>
<component>
<component-name>LimitingResourcesPanel</component-name>
<component-class>org.zkoss.ganttz.limitingresources.LimitingResourcesPanel</component-class>
<macro-uri>~./ganttz/zul/limitingResourcesLayout.zul</macro-uri>
</component>
<component>
<component-name>LimitingResourcesList</component-name>
<component-class>org.zkoss.ganttz.limitingresources.LimitingResourcesList</component-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/limitingresources/limitingresourceslist.dsp</mold-uri>
</mold>
</component>
<component>
<component-name>LimitingResourcesLeftPane</component-name>
<component-class>org.zkoss.ganttz.limitingresources.LimitingResourcesLeftPane</component-class>
<macro-uri>~./ganttz/limitingresources/leftPane.zul</macro-uri>
</component>
<component>
<component-name>leftPane</component-name>
<component-class>org.zkoss.ganttz.LeftPane</component-class>
@ -79,6 +102,17 @@
</mold>
</component>
<component>
<component-name>limitingresources</component-name>
<component-class>org.zkoss.ganttz.limitingresources.LimitingResourcesComponent
</component-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/limitingresources/limitingresources.dsp</mold-uri>
</mold>
</component>
<component>
<component-name>taskRow</component-name>
<component-class>org.zkoss.ganttz.TaskRow</component-class>

View file

@ -0,0 +1,28 @@
<!--
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/>.
-->
<zk>
<zscript><![CDATA[
top = self;
]]>
</zscript>
<tree id="loadsTree" sclass="resourceloadleftpane" fixedLayout="true">
</tree>
</zk>

View file

@ -0,0 +1,12 @@
<%@ taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c" %>
<%@ taglib uri="http://www.zkoss.org/dsp/zk/core" prefix="z" %>
<c:set var="self" value="${requestScope.arg.self}"/>
<div id="${self.uuid}" class="row_resourceload resourceload-${self.resourceLoadType}"
z.autoz="true" ${self.outerAttrs}">
<span class="resourceload_name">${self.resourceLoadName}</span>
<c:forEach var="child" items="${self.children}">
${z:redraw(child, null)}
</c:forEach>
</div>

View file

@ -0,0 +1,11 @@
<%@ taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c" %>
<%@ taglib uri="http://www.zkoss.org/dsp/zk/core" prefix="z" %>
<c:set var="self" value="${requestScope.arg.self}"/>
<div id="${self.uuid}" ${self.outerAttrs} class="resourceloadlist"
z.type="ganttz.resourceload.resourcesloadlist.ResourcesLoadList">
<c:forEach var="child" items="${self.children}">
${z:redraw(child, null)}
</c:forEach>
</div>

View file

@ -0,0 +1,148 @@
<!--
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/>.
-->
<?xel-method prefix="i18n" name="_" class="org.zkoss.ganttz.i18n.I18nHelper"
signature="java.lang.String _(java.lang.String name)" ?>
<zk xmlns:n="http://www.zkoss.org/2005/zk/native">
<zscript><![CDATA[
resourcesLoadPanel = self;
]]>
</zscript>
<borderlayout sclass="resourcesloadlayout" width="auto">
<north height="30px" border="0" sclass="toolbar-box">
<hbox align="center" id="toolbar">
<separator/>
<label>${i18n:_('Zoom')}:</label>
<listbox id="listZoomLevels" mold="select" rows="1"
model="${resourcesLoadPanel.zoomLevels}"
onSelect="resourcesLoadPanel.setZoomLevel(self.selectedItem.value);" >
</listbox>
<separator/>
<label>${i18n:_('Pagination')}:</label>
<button tooltiptext="Page down" image="/common/img/ico_left.png" id="paginationDownButton"
onClick="advancedAllocationController.paginationDown();" disabled="true" />
<listbox mold="select" rows="1" visible="false" id="advancedAllocationHorizontalPagination"
onSelect="advancedAllocationController.goToSelectedHorizontalPage();" />
<button tooltiptext="Page up" image="/common/img/ico_right.png" id="paginationUpButton"
onClick="advancedAllocationController.paginationUp();" />
<separator/>
Filter:
<listbox id="listFilters" mold="select" rows="1" width="200px"
model="${resourcesLoadPanel.filters}"
onSelect="resourcesLoadPanel.setFilter(self.selectedItem.value);" >
</listbox>
<button image="/common/img/ico_filter.png" style="margin-top: -4px"
tooltiptext="${i18n:_('Apply filtering to resource load satisfying required criteria')}"
onClick="resourcesLoadPanel.onApplyFilter()"/>
</hbox>
</north>
<center border="0">
<borderlayout sclass="resourcesload">
<west size="250px" flex="true" collapsible="true"
splittable="true" autoscroll="true">
<borderlayout >
<north border="0" height="38px" flex="true" collapsible="true">
<vbox pack="top" align="center">
<tree fixedLayout="true">
<treecols>
<treecol label="Name" height="29px"/>
</treecols>
</tree>
</vbox>
</north>
<center border="0" style="overflow-x:scroll">
<div sclass="leftpanelgap" id="insertionPointLeftPanel"></div>
</center>
</borderlayout>
</west>
<center sclass="taskspanel">
<borderlayout>
<north border="0"><div sclass="timetrackergap" height="33px" id="insertionPointTimetracker"></div></north>
<center autoscroll="true" border="0" sclass="rightpanellayout">
<div id="insertionPointRightPanel" sclass="taskspanelgap"></div>
</center>
</borderlayout>
</center>
</borderlayout>
</center>
<south height="170px" collapsible="true" title="Tasks input buffer" sclass="limiting-resources-buffer">
<grid style="margin:10px;">
<columns sizable="true">
<column label="Project" sort="auto"/>
<column label="Task name" sort="auto"/>
<column label="Operations" width="100px"/>
<column label="Auto" width="50px" tooltiptext="Select " />
</columns>
<rows>
<row>
<label value="Project A"/>
<label value="Task A.1"/>
<button tooltiptext="${i18n:_('Select queue')}" sclass="icono"
image="/common/img/ico_schedule1.png" hoverImage="/common/img/ico_schedule.png" />
<checkbox tooltiptext="${i18n:_('Select for automatic queuing')}" />
</row>
<row>
<label value="Project A"/>
<label value="Task A.2"/>
<button tooltiptext="${i18n:_('Select queue')}" sclass="icono"
image="/common/img/ico_schedule1.png" hoverImage="/common/img/ico_schedule.png" />
<checkbox tooltiptext="${i18n:_('Select for automatic queuing')}" />
</row>
<row>
<label value="Project A"/>
<label value="Task A.3"/>
<button tooltiptext="${i18n:_('Select queue')}" sclass="icono"
image="/common/img/ico_schedule1.png" hoverImage="/common/img/ico_schedule.png" />
<checkbox tooltiptext="${i18n:_('Select for automatic queuing')}" />
</row>
<row>
<label value="Project B"/>
<label value="Task B.2"/>
<button tooltiptext="${i18n:_('Select queue')}" sclass="icono"
image="/common/img/ico_schedule1.png" hoverImage="/common/img/ico_schedule.png" />
<checkbox tooltiptext="${i18n:_('Select for automatic queuing')}" />
</row>
<row>
<label value="Project B"/>
<label value="Task B.3"/>
<button tooltiptext="${i18n:_('Select queue')}" sclass="icono"
image="/common/img/ico_schedule1.png" hoverImage="/common/img/ico_schedule.png" />
<checkbox tooltiptext="${i18n:_('Select for automatic queuing')}" />
</row>
</rows>
</grid>
</south>
</borderlayout>
</zk>

View file

@ -0,0 +1,150 @@
/*
* 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.navalplanner.web.limitingresources;
import static org.navalplanner.web.I18nHelper._;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.web.planner.order.BankHolidaysMarker;
import org.navalplanner.web.resourceload.IResourceLoadModel;
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.limitingresources.LimitingResourcesPanel;
import org.zkoss.ganttz.limitingresources.LimitingResourcesPanel.IToolbarCommand;
import org.zkoss.ganttz.resourceload.IFilterChangedListener;
import org.zkoss.ganttz.timetracker.TimeTracker;
import org.zkoss.ganttz.timetracker.zoom.SeveralModificators;
import org.zkoss.zk.ui.util.Composer;
import org.zkoss.zul.Messagebox;
/**
* Controller for global limitingresources view
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class LimitingResourcesController implements Composer {
@Autowired
private IResourceLoadModel resourceLoadModel;
private List<IToolbarCommand> commands = new ArrayList<IToolbarCommand>();
private Order filterBy;
private org.zkoss.zk.ui.Component parent;
private LimitingResourcesPanel limitingResourcesPanel;
private TimeTracker timeTracker;
private transient IFilterChangedListener filterChangedListener;
public LimitingResourcesController() {
}
public void add(IToolbarCommand... commands) {
Validate.noNullElements(commands);
this.commands.addAll(Arrays.asList(commands));
}
@Override
public void doAfterCompose(org.zkoss.zk.ui.Component comp) throws Exception {
this.parent = comp;
reload();
}
public void reload() {
// by default show the task by resources
boolean filterByResources = true;
reload(filterByResources);
}
private void reload(boolean filterByResources) {
try {
if (filterBy == null) {
resourceLoadModel.initGlobalView(filterByResources);
} else {
resourceLoadModel.initGlobalView(filterBy, filterByResources);
}
timeTracker = buildTimeTracker();
limitingResourcesPanel = buildResourcesLoadPanel();
addListeners();
this.parent.getChildren().clear();
this.parent.appendChild(limitingResourcesPanel);
limitingResourcesPanel.afterCompose();
addCommands(limitingResourcesPanel);
} catch (IllegalArgumentException e) {
try {
Messagebox
.show(
_("Some lines have not allocation periods.\nBelow it shows the load all company resources"),
_("Error"), Messagebox.OK, Messagebox.ERROR);
} catch (InterruptedException o) {
throw new RuntimeException(e);
}
}
}
private void addListeners() {
filterChangedListener = new IFilterChangedListener() {
@Override
public void filterChanged(boolean filter) {
onApplyFilter(filter);
}
};
// this.limitingResourcesPanel.addFilterListener(filterChangedListener);
}
public void onApplyFilter(boolean filterByResources) {
limitingResourcesPanel.clearComponents();
reload(filterByResources);
}
private void addCommands(LimitingResourcesPanel limitingResourcesPanel) {
limitingResourcesPanel.add(commands.toArray(new IToolbarCommand[0]));
}
private TimeTracker buildTimeTracker() {
return timeTracker = new TimeTracker(resourceLoadModel
.getViewInterval(), resourceLoadModel
.calculateInitialZoomLevel(), SeveralModificators.create(),
SeveralModificators.create(new BankHolidaysMarker()), parent);
}
private LimitingResourcesPanel buildResourcesLoadPanel() {
return new LimitingResourcesPanel(resourceLoadModel.getLoadTimeLines(),
timeTracker);
}
public void filterBy(Order order) {
this.filterBy = order;
}
}

View file

@ -46,4 +46,6 @@ public interface IGlobalViewEntryPoints {
@EntryPoint( { "orderElement", "order" })
public void goToOrderElementDetails(OrderElement orderElement, Order order);
void goToCompanyLimitingResources();
}

View file

@ -0,0 +1,160 @@
/*
* 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.navalplanner.web.planner.tabs;
import static org.navalplanner.web.I18nHelper._;
import static org.navalplanner.web.planner.tabs.MultipleTabsPlannerController.BREADCRUMBS_SEPARATOR;
import static org.navalplanner.web.planner.tabs.MultipleTabsPlannerController.PLANNIFICATION;
import java.util.HashMap;
import java.util.Map;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.web.limitingresources.LimitingResourcesController;
import org.navalplanner.web.planner.tabs.CreatedOnDemandTab.IComponentCreator;
import org.zkoss.ganttz.extensions.ITab;
import org.zkoss.ganttz.resourceload.ResourcesLoadPanel.IToolbarCommand;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zul.Image;
import org.zkoss.zul.Label;
/**
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
public class LimitingResourcesTabCreator {
private static final String LIMITING_RESOURCES_VIEW = _("Limiting resources");
/* Unnecesary */
private static final String ORDER_LIMITING_RESOURCES_VIEW = _("Limiting resources (order)");
public static ITab create(Mode mode,
LimitingResourcesController LimitingResourcesController,
IToolbarCommand upCommand,
LimitingResourcesController LimitingResourcesControllerGlobal,
Component breadcrumbs) {
return new LimitingResourcesTabCreator(mode,
LimitingResourcesController, upCommand,
LimitingResourcesControllerGlobal, breadcrumbs)
.build();
}
private final Mode mode;
private final LimitingResourcesController LimitingResourcesController;
private final LimitingResourcesController LimitingResourcesControllerGlobal;
private final IToolbarCommand upCommand;
private final Component breadcrumbs;
private LimitingResourcesTabCreator(Mode mode,
LimitingResourcesController LimitingResourcesController,
IToolbarCommand upCommand,
LimitingResourcesController LimitingResourcesControllerGlobal,
Component breadcrumbs) {
this.mode = mode;
this.LimitingResourcesController = LimitingResourcesController;
this.upCommand = upCommand;
this.LimitingResourcesControllerGlobal = LimitingResourcesControllerGlobal;
this.breadcrumbs = breadcrumbs;
}
private ITab build() {
return TabOnModeType.forMode(mode)
.forType(ModeType.GLOBAL, createGlobalResourcesLoadTab())
.forType(ModeType.ORDER, createOrderResourcesLoadTab())
.create();
}
private ITab createOrderResourcesLoadTab() {
IComponentCreator componentCreator = new IComponentCreator() {
@Override
/* Should never be called */
public org.zkoss.zk.ui.Component create(
org.zkoss.zk.ui.Component parent) {
Map<String, Object> arguments = new HashMap<String, Object>();
// LimitingResourcesController.add(upCommand);
arguments.put("LimitingResourcesController",
LimitingResourcesController);
return Executions.createComponents(
"/limitingresources/_limitingresources.zul", parent,
arguments);
}
};
return new CreatedOnDemandTab(ORDER_LIMITING_RESOURCES_VIEW,
"order-limiting-resources",
componentCreator) {
@Override
protected void afterShowAction() {
breadcrumbs.getChildren().clear();
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
breadcrumbs.appendChild(new Label(PLANNIFICATION));
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
breadcrumbs
.appendChild(new Label(ORDER_LIMITING_RESOURCES_VIEW));
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
Order currentOrder = mode.getOrder();
LimitingResourcesController.filterBy(currentOrder);
LimitingResourcesController.reload();
breadcrumbs.appendChild(new Label(currentOrder.getName()));
}
};
}
private ITab createGlobalResourcesLoadTab() {
final IComponentCreator componentCreator = new IComponentCreator() {
@Override
public org.zkoss.zk.ui.Component create(
org.zkoss.zk.ui.Component parent) {
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("LimitingResourcesController",
LimitingResourcesControllerGlobal);
return Executions.createComponents(
"/limitingresources/_limitingresources.zul", parent,
// "/resourceload/_resourceload.zul", parent,
arguments);
}
};
return new CreatedOnDemandTab(LIMITING_RESOURCES_VIEW,
"limiting-resources",
componentCreator) {
@Override
protected void afterShowAction() {
LimitingResourcesControllerGlobal.filterBy(null);
LimitingResourcesControllerGlobal.reload();
if (breadcrumbs.getChildren() != null) {
breadcrumbs.getChildren().clear();
}
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
breadcrumbs.appendChild(new Label(PLANNIFICATION));
breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR));
breadcrumbs.appendChild(new Label(LIMITING_RESOURCES_VIEW));
}
};
}
}

View file

@ -33,6 +33,7 @@ import org.navalplanner.business.planner.entities.TaskElement;
import org.navalplanner.business.resources.daos.IResourceDAO;
import org.navalplanner.web.common.entrypoints.URLHandler;
import org.navalplanner.web.common.entrypoints.URLHandlerRegistry;
import org.navalplanner.web.limitingresources.LimitingResourcesController;
import org.navalplanner.web.orders.OrderCRUDController;
import org.navalplanner.web.planner.allocation.AdvancedAllocationController.IBack;
import org.navalplanner.web.planner.company.CompanyPlanningController;
@ -131,6 +132,8 @@ public class MultipleTabsPlannerController implements Composer,
private ITab resourceLoadTab;
private ITab limitingResourcesTab;
private ITab ordersTab;
private TabSwitcher tabsSwitcher;
@ -144,6 +147,12 @@ public class MultipleTabsPlannerController implements Composer,
@Autowired
private ResourceLoadController resourceLoadControllerGlobal;
@Autowired
private LimitingResourcesController limitingResourcesController;
@Autowired
private LimitingResourcesController limitingResourcesControllerGlobal;
private org.zkoss.zk.ui.Component breadcrumbs;
@Autowired
@ -193,6 +202,12 @@ public class MultipleTabsPlannerController implements Composer,
}
}, breadcrumbs);
/* FIX */
limitingResourcesTab = LimitingResourcesTabCreator.create(mode,
limitingResourcesController, upCommand(),
limitingResourcesControllerGlobal, breadcrumbs);
ordersTab = OrdersTabCreator.create(mode, orderCRUDController,
breadcrumbs, new IOrderPlanningGate() {
@ -222,6 +237,8 @@ public class MultipleTabsPlannerController implements Composer,
return TabsConfiguration.create()
.add(tabWithNameReloading(planningTab, typeChanged))
.add(tabWithNameReloading(resourceLoadTab, typeChanged))
.add(
tabWithNameReloading(limitingResourcesTab, typeChanged))
.add(tabWithNameReloading(ordersTab, typeChanged))
.add(visibleOnlyAtOrderMode(advancedAllocation));
}
@ -347,6 +364,11 @@ public class MultipleTabsPlannerController implements Composer,
getTabsRegistry().show(resourceLoadTab);
}
@Override
public void goToCompanyLimitingResources() {
getTabsRegistry().show(limitingResourcesTab);
}
@Override
public void goToOrdersList() {
// ordersTab.show();

View file

@ -1048,6 +1048,13 @@ span.z-dottree-line {
.perspective-active.order-load .z-button-cm {
background-image: url(../img/ico_order-load.png);
}
.perspective.limiting-resources .z-button-cm,
.perspective-active.limiting-resources .z-button-cm {
background-image: url(../img/ico_order-load.png);
}
.perspective.order-limiting-resources {
display: none;
}
.perspective.order-data .z-button-cm,
.perspective-active.order-data .z-button-cm {
background-image: url(../img/ico_order-data.png);

View file

@ -0,0 +1,31 @@
<!--
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/>.
-->
<?taglib uri="/WEB-INF/tld/i18n.tld" prefix="i18n" ?>
<zk>
<zscript><![CDATA[
rsController = arg.get("LimitingResourcesController");;
]]>
</zscript>
<div apply="${rsController}" self="@{define(content)}">
</div>
</zk>

View file

@ -970,3 +970,9 @@ body .perspectives-column {
.row .partially-assigned {
background-color: #FF5A11; /* PARTIALLY_ALLOCATED_TASK_ORANGE */
}
/* ------------ Limiting resources ------------ */
.limiting-resources-buffer .z-south-body {
overflow-y:scroll;
}