Merge branch 'migration-to-ZK5' into master

Conflicts:
	ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java
	ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul
	navalplanner-webapp/src/main/java/org/navalplanner/web/planner/tabs/MultipleTabsPlannerController.java

FEA: ItEr75S08MigrationZK5
This commit is contained in:
Óscar González Fernández 2011-06-28 20:00:26 +02:00
commit d2c759bb03
320 changed files with 2101 additions and 42283 deletions

1
NEWS
View file

@ -1489,7 +1489,6 @@ Changes
* [Bug #809] Fixed marking to translate missing label.
* Fixed wrong e-mail on debian/changelog.
Version 1.0.1 (14 Jan 2011)
---------------------------

23
debian/control.lucid vendored Normal file
View file

@ -0,0 +1,23 @@
Source: navalplan
Section: web
Priority: optional
Maintainer: Adrian Perez <aperez@igalia.com>
Build-Depends: debhelper (>= 7.0.50), maven2, python-docutils,
gettext (>= 0.17), texlive-latex-recommended, pgf, openjdk-6-jdk
Standards-Version: 3.8.4
Homepage: http://www.navalplan.org/en/
Package: navalplan
Architecture: any
Depends: cutycapt, postgresql, postgresql-client, xvfb, dbconfig-common, ucf,
tomcat6, openjdk-6-jre-headless | openjdk-6-jre, libpg-java, ttf-freefont,
${misc:Depends}
Description: Web application for project management.
NavalPlan is a planning tool for users based on some concepts: company and
multi-project overview, criteria assignments, tasks tagging, resources
management, resource allocation (specific and generic), company load control,
external integration, etc.
.
Although its name is clearly related to shipbuilding, NavalPlan is a fully
useful planning tool for any type of company whose workflow requires project
and order administration and scheduling.

23
debian/control.squeeze vendored Normal file
View file

@ -0,0 +1,23 @@
Source: navalplan
Section: web
Priority: optional
Maintainer: Adrian Perez <aperez@igalia.com>
Build-Depends: debhelper (>= 7.0.50), maven2, python-docutils,
gettext (>= 0.17), texlive-latex-recommended, pgf, openjdk-6-jdk
Standards-Version: 3.8.4
Homepage: http://www.navalplan.org/en/
Package: navalplan
Architecture: any
Depends: cutycapt, postgresql, postgresql-client, xvfb, dbconfig-common, ucf,
tomcat6, openjdk-6-jre-headless | openjdk-6-jre, libpg-java, ttf-freefont,
${misc:Depends}
Description: Web application for project management.
NavalPlan is a planning tool for users based on some concepts: company and
multi-project overview, criteria assignments, tasks tagging, resources
management, resource allocation (specific and generic), company load control,
external integration, etc.
.
Although its name is clearly related to shipbuilding, NavalPlan is a fully
useful planning tool for any type of company whose workflow requires project
and order administration and scheduling.

View file

@ -31,6 +31,21 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>default</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

View file

@ -24,6 +24,7 @@ package org.zkoss.ganttz;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import org.apache.commons.lang.Validate;
import org.zkoss.ganttz.data.Dependency;
@ -35,6 +36,7 @@ import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener;
import org.zkoss.ganttz.util.WeakReferencedListeners.Mode;
import org.zkoss.zk.au.out.AuInvoke;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zk.ui.sys.ContentRenderer;
import org.zkoss.zul.impl.XulElement;
/**
@ -95,8 +97,13 @@ public class DependencyComponent extends XulElement implements AfterCompose {
return violated ? "violated-dependency" : "dependency";
}
private boolean listenerAdded = false;
@Override
public void afterCompose() {
if (listenerAdded) {
return;
}
PropertyChangeListener listener = new PropertyChangeListener() {
@Override
@ -106,6 +113,7 @@ public class DependencyComponent extends XulElement implements AfterCompose {
};
this.source.getTask().addFundamentalPropertiesChangeListener(listener);
this.destination.getTask().addFundamentalPropertiesChangeListener(listener);
listenerAdded = true;
}
/**
@ -140,7 +148,7 @@ public class DependencyComponent extends XulElement implements AfterCompose {
}
public void redrawDependency() {
response("zoomChanged", new AuInvoke(this, "draw"));
response("redrawDependency" + getId(), new AuInvoke(this, "draw"));
}
public boolean contains(Task task) {
@ -172,6 +180,14 @@ public class DependencyComponent extends XulElement implements AfterCompose {
&& destinationTask.equals(dependency.getDestination());
}
protected void renderProperties(ContentRenderer renderer) throws IOException{
super.renderProperties(renderer);
render(renderer, "_idTaskOrig", getIdTaskOrig());
render(renderer, "_idTaskEnd", getIdTaskEnd());
render(renderer, "_dependencyType", getDependencyType());
}
public boolean hasLimitingTasks() {
return (source.isLimiting() || destination.isLimiting());
}

View file

@ -25,7 +25,6 @@ import static org.zkoss.ganttz.i18n.I18nHelper._;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
@ -105,6 +104,7 @@ public class DependencyList extends XulElement implements AfterCompose {
void toggleDependencyExistence(boolean visible) {
if (visible) {
appendChild(dependencyComponent);
dependencyComponent.afterCompose();
addContextMenu(dependencyComponent);
} else {
removeChild(dependencyComponent);
@ -265,24 +265,6 @@ public class DependencyList extends XulElement implements AfterCompose {
return getGanttPanel().getTimeTrackerComponent();
}
public void redrawDependenciesConnectedTo(TaskComponent taskComponent) {
redrawDependencyComponents(getDependencyComponentsConnectedTo(taskComponent));
}
private List<DependencyComponent> getDependencyComponentsConnectedTo(
TaskComponent taskComponent) {
ArrayList<DependencyComponent> result = new ArrayList<DependencyComponent>();
List<DependencyComponent> dependencies = getDependencyComponents();
for (DependencyComponent dependencyComponent : dependencies) {
if (dependencyComponent.getSource().equals(taskComponent)
|| dependencyComponent.getDestination().equals(
taskComponent)) {
result.add(dependencyComponent);
}
}
return result;
}
public void redrawDependencies() {
redrawDependencyComponents(getDependencyComponents());
}

View file

@ -28,6 +28,7 @@ import org.zkoss.ganttz.adapters.IDisabilityConfiguration;
import org.zkoss.ganttz.data.GanttDiagramGraph;
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.Interval;
import org.zkoss.zk.au.out.AuInvoke;
@ -46,6 +47,8 @@ public class GanttPanel extends XulElement implements AfterCompose {
private final Planner planner;
private transient IZoomLevelChangedListener zoomLevelChangedListener;
private LocalDate previousStart;
private Interval previousInterval;
@ -84,6 +87,7 @@ public class GanttPanel extends XulElement implements AfterCompose {
moveCurrentPositionScroll();
}
// FIXME: this is quite awful, it should be simple
@Override
protected void moveCurrentPositionScroll() {
// get the previous data.
@ -129,6 +133,7 @@ public class GanttPanel extends XulElement implements AfterCompose {
planner.getPredicate().setFilterContainers(true);
planner.setTaskListPredicate(planner.getPredicate());
}
registerZoomLevelChangedListener();
}
public TimeTrackerComponent getTimeTrackerComponent() {
@ -163,10 +168,10 @@ public class GanttPanel extends XulElement implements AfterCompose {
return timeTrackerComponent.getTimeTracker();
}
public void setZoomLevel(ZoomLevel zoomLevel) {
public void setZoomLevel(ZoomLevel zoomLevel, int scrollLeft) {
savePreviousData();
getTimeTrackerComponent().updateDayScroll();
getTimeTracker().setZoomLevel(zoomLevel);
getTimeTrackerComponent().setZoomLevel(zoomLevel, scrollLeft);
}
private void savePreviousData() {
@ -178,6 +183,22 @@ public class GanttPanel extends XulElement implements AfterCompose {
return planner;
}
private void registerZoomLevelChangedListener() {
if (zoomLevelChangedListener == null) {
zoomLevelChangedListener = new IZoomLevelChangedListener() {
@Override
public void zoomLevelChanged(ZoomLevel detailLevel) {
adjustZoomColumnsHeight();
}
};
getTimeTracker().addZoomListener(zoomLevelChangedListener);
}
}
public void adjustZoomColumnsHeight() {
response("adjust_height", new AuInvoke(this, "adjust_height"));
}
public LocalDate getPreviousStart() {
return previousStart;
}

View file

@ -55,34 +55,27 @@ import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
import org.zkoss.ganttz.util.WeakReferencedListeners;
import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification;
import org.zkoss.ganttz.util.script.IScriptsRegister;
import org.zkoss.zk.au.AuRequest;
import org.zkoss.zk.au.AuService;
import org.zkoss.zk.mesg.MZk;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.HtmlMacroComponent;
import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zkex.zul.api.South;
import org.zkoss.zul.Button;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import org.zkoss.zul.Separator;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.South;
public class Planner extends HtmlMacroComponent {
public static void registerNeededScripts() {
IScriptsRegister register = getScriptsRegister();
register.register(ScriptsRequiredByPlanner.class);
}
private static IScriptsRegister getScriptsRegister() {
return OnZKDesktopRegistry.getLocatorFor(IScriptsRegister.class)
.retrieve();
}
public static boolean guessContainersExpandedByDefaultGivenPrintParameters(
Map<String, String> printParameters) {
return guessContainersExpandedByDefault(convertToURLParameters(printParameters));
@ -174,7 +167,6 @@ public class Planner extends HtmlMacroComponent {
.create();
public Planner() {
registerNeededScripts();
}
TaskList getTaskList() {
@ -265,13 +257,13 @@ public class Planner extends HtmlMacroComponent {
return new SimpleListModel(selectableZoomlevels);
}
public void setZoomLevel(final ZoomLevel zoomLevel) {
public void setZoomLevel(final ZoomLevel zoomLevel, int scrollLeft) {
if (ganttPanel == null) {
return;
}
this.fixedZoomByUser = true;
initialZoomLevel = zoomLevel;
ganttPanel.setZoomLevel(zoomLevel);
ganttPanel.setZoomLevel(zoomLevel, scrollLeft);
}
public void zoomIncrease() {
@ -373,6 +365,35 @@ public class Planner extends HtmlMacroComponent {
this.visibleChart = configuration.isExpandPlanningViewCharts();
((South) getFellow("graphics")).setOpen(this.visibleChart);
setAuService(new AuService(){
public boolean service(AuRequest request, boolean everError){
String command = request.getCommand();
String[] requestData;
int zoomindex;
int scrollLeft;
if (command.equals("onZoomLevelChange")){
zoomindex= (Integer) retrieveData(request, "zoomindex");
scrollLeft = (Integer) retrieveData(request, "scrollLeft");
setZoomLevel((ZoomLevel)((Listbox)getFellow("listZoomLevels"))
.getModel().getElementAt(zoomindex),
scrollLeft);
return true;
}
return false;
}
private Object retrieveData(AuRequest request, String key){
Object value = request.getData().get(key);
if ( value == null)
throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA,
new Object[] { key, this });
return value;
}
});
}
private void resettingPreviousComponentsToNull() {
@ -484,7 +505,7 @@ public class Planner extends HtmlMacroComponent {
getDependencyList().taskRemoved(task);
leftPane.taskRemoved(task);
setHeight(getHeight());// forcing smart update
taskList.adjustZoomColumnsHeight();
ganttPanel.adjustZoomColumnsHeight();
getDependencyList().redrawDependencies();
}
@ -605,10 +626,10 @@ public class Planner extends HtmlMacroComponent {
public void showAllLabels() {
Button showAllLabelsButton = (Button) getFellow("showAllLabels");
if (isShowingLabels) {
Clients.evalJavaScript("zkTasklist.hideAllTooltips();");
Clients.evalJavaScript("ganttz.TaskList.getInstance().hideAllTaskLabels()");
showAllLabelsButton.setSclass("planner-command show-labels");
} else {
Clients.evalJavaScript("zkTasklist.showAllTooltips();");
Clients.evalJavaScript("ganttz.TaskList.getInstance().showAllTaskLabels()");
showAllLabelsButton
.setSclass("planner-command show-labels clicked");
}
@ -618,10 +639,10 @@ public class Planner extends HtmlMacroComponent {
public void showAllResources() {
Button showAllLabelsButton = (Button) getFellow("showAllResources");
if (isShowingResources) {
Clients.evalJavaScript("zkTasklist.hideResourceTooltips();");
Clients.evalJavaScript("ganttz.TaskList.getInstance().hideResourceTooltips()");
showAllLabelsButton.setSclass("planner-command show-resources");
} else {
Clients.evalJavaScript("zkTasklist.showResourceTooltips();");
Clients.evalJavaScript("ganttz.TaskList.getInstance().showResourceTooltips()");
showAllLabelsButton
.setSclass("planner-command show-resources clicked");
}
@ -820,6 +841,10 @@ public class Planner extends HtmlMacroComponent {
return null;
}
public String getWidgetClass(){
return getDefinition().getDefaultWidgetClass();
}
public List getCriticalPath() {
return context.getCriticalPath();
}

View file

@ -1,43 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script.ScriptsRequiredDeclaration;
@ScriptsRequiredDeclaration(dependsOn = { YUIMin.class, ScrollSyncScript.class })
public class ScriptsRequiredByPlanner {
private ScriptsRequiredByPlanner() {
}
public static final String SELECTOR = "/zkau/web/js/yui/2.7.0/selector/selector-min.js";
public static final String YAHOO_DOM_EVENT = "/zkau/web/js/yui/2.7.0/yahoo-dom-event/yahoo-dom-event.js";
public static final String DRAGDROPMIN = "/zkau/web/js/yui/2.7.0/dragdrop/dragdrop-min.js";
public static final String ELEMENT_MIN = "/zkau/web/js/yui/2.7.0/element/element-min.js";
public static final String RESIZE_MIN = "/zkau/web/js/yui/2.7.0/resize/resize-min.js";
public static final String LOGGER_MIN = "/zkau/web/js/yui/2.7.0/logger/logger-min.js";
// adding manually js associated to components since they can be used by
// other files with no dependencies being present
public static final String DEPENDENCY_LIST = "/zkau/web/js/ganttz/dependencylist.js";
public static final String DEPENDENCY = "/zkau/web/js/ganttz/dependency.js";
}

View file

@ -1,36 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script.ScriptsRequiredDeclaration;
@ScriptsRequiredDeclaration(dependsOn = YUIMin.class)
public class ScrollSyncScript {
private ScrollSyncScript() {
}
public static final String SCROLL_SYNC = "/zkau/web/js/ganttz/scrollSync.js";
public static final String YAHOO_DOM_EVENT = "/zkau/web/js/yui/2.7.0/yahoo-dom-event/yahoo-dom-event.js";
}

View file

@ -23,10 +23,9 @@ package org.zkoss.ganttz;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.IOException;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang.Validate;
import org.apache.commons.logging.Log;
@ -43,10 +42,8 @@ import org.zkoss.ganttz.data.constraint.Constraint;
import org.zkoss.ganttz.data.constraint.Constraint.IConstraintViolationListener;
import org.zkoss.ganttz.util.WeakReferencedListeners.Mode;
import org.zkoss.lang.Objects;
import org.zkoss.xml.HTMLs;
import org.zkoss.zk.au.AuRequest;
import org.zkoss.zk.au.Command;
import org.zkoss.zk.au.ComponentCommand;
import org.zkoss.zk.au.AuService;
import org.zkoss.zk.au.out.AuInvoke;
import org.zkoss.zk.mesg.MZk;
import org.zkoss.zk.ui.Component;
@ -54,6 +51,7 @@ import org.zkoss.zk.ui.UiException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zk.ui.sys.ContentRenderer;
import org.zkoss.zul.Div;
/**
@ -70,94 +68,6 @@ public class TaskComponent extends Div implements AfterCompose {
private static final int HALF_DEADLINE_MARK = 3;
private static Pattern pixelsSpecificationPattern = Pattern
.compile("\\s*(\\d+)px\\s*;?\\s*");
private static int stripPx(String pixels) {
Matcher matcher = pixelsSpecificationPattern.matcher(pixels);
if (!matcher.matches()) {
throw new IllegalArgumentException("pixels " + pixels
+ " is not valid. It must be "
+ pixelsSpecificationPattern.pattern());
}
return Integer.valueOf(matcher.group(1));
}
private static Command _updatecmd = new ComponentCommand(
"onUpdatePosition", 0) {
protected void process(AuRequest request) {
final TaskComponent ta = (TaskComponent) request.getComponent();
if (ta == null) {
throw new UiException(MZk.ILLEGAL_REQUEST_COMPONENT_REQUIRED,
this);
}
String[] requestData = request.getData();
if (requestData == null || requestData.length != 2) {
throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA,
new Object[] { Objects.toString(requestData), this });
} else {
ta.doUpdatePosition(requestData[0], requestData[1]);
Events.postEvent(new Event(getId(), ta, request.getData()));
}
}
};
private static Command _updatewidthcmd = new ComponentCommand(
"onUpdateWidth", 0) {
protected void process(AuRequest request) {
final TaskComponent ta = (TaskComponent) request.getComponent();
if (ta == null) {
throw new UiException(MZk.ILLEGAL_REQUEST_COMPONENT_REQUIRED,
this);
}
String[] requestData = request.getData();
if (requestData == null || requestData.length != 1) {
throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA,
new Object[] { Objects.toString(requestData), this });
} else {
ta.doUpdateSize(requestData[0]);
Events.postEvent(new Event(getId(), ta, request.getData()));
}
}
};
private static Command _adddependencycmd = new ComponentCommand(
"onAddDependency", 0) {
protected void process(AuRequest request) {
final TaskComponent taskComponent = (TaskComponent) request.getComponent();
if (taskComponent == null) {
throw new UiException(MZk.ILLEGAL_REQUEST_COMPONENT_REQUIRED,
this);
}
String[] requestData = request.getData();
if (requestData == null || requestData.length != 1) {
throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA,
new Object[] { Objects.toString(requestData), this });
} else {
taskComponent.doAddDependency(requestData[0]);
Events.postEvent(new Event(getId(), taskComponent, request.getData()));
}
}
};
protected final IDisabilityConfiguration disabilityConfiguration;
private PropertyChangeListener criticalPathPropertyListener;
@ -195,7 +105,6 @@ public class TaskComponent extends Div implements AfterCompose {
setContext("idContextMenuTaskAssignment");
this.task = task;
setClass(calculateCSSClass());
setId(UUID.randomUUID().toString());
this.disabilityConfiguration = disabilityConfiguration;
taskViolationListener = Constraint
@ -234,6 +143,64 @@ public class TaskComponent extends Div implements AfterCompose {
};
this.task.addReloadListener(reloadResourcesTextRequested);
setAuService(new AuService(){
public boolean service(AuRequest request, boolean everError){
String command = request.getCommand();
final TaskComponent ta;
if (command.equals("onUpdatePosition")){
ta = retrieveTaskComponent(request);
ta.doUpdatePosition(
toInteger(retrieveData(request, "left")),
toInteger(retrieveData(request, "top")));
Events.postEvent(new Event(getId(), ta, request.getData()));
return true;
}
if (command.equals("onUpdateWidth")){
ta = retrieveTaskComponent(request);
ta.doUpdateSize(toInteger(retrieveData(request, "width")));
Events.postEvent(new Event(getId(), ta, request.getData()));
return true;
}
if (command.equals("onAddDependency")){
ta = retrieveTaskComponent(request);
ta.doAddDependency((String) retrieveData(request, "dependencyId"));
Events.postEvent(new Event(getId(), ta, request.getData()));
return true;
}
return false;
}
private int toInteger(Object valueFromRequestData) {
return ((Number) valueFromRequestData).intValue();
}
private TaskComponent retrieveTaskComponent(AuRequest request){
final TaskComponent ta = (TaskComponent) request.getComponent();
if (ta == null) {
throw new UiException(MZk.ILLEGAL_REQUEST_COMPONENT_REQUIRED,
this);
}
return ta;
}
private Object retrieveData(AuRequest request, String key){
Object value = request.getData().get(key);
if ( value == null)
throw new UiException(MZk.ILLEGAL_REQUEST_WRONG_DATA,
new Object[] { key, this });
return value;
}
});
}
/* Generate CSS class attribute depending on task properties */
@ -261,8 +228,7 @@ public class TaskComponent extends Div implements AfterCompose {
}
protected void updateClass() {
response(null, new AuInvoke(this, "setClass",
new Object[] { calculateCSSClass() }));
setSclass(calculateCSSClass());
}
public final void afterCompose() {
@ -369,20 +335,6 @@ public class TaskComponent extends Div implements AfterCompose {
return null;
}
public Command getCommand(String cmdId) {
Command result = null;
if ("updatePosition".equals(cmdId)
&& isMovingTasksEnabled()) {
result = _updatecmd;
} else if ("updateSize".equals(cmdId)
&& isResizingTasksEnabled()) {
result = _updatewidthcmd;
} else if ("addDependency".equals(cmdId)) {
result = _adddependencycmd;
}
return result;
}
public boolean isResizingTasksEnabled() {
return (disabilityConfiguration != null)
&& disabilityConfiguration.isResizingTasksEnabled()
@ -395,9 +347,10 @@ public class TaskComponent extends Div implements AfterCompose {
&& task.canBeExplicitlyMoved();
}
void doUpdatePosition(String leftX, String topY) {
void doUpdatePosition(int leftX, int topY) {
GanttDate startBeforeMoving = this.task.getBeginDate();
LocalDate newPosition = getMapper().toDate(stripPx(leftX));
LocalDate newPosition = getMapper().toDate(leftX);
this.task.moveTo(GanttDate.createFrom(newPosition));
boolean remainsInOriginalPosition = this.task.getBeginDate().equals(
startBeforeMoving);
@ -406,11 +359,10 @@ public class TaskComponent extends Div implements AfterCompose {
}
}
void doUpdateSize(String size) {
int pixels = stripPx(size);
void doUpdateSize(int size) {
DateTime end = new DateTime(this.task.getBeginDate()
.toDayRoundedDate().getTime()).plus(getMapper().toDuration(
pixels));
size));
this.task.resizeTo(end.toLocalDate());
updateProperties();
}
@ -436,20 +388,26 @@ public class TaskComponent extends Div implements AfterCompose {
}
/*
* We override the method of getRealStyle to put the color property as part
* We override the method of renderProperties to put the color property as part
* of the style
*/
protected void renderProperties(ContentRenderer renderer) throws IOException{
if(getColor() != null)
setStyle("background-color : " + getColor());
protected String getRealStyle() {
setWidgetAttribute("movingTasksEnabled",((Boolean)isMovingTasksEnabled()).toString());
setWidgetAttribute("resizingTasksEnabled", ((Boolean)isResizingTasksEnabled()).toString());
final StringBuffer sb = new StringBuffer(super.getRealStyle());
/*We can't use setStyle because of restrictions
* involved with UiVisualizer#getResponses and the
* smartUpdate method (when the request is asynchronous) */
render(renderer, "style", "position : absolute");
if (getColor() != null) {
HTMLs.appendStyle(sb, "background-color", getColor());
}
HTMLs.appendStyle(sb, "position", "absolute");
render(renderer, "_labelsText", getLabelsText());
render(renderer, "_resourcesText", getResourcesText());
render(renderer, "_tooltipText", getTooltipText());
return sb.toString();
super.renderProperties(renderer);
}
/*
@ -487,10 +445,6 @@ public class TaskComponent extends Div implements AfterCompose {
setLeft(this.task.getBeginDate().toPixels(getMapper()) + "px");
updateWidth();
smartUpdate("name", this.task.getName());
DependencyList dependencyList = getDependencyList();
if (dependencyList != null) {
dependencyList.redrawDependenciesConnectedTo(this);
}
updateDeadline();
updateCompletionIfPossible();
updateClass();

View file

@ -49,7 +49,6 @@ import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.Interval;
import org.zkoss.ganttz.util.MenuBuilder;
import org.zkoss.ganttz.util.MenuBuilder.ItemAction;
import org.zkoss.zk.au.out.AuInvoke;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.ext.AfterCompose;
@ -144,7 +143,7 @@ public class TaskList extends XulElement implements AfterCompose {
taskComponent.afterCompose();
if (relocate) {
setHeight(getHeight());// forcing smart update
adjustZoomColumnsHeight();
getGanttPanel().adjustZoomColumnsHeight();
getGanttPanel().getDependencyList().redrawDependencies();
}
}
@ -187,17 +186,7 @@ public class TaskList extends XulElement implements AfterCompose {
}
private void addContextMenu(final TaskComponent taskComponent) {
taskComponent.addEventListener("onRightClick", new EventListener() {
@Override
public void onEvent(Event event) {
try {
getContextMenuFor(taskComponent).open(taskComponent);
} catch (Exception e) {
e.printStackTrace();
}
}
});
taskComponent.setContext(getContextMenuFor(taskComponent));
}
@Override
@ -295,7 +284,6 @@ public class TaskList extends XulElement implements AfterCompose {
for (TaskComponent taskComponent : getTaskComponents()) {
taskComponent.zoomChanged();
}
adjustZoomColumnsHeight();
adjustZoomPositionScroll();
}
};
@ -344,10 +332,6 @@ public class TaskList extends XulElement implements AfterCompose {
return (GanttPanel) getParent();
}
public void adjustZoomColumnsHeight() {
response("adjust_height", new AuInvoke(TaskList.this, "adjust_height"));
}
private void adjustZoomPositionScroll() {
getTimeTrackerComponent().movePositionScroll();
}

View file

@ -1,34 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script.ScriptsRequiredDeclaration;
@ScriptsRequiredDeclaration
public class YUIMin {
private YUIMin() {
}
public static final String YUI_MIN = "/zkau/web/js/yui/2.7.0/yahoo/yahoo-min.js";
}

View file

@ -23,6 +23,7 @@ package org.zkoss.ganttz.resourceload;
import static org.zkoss.ganttz.i18n.I18nHelper._;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -42,6 +43,7 @@ import org.zkoss.ganttz.util.MenuBuilder.ItemAction;
import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.sys.ContentRenderer;
import org.zkoss.zul.Div;
import org.zkoss.zul.Menupopup;
import org.zkoss.zul.impl.XulElement;
@ -105,6 +107,15 @@ public class ResourceLoadComponent extends XulElement {
private void addContextMenu(final List<Div> divs, final Div div,
final LoadTimeLine loadLine) {
/*
* This EventListener could be replaced with
* div.setContext(getContextMenuFor(divs, div, loadLine)) but
* on this case this is not valid as we'll got an exception.
* As this component (ResourceLoadComponent) hasn't be added to
* a page yet, its getPage() method will return null and a
* non-null page is required by MenuBuilder or a NullPointerException
* will be raised.
* */
div.addEventListener("onRightClick", new EventListener() {
@Override
public void onEvent(Event event) {
@ -213,4 +224,11 @@ public class ResourceLoadComponent extends XulElement {
return datesMapper.toPixels(loadPeriod.getStart());
}
protected void renderProperties(ContentRenderer renderer) throws IOException{
render(renderer, "_resourceLoadName", getResourceLoadName());
render(renderer, "_resourceLoadType", getResourceLoadType());
super.renderProperties(renderer);
}
}

View file

@ -35,16 +35,14 @@ 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;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.impl.XulElement;
/**
* Component to include a list of ResourceLoads inside the ResourcesLoadPanel.
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
public class ResourceLoadList extends HtmlMacroComponent implements
AfterCompose {
public class ResourceLoadList extends XulElement {
private final IZoomLevelChangedListener zoomListener;
@ -97,8 +95,8 @@ public class ResourceLoadList extends HtmlMacroComponent implements
for (LoadTimeLine l : line.getAllChildren()) {
getComponentFor(l).detach();
}
Clients
.evalJavaScript("zkResourcesLoadList.recalculateTimetrackerHeight();");
Clients.evalJavaScript(getWidgetClass() + ".getInstance().recalculateTimeTrackerHeight();");
}
private ResourceLoadComponent getComponentFor(LoadTimeLine l) {
@ -119,8 +117,8 @@ public class ResourceLoadList extends HtmlMacroComponent implements
insertBefore(child, nextSibling);
nextSibling = child;
}
Clients
.evalJavaScript("zkResourcesLoadList.recalculateTimetrackerHeight();");
Clients.evalJavaScript(getWidgetClass() + ".getInstance().recalculateTimeTrackerHeight();");
}
private List<LoadTimeLine> getChildrenReverseOrderFor(LoadTimeLine line) {
@ -129,11 +127,6 @@ public class ResourceLoadList extends HtmlMacroComponent implements
return childrenOf;
}
@Override
public void afterCompose() {
super.afterCompose();
}
public void addSeeScheduledOfListener(
ISeeScheduledOfListener seeScheduledOfListener) {
for (Entry<LoadTimeLine, ResourceLoadComponent> entry : fromTimeLineToComponent

View file

@ -37,17 +37,14 @@ import org.zkoss.ganttz.util.Interval;
import org.zkoss.ganttz.util.LongOperationFeedback;
import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation;
import org.zkoss.ganttz.util.MutableTreeModel;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
import org.zkoss.ganttz.util.WeakReferencedListeners;
import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification;
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.zkex.zul.api.South;
import org.zkoss.zul.Button;
import org.zkoss.zul.Comboitem;
import org.zkoss.zul.ListModel;
@ -55,6 +52,7 @@ import org.zkoss.zul.Separator;
import org.zkoss.zul.SimpleListModel;
import org.zkoss.zul.api.Combobox;
import org.zkoss.zul.api.Listbox;
import org.zkoss.zul.api.South;
public class ResourcesLoadPanel extends HtmlMacroComponent {
public interface IToolbarCommand {
@ -128,7 +126,6 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker);
resourceLoadList = new ResourceLoadList(timeTracker, treeModel);
leftPane = new ResourceLoadLeftPane(treeModel, resourceLoadList);
registerNeededScripts();
}
public ListModel getFilters() {
@ -278,15 +275,6 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
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);
@ -513,7 +501,6 @@ public class ResourcesLoadPanel extends HtmlMacroComponent {
timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker);
resourceLoadList = new ResourceLoadList(timeTracker, treeModel);
leftPane = new ResourceLoadLeftPane(treeModel, resourceLoadList);
registerNeededScripts();
}
nameFilterListener.fireEvent(new IListenerNotification<IPaginationFilterChangedListener>() {
@Override

View file

@ -1,37 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.resourceload;
import org.zkoss.ganttz.ScrollSyncScript;
import org.zkoss.ganttz.YUIMin;
import org.zkoss.ganttz.util.script.ScriptsRequiredDeclaration;
@ScriptsRequiredDeclaration(dependsOn = { YUIMin.class, ScrollSyncScript.class })
public class ScriptsRequiredByResourceLoadPanel {
private ScriptsRequiredByResourceLoadPanel() {
}
public static final String SELECTOR = "/zkau/web/js/yui/2.7.0/selector/selector-min.js";
public static final String YAHOO_DOM_EVENT = "/zkau/web/js/yui/2.7.0/yahoo-dom-event/yahoo-dom-event.js";
}

View file

@ -30,9 +30,6 @@ import org.zkoss.ganttz.timetracker.zoom.DetailItem;
import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener;
import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.zk.au.AuRequest;
import org.zkoss.zk.au.Command;
import org.zkoss.zk.au.ComponentCommand;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.HtmlMacroComponent;
@ -46,6 +43,7 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent {
private IZoomLevelChangedListener zoomListener;
private final String secondLevelZul;
private String timeTrackerElementId;
private int scrollLeft;
public TimeTrackerComponent(TimeTracker timeTracker) {
this(timeTracker,
@ -63,6 +61,7 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent {
public void zoomLevelChanged(ZoomLevel detailLevel) {
if (isInPage()) {
recreate();
changeDetailLevel(getDaysFor(scrollLeft));
}
}
};
@ -82,9 +81,15 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent {
return timeTrackerElementId;
}
/*
* fsanjurjo: I'm temporary changing the name of this method
* (from afterCompose to compose) to get it called after calling recreate().
* To understand why, please read this: http://www.zkoss.org/forum/listComment/14905
* Also renamed the call to its parent.
* */
@Override
public void afterCompose() {
super.afterCompose();
public void compose() {
super.compose();
Component fellow = getFellow("firstleveldetails");
addSecondLevels(fellow.getParent());
}
@ -116,49 +121,6 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent {
return getTimeTracker().getTimeTrackerState();
}
private Command _onincreasecmd = new ComponentCommand("onIncrease", 0) {
protected void process(AuRequest request) {
String[] requestData = request.getData();
int pixelsOffset = Integer.parseInt(requestData[0]);
onIncrease(pixelsOffset);
}
};
private Command _ondecreasecmd = new ComponentCommand("onDecrease", 0) {
protected void process(AuRequest request) {
String[] requestData = request.getData();
int pixelsOffset = Integer.parseInt(requestData[0]);
onDecrease(pixelsOffset);
}
};
private Command[] commands = { _onincreasecmd, _ondecreasecmd };
public Command getCommand(String cmdId) {
for (Command command : commands) {
if (command.getId().equals(cmdId)) {
return command;
}
}
return super.getCommand(cmdId);
}
public void onIncrease(int offset) {
double daysOffset = getDaysFor(offset);
getTimeTracker().zoomIncrease();
changeDetailLevel(daysOffset);
}
public void onDecrease(int offset) {
double daysOffset = getDaysFor(offset);
getTimeTracker().zoomDecrease();
changeDetailLevel(daysOffset);
}
public TimeTracker getTimeTracker() {
return timeTracker;
}
@ -198,4 +160,13 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent {
return timeTracker.getDetailLevel() == ZoomLevel.DETAIL_FOUR;
}
public void setZoomLevel(ZoomLevel zoomlevel, int scrollLeft){
this.scrollLeft = scrollLeft;
getTimeTracker().setZoomLevel(zoomlevel);
}
public String getWidgetClass(){
return getDefinition().getDefaultWidgetClass();
}
}

View file

@ -39,6 +39,7 @@ import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
/**
* @author Óscar González Fernández <ogonzalez@igalia.com>
*
@ -71,7 +72,7 @@ public class LongOperationFeedback {
return;
}
Clients.showBusy(longOperation.getName(), true);
Clients.showBusy(longOperation.getName());
executeLater(component, new Runnable() {
public void run() {
try {
@ -81,7 +82,7 @@ public class LongOperationFeedback {
throw new RuntimeException(e);
} finally {
alreadyInside.remove();
Clients.showBusy(null, false);
Clients.clearBusy();
}
}
});
@ -99,6 +100,7 @@ public class LongOperationFeedback {
try {
runnable.run();
} finally {
Clients.clearBusy();
component.removeEventListener(eventName, this);
}
}

View file

@ -1,29 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
public interface IScriptsRegister {
public void register(Class<?> klassContainingScripts)
throws IllegalArgumentException;
}

View file

@ -1,137 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.commons.lang.Validate;
public class ScriptDependenciesSorter implements IScriptsRegister {
public static List<ScriptDependency> extractFrom(Class<?> classWithScripts) {
ScriptsRequiredDeclaration annotation = classWithScripts
.getAnnotation(ScriptsRequiredDeclaration.class);
if (annotation == null) {
throw new IllegalArgumentException(classWithScripts
+ " must be annotated with "
+ ScriptsRequiredDeclaration.class.getName());
}
List<ScriptDependency> dependsOn = getDependencies(annotation);
List<ScriptDependency> result = new ArrayList<ScriptDependency>();
for (Field field : getStringFields(getStaticFields(classWithScripts
.getFields()))) {
result.add(new ScriptDependency(getValueFromStringField(field),
dependsOn));
}
return result;
}
static ArrayList<ScriptDependency> getDependencies(
ScriptsRequiredDeclaration declaration) {
Class<?>[] dependsOn = declaration.dependsOn();
ArrayList<ScriptDependency> result = new ArrayList<ScriptDependency>();
for (Class<?> klass : dependsOn) {
result.addAll(extractFrom(klass));
}
return result;
}
static String getValueFromStringField(Field stringField) {
try {
return (String) stringField.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static List<Field> getStaticFields(Field[] fields) {
List<Field> result = new ArrayList<Field>();
for (Field field : fields) {
if (Modifier.isStatic(field.getModifiers())) {
result.add(field);
}
}
return result;
}
static List<Field> getStringFields(Collection<Field> fields) {
List<Field> stringFields = new ArrayList<Field>();
for (Field field : fields) {
if (field.getType().equals(String.class)) {
stringFields.add(field);
}
}
return stringFields;
}
private List<ScriptDependency> allScripts = new ArrayList<ScriptDependency>();
public ScriptDependenciesSorter() {
}
public void add(ScriptDependency scriptDependency) {
addAll(Arrays.asList(scriptDependency));
}
public void addAll(List<ScriptDependency> dependencies) {
Validate.noNullElements(dependencies);
allScripts.addAll(dependencies);
}
public List<ScriptDependency> getScriptDependenciesOrderered() {
List<ScriptDependency> result = new ArrayList<ScriptDependency>();
Set<ScriptDependency> alreadyAdded = new HashSet<ScriptDependency>();
for (ScriptDependency scriptDependency : allScripts) {
result.addAll(extract(alreadyAdded, scriptDependency));
}
return Collections.unmodifiableList(result);
}
private List<ScriptDependency> extract(Set<ScriptDependency> alreadyAdded,
ScriptDependency scriptDependency) {
List<ScriptDependency> result = new ArrayList<ScriptDependency>();
if (alreadyAdded.contains(scriptDependency)) {
return result;
}
for (ScriptDependency d : scriptDependency.getDependsOn()) {
result.addAll(extract(alreadyAdded, d));
}
result.add(scriptDependency);
alreadyAdded.add(scriptDependency);
return result;
}
@Override
public void register(Class<?> klassContainingScripts)
throws IllegalArgumentException {
addAll(extractFrom(klassContainingScripts));
}
}

View file

@ -1,91 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.HashCodeBuilder;
/**
* Represents a dependency to a script
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
public class ScriptDependency {
public static List<String> getOnlyURLs(
Collection<? extends ScriptDependency> dependencies) {
List<String> result = new ArrayList<String>();
for (ScriptDependency scriptDependency : dependencies) {
result.add(scriptDependency.getURL());
}
return result;
}
private final String url;
private final List<ScriptDependency> dependsOn;
public ScriptDependency(String url) {
this(url, Collections.<ScriptDependency> emptyList());
}
public ScriptDependency(String url, Collection<? extends ScriptDependency> dependencies) {
Validate.notEmpty(url);
Validate.noNullElements(dependencies);
this.url = url;
this.dependsOn = Collections.unmodifiableList(new ArrayList<ScriptDependency>(
dependencies));
}
public String getURL() {
return this.url;
}
public List<ScriptDependency> getDependsOn() {
return dependsOn;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (other instanceof ScriptDependency) {
return url.equals(((ScriptDependency) other).url);
}
return false;
}
@Override
public int hashCode() {
return new HashCodeBuilder().append(url).toHashCode();
}
@Override
public String toString() {
return url;
}
}

View file

@ -1,102 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
import org.zkoss.zk.ui.Execution;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.HtmlMacroComponent;
public class ScriptsComponent extends HtmlMacroComponent {
private List<ScriptDependency> current = Collections.emptyList();
public ScriptsComponent() {
OnZKDesktopRegistry<IScriptsRegister> singleton = getScriptsRegister();
ScriptRegister register;
if (singleton.isRegistered()) {
register = (ScriptRegister) singleton.retrieve();
} else {
register = new ScriptRegister();
singleton.store(register);
}
register.addDependant(this);
}
private OnZKDesktopRegistry<IScriptsRegister> getScriptsRegister() {
return OnZKDesktopRegistry.getLocatorFor(IScriptsRegister.class);
}
public List<ScriptDependency> getScriptDependencies() {
return current;
}
void setDependencies(List<ScriptDependency> current) {
this.current = current;
if (!executionIsUpdatingPage()) {
recreate();
}
}
private boolean executionIsUpdatingPage() {
return Executions.getCurrent().isAsyncUpdate(null);
}
}
class ScriptRegister implements IScriptsRegister {
private ScriptDependenciesSorter dependenciesSorter = new ScriptDependenciesSorter();
private List<ScriptsComponent> dependant = new ArrayList<ScriptsComponent>();
void addDependant(ScriptsComponent component) {
dependant.add(component);
}
@Override
public void register(Class<?> klassContainingScripts)
throws IllegalArgumentException {
dependenciesSorter.register(klassContainingScripts);
notifyDependant(encodeURLs(dependenciesSorter
.getScriptDependenciesOrderered()));
}
private List<ScriptDependency> encodeURLs(
List<ScriptDependency> scriptDependenciesOrderered) {
List<ScriptDependency> result = new ArrayList<ScriptDependency>();
Execution execution = Executions.getCurrent();
for (ScriptDependency s : scriptDependenciesOrderered) {
result.add(new ScriptDependency(execution.encodeURL(s.getURL())));
}
return result;
}
private void notifyDependant(List<ScriptDependency> current) {
for (ScriptsComponent d : dependant) {
d.setDependencies(current);
}
}
}

View file

@ -1,34 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ScriptsRequiredDeclaration {
public Class<?>[] dependsOn() default {};
}

View file

@ -14,6 +14,7 @@
<component>
<component-name>planner</component-name>
<component-class>org.zkoss.ganttz.Planner</component-class>
<widget-class>ganttz.Planner</widget-class>
<macro-uri>~./ganttz/zul/plannerLayout.zul</macro-uri>
<!-- mold>
<mold-name>default</mold-name>
@ -36,9 +37,11 @@
<component>
<component-name>resourcesLoadList</component-name>
<component-class>org.zkoss.ganttz.resourceload.ResourceLoadList</component-class>
<widget-class>ganttz.resourceload.ResourceLoadList</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/resourceload/resourceloadlist.dsp</mold-uri>
<mold-uri>mold/resource-load-list.js</mold-uri>
<!-- <mold-uri>~./ganttz/resourceload/resourceloadlist.dsp</mold-uri> -->
</mold>
</component>
@ -64,9 +67,11 @@
<component>
<component-name>ganttpanel</component-name>
<component-class>org.zkoss.ganttz.GanttPanel</component-class>
<widget-class>ganttz.GanttPanel</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/ganttpanel.dsp</mold-uri>
<!-- <mold-uri>~./ganttz/ganttpanel.dsp</mold-uri> -->
<mold-uri>mold/gantt-panel.js</mold-uri>
</mold>
</component>
@ -74,9 +79,11 @@
<component-name>resourceload</component-name>
<component-class>org.zkoss.ganttz.resourceload.ResourceLoadComponent
</component-class>
<widget-class>ganttz.resourceload.ResourceLoadComponent</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/resourceload/resourceload.dsp</mold-uri>
<mold-uri>mold/resource-load-component.js</mold-uri>
<!-- <mold-uri>~./ganttz/resourceload/resourceload.dsp</mold-uri> -->
</mold>
</component>
@ -84,27 +91,33 @@
<component>
<component-name>taskRow</component-name>
<component-class>org.zkoss.ganttz.TaskRow</component-class>
<widget-class>ganttz.TaskRow</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/row.dsp</mold-uri>
<!-- <mold-uri>~./ganttz/row.dsp</mold-uri> -->
<mold-uri>mold/task-row.js</mold-uri>
</mold>
</component>
<component>
<component-name>task</component-name>
<component-class>org.zkoss.ganttz.TaskComponent</component-class>
<widget-class>ganttz.TaskComponent</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/task.dsp</mold-uri>
<!-- <mold-uri>~./ganttz/task.dsp</mold-uri> -->
<mold-uri>mold/task-component.js</mold-uri>
</mold>
</component>
<component>
<component-name>milestone</component-name>
<component-class>org.zkoss.ganttz.MilestoneComponent</component-class>
<widget-class>ganttz.Milestone</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/milestone.dsp</mold-uri>
<!-- <mold-uri>~./ganttz/milestone.dsp</mold-uri> -->
<mold-uri>mold/milestone.js</mold-uri>
</mold>
</component>
@ -113,27 +126,33 @@
<component-name>taskcontainer</component-name>
<component-class>org.zkoss.ganttz.TaskContainerComponent
</component-class>
<widget-class>ganttz.TaskContainerComponent</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/taskcontainer.dsp</mold-uri>
<mold-uri>mold/task-container.js</mold-uri>
<!-- <mold-uri>~./ganttz/taskcontainer.dsp</mold-uri> -->
</mold>
</component>
<component>
<component-name>tasklist</component-name>
<component-class>org.zkoss.ganttz.TaskList</component-class>
<widget-class>ganttz.TaskList</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/tasklist.dsp</mold-uri>
<!-- <mold-uri>~./ganttz/tasklist.dsp</mold-uri> -->
<mold-uri>mold/task-list.js</mold-uri>
</mold>
</component>
<component>
<component-name>dependencylist</component-name>
<component-class>org.zkoss.ganttz.DependencyList</component-class>
<widget-class>ganttz.DependencyList</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/dependencylist.dsp</mold-uri>
<!-- <mold-uri>~./ganttz/dependencylist.dsp</mold-uri> -->
<mold-uri>mold/dependency-list.js</mold-uri>
</mold>
</component>
@ -141,9 +160,11 @@
<component-name>dependency</component-name>
<component-class>org.zkoss.ganttz.DependencyComponent
</component-class>
<widget-class>ganttz.DependencyComponent</widget-class>
<mold>
<mold-name>default</mold-name>
<mold-uri>~./ganttz/dependency.dsp</mold-uri>
<mold-uri>mold/dependency-component.js</mold-uri>
<!-- <mold-uri>~./ganttz/dependency.dsp</mold-uri> -->
</mold>
</component>
@ -151,7 +172,8 @@
<component>
<component-name>timetracker</component-name>
<component-class>org.zkoss.ganttz.timetracker.TimeTrackerComponent</component-class>
<macro-uri>~./ganttz/zul/timetracker/timetracker.zul</macro-uri>
<widget-class>ganttz.TimeTracker</widget-class>
<macro-uri>~./ganttz/zul/timetracker/timetracker.zul</macro-uri>
</component>
<component>
@ -160,10 +182,4 @@
<macro-uri>~./ganttz/zul/timetracker/timetrackedtable.zul</macro-uri>
</component>
<component>
<component-name>scripts</component-name>
<component-class>org.zkoss.ganttz.util.script.ScriptsComponent</component-class>
<macro-uri>~./ganttz/zul/scripts.zul</macro-uri>
</component>
</language-addon>

View file

@ -19,7 +19,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
-->
<zk xmlns:n="http://www.zkoss.org/2005/zk/native">
<n:div id="listdetails_container">
</n:div>
<zk>
<div id="listdetails_container">
</div>
</zk>

View file

@ -18,104 +18,99 @@
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 xmlns:n="http://www.zkoss.org/2005/zk/native">
<?component name="button" extends="button" mold="trendy"?>
<?xel-method prefix="ganttzk_i18n" name="_" class="org.zkoss.ganttz.i18n.I18nHelper"
signature="java.lang.String _(java.lang.String name)" ?>
<zscript><![CDATA[
planner = self;
]]>
</zscript>
<borderlayout sclass="plannerlayout" width="auto">
<north height="30px" border="0" sclass="toolbar-box">
<hbox align="center" id="toolbar">
<borderlayout width="auto" height="100%" class="inner-layout">
<north height="32px" border="0" sclass="toolbar-box">
<zscript><![CDATA[
planner = self;
]]>
</zscript>
<separator/>
<!-- Commands -->
<templateFinderPopup id="templateFinderPopup" acceptButtonLabel="${ganttzk_i18n:_('Create Project')}" caption="${i18n:_('Choosing Template')}" />
<hbox align="center" id="toolbar">
<separator />
<button onClick="planner.invalidate()"
image="/common/img/ico_refresh.png"
tooltiptext="${ganttzk_i18n:_('Refresh')}" visible="false" />
<button id="btnPrint" onClick="planner.print()"
image="/common/img/ico_print.png"
tooltiptext="${ganttzk_i18n:_('Print')}" />
<separator/>
<!-- Commands -->
<templateFinderPopup id="templateFinderPopup"
acceptButtonLabel="${ganttzk_i18n:_('Create Project')}"
caption="${ganttzk_i18n:_('Choosing Template')}" />
<button onClick="planner.invalidate()" image="/common/img/ico_refresh.png"
tooltiptext="${ganttzk_i18n:_('Refresh')}" visible="false" />
<button id="btnPrint" onClick="planner.print()"
image="/common/img/ico_print.png" tooltiptext="${ganttzk_i18n:_('Print')}" />
<!-- Visualization modes -->
<label>${ganttzk_i18n:_('Zoom')}:</label>
<listbox id="listZoomLevels" mold="select" rows="1"
model="${planner.zoomLevels}">
</listbox>
<separator />
<!-- Progress type -->
<!-- Visualization modes -->
<label>${ganttzk_i18n:_('Zoom')}:</label>
<listbox id="listZoomLevels" mold="select" rows="1"
model="${planner.zoomLevels}" onSelect="planner.setZoomLevel(self.selectedItem.value);">
</listbox>
<!-- Progress type -->
<hbox sclass="view-options">
<button id="showCriticalPath" onClick="planner.showCriticalPath();"
image="/common/img/ico_criticalpath.png"
tooltiptext="${ganttzk_i18n:_('Show/Hide critical path')}"
sclass="planner-command" />
<button id="showAllLabels" onClick="planner.showAllLabels();"
image="/common/img/ico_labels.png"
tooltiptext="${ganttzk_i18n:_('Show/Hide labels')}"
sclass="planner-command show-labels" />
<button id="showAllResources" onClick="planner.showAllResources();"
image="/common/img/ico_resources.png" tooltiptext="${ganttzk_i18n:_('Show/Hide resources')}"
sclass="planner-command show-resources" />
<button id="expandAll" onClick="planner.expandAll();"
image="/common/img/ico_expand.png" tooltiptext="${ganttzk_i18n:_('Expand/Collapse all')}"
sclass="planner-command" />
<button id="flattenTree" onClick="planner.flattenTree();"
image="/common/img/ico_flatten.png" tooltiptext="${ganttzk_i18n:_('Flatten/Unflatten tree')}"
sclass="planner-command" />
<button id="showReportedHours" onClick="planner.showReportedHours();"
image="/common/img/ico_costs.png" tooltiptext="${ganttzk_i18n:_('Show/Hide reported hours')}"
sclass="planner-command" />
</hbox>
<hbox class="show-advances" align="center">
<button id="showAdvances" onClick="planner.showAdvances();"
image="/common/img/ico_progress.png" style="width:46px"
tooltiptext="${ganttzk_i18n:_('Show/Hide progress')}"
sclass="planner-command" />
<combobox id="cbProgressTypes" width="1px"
visible="false" sclass="progress-types" />
</hbox>
<separator />
<!-- Filtering -->
<vbox id="orderFilter" />
<vbox id="orderElementFilter" />
<separator />
<button id="showCriticalPath" onClick="planner.showCriticalPath();"
image="/common/img/ico_criticalpath.png"
tooltiptext="${ganttzk_i18n:_('Show/Hide critical path')}" />
<button id="showAllLabels" onClick="planner.showAllLabels();"
image="/common/img/ico_labels.png"
tooltiptext="${ganttzk_i18n:_('Show/Hide labels')}" sclass="planner-command show-labels" />
<button id="showAllResources" onClick="planner.showAllResources();"
image="/common/img/ico_resources.png"
tooltiptext="${ganttzk_i18n:_('Show/Hide resources')}" sclass="planner-command show-resources" />
<button id="expandAll" onClick="planner.expandAll();"
image="/common/img/ico_expand.png"
tooltiptext="${ganttzk_i18n:_('Expand/Collapse all')}"
sclass="planner-command" />
<button id="flattenTree" onClick="planner.flattenTree();"
image="/common/img/ico_flatten.png"
tooltiptext="${ganttzk_i18n:_('Flatten/Unflatten tree')}"
sclass="planner-command" />
<hbox class="show-advances" align="center">
<button id="showAdvances" onClick="planner.showAdvances();"
image="/common/img/ico_progress.png"
style="width:46px"
tooltiptext="${ganttzk_i18n:_('Show/Hide progress')}"
sclass="planner-command" />
<combobox id="cbProgressTypes" width="1px" visible="false" sclass="progress-types"/>
</hbox>
</north>
<center border="0">
<borderlayout sclass="plannerlayout_center" height="100%">
<west flex="false" collapsible="true" splittable="true"
width="300px" id="taskdetailsContainer" sclass="taskdetailsContainer">
<div sclass="leftpanelgap" id="insertionPointLeftPanel"></div>
</west>
<center id="taskpanel" sclass="taskspanel">
<borderlayout>
<north border="0">
<div sclass="timetrackergap" id="insertionPointTimetracker"></div>
</north>
<center id="centerPanel" autoscroll="true"
border="10" sclass="rightpanellayout">
<div id="insertionPointRightPanel" sclass="taskspanelgap"></div>
</center>
</borderlayout>
<button id="showReportedHours" onClick="planner.showReportedHours();"
image="/common/img/ico_costs.png"
tooltiptext="${ganttzk_i18n:_('Show/Hide reported hours')}"
sclass="planner-command"/>
<separator />
</center>
</borderlayout>
</center>
<south collapsible="true" title="${ganttzk_i18n:_('Graphics')}"
sclass="scheduling-graphics" id="graphics"
onOpen="planner.changeChartVisibility(event.open);" height="200px">
<div id="insertionPointChart" />
</south>
</borderlayout>
<!-- Filtering -->
<vbox id="orderFilter"/>
<vbox id="orderElementFilter"/>
<separator />
</hbox>
</north>
<center border="0">
<borderlayout sclass="plannerlayout_center" height="100%">
<west flex="false" collapsible="true" splittable="true" width="300px"
id="taskdetailsContainer" sclass="taskdetailsContainer">
<div sclass="leftpanelgap" id="insertionPointLeftPanel"></div>
</west>
<center sclass="taskspanel">
<borderlayout>
<north border="0"><div sclass="timetrackergap" id="insertionPointTimetracker"></div></north>
<center autoscroll="true" border="0" sclass="rightpanellayout">
<div id="insertionPointRightPanel" sclass="taskspanelgap"></div>
</center>
</borderlayout>
</center>
</borderlayout>
</center>
<south collapsible="true" title="${ganttzk_i18n:_('Graphics')}" sclass="scheduling-graphics"
id="graphics" onOpen="planner.changeChartVisibility(event.open);" height="200px">
<div id="insertionPointChart" />
</south>
</borderlayout>
</zk>

View file

@ -62,8 +62,8 @@ resourcesLoadPanel = self;
<borderlayout >
<north border="0" height="35px" flex="true" collapsible="true">
<vbox pack="top" align="center" width="100%">
<tree fixedLayout="true" width="100%">
<vbox pack="top" align="center">
<tree fixedLayout="true" hflex="true">
<treecols>
<treecol label="${ganttzk_i18n:_('Name')}" height="29px"/>
</treecols>

View file

@ -27,29 +27,6 @@ top = self;
</zscript>
<div>
<n:script language="javascript">
function getHorizontalScroll(timetracker) {
return document.getElementById('${top.timeTrackerId}').scrollLeft;
}
function onIncrease(timetracker) {
zkau.send( {
uuid : timetracker.id,
cmd : "onIncrease",
data : [ getHorizontalScroll(timetracker) ]
});
}
function onDecrease(timetracker) {
zkau.send( {
uuid : timetracker.id,
cmd : "onDecrease",
data : [ getHorizontalScroll(timetracker) ]
});
}
</n:script>
<n:div id="${top.timeTrackerId}">
<vbox>
<grid id="firstleveldetails" width="${top.horizontalSizePixels}px;">

View file

@ -0,0 +1,72 @@
zk.$package("common");
common.Common = zk.$extends(zk.Widget,{},{
webAppContextPath : function(){ return window.location.pathname.split( '/' )[1];},
throttle: function(timeoutTimeMillis, functionToExecute) {
var lastTimeCalled = null;
var cachedResult = null;
return function() {
var now = Date.now();
if (lastTimeCalled !== null && ((now - lastTimeCalled) < timeoutTimeMillis)) {
return cachedResult;
}
lastTimeCalled = now;
cachedResult = functionToExecute.apply(null, arguments);
return cachedResult;
};
},
/**
* It can be called in the constructor of a widget.
* It is required that the widget has the method _divsToRestoreDayInto that returns
* the divs which their scroll must be changed back to the previous day.
*/
// TODO: Refactoring should be done, not so many methods should be needed to synchronize the day.
mixInDayPositionRestorer: function(widget) {
if (! ('_divsToRestoreDayInto' in widget)) {
throw '_divsToRestoreDayInto function must be present in widget';
}
var scrollDay = 0;
/**
* Scrolls horizontally the ganttpanel when the zoom has resized the component
* width.
*/
widget.scroll_horizontal = function(daysDisplacement) {
scrollDay = daysDisplacement;
};
widget.update_day_scroll = function(previousPixelPerDay) {
var divs = this._divsToRestoreDayInto();
var topScrollDiv = divs[divs.length - 1];
var maxHPosition = topScrollDiv.scrollWidth - topScrollDiv.clientWidth;
if (maxHPosition > 0) {
var proportion = topScrollDiv.scrollWidth / maxHPosition;
var positionInScroll = topScrollDiv.scrollLeft;
var positionInPx = positionInScroll * proportion;
if (positionInPx > 0) {
scrollDay = positionInPx / previousPixelPerDay;
}
}
};
widget.move_scroll = function(diffDays, pixelPerDay) {
var divs = this._divsToRestoreDayInto();
var topScrollDiv = divs[divs.length - 1];
var day = this.scrollDay + parseInt(diffDays);
var newPosInPx = parseInt(day * pixelPerDay);
var maxHPosition = topScrollDiv.scrollWidth - topScrollDiv.clientWidth;
var newProportion = topScrollDiv.scrollWidth / maxHPosition;
if (newProportion > 0) {
var newPosInScroll = newPosInPx / newProportion;
if (newPosInScroll < 0) {
newPosInScroll = 0;
}
for ( var i = 0; i < divs.length; i++) {
divs[i].scrollLeft = newPosInScroll;
}
}
};
}
});

View file

@ -0,0 +1,3 @@
<package name="common" language="xul/html">
<widget name="Common"/>
</package>

View file

@ -0,0 +1,345 @@
zk.$package("ganttz");
ganttz.DependencyComponentBase = zk.$extends(zul.Widget,{
$define : {
idTaskOrig : null,
idTaskEnd : null,
dependencyType : null
},
bind_ : function(){
this.$supers('bind_', arguments);
this.setupArrow_();
},
setCSSClass: function(newClass) {
this.$n().setAttribute("class", newClass);
},
draw : function(){throw "draw method must be overwriten by extending classes"},
drawArrow_ : function(coordOrig, coordDest){
switch(this.getDependencyType())
{
case this.$class.START_START:
this._drawArrowStartStart(coordOrig, coordDest);
break;
case this.$class.END_END:
this._drawArrowEndEnd(coordOrig, coordDest);
break;
case this.$class.END_START:
default:
this._drawArrowEndStart(coordOrig, coordDest);
}
},
_drawArrowStartStart : function(coordOrig, coordDest){
var yorig = coordOrig.top -
ganttz.TaskComponent.CORNER_WIDTH/2 +
this.$class.HALF_DEPENDENCY_PADDING;
var xorig = coordOrig.left - this.$class.HALF_DEPENDENCY_PADDING;
var xend = coordDest.left + this.$class.HALF_DEPENDENCY_PADDING;
var yend = coordDest.top - this.$class.HALF_DEPENDENCY_PADDING;
if (yend < yorig) yorig = coordOrig.top + this.$class.DEPENDENCY_PADDING;
var width1 = ganttz.TaskComponent.CORNER_WIDTH;
var width2 = Math.abs(xend - xorig) + ganttz.TaskComponent.CORNER_WIDTH;
var height = Math.abs(yend - yorig);
if (xorig > xend) {
width1 = width2;
width2 = ganttz.TaskComponent.CORNER_WIDTH;
}
// First segment
var depstart = this._findImageElement('start');
depstart.css({ top : yorig,
left : (xorig - width1),
width : width1 ,
display : 'inline'})
// Second segment
var depmid = this._findImageElement('mid');
var depmidcss = {left : depstart.css('left'), height : height};
if (yend > yorig) {
depmidcss.top = yorig;
} else {
depmidcss.top = yend;
}
depmid.css(depmidcss);
// Third segment
var depend = this._findImageElement('end');
depend.css({ top : yend,
left : depstart.css('left'),
width : width2 - ganttz.TaskComponent.HALF_HEIGHT});
var deparrow = this._findImageElement('arrow');
deparrow.css({top : (yend - ganttz.TaskComponent.HALF_HEIGHT),left : xend - 15});
},
_drawArrowEndEnd : function(coordOrig, coordDest){
var xorig = coordOrig.left - this.$class.DEPENDENCY_PADDING;
var yorig = coordOrig.top - ganttz.TaskComponent.CORNER_WIDTH/2 + this.$class.HALF_DEPENDENCY_PADDING;
var xend = coordDest.left + this.$class.HALF_DEPENDENCY_PADDING;
var yend = coordDest.top - this.$class.DEPENDENCY_PADDING;
var width1 = Math.abs(xend - xorig) + ganttz.TaskComponent.CORNER_WIDTH;
var width2 = ganttz.TaskComponent.CORNER_WIDTH;
var height = Math.abs(yend - yorig);
if (xorig > xend) {
width2 = width1;
width1 = ganttz.TaskComponent.CORNER_WIDTH;
}
// First segment
var depstart = this._findImageElement('start');
var depstartcss = {left : xorig, width : width1, display : 'inline'}
if (yend > yorig)
depstartcss.top = yorig ;
else
depstartcss.top = yorig + ganttz.TaskComponent.HEIGHT;
depstart.css(depstartcss);
// Second segment
var depmid = this._findImageElement('mid');
var depmidcss = {left : (xorig + width1), height : height};
if (yend > yorig) {
depmidcss.top = yorig;
} else {
depmidcss.top = yend;
depmidcss.height = height + 10;
}
depmid.css(depmidcss);
// Third segment
var depend = this._findImageElement('end');
depend.css({ left : (xorig + width1 - width2),
top:yend,
width:width2 });
var deparrow = this._findImageElement('arrow');
deparrow.attr('src', this.$class.getImagesDir() + "arrow3.png");
deparrow.css({top : yend - 5, left : xend - 8});
},
_drawArrowEndStart : function(coordOrig, coordDest){
var xorig = coordOrig.left - this.$class.DEPENDENCY_PADDING;
var yorig = coordOrig.top - this.$class.HALF_DEPENDENCY_PADDING;
var xend = coordDest.left - this.$class.DEPENDENCY_PADDING;
var yend = coordDest.top - this.$class.HALF_DEPENDENCY_PADDING;
var width = (xend - xorig);
var xmid = xorig + width;
// First segment not used
var depstart = this._findImageElement('start');
depstart.hide();
// Second segment not used
var depmid = this._findImageElement('mid');
var depmidcss;
if (yend > yorig)
depmidcss = {top : yorig, height : yend - yorig};
else
depmidcss = {top : yend, height : (yorig - yend)};
depmidcss.left = xorig;
depmid.css(depmidcss);
var depend = this._findImageElement('end');
var dependcss = {top : yend, left : xorig, width : width};
if(width < 0) {
dependcss.left = xend;
dependcss.width = Math.abs(width);
}
depend.css(dependcss);
var deparrow = this._findImageElement('arrow');
var deparrowsrc, deparrowcss;
if ( width == 0 ) {
deparrowcss = {top : (yend - 10) , left : (xend - 5)};
deparrowsrc = this.$class.getImagesDir() + "arrow2.png";
if ( yorig > yend ) {
deparrowcss = {top : yend};
deparrowsrc = this.$class.getImagesDir() + "arrow4.png";
}
} else {
deparrowcss = {top : (yend -5), left : (xend - 10)};
deparrowsrc = this.$class.getImagesDir() + "arrow.png";
if (width < 0) {
deparrowcss = {top : (yend - 5), left : xend}
deparrowsrc = this.$class.getImagesDir() + "arrow3.png";
}
}
deparrow.attr('src', deparrowsrc);
deparrow.css(deparrowcss);
},
findPos_ : function(element){
var pos1 = jq('#listdependencies').offset();
var pos2 = element.offset();
return {left : (pos2.left - pos1.left), top : (pos2.top - pos1.top)};
},
_findImageElement : function(name) {
var img = jq('.' + name + '', this.$n());
return img;
},
setupArrow_ : function(){
var image_data = [ [ "start", "pixel.gif" ], [ "mid", "pixel.gif" ],
[ "end", "pixel.gif" ], [ "arrow", "arrow.png" ] ];
var img;
var insertPoint = jq(this.$n());
for ( var i = 0; i < image_data.length; i++) {
img = jq(document.createElement('img'));
img.attr({
'class' : image_data[i][0] + " extra_padding",
'src' : this.$class.getImagesDir() + image_data[i][1]
});
insertPoint.append(img);
}
}
},{
END_END : "END_END",
END_START : "END_START",
START_START : "START_START",
HALF_DEPENDENCY_PADDING : 2,
DEPENDENCY_PADDING : 4,
DRAGABLE_PADDING : 20, // Drag padding for dependency creation
getImagesDir : function(){
return "/" + common.Common.webAppContextPath() + "/zkau/web/ganttz/img/";
}
})
ganttz.DependencyComponent = zk.$extends(ganttz.DependencyComponentBase,{
$define : {
idTaskOrig : null,
idTaskEnd : null,
dependencyType : null
},
bind_ : function(){
this.$supers('bind_', arguments);
//this.setupArrow_();
/*maybe move this listener to the $init method*/
YAHOO.util.Event.onDOMReady(this.proxy(function() {
this.draw();
}));
},
draw : function() {
this._withOriginAndDestination(function(origin, destination) {
var orig = this.findPos_(origin);
var dest = this.findPos_(destination);
// This corner case may depend on dependence type
var offsetX = origin.outerWidth() - ganttz.TaskComponent.CORNER_WIDTH;
var separation = orig.left + origin.outerWidth() - dest.left;
if (separation > 0) {
offsetX = offsetX - separation;
}
if (this.getDependencyType() == this.$class.END_START
|| this.getDependencyType() == null) {
orig.left = orig.left + Math.max(0, offsetX);
} else if (this.getDependencyType() == this.$class.END_END) {
orig.left = orig.left + origin.outerWidth();
dest.left = dest.left + destination.outerWidth();
}
orig.top = orig.top + ganttz.TaskComponent.HEIGHT;
dest.top = dest.top + ganttz.TaskComponent.HALF_HEIGHT;
if (orig.top > dest.top) {
orig.top = orig.top - ganttz.TaskComponent.HEIGHT;
}
this.drawArrow_(orig, dest);
});
},
_withOriginAndDestination : function(f) {
f.call(this, jq('#' + this.getIdTaskOrig()), jq('#' + this.getIdTaskEnd()));
}
},{});
ganttz.UnlinkedDependencyComponent = zk.$extends(ganttz.DependencyComponentBase,{
$init : function(){
this.$supers('$init', arguments);
this._DOMlisttasks = jq('#listtasks');
this._DOMlistdependencies = jq('#listdependencies');
this._WGTganttpanel = ganttz.GanttPanel.getInstance();
},
bind_ : function(){
this.$supers('bind_', arguments);
/*We use document.documentElement as the DOM element to attach this listener
* because document.documentElement always gets the key events (in all browsers)*/
this.domListen_(document.documentElement,'onKeyup','_handleKeyUp');
this._updateArrow();
},
unbind_ : function(){
this.domUnlisten_(document.documentElement,'onKeyup','_handleKeyUp');
this.domUnlisten_(this._WGTganttpanel.$n(), 'onMousemove', '_updateArrow');
this.domUnlisten_(this._WGTganttpanel.$n(), 'onClick', '_consolidateDependency');
this.$supers('unbind_', arguments);
},
draw : function(){
this.domListen_(this._WGTganttpanel.$n(), 'onMousemove', '_updateArrow');
this.domListen_(this._WGTganttpanel.$n(), 'onClick', '_consolidateDependency');
},
setOrigin : function(origin){
this._DOMorigin = jq(origin);
this._WGTorigin = ganttz.TaskComponent.$(origin.id);
},
_consolidateDependency : function(){
var dependency = null;
if ((dependency = this._isOverTask()) != null){
this._WGTorigin.consolidateNewDependency(dependency);
}
/* We remove the dependency line. If the user clicked over a
* task, a new dependecy line will be created */
ganttz.DependencyList.getInstance().removeChild(this);
},
_isOverTask : function() {
var tasksArray = jq('div[z\\.type="ganttz.task.Task"]');
var overTask = null;
tasksArray.each(function(index, element){
if(ganttz.TaskComponent.$(element.id).mouseOverTask) overTask = ganttz.TaskComponent.$(element.id);
});
return overTask;
},
updateCoordOrigin : function(){
var coordOrigin = this.findPos_(this._DOMorigin);
coordOrigin.left = coordOrigin.left
+ Math.max(0, this._DOMorigin.outerWidth() -
ganttz.TaskComponent.CORNER_WIDTH);
coordOrigin.top = coordOrigin.top - this._DOMlisttasks.position().top +
this._DOMlistdependencies.position().top +
ganttz.TaskComponent.HEIGHT;
this._coordOrigin = coordOrigin;
return this._coordOrigin;
},
_updateArrow : function(event){
if (! this._coordOrigin ) this.updateCoordOrigin();
var coordDest;
coordDest = this._findCoordsForMouse();
this.drawArrow_(this._coordOrigin, coordDest);
},
_findCoordsForMouse : function(){
var pos1 = YAHOO.util.Dom.getXY('listtasks');
return { left : this._WGTganttpanel.getXMouse() - pos1[0],
top: this._WGTganttpanel.getYMouse() - pos1[1]};
},
_handleKeyUp: function(event){
if ( event.keyCode != 27 )
return;
event.stop();
ganttz.DependencyList.getInstance().removeChild(this);
}
})
zk.afterLoad('ganttz',function(){
ganttz.UnlinkedDependencyComponent.molds = ganttz.DependencyComponent.molds;
})

View file

@ -0,0 +1,15 @@
zk.$package("ganttz");
ganttz.DependencyList = zk.$extends(zk.Widget, {
$init : function(){
this.$supers('$init', arguments);
this.$class.setInstance(this);
}
},{
setInstance : function(instance){
this._instance = instance;
},
getInstance : function(){
return this._instance;
}
});

View file

@ -0,0 +1,77 @@
zk.$package("ganttz");
ganttz.GanttPanel = zk.$extends(zk.Widget,{
$define: {
xMouse : null,
yMouse : null
},
scrollDay: 0,
$init : function(){
this.$supers('$init', arguments);
this.$class.setInstance(this);
common.Common.mixInDayPositionRestorer(this);
},
bind_ : function(evt){
this.$supers('bind_', arguments);
this._initializeProperties();
this.domListen_(this.$n(), 'onMousemove', '_calcXY');
this.domListen_(this._rightpannellayout, 'onScroll', '_listenToScroll');
},
unbind_ : function(evt){
this.domUnlisten_(this._rightpannellayout, 'onScroll', '_listenToScroll');
this.domUnlisten_(this.$n(), 'onMousemove', '_calcXY');
this.$supers('unbind_', arguments);
},
_divsToRestoreDayInto: function() {
var first = jq("#ganttpanel").get(0);
return [first, first.parentNode, first.parentNode.parentNode];
},
timeplotContainerRescroll : function(){
this._timeplotcontainer.each(jq.proxy(function(index, element){
jq(element).css("left", "-" + this._rightpannellayout.scrollLeft() + "px")
}, this));
},
adjust_height : function(){
jq(this.$n()).height(jq('#scroll_container').height());
ganttz.Planner.getInstance().adjustScrollableDimensions();
},
_calcXY : function(event){
var arrPos = YAHOO.util.Event.getXY(event);
this.setXMouse(arrPos[0]);
this.setYMouse(arrPos[1]);
},
_listenToScroll : function(){
this._timetrackergap.css("left","-" + this._rightpannellayout.scrollLeft() + "px");
this._taskdetails.css("top", "-" + this._rightpannellayout.scrollTop() + "px");
this._plannergraph.scrollLeft( this._rightpannellayout.scrollLeft() );
this.timeplotContainerRescroll();
},
_initializeProperties : function(){
/*The canvas is inserted in the DOM after this component so
* it's not available right now. We set up a handler to do
* job*/
jq(document).ready(jq.proxy(
function(){ this._timeplotcontainer = jq('canvas.timeplot-canvas');
},this));
this._timetrackergap = jq('.timetrackergap');
this._rightpannellayout = jq('.rightpanellayout div:first');
this._taskdetails = jq('.listdetails .z-tree-body');
this._plannergraph = jq('.plannergraph:first');
},
reScrollY : function(px){
jq('#ganttpanel_inner_scroller_y').height(px);
},
reScrollX : function(px){
jq('#ganttpanel_inner_scroller_x').width(px);
}
},{
getInstance : function(){
return this._instance;
},
setInstance : function(instance){
this._instance = instance;
}
});

View file

@ -0,0 +1,2 @@
zk.$package("ganttz");
ganttz.Milestone = zk.$extends(ganttz.TaskComponent, {},{});

View file

@ -0,0 +1,75 @@
zk.$package("ganttz");
ganttz.Planner = zk.$extends(zk.Macro,{
$init : function(){
this.$supers('$init', arguments);
this.$class.setInstance(this);
},
bind_ : function(){
this.$supers('bind_', arguments);
this.adjustScrollableDimensions();
//Zoomlevel selector
this.domListen_(jq('.plannerlayout .toolbar-box select'), 'onChange', '_zoomLevelChanged');
},
unbind_ : function(){
this.$supers('unbind_', arguments);
this.domUnlisten_(jq('.plannerlayout .toolbar-box select'), 'onChange', '_zoomLevelChanged');
},
adjustScrollableDimensions : function(){
// Timetracker is recalculated when the window is resized and when zoom
// level is changed as the component is recreated
var DOMTimetracker = jq('#timetracker');
var DOMWatermark = jq('#watermark');
var DOMScrollContainer = jq('#scroll_container');
DOMTimetracker.width(
jq(window).width() -
this.$class.TASKDETAILS_WIDTH -
this.$class.SCROLLBAR_WIDTH * 2);
DOMScrollContainer.width(
jq('.second_level_ :first').innerWidth());
DOMTimetracker.width(DOMScrollContainer.innerWidth());
DOMTimetracker.height(
Math.max(
jq(window).height() -
this.$class.TIMETRACKER_OFFSET_TOP +
26),
(
jq('#listdetails_container').height() +
12));
DOMScrollContainer.height(
jq(window).height() -
this.$class.TIMETRACKER_OFFSET_TOP -
this.$class.FOOTER_HEIGHT +
this.$class.SCROLLBAR_WIDTH * 2);
// Inner divs need recalculation to adjust to new scroll displacement lenght
ganttz.GanttPanel.getInstance().reScrollY(jq('#listdetails_container').height());
// Inner divs need recalculation to adjust to new scroll displacement lenght
ganttz.GanttPanel.getInstance().reScrollX(DOMWatermark.outerWidth());
},
_zoomLevelChanged : function(event){
var zoomindex = event.domTarget.selectedIndex;
var scrollLeft = parseFloat(jq('.timetrackergap').css('left').replace(/px/, ""));
zAu.send(new zk.Event(this, 'onZoomLevelChange', {zoomindex : zoomindex, scrollLeft : scrollLeft}));
}
},{
FOOTER_HEIGHT : 40, // Design-relative footer height
TIMETRACKER_OFFSET_TOP : 120, // Design-relative height above timetracker
TASKDETAILS_WIDTH : 300, // Taskdetails column fixed width (300)
TASKDETAILS_HEIGHT : 180, // 260 // Design-relative reservated height for taskdetails (300,260)
SCROLLBAR_WIDTH : 15, // Scrollbars default width
getInstance : function(){
return this._instance;
},
setInstance : function(instance){
this._instance = instance;
}
})

View file

@ -0,0 +1,232 @@
zk.$package("ganttz");
/*
* This YAHOO code is here because it's used for the Drag&Drop. Once the Drag&Drop is implemented with jQuery
* this code must be removed
* */
YAHOO.example.DDRegion = function(id, sGroup, config) {
this.cont = config.cont;
YAHOO.example.DDRegion.superclass.constructor.apply(this, arguments);
};
var myDom = YAHOO.util.Dom, myEvent = YAHOO.util.Event
YAHOO.extend(YAHOO.example.DDRegion, YAHOO.util.DD, {
cont : null,
init : function() {
// Call the parent's init method
YAHOO.example.DDRegion.superclass.init.apply(this, arguments);
this.initConstraints();
myEvent.on(window, 'resize', function() {
this.initConstraints();
}, this, true);
},
initConstraints : function() {
// Get the top, right, bottom and left positions
var region = myDom.getRegion(this.cont);
// Get the element we are working on
var el = this.getEl();
// Get the xy position of it
var xy = myDom.getXY(el);
// Get the width and height
var width = parseInt(myDom.getStyle(el, 'width'), 10);
var height = parseInt(myDom.getStyle(el, 'height'), 10);
// Set left to x minus left
var left = xy[0] - region.left;
// Set right to right minus x minus width
var right = region.right - xy[0] - width;
// Set top to y minus top
var top = xy[1] - region.top;
// Set bottom to bottom minus y minus height
var bottom = region.bottom - xy[1] - height;
// Set the constraints based on the above calculations
this.setXConstraint(left, right);
this.setYConstraint(top, bottom);
}
});
ganttz.TaskComponent = zk.$extends(zul.Widget, {
$define :{
resourcesText : null,
labelsText : null,
tooltipText : null
},
$init : function(){
this.$supers('$init', arguments);
/*
* We have to implement the setLeft method because if we use the one provided by ZK
* the tasks won't we moved back to its original position when they are dropped on an invalid position (i.e before the end
* of the main task) on a dependency relation
*
* This is the default boddy for a ZK set<AttributeName>
*
* function (v, opts) {
if (before) v = before.apply(this, arguments);
var o = this[nm];
this[nm] = v;
if (after && (o !== v || (opts && opts.force)))
after.apply(this, arguments);
return this;
};
*
* The before and and after properties can be set to something different to the default using the $define property.
*
*
* Our problem happens because if the dependent task is already aligned at the end of the main tasks
* and thats (for example) style. left = 800px, when we move it to an invalid position the server will try to set again
* the left property to 800px but when the default setter works it checks if we are trying to set a value equal to the previous
* one and in that case it doesn't apply the after function.
*
* Setting the force option to true does the trick
* */
var oldSetLeft = this.setLeft;
this.setLeft = this.proxy(function(left, options){
oldSetLeft.call(this, left, {force : true});
})
},
bind_ : function(event){
this.$supers('bind_', arguments);
this.domListen_(this.$n(), "onMouseover", '_showTooltip');
this.domListen_(this.$n(), "onMouseout", '_hideTooltip');
if( jq(this.$n()).attr('movingtasksenabled') == "true" ) this._addDragDrop();
if( jq(this.$n()).attr('resizingtasksenabled') == "true" ) this._addResize();
},
unbind_ : function(event){
this.domUnlisten_(this.$n(), "onMouseout", '_hideTooltip');
this.domUnlisten_(this.$n(), "onMouseover", '_showTooltip');
this.$supers('unbind_', arguments);
},
addDependency : function(){
this._createArrow();
},
consolidateNewDependency : function(task){
zAu.send(new zk.Event(this, 'onAddDependency', {dependencyId : task.id}));
},
_addDragDrop : function(){
var dragdropregion = this._getDragDropRegion();
var thisTaskId = this.$n().id;
var relatedDependencies = common.Common.throttle(3000, function() {
return jq('.dependency[idtaskorig='+ thisTaskId + ']')
.add('.dependency[idtaskend='+ thisTaskId + ']')
.get()
.map(function(dep) {
return ganttz.DependencyComponentBase.$(dep);
});
});
var drawDependencies = common.Common.throttle(25, function() {
relatedDependencies().forEach(function(dependency) {
dependency.draw();
});
});
dragdropregion.on('dragEvent', this.proxy(function(ev) {
// Slight overload. It could be more efficent to overwrite the YUI
// method
// that is setting the top property
jq(this.$n()).css('top','');
drawDependencies();
}), null, false);
// Register the event endDragEvent
dragdropregion.on('endDragEvent', this.proxy(function(ev) {
var position = jq(this.$n()).position();
zAu.send(new zk.Event(this, 'onUpdatePosition',{left : position.left, top : position.top}))
}), null, false);
},
_addResize : function(){
// Configure the task element to be resizable
var resize = new YAHOO.util.Resize(this.uuid, {
handles : [ 'r' ],
proxy : true
});
resize.on("resize", function(event){
jq(this.$n()).css({top : ""});
zAu.send(new zk.Event(this, 'onUpdateWidth', { width : jq(this.$n()).width() }));
},null , this);
},
_createArrow : function(){
var WGTdependencylist = ganttz.DependencyList.getInstance();
var unlinkedDependency = new ganttz.UnlinkedDependencyComponent();
unlinkedDependency.setOrigin(this.$n());
WGTdependencylist.appendChild(unlinkedDependency, false);
unlinkedDependency.draw();
},
_getDragDropRegion : function(){
if (typeof (this._dragDropRegion) == 'undefined') {
// Create the laned drag&drop component
this._dragDropRegion = new YAHOO.example.DDRegion(this.uuid, '', {
cont : this.parent.getId()
});
}
return this._dragDropRegion;
},
_showTooltip : function(){
this.mouseOverTask = true;
this._tooltipTimeout = setTimeout(jq.proxy(function(offset) {
var element = jq("#tasktooltip" + this.uuid);
if (element!=null) {
element.show();
offset = ganttz.GanttPanel.getInstance().getXMouse()
- element.parent().offset().left
- jq('.leftpanelcontainer').offsetWidth
- this.$class._PERSPECTIVES_WIDTH
+ jq('.rightpanellayout div').scrollLeft();
element.css( 'left' , offset +'px' );
}
}, this), this.$class._TOOLTIP_DELAY);
},
_hideTooltip : function(){
this.mouseOverTask = false;
if (this._tooltipTimeout) {
clearTimeout(this._tooltipTimeout);
}
jq('#tasktooltip' + this.uuid).hide();
},
moveDeadline : function(width){
jq('#deadline' + this.parent.uuid).css('left', width);
},
moveConsolidatedline : function(width){
jq('#consolidatedline' + this.parent.uuid).css('left', width);
},
resizeCompletionAdvance : function(width){
jq('#' + this.uuid + ' > .completion:first').css('width', width);
},
resizeCompletion2Advance : function(width){
jq('#' + this.uuid + ' > .completion2:first').css('width', width);
},
showTaskLabel : function(){
jq('#'+ this.uuid + ' .task-labels').show();
},
hideTaskLabel : function(){
jq('#'+ this.uuid + ' .task-labels').hide();
},
showResourceTooltip : function(){
jq('#'+ this.uuid + ' .task-resources').show();
},
hideResourceTooltip : function(){
jq('#'+ this.uuid + ' .task-resources').hide();
},
setClass : function(cssClass){
jq(this.$n()).addClass(cssClass);
}
},{
//"Class" methods and properties
_TOOLTIP_DELAY : 10, // 10 milliseconds
_PERSPECTIVES_WIDTH : 80,
CORNER_WIDTH : 20,
HEIGHT : 10,
HALF_HEIGHT : 5
});

View file

@ -0,0 +1,3 @@
zk.$package("ganttz");
ganttz.TaskContainerComponent = zk.$extends(ganttz.TaskComponent,{})

View file

@ -0,0 +1,31 @@
zk.$package("ganttz");
ganttz.TaskList = zk.$extends(zk.Widget, {
$init : function(){
this.$supers('$init', arguments);
this.$class.setInstance(this);
},
showAllTaskLabels : function(){
for(var child = this.firstChild; child; child = child.nextSibling)
child.showTaskLabel();
},
hideAllTaskLabels : function(){
for(var child = this.firstChild; child; child = child.nextSibling)
child.hideTaskLabel();
},
showResourceTooltips : function(){
for(var child = this.firstChild; child; child = child.nextSibling)
child.showResourceTooltip();
},
hideResourceTooltips : function(){
for(var child = this.firstChild; child; child = child.nextSibling)
child.hideResourceTooltip();
}
},{//Class stuff
setInstance : function(instance){
this.instance = instance;
},
getInstance : function(){
return this.instance;
}
});

View file

@ -0,0 +1,16 @@
zk.$package("ganttz");
ganttz.TaskRow = zk.$extends(zk.Widget, {
hideTaskLabel : function(){
this.firstChild.hideTaskLabel();
},
showTaskLabel : function(){
this.firstChild.showTaskLabel();
},
hideResourceTooltip : function(){
this.firstChild.hideResourceTooltip();
},
showResourceTooltip : function(){
this.firstChild.showResourceTooltip();
}
});

View file

@ -0,0 +1,26 @@
zk.$package("ganttz");
ganttz.TimeTracker = zk.$extends(zk.Macro,{
$init : function(){
this.$supers('$init', arguments);
this.$class.setInstance(this);
},
bind_ : function (){
this.$supers('bind_', arguments);
this._timetrackerGap = jq('.timetrackergap');
this._timetrackerHeader = jq('#timetrackerheader .z-vbox');
},
realWidth : function(){
return this._timetrackerHeader.width();
},
scrollLeft : function(ammount){
this._timetrackerGap.css({left : -ammount});
}
},{
getInstance : function(){
return this._instance;
},
setInstance : function(instance){
this._instance = instance;
}
})

View file

@ -1,318 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
/**
* Javascript behaviuor for TaskList elements
* @author Javier Morán Rúa <jmoran@igalia.com>
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
webapp_context_path = window.location.pathname.split( '/' )[1];
zkPlanner = {};
zkPlanner.constants = {
END_START: "END_START",
START_START: "START_START",
END_END: "END_END"
};
zkPlanner.getImagesDir = function() {
return "/" + webapp_context_path + "/zkau/web/ganttz/img/";
}
zkPlanner.init = function(planner){
}
zkPlanner.findImageElement = function(arrow, name) {
var children = arrow.getElementsByTagName("div");
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.getAttribute("class").indexOf(name) != -1) {
return child;
}
}
return null;
}
function get_origin() {
return YAHOO.util.Dom.getXY('listdependencies');
}
zkPlanner.findPos = function(obj) {
var pos1 = get_origin();
var pos2 = YAHOO.util.Dom.getXY(obj.id);
return [ pos2[0] - pos1[0], pos2[1] - pos1[1] ];
}
zkPlanner.findPosForMouseCoordinates = function(x, y){
/* var pos1 = get_origin() */
var pos1 = YAHOO.util.Dom.getXY('listtasks');
return [x - pos1[0], y - pos1[1]];
}
function getContextPath(element){
return element.getAttribute('contextpath');
}
zkPlanner.setupArrow = function(arrowDiv){
var image_data = [ [ "start", "pixel.gif" ], [ "mid", "pixel.gif" ],
[ "end", "pixel.gif" ], [ "arrow", "arrow.png" ] ];
for ( var i = 0; i < image_data.length; i++) {
var img = document.createElement('div');
img.setAttribute("class", image_data[i][0] );
img.src = this.getImagesDir() + image_data[i][1];
arrowDiv.appendChild(img);
}
}
zkPlanner.drawArrow = function(dependency, orig, dest) {
switch(dependency.getAttribute('type'))
{
case zkPlanner.constants.START_START:
zkPlanner.drawArrowStartStart(dependency, orig, dest);
break;
case zkPlanner.constants.END_END:
zkPlanner.drawArrowEndEnd(dependency, orig, dest);
break;
case zkPlanner.constants.END_START:
default:
zkPlanner.drawArrowEndStart(dependency, orig, dest);
}
}
zkPlanner.drawArrowStartStart = function(arrow, orig, dest){
var xorig = orig[0] - zkTask.HALF_DEPENDENCY_PADDING;
var yorig = orig[1] - zkTask.CORNER_WIDTH/2 + zkTask.HALF_DEPENDENCY_PADDING;
var xend = dest[0] + zkTask.HALF_DEPENDENCY_PADDING;
var yend = dest[1] - zkTask.HALF_DEPENDENCY_PADDING;
if (yend < yorig) {
yorig = orig[1] + zkTask.DEPENDENCY_PADDING;
}
width1 = zkTask.CORNER_WIDTH;
width2 = Math.abs(xend - xorig) + zkTask.CORNER_WIDTH;
height = Math.abs(yend - yorig);
if (xorig > xend) {
width1 = width2;
width2 = zkTask.CORNER_WIDTH;
}
// First segment
var depstart = this.findImageElement(arrow, 'start');
depstart.style.left = (xorig - width1) + "px";
depstart.style.top = yorig + "px";
depstart.style.width = width1 + "px";
depstart.style.display = "inline";
// Second segment
var depmid = this.findImageElement(arrow, 'mid');
depmid.style.left = depstart.style.left;
if (yend > yorig) {
depmid.style.top = yorig + "px";
} else {
depmid.style.top = yend + "px";
}
depmid.style.height = height + "px";
// Third segment
var depend = this.findImageElement(arrow, 'end');
depend.style.left = depstart.style.left;
depend.style.top = yend + "px";
depend.style.width = width2 - zkTask.HALF_HEIGHT + "px";
var deparrow = this.findImageElement(arrow, 'arrow');
// deparrow.src = this.getImagesDir()+"arrow.png";
deparrow.setAttribute("class", "arrow point-east");
deparrow.style.top = yend - zkTask.HALF_HEIGHT + "px";
deparrow.style.left = xend - 15 + "px";
}
zkPlanner.drawArrowEndEnd = function(arrow, orig, dest){
var xorig = orig[0] - zkTask.DEPENDENCY_PADDING;
var yorig = orig[1] - zkTask.CORNER_WIDTH/2 + zkTask.HALF_DEPENDENCY_PADDING;
var xend = dest[0] + zkTask.HALF_DEPENDENCY_PADDING;
var yend = dest[1] - zkTask.DEPENDENCY_PADDING;
width1 = Math.abs(xend - xorig) + zkTask.CORNER_WIDTH;
width2 = zkTask.CORNER_WIDTH;
height = Math.abs(yend - yorig);
if (xorig > xend) {
width2 = width1;
width1 = zkTask.CORNER_WIDTH;
}
// First segment
var depstart = this.findImageElement(arrow, 'start');
depstart.style.left = xorig + "px";
if (yend > yorig) {
depstart.style.top = yorig + "px";
} else {
depstart.style.top = yorig + zkTask.HEIGHT + "px";
}
depstart.style.width = width1 + "px";
depstart.style.display = "inline";
// Second segment
var depmid = this.findImageElement(arrow, 'mid');
depmid.style.left = (xorig + width1) + "px";
if (yend > yorig) {
depmid.style.top = yorig + "px";
} else {
depmid.style.top = yend + "px";
height = height + 10;
}
depmid.style.height = height + "px";
// Third segment
var depend = this.findImageElement(arrow, 'end');
depend.style.left = (xorig + width1 - width2) + "px";
depend.style.top = yend + "px";
depend.style.width = width2 + "px";
var deparrow = this.findImageElement(arrow, 'arrow');
// deparrow.src = this.getImagesDir()+"arrow3.png";
deparrow.setAttribute("class", "arrow point-west");
deparrow.style.top = yend - 5 + "px";
deparrow.style.left = xend - 8 + "px";
}
zkPlanner.drawArrowEndStart = function(arrow, orig, dest){
var xorig = orig[0] - zkTask.DEPENDENCY_PADDING;
var yorig = orig[1] - zkTask.HALF_DEPENDENCY_PADDING;
var xend = dest[0] - zkTask.DEPENDENCY_PADDING;
var yend = dest[1] - zkTask.HALF_DEPENDENCY_PADDING;
var width = (xend - xorig);
var xmid = xorig + width;
// First segment not used
var depstart = this.findImageElement(arrow, 'start');
depstart.style.display = "none";
// Second segment not used
var depmid = this.findImageElement(arrow, 'mid');
if (yend > yorig) {
depmid.style.top = yorig + "px";
depmid.style.height = yend - yorig + "px";
} else {
depmid.style.top = yend + "px";
depmid.style.height = yorig - yend + "px";
}
depmid.style.left = xorig + "px";
var depend = this.findImageElement(arrow, 'end');
depend.style.top = yend + "px";
depend.style.left = xorig + "px";
depend.style.width = width + "px";
if (width < 0) {
depend.style.left = xend + "px";
depend.style.width = Math.abs(width) + "px";
}
var deparrow = this.findImageElement(arrow, 'arrow');
if ( width == 0 ) {
deparrow.setAttribute("class", "arrow point-south");
deparrow.style.top = yend - 10 + "px";
deparrow.style.left = xend - 5 + "px";
if ( yorig > yend ) {
deparrow.setAttribute("class", "arrow point-north");
deparrow.style.top = yend + "px";
}
} else {
deparrow.style.top = yend - 5 + "px";
deparrow.style.left = xend - 10 + "px";
deparrow.setAttribute("class", "arrow point-east");
if (width < 0) {
deparrow.setAttribute("class", "arrow point-west");
deparrow.style.left = xend + "px";
deparrow.style.top = yend - 5 + "px";
}
}
}
zkDependency = {};
zkDependency.origin = function(dependency) {
var id = dependency.getAttribute("idTaskOrig");
return document.getElementById(id);
}
zkDependency.destination = function(dependency) {
var id = dependency.getAttribute("idTaskEnd");
return document.getElementById(id);
}
zkDependency.setCSSClass = function(dependency,value) {
dependency.setAttribute("class", value);
}
zkDependency.draw = function(dependency) {
var orig = zkPlanner.findPos(this.origin(dependency));
var dest = zkPlanner.findPos(this.destination(dependency));
// This corner case may depend on dependence type
offsetX = this.origin(dependency).offsetWidth - zkTask.CORNER_WIDTH;
separation = orig[0] + this.origin(dependency).offsetWidth - dest[0];
if (separation > 0) {
offsetX = offsetX - separation;
}
if (dependency.getAttribute('type') == zkPlanner.constants.END_START
|| dependency.getAttribute('type') == null) {
orig[0] = orig[0] + Math.max(0, offsetX);
} else if (dependency.getAttribute('type') == zkPlanner.constants.END_END) {
orig[0] = orig[0] + this.origin(dependency).offsetWidth;
dest[0] = dest[0] + this.destination(dependency).offsetWidth;
}
orig[1] = orig[1] + zkTask.HEIGHT;
dest[1] = dest[1] + zkTask.HALF_HEIGHT;
if ((orig[1] > dest[1])) {
orig[1] = orig[1] - zkTask.HEIGHT;
}
zkPlanner.drawArrow(dependency, orig, dest);
}
zkDependency.init = function(dependency) {
zkPlanner.setupArrow(dependency);
var parent = dependency.parentNode;
if (parent.id !== "listdependencies") {
document.getElementById("listdependencies").appendChild(dependency);
}
YAHOO.util.Event.onDOMReady(function() {
var origin = zkDependency.origin(dependency);
var destination = zkDependency.destination(dependency);
zkDependency.draw(dependency);
zkTask.addRelatedDependency(origin, dependency);
zkTask.addRelatedDependency(destination, dependency);
});
}

View file

@ -1,25 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
zkDependencylist = {};
zkDependencylist.init = function (cmp) {
}

View file

@ -1,86 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
/**
* Javascript behaviuor for GanttPanel element
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
zkGanttPanel = {};
SCROLL_DAY = 0;
zkGanttPanel.init = function(cmp){
}
zkGanttPanel.update_day_scroll = function(cmp,previousPixelPerDay) {
fromPixelToDay(previousPixelPerDay);
}
/**
* Scrolls horizontally the ganttpanel when the zoom has resized the component
* width.
*/
zkGanttPanel.scroll_horizontal = function(cmp,daysDisplacement) {
SCROLL_DAY = daysDisplacement;
}
zkGanttPanel.move_scroll = function(cmp,diffDays,pixelPerDay) {
fromDayToPixel(diffDays,pixelPerDay);
}
function fromPixelToDay(previousPixelPerDay){
var div1 = document.getElementById ("ganttpanel").parentNode;
var div2 = div1.parentNode;
var div3 = div2.parentNode;
var maxHPosition = div3.scrollWidth - div3.clientWidth;
if( maxHPosition > 0 ){
var proportion = div3.scrollWidth / maxHPosition;
var positionInScroll = div3.scrollLeft;
var positionInPx = positionInScroll * proportion;
if(positionInPx > 0){
var position = positionInPx / previousPixelPerDay;
var day = position;
SCROLL_DAY = position;
}
}
}
function fromDayToPixel(diffDays,pixelPerDay){
var div1 = document.getElementById ("ganttpanel").parentNode;
var div2 = div1.parentNode;
var div3 = div2.parentNode;
var day = SCROLL_DAY;
day += parseInt(diffDays);
var newPosInPx = parseInt(day * pixelPerDay);
var maxHPosition = div3.scrollWidth - div3.clientWidth;
var newProportion = div3.scrollWidth / maxHPosition;
if( newProportion > 0){
var newPosInScroll = newPosInPx / newProportion;
if(newPosInScroll < 0){
newPosInScroll = 0;
}
div1.scrollLeft = newPosInScroll;
div2.scrollLeft = newPosInScroll;
div3.scrollLeft = newPosInScroll;
}
}

View file

@ -1,25 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
// making believe to zk that milestone.js exists, so it doesn't throw error.
// zkMilestone code is in tasklist.js
//This way there can be a schedule showing only tasks or taskcontainers.

View file

@ -0,0 +1,10 @@
function(out){
out.push('<div ', this.domAttrs_(),
'class="dependency"',
'z.type="ganttz.dependency.Dependency"',
'idTaskOrig="', this.getIdTaskOrig(),'"',
'idTaskEnd="', this.getIdTaskEnd(),'"',
'type="', this.getDependencyType(),'"',
'>');
out.push('</div>');
}

View file

@ -0,0 +1,11 @@
function(out){
out.push('<div ', this.domAttrs_(),
'z.type="ganttz.dependencylist.Dependencylist"',
'z.autoz="true"',
'>');
out.push('<div id="listdependencies">');
for (var w = this.firstChild; w; w = w.nextSibling)
w.redraw(out);
out.push('</div>');
out.push('</div>');
}

View file

@ -0,0 +1,23 @@
function(out){
out.push('<div ',
'z.type="ganttz.ganttpanel.GanttPanel" ',
this.domAttrs_(),
'>');
out.push('<div id="ganttpanel">');
for (var w = this.firstChild; w; w = w.nextSibling)
w.redraw(out);
out.push('</div>');
out.push('</div>');
out.push('<br>');
out.push('<div id="ganttpanel_scroller_x">',
'<div id="ganttpanel_inner_scroller_x"></div>',
'</div>');
out.push('<div id="ganttpanel_scroller_y">',
'<div id="ganttpanel_inner_scroller_y"/></div>',
'</div>');
}

View file

@ -0,0 +1,12 @@
function(out){
out.push('<div ', this.domAttrs_(),
'z.type="ganttz.task.Task"',
'idTask="', this.id,'"',
'z.autoz="true"',
'class="milestone"',
'>');
out.push('<div class="completion"></div>');
out.push('<div class="completion2"></div>');
out.push('<div class="milestone_end"></div>');
out.push('</div>');
}

View file

@ -0,0 +1,19 @@
function(out){
out.push('<div ',this.domAttrs_(),
' z.type="ganttz.task.Task" idTask="', this.id,'"',
' class="box" >');
out.push('<div class="task-labels">', this.getLabelsText(),'</div>');
out.push('<div class="task-resources">');
out.push('<div class="task-resources-inner">', this.getResourcesText(),'</div>');
out.push('</div>');
out.push('<div class="completion"></div>');
out.push('<div class="completion2"></div>');
out.push('<div id="tasktooltip', this.uuid,'" class="task_tooltip">',
this.getTooltipText(),
'</div>');
out.push('</div>');
}

View file

@ -0,0 +1,35 @@
function(out){
out.push('<div ', this.domAttrs_(),
'z.type="ganttz.taskcontainer.TaskContainer"',
'idTask="', this.id,'"',
'z.autoz="true"',
'class="taskgroup"',
'>');
out.push('<div class="task-labels">',
this.getLabelsText(),
'</div>');
out.push('<div class="task-resources">',
'<div class="task-resources-inner">',
this.getResourcesText(),
'</div>',
'</div>');
out.push('<div class="taskcontainer_completion">',
'<div class="completion"></div>',
'<div class="completion2"></div>',
'</div>');
out.push('<div class="border-container">',
'<div class="taskgroup_start"></div>',
'<div class="taskgroup_end"></div>',
'</div>');
out.push('<div id="tasktooltip', this.uuid, '"',
'class="task_tooltip">',
this.getTooltipText(),
'</div>');
out.push('</div>');
}

View file

@ -0,0 +1,14 @@
function(out){
out.push('<script type="text/javascript">',
'document.body.class = "yui-skin-sam";',
'</script>');
out.push('<div id="scroll_container">');
out.push('<div z.type="gantt.tasklist.TaskList" z.autoz="true" ' + this.domAttrs_() + '>');
out.push('<div id="listtasks">');
for(var w = this.firstChild; w; w = w.nextSibling)
w.redraw(out);
out.push('</div>');
out.push('</div>');
out.push('</div>');
}

View file

@ -0,0 +1,8 @@
function(out){
out.push('<div id="'+ this.uuid + '" class="row" z.valor="boxid=' + this.uuid +'">');
for(var w = this.firstChild; w; w = w.nextSibling)
w.redraw(out);
out.push('<div id="deadline'+ this.uuid + '" class="deadline"></div>');
out.push('<div id="consolidatedline' + this.uuid + '" class="consolidatedline"></div>');
out.push('</div>');
}

View file

@ -1,94 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
/**
* Javascript behaviuor for Planner elements
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
zkPlanner = {};
zkPlanner.constants = {
END_START: "END_START",
START_START: "START_START",
END_END: "END_END"
};
zkPlanner.getImagesDir = function() {
return webapp_context_path + "/zkau/web/ganttz/img/";
}
zkPlanner.init = function(planner){
}
zkPlanner.findImageElement = function(arrow, name) {
var children = arrow.getElementsByTagName("div");
for (var i = 0; i < children.length; i++) {
var child = children[i];
if (child.getAttribute("class").indexOf(name) != -1) {
return child;
}
}
return null;
}
function get_origin() {
return YAHOO.util.Dom.getXY('listdependencies');
}
zkPlanner.findPos = function(obj) {
var pos1 = get_origin();
var pos2 = YAHOO.util.Dom.getXY(obj.id);
return [ pos2[0] - pos1[0], pos2[1] - pos1[1] ];
}
zkPlanner.findPosForMouseCoordinates = function(x, y){
/* var pos1 = get_origin() */
var pos1 = YAHOO.util.Dom.getXY('listtasks');
return [x - pos1[0], y - pos1[1]];
}
function getContextPath(element){
return element.getAttribute('contextpath');
}
zkPlanner.setupArrow = function(arrowDiv){
var image_data2 = [ "start", "mid", "end", "arrow" ];
for ( var i = 0; i < image_data2.length; i++) {
var img = document.createElement('div');
img.setAttribute("class", image_data[i]+" extra_padding");
arrowDiv.appendChild(img);
}
}
zkPlanner.drawArrow = function(dependency, orig, dest) {
switch(dependency.getAttribute('type'))
{
case zkPlanner.constants.START_START:
zkPlanner.drawArrowStartStart(dependency, orig, dest);
break;
case zkPlanner.constants.END_END:
zkPlanner.drawArrowEndEnd(dependency, orig, dest);
break;
case zkPlanner.constants.END_START:
default:
zkPlanner.drawArrowEndStart(dependency, orig, dest);
}
}

View file

@ -0,0 +1,8 @@
zk.$package("ganttz.resourceload");
ganttz.resourceload.ResourceLoadComponent = zk.$extends(zk.Widget,{
$define : {
resourceLoadName : null,
resourceLoadType : null
}
});

View file

@ -0,0 +1,73 @@
zk.$package("ganttz.resourceload");
ganttz.resourceload.ResourceLoadList = zk.$extends(zk.Widget,{
$init : function(){
this.$supers('$init', arguments);
this.$class.setInstance(this);
common.Common.mixInDayPositionRestorer(this);
},
bind_ : function(evt){
this.$supers('bind_', arguments);
this.domListen_(jq(window), 'onResize', 'adjustTimeTrackerSize');
this.domListen_(jq('.rightpanellayout div:first'), 'onScroll', '_listenToScroll');
},
unbind_ : function(evt){
this.domUnlisten_(jq(window), 'onResize', 'adjustTimeTrackerSize');
this.domUnlisten_(jq('.rightpanellayout div:first'), 'onScroll', '_listenToScroll');
this.$supers('unbind_', arguments);
},
_divsToRestoreDayInto: function() {
var first = this.$n();
return [first, first.parentNode, first.parentNode.parentNode];
},
recalculateTimeTrackerHeight : function(){
var DOMResourceLoadList = jq('.resourceloadlist');
var DOMfirstWatermarkColumn = jq('.rightpanellayout tr#watermark td :first');
if ( DOMResourceLoadList != undefined && DOMfirstWatermarkColumn != undefined){
DOMResourceLoadList.height(
Math.max(
DOMResourceLoadList.innerHeight() + this.$class.WATERMARK_MARGIN_BOTTOM,
this.$class.WATERMARK_MIN_HEIGHT));
}
},
adjustTimeTrackerSize : function(){
this.recalculateTimeTrackerHeight();
/*We can't use this.getHeight() as the _height property
* won't be set for this object and even
*
* TODO: maybe create a _height property and update it
* when it changes (recalculateTimeTrackerHeight) son we avoid
* using DOM selectors
* */
jq('#watermark').height(jq(this.$n()).innerHeight());
jq('#timetracker').width(jq(this.$n()).innerWidth());
/*this.$n() is <div class="resourceloadlist" ...>*/
jq(this.$n()).width(jq('.second_level_ :first'));
},
adjustResourceLoadRows : function(){
jq('.row_resourceload').each(jq.proxy(function(index, element){
jq(element).width( jq(this.$n()).innerWidth() );
}, this));
},
_listenToScroll : function(){
var scrolledPannelScrollLeft = jq('.rightpanellayout div:first').scrollLeft();
var scrolledPannelScrollTop = jq('.rightpanellayout div:first').scrollTop();
jq('canvas.timeplot-canvas').css("left", "-" + scrolledPannelScrollLeft + "px");
jq('.timetrackergap').css("left", "-" + scrolledPannelScrollLeft + "px");
jq('.leftpanelgap .z-tree-body').css("top", "-" + scrolledPannelScrollTop + "px");
jq('.resourcesloadgraph div').scrollLeft(scrolledPannelScrollLeft + "px");
}
},{ //Class stuff
WATERMARK_MIN_HEIGHT : 450,
WATERMARK_MARGIN_BOTTOM : 40,
setInstance : function(instance){
this._instance = instance;
},
getInstance : function(){
return this._instance;
}
});

View file

@ -0,0 +1,10 @@
function(out){
out.push('<div ', this.domAttrs_(),
' class="row_resourceload resourceload-'+ this.getResourceLoadType(),'"',
' z.autoz="true"',
'>');
out.push('<span class="resourceload_name">', this.getResourceLoadName(),'</span>');
for(var w = this.firstChild; w; w = w.nextSibling)
w.redraw(out);
out.push('</div>');
}

View file

@ -0,0 +1,8 @@
function(out){
out.push('<div ' + this.domAttrs_(),
' class="resourceloadlist"',
' z.type="ganttz.resourceload.resourceloadlist.ResourceLoadList">');
for(var w = this.firstChild; w; w = w.nextSibling)
w.redraw(out);
out.push('</div>');
}

View file

@ -1,183 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
zkResourcesLoadList = addResourcesLoadListMethods( {});
zkResourcesLoadList.WATERMARK_MIN_HEIGHT = 450;
zkResourcesLoadList.WATERMARK_MARGIN_BOTTOM = 40;
zkResourcesLoadList.recalculateTimetrackerHeight = function (cmp) {
zkResourcesLoadList.resourceloadlist = function(elem) {
return YAHOO.util.Selector.query('.resourceloadlist')[0];
}
zkResourcesLoadList.firstWatermarkColumn = function(elem) {
return YAHOO.util.Selector.query('.rightpanellayout tr#watermark td')[0];
}
if (zkResourcesLoadList.resourceloadlist() != undefined && zkResourcesLoadList.firstWatermarkColumn() != undefined) {
var height = Math.max(
zkResourcesLoadList.resourceloadlist().clientHeight + zkResourcesLoadList.WATERMARK_MARGIN_BOTTOM,
zkResourcesLoadList.WATERMARK_MIN_HEIGHT);
zkResourcesLoadList.firstWatermarkColumn().style.height = height + "px";
}
}
function addResourcesLoadListMethods(object) {
var scrollSync;
var SCROLL_DAY = 0;
function watermark() {
return document.getElementById('watermark');
}
function timetracker() {
return document.getElementById('timetracker');
}
function resourceloadlist() {
return YAHOO.util.Selector.query('.resourceloadlist')[0];
}
function taskspanelgap() {
return YAHOO.util.Selector.query('.taskspanelgap')[0];
}
function resourcesloadgraph() {
return YAHOO.util.Selector.query('.resourcesloadgraph div')[0];
}
function scrolledpannel() {
return YAHOO.util.Selector.query('.rightpanellayout div')[0];
}
function timetrackergap() {
return YAHOO.util.Selector.query('.timetrackergap')[0];
}
function leftpanel() {
return YAHOO.util.Selector.query('.leftpanelgap .z-tree-body')[0];
}
function rightpanel() {
return YAHOO.util.Selector.query('.rightpanellayout div')[0];
}
object.init = function(cmp) {
this.adjustTimeTrackerSize(cmp);
YAHOO.util.Event.addListener(window, 'resize',
zkResourcesLoadList.adjustTimeTrackerSize, cmp);
scrollSync = new ScrollSync(cmp);
scrollSync.synchXChangeTo(timetracker);
listenToScroll();
};
function listenToScroll() {
var timetrackergap_ = timetrackergap();
var scrolledpannel_ = scrolledpannel();
var resourcesloadgraph_ = resourcesloadgraph();
var leftpanel_ = leftpanel();
var rightpanel_ = rightpanel();
var onScroll = function() {
var timeplotcontainer_ = YAHOO.util.Selector.query('canvas.timeplot-canvas')[0];
timeplotcontainer_.style["left"] = "-" + scrolledpannel_.scrollLeft + "px";
timetrackergap_.style["left"] = "-" + scrolledpannel_.scrollLeft + "px";
leftpanel_.style["top"] = "-" + scrolledpannel_.scrollTop + "px";
resourcesloadgraph_.scrollLeft = scrolledpannel_.scrollLeft;
};
rightpanel_.onscroll = onScroll;
}
object.adjustTimeTrackerSize = function(cmp) {
zkResourcesLoadList.recalculateTimetrackerHeight();
watermark().style["height"] = cmp.clientHeight + "px";
timetracker().style["width"] = cmp.clientWidth + "px";
/* Set watermark width */
YAHOO.util.Selector.query('.resourceloadlist')[0].style["width"] = YAHOO.util.Selector
.query('.second_level_')[0].clientWidth + "px";
};
object.adjustResourceLoadRows = function(cmp) {
YAHOO.util.Selector.query('.row_resourceload').each(function(node) {
node.style["width"] = cmp.clientWidth + "px";
});
};
object.adjustScrollHorizontalPosition = function(cmp, offsetInPx) {
cmp.scrollLeft = offsetInPx;
}
object.update_day_scroll = function(cmp,previousPixelPerDay) {
var div1 = cmp;
var div2 = div1.parentNode;
var div3 = div2.parentNode;
var maxHPosition = div3.scrollWidth - div3.clientWidth;
if( maxHPosition > 0 ){
var proportion = div3.scrollWidth / maxHPosition;
var positionInScroll = div3.scrollLeft;
var positionInPx = positionInScroll * proportion;
if(positionInPx > 0){
var position = positionInPx / previousPixelPerDay;
var day = position;
SCROLL_DAY = position;
}
}
};
/**
* Scrolls horizontally the ganttpanel when the zoom has resized the component
* width.
*/
object.scroll_horizontal = function(cmp,daysDisplacement) {
SCROLL_DAY = daysDisplacement;
};
object.move_scroll = function(cmp,diffDays,pixelPerDay) {
var div1 = cmp;
var div2 = div1.parentNode;
var div3 = div2.parentNode;
var day = SCROLL_DAY;
day += parseInt(diffDays);
var newPosInPx = parseInt(day * pixelPerDay);
var maxHPosition = div3.scrollWidth - div3.clientWidth;
var newProportion = div3.scrollWidth / maxHPosition;
if( newProportion > 0){
var newPosInScroll = newPosInPx / newProportion;
if(newPosInScroll < 0){
newPosInScroll = 0;
}
div1.scrollLeft = newPosInScroll;
div2.scrollLeft = newPosInScroll;
div3.scrollLeft = newPosInScroll;
}
};
return object;
}

View file

@ -1,29 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
/**
* Javascript behaviuor for ResourcesLoadPanel element
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
zkResourcesLoadPanel = {};
zkResourcesLoadPanel.init = function(cmp){
}

View file

@ -0,0 +1,4 @@
<package name="ganttz.resourceload" language="xul/html">
<widget name="ResourceLoadList"/>
<widget name="ResourceLoadComponent"/>
</package>

View file

@ -1,70 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
function ScrollSync(element){
var xChanges = [];
var yChanges = [];
var notifyScrollX = function(){
for ( var i = 0; i < xChanges.length; i++) {
xChanges[i]();
}
};
var notifyScrollY = function(){
for ( var i = 0; i < yChanges.length; i++) {
yChanges[i]();
}
};
var notifyListeners = function(){
notifyScrollX();
notifyScrollY();
};
var toFunction = function(value){
var result = value;
if(typeof(value) !== 'function'){
result = function(){return synched};
}
return result;
};
this.synchXChangeTo = function(synched){
var target = toFunction(synched);
xChanges.push(function(){ target().scrollLeft = element.scrollLeft; });
};
this.synchYChangeTo = function(synched){
var target = toFunction(synched);
yChanges.push(function(){ target().scrollTop = element.scrollTop; });
};
this.notifyXChangeTo = function(listenerReceivingScroll){
xChanges.push(function(){
listenerReceivingScroll(element.scrollLeft);
});
};
this.notifyYChangeTo = function(listenerReceivingScroll){
yChanges.push(function() {
listenerReceivingScroll(element.scrollTop);
});
};
YAHOO.util.Event.addListener(element,'scroll', notifyListeners);
return this;
}

View file

@ -1,25 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
// making believe to zk that task.js exists, so it doesn't throw error.
// zkTask code is in tasklist.js
//This way there can be a schedule showing only tasks or taskcontainers.

View file

@ -1,25 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
// making believe to zk that taskcontainer.js exists, so it doesn't throw error.
// zkTaskContainer code is in tasklist.js
//This way there can be a schedule showing only tasks or taskcontainers.

View file

@ -1,26 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
zkTaskDetails = {};
zkTaskDetails.init = function(cmp) {
}

View file

@ -1,738 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
/**
* Javascript behaviuor for TaskList elements
*
* @author Javier Morán Rúa <jmoran@igalia.com>
* @author Óscar González Fernández <ogonzalez@igalia.com>
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
*/
zkTasklist = {};
HEIGHT_PER_ROW = 15; // Ganttz task row height
HEIGHT_TIME_TRACKER = -10; // Timetracker legend height (80)
MIN_RESOLUTION_X = 600; // Minimun horizontal autoresizable window
MIN_RESOLUTION_Y = 600; // Minimun vertical autoresizable window
TASKDETAILS_WIDTH = 300; // Taskdetails column fixed width (300)
TASKDETAILS_HEIGHT = 180; // 260 // Design-relative reservated height for
// taskdetails (300,260)
TIMETRACKER_OFFSET_TOP = 120 // Design-relative height above timetracker
FOOTER_HEIGHT = 40; // Design-relative footer height
SCROLLBAR_WIDTH = 15; // Scrollbars default width
DRAGABLE_PADDING = 20; // Drag padding for dependency creation
PERSPECTIVES_WIDTH = 90;
LEGEND_CONTAINER_OFFSET = 75; // Taskdetail width - legend container width
zkTasklist.DELAY = 10 // Delay in ms to show task tooltips
zkTasklist.tooltipTimeout = "";
zkTasklist.showTooltip = function(elem) {
zkTasklist.tooltipTimeout = setTimeout(function(offset) {
component = document.getElementById(elem);
if (component!=null) {
component.style['display'] = 'block';
offset = zkTask.xMouse - component.parentNode.offsetLeft - taskdetailsContainer().offsetWidth - PERSPECTIVES_WIDTH + rightpanellayout().scrollLeft;
component.style['left'] = offset + 'px';
}
}, zkTasklist.DELAY);
}
zkTasklist.showAllTooltips = function(elem) {
var tooltips = YAHOO.util.Selector.query('.task-labels');
for (j=0;j<tooltips.length;j++) {
tooltips[j].style["display"] = "inline";
}
}
zkTasklist.hideAllTooltips = function(elem) {
var tooltips = YAHOO.util.Selector.query('.task-labels');
for (j=0;j<tooltips.length;j++) {
tooltips[j].style["display"] = "none";
}
}
zkTasklist.showResourceTooltips = function(elem) {
var tooltips = YAHOO.util.Selector.query('.task-resources');
for (j=0;j<tooltips.length;j++) {
tooltips[j].style["display"] = "inline";
}
}
zkTasklist.hideResourceTooltips = function(elem) {
var tooltips = YAHOO.util.Selector.query('.task-resources');
for (j=0;j<tooltips.length;j++) {
tooltips[j].style["display"] = "none";
}
}
/* Refreshes
* Can be optimized creating the new tasks with
*/
zkTasklist.refreshTooltips = function(elem) {
var resourcesButton = YAHOO.util.Selector.query('.show-resources')[0];
if (resourcesButton.className.indexOf("clicked") != -1 ) {
zkTasklist.showResourceTooltips();
}
var resourcesButton = YAHOO.util.Selector.query('.show-labels')[0];
if (resourcesButton.className.indexOf("clicked") != -1 ) {
zkTasklist.showAllTooltips();
}
}
zkTasklist.hideTooltip = function(elem) {
if (zkTasklist.tooltipTimeout) {
clearTimeout(zkTasklist.tooltipTimeout);
}
node = document.getElementById(elem);
if ((elem != null) && (node != null)) node.style["display"] = "none";
}
zkTasklist.timeplotcontainer_rescroll = function(elem) {
var timeplotcontainer_all_ = YAHOO.util.Selector.query('.timeplot-canvas');
var scrolledpannel_ = scrolledpannel();
for (j=0;j<timeplotcontainer_all_.length;j++) {
timeplotcontainer_all_[j].style["left"] = "-" + scrolledpannel_.scrollLeft + "px";
}
}
function scrolledpannel() {
return YAHOO.util.Selector.query('.rightpanellayout div')[0];
}
function taskdetailsBody() {
return YAHOO.util.Selector.query('.listdetails .z-tree-body')[0];
}
function plannergraph() {
return YAHOO.util.Selector.query('.plannergraph')[0];
}
function timetrackergap() {
return YAHOO.util.Selector.query('.timetrackergap')[0];
}
function taskheadersgap() {
return YAHOO.util.Selector.query('.taskheadersgap')[0];
}
function taskheaderscontainer() {
return YAHOO.util.Selector.query('.taskheaderscontainer')[0];
}
function rightpanellayout() {
return YAHOO.util.Selector.query('.rightpanellayout div')[0];
}
function taskdetailsContainer() {
return YAHOO.util.Selector.query('.taskdetailsContainer')[0];
}
function timeplotcontainer_load() {
return YAHOO.util.Selector.query('.timeplot-canvas')[0];
}
function timeplotcontainer_earnedvalue() {
return YAHOO.util.Selector.query('.timeplot-canvas')[1];
}
function timeplotcontainer_all() {
return YAHOO.util.Selector.query('.timeplot-canvas');
}
zkTasklist.init = function(cmp) {
zkTasklist.adjust_height();
listenToScroll();
}
/* Resizes ganttpanel heigh to fit window size */
zkTasklist.adjust_height = function(cmp) {
document.getElementById('ganttpanel').style["height"] = document
.getElementById('scroll_container').style["height"];
adjustScrollableDimensions();
}
/* Scrolls taskdetails component when scrolling ganttpanel component */
function listenToScroll() {
timetrackergap_ = timetrackergap();
scrolledpannel_ = scrolledpannel();
leftpanel_ = taskdetailsBody();
rightpanellayout_ = rightpanellayout();
var onScroll = function() {
// Can be optimized caching it outside of onScroll method
// explicitly invalidating its value when timeplot is regenerated
var timeplotcontainer_all_ = YAHOO.util.Selector.query('canvas.timeplot-canvas');
timetrackergap_.style["left"] = "-" + scrolledpannel_.scrollLeft + "px";
leftpanel_.style["top"] = "-" + scrolledpannel_.scrollTop + "px";
plannergraph_ = plannergraph();
if(plannergraph_ != undefined) {
plannergraph_.scrollLeft = scrolledpannel_.scrollLeft;
}
for (j=0;j<timeplotcontainer_all_.length;j++)
{
timeplotcontainer_all_[j].style["left"] = "-" + scrolledpannel_.scrollLeft + "px";
}
};
rightpanellayout_.onscroll = onScroll;
}
/*
* Move scrollbars to locate them on left and bottom window borders
*/
function relocateScrolls() {
scroller_y = document.getElementById('ganttpanel_scroller_y');
scroller_x = document.getElementById('ganttpanel_scroller_x');
listdetails = document.getElementById('listdetails_container');
// Shift scroll-y and scroll-x width (Width change)
if (window.innerWidth > MIN_RESOLUTION_X) {
scroller_y.style["left"] = (window.innerWidth - SCROLLBAR_WIDTH * 3)
+ "px"; // Extra padding
scroller_x.style["width"] = (window.innerWidth - TASKDETAILS_WIDTH - SCROLLBAR_WIDTH * 2)
+ "px"; // Extra padding
}
// Shift scroll-y and scroll-x width (Height change)
if (window.innerHeight > MIN_RESOLUTION_Y) {
scroller_x.style["top"] = (window.innerHeight - SCROLLBAR_WIDTH * 2 - HEIGHT_TIME_TRACKER)
+ "px";
scroller_y.style["height"] = (window.innerHeight - TASKDETAILS_HEIGHT + SCROLLBAR_WIDTH * 2)
+ "px";
listdetails.style["height"] = (window.innerHeight - TASKDETAILS_HEIGHT + SCROLLBAR_WIDTH * 2)
+ "px";
}
adjustScrollableDimensions();
}
/*
* Recalculate component dimensions
*/
function adjustScrollableDimensions() {
// Timetracker is recalculated when the window is resized and when zoom
// level is changed as the component is recreated
// timetracker = document.getElementById('timetracker');
timetracker = YAHOO.util.Selector.query('#timetracker')[0];
watermark = document.getElementById('watermark');
scroll_container = document.getElementById('scroll_container');
timetracker.style["width"] = (window.innerWidth - TASKDETAILS_WIDTH - SCROLLBAR_WIDTH * 2)
+ "px";
scroll_container.style["width"] = YAHOO.util.Selector.query('.second_level_')[0].clientWidth +"px";
document.getElementById('timetracker').style["width"] = scroll_container.style["width"];
timetracker.style["height"] =
Math.max((window.innerHeight - TIMETRACKER_OFFSET_TOP + 26 ),
document.getElementById('listdetails_container').scrollHeight + 12 )
+"px";
scroll_container.style["height"] = (window.innerHeight
- TIMETRACKER_OFFSET_TOP - (FOOTER_HEIGHT + SCROLLBAR_WIDTH * 2))
+ "px";
/* Watermark heigh also needs recalculations due to the recreation
document.getElementById('watermark').style["height"] = (window.innerHeight
- TIMETRACKER_OFFSET_TOP - (FOOTER_HEIGHT + SCROLLBAR_WIDTH))
+ "px";
// Pbs with document.getElementById('watermark').firstChild
YAHOO.util.Selector.query('.timetracker_column_even')[0].style["height"]= (window.innerHeight
- TIMETRACKER_OFFSET_TOP - (FOOTER_HEIGHT + SCROLLBAR_WIDTH))
+ "px"; */
// Inner divs need recalculation to adjust to new scroll displacement lenght
document.getElementById('ganttpanel_inner_scroller_y').style["height"] = document
.getElementById('listdetails_container').scrollHeight
+ "px";
// Inner divs need recalculation to adjust to new scroll displacement lenght
document.getElementById('ganttpanel_inner_scroller_x').style["width"] = watermark.offsetWidth
+ "px";
}
/**
*
* task.js
*
*/
zkTask = {};
zkTask.CORNER_WIDTH = 20;
zkTask.HEIGHT = 10;
zkTask.HALF_HEIGHT = 5;
zkTask.DEPENDENCY_PADDING = 4;
zkTask.HALF_DEPENDENCY_PADDING = 2;
// Task borders are default 1px
zkTask.getDD = function(cmp) {
if (typeof (cmp.created_dd) == 'undefined') {
// Create the laned drag&drop component
cmp.created_dd = new YAHOO.example.DDRegion(cmp.id, '', {
cont : cmp.parentNode.id
});
}
return cmp.created_dd;
}
zkTask.init = function(cmp) {
function addDragSupport() {
// Configure the drag&drop over the component
var dd = zkTask.getDD(cmp);
// when the tasks is being dragged the related dependencies are redrawn
dd.on('dragEvent', function(ev) {
// Slight overload. It could be more efficent to overwrite the YUI
// method
// that is setting the top property
cmp.style.top = "";
if (cmp['relatedDependencies']) {
for ( var i = 0; i < cmp.relatedDependencies.length; i++) {
zkDependency.draw(cmp.relatedDependencies[i]);
}
}
}, null, false);
// Register the event endDragEvent
dd.on('endDragEvent', function(ev) {
zkau.send( {
uuid : cmp.id,
cmd : "updatePosition",
data : [ cmp.style.left, cmp.style.top ]
});
}, null, false);
}
function addResizeSupport() {
// Configure the task element to be resizable
var resize = new YAHOO.util.Resize(cmp.id, {
handles : [ 'r' ],
proxy : true
});
resize.on('resize', function(ev) {
cmp.style.top = "";
zkau.send( {
uuid : cmp.id,
cmd : "updateSize",
data : [ cmp.style.width ]
});
}, zkTask, true);
}
function movingTasksEnabled() {
return cmp.getAttribute('movingTasksEnabled') === 'true';
}
function resizingTasksEnabled() {
return cmp.getAttribute('resizingTasksEnabled') === 'true';
}
// Instead of executing the code directly, a callback is created
// that will be executed when the user passes the mouse over the task
var callback = function() {
if (movingTasksEnabled()) {
addDragSupport();
}
addResizeSupport();
if (!resizingTasksEnabled()) {
cmp.className = cmp.className.replace("yui-resize", "");
}
// it removes itself, so it's not executed again:
YAHOO.util.Event.removeListener(cmp, "mouseover", callback);
}
YAHOO.util.Event.addListener(cmp, "mouseover", callback);
};
zkTask.xMouse;
zkTask.yMouse;
// Listen to mousemove events
YAHOO.util.Event.on(document.body, 'mousemove', function(e) {
var arrPos = YAHOO.util.Event.getXY(e);
zkTask.xMouse = arrPos[0];
zkTask.yMouse = arrPos[1];
});
zkTask.setClass = function(cmp, newclass) {
cmp.className = newclass;
};
zkTask.setAttr = function(cmp, name, val) {
switch (name) {
case "resourcesText":{
var resourcesTextElement = YAHOO.util.Selector.query(
'.task-resources .task-resources-inner', cmp, true);
resourcesTextElement.innerHTML = val;
return true;
}
case "taskTooltipText":{
var taskTooltipTextElement = YAHOO.util.Selector.query(
'.task_tooltip', cmp, true);
taskTooltipTextElement.innerHTML = val;
return true;
}
default: {
return false;
}
}
};
zkTask.addDependency = function(cmp) {
zkTask.createArrow(cmp);
};
zkTask.next = function(elem) {
do {
elem = elem.nextSibling;
} while (elem && elem.nodeType != 1);
return elem;
}
zkTask.addRelatedDependency = function(cmp, dependency) {
if (!cmp['relatedDependencies']) {
cmp.relatedDependencies = [];
}
cmp.relatedDependencies.push(dependency);
}
zkTask.createArrow = function(cmp) {
var arrow = document.createElement('div');
var listtasksNode = document.getElementById("listtasks");
var listdependenciesNode = document.getElementById("listdependencies");
var cmpNode = document.getElementById(cmp.id);
cmp.parentNode.appendChild(arrow);
zkPlanner.setupArrow(arrow);
var xMouse = zkTask.xMouse;
var yMouse = zkTask.yMouse;
function updateArrow() {
var origin = zkPlanner.findPos(cmp);
origin[0] = origin[0]
+ Math.max(0, cmpNode.offsetWidth - zkTask.CORNER_WIDTH);
origin[1] = origin[1] - listtasksNode.offsetTop
+ listdependenciesNode.offsetTop + zkTask.HEIGHT;
var destination = zkPlanner.findPosForMouseCoordinates(xMouse, yMouse);
zkPlanner.drawArrow(arrow, origin, destination);
}
updateArrow();
mousemoveListener = function(e) {
var arrPos = YAHOO.util.Event.getXY(e);
xMouse = arrPos[0];
yMouse = arrPos[1];
updateArrow();
};
mouseClickListener = function(e) {
var parentNode = arrow.parentNode;
var task;
if ((task = zkTask.isOverTask(cmp, arrow))) {
zkau.send( {
uuid : cmp.id,
cmd : "addDependency",
data : [ task.getAttribute('idtask') ]
});
}
parentNode.removeChild(arrow);
YAHOO.util.Event.removeListener(document.body, 'click',
mouseClickListener);
YAHOO.util.Event.removeListener(document.body, 'mousemove',
mousemoveListener);
};
YAHOO.util.Event.on(document.body, 'mousemove', mousemoveListener);
YAHOO.util.Event.on(document.body, 'click', mouseClickListener);
};
function findPosX(obj)
{
var curleft = 0;
if(obj.offsetParent)
while(1)
{
curleft += obj.offsetLeft;
if(!obj.offsetParent)
break;
obj = obj.offsetParent;
}
else if(obj.x)
curleft += obj.x;
return curleft;
}
function findPosY(obj)
{
var curtop = 0;
if(obj.offsetParent)
while(1)
{
curtop += obj.offsetTop;
if(!obj.offsetParent)
break;
obj = obj.offsetParent;
}
else if(obj.y)
curtop += obj.y;
return curtop;
}
/*
* This method is binded to the mouse click listener to determine if it is
* positioned over any task
*/
zkTask.isOverTask = function(cmp, arrow) {
var listtasksNode = document.getElementById("listtasks");
var ganttPanelNode = document.getElementById("ganttpanel");
var scrollContainerPanelNode = document.getElementById("scroll_container");
var innerLayout = YAHOO.util.Selector.query('.rightpanellayout div')[0];
arrayTasks = zkTask.getElementsByAttribute(listtasksNode, "div", "z.type",
"ganttz.task.Task");
arrayTasks = arrayTasks.concat(zkTask.getElementsByAttribute(listtasksNode,
"div", "z.type", "ganttz.taskcontainer.TaskContainer"));
a = findPosX(innerLayout);
b = findPosY(innerLayout);
var xpos = zkTask.xMouse - findPosX(innerLayout)
+ innerLayout.scrollLeft;
var ypos = zkTask.yMouse - findPosY(innerLayout)
+ innerLayout.scrollTop - listtasksNode.offsetTop;
for ( var i = 0; i < arrayTasks.length; i++) {
var task = arrayTasks[i];
/* Added margins to pointing errors */
if (((xpos) > (task.offsetLeft - DRAGABLE_PADDING))
&& ((xpos) < (task.offsetLeft + task.offsetWidth + DRAGABLE_PADDING))
&& (ypos > (task.offsetTop))
&& (ypos < (task.offsetTop + task.offsetHeight))) {
return task;
}
}
return false;
};
zkTask.getElementsByAttribute = function(oElm, strTagName, strAttributeName,
strAttributeValue) {
var arrElements = (strTagName == "*" && oElm.all) ? oElm.all : oElm
.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
var oAttributeValue = (typeof strAttributeValue != "undefined") ? new RegExp(
"(^|\\s)" + strAttributeValue + "(\\s|$)")
: null;
var oCurrent;
var oAttribute;
for ( var i = 0; i < arrElements.length; i++) {
oCurrent = arrElements[i];
oAttribute = oCurrent.getAttribute
&& oCurrent.getAttribute(strAttributeName);
if (typeof oAttribute == "string" && oAttribute.length > 0) {
if (typeof strAttributeValue == "undefined"
|| (oAttributeValue && oAttributeValue.test(oAttribute))) {
arrReturnElements.push(oCurrent);
}
}
}
return arrReturnElements;
}
zkTask.moveDeadline = function(cmp, width) {
var deadlineDiv = zkTask.next(cmp);
deadlineDiv["style"].left = width;
}
zkTask.moveConsolidatedline = function(cmp, width) {
var deadlineDiv = zkTask.next(cmp);
var consolidatedlineDiv = zkTask.next(deadlineDiv);
consolidatedlineDiv["style"].left = width;
}
zkTask.resizeCompletionAdvance = function(cmp, width) {
var completionDiv = YAHOO.util.Selector.query('.completion', cmp, true);
completionDiv["style"].width = width;
}
zkTask.resizeCompletion2Advance = function(cmp, width) {
var completionDiv = YAHOO.util.Selector.query('.completion2', cmp, true);
completionDiv["style"].width = width;
}
YAHOO.example.DDRegion = function(id, sGroup, config) {
this.cont = config.cont;
YAHOO.example.DDRegion.superclass.constructor.apply(this, arguments);
};
var myDom = YAHOO.util.Dom, myEvent = YAHOO.util.Event
YAHOO.extend(YAHOO.example.DDRegion, YAHOO.util.DD, {
cont : null,
init : function() {
// Call the parent's init method
YAHOO.example.DDRegion.superclass.init.apply(this, arguments);
this.initConstraints();
myEvent.on(window, 'resize', function() {
this.initConstraints();
}, this, true);
},
initConstraints : function() {
// Get the top, right, bottom and left positions
var region = myDom.getRegion(this.cont);
// Get the element we are working on
var el = this.getEl();
// Get the xy position of it
var xy = myDom.getXY(el);
// Get the width and height
var width = parseInt(myDom.getStyle(el, 'width'), 10);
var height = parseInt(myDom.getStyle(el, 'height'), 10);
// Set left to x minus left
var left = xy[0] - region.left;
// Set right to right minus x minus width
var right = region.right - xy[0] - width;
// Set top to y minus top
var top = xy[1] - region.top;
// Set bottom to bottom minus y minus height
var bottom = region.bottom - xy[1] - height;
// Set the constraints based on the above calculations
this.setXConstraint(left, right);
this.setYConstraint(top, bottom);
}
});
/**
*
* taskContainer.js
*
*/
zkTaskContainer = {};
/*
* We will not allow taskcontainer move or resize untill its behaviour its
* clearly specified zkTaskContainer.getDD = function(cmp) { zkTask.getDD(cmp); };
*/
zkTaskContainer.init = function(cmp) {
/*
* We will not allow taskcontainer move or resize untill its behaviour its
* clearly specified zkTask.init(cmp);
*/
};
zkTaskContainer.xMouse;
zkTaskContainer.yMouse;
// Listen to mousemove events
YAHOO.util.Event.on(document.body, 'mousemove', function(e) {
var arrPos = YAHOO.util.Event.getXY(e);
zkTaskContainer.xMouse = arrPos[0];
zkTaskContainer.yMouse = arrPos[1];
});
zkTaskContainer.setAttr = function(cmp, nm, val) {
zkTask.setAttr(cmp, nm, val);
};
zkTaskContainer.addDependency = function(cmp) {
zkTask.addDependency(cmp);
};
zkTaskContainer.setAttr = function(cmp, name, value) {
zkTask.setAttr(cmp, name, value);
};
zkTaskContainer.addRelatedDependency = function(cmp, dependency) {
zkTask.addRelatedDependency(cmp, dependency);
};
/*
* Dependencies with origin in a task container will be redrawn with a different
* algorithm
*/
zkTaskContainer.createArrow = function(cmp) {
zkTask.createArrow(cmp)
};
zkTaskContainer.isOverTask = function(cmp, arrow) {
zkTask.isOverTask(cmp, arrow);
};
zkTaskContainer.getElementsByAttribute = function(oElm, strTagName,
strAttributeName, strAttributeValue) {
zkTask.getElementsByAttribute(oElm, strTagName, strAttributeName,
strAttributeValue);
}
zkTaskContainer.setClass = function(cmp, newclass) {
cmp.className = newclass;
};
zkTaskContainer.legendResize = function(cmp) {
var taskdetailsContainer = YAHOO.util.Selector.query('.taskdetailsContainer')[0];
var legendContainer = YAHOO.util.Selector.query('.legend-container')[0];
var legendContainerEarned = YAHOO.util.Selector.query('.legend-container')[1];
if ( legendContainer != undefined ) {
legendContainer.style["width"] = (taskdetailsContainer.clientWidth - LEGEND_CONTAINER_OFFSET )+"px";
}
if ( legendContainerEarned != undefined ) {
legendContainerEarned.style["width"] = (taskdetailsContainer.clientWidth - LEGEND_CONTAINER_OFFSET )+"px";
}
};
zkTaskContainer.resizeCompletionAdvance = zkTask.resizeCompletionAdvance;
zkTaskContainer.resizeCompletion2Advance = zkTask.resizeCompletion2Advance;

View file

@ -1,22 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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/>.
*/
zkTimeTrackedTableWithLeftPane = {};

View file

@ -0,0 +1,21 @@
<package name="ganttz" language="xul/html" depends="common">
<script src="../yui/2.7.0/yahoo/yahoo-min.js"/>
<script src="../yui/2.7.0/yahoo-dom-event/yahoo-dom-event.js"/>
<script src="../yui/2.7.0/selector/selector-min.js"/>
<script src="../yui/2.7.0/yahoo-dom-event/yahoo-dom-event.js"/>
<script src="../yui/2.7.0/dragdrop/dragdrop-min.js"/>
<script src="../yui/2.7.0/element/element-min.js"/>
<script src="../yui/2.7.0/resize/resize-min.js"/>
<script src="../yui/2.7.0/logger/logger-min.js"/>
<widget name="GanttPanel"/>
<widget name="TaskRow"/>
<widget name="TaskComponent"/>
<widget name="TaskContainerComponent"/>
<widget name="TaskList"/>
<widget name="DependencyList"/>
<widget name="Planner"/>
<widget name="DependencyComponent"/>
<widget name="TimeTracker" />
<widget name="Milestone" />
</package>

View file

@ -1,107 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
import static org.junit.Assert.assertThat;
import java.util.Arrays;
import java.util.List;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Test;
public class ScriptDependenciesSorterTest {
private ScriptDependenciesSorter scriptDependenciesSorter;
@Test(expected = IllegalArgumentException.class)
public void cannotAddNullDependency() {
givenAllScriptsRequired();
scriptDependenciesSorter.add(null);
}
@Test
public void testWithoutDependencies() {
givenAllScriptsRequired();
scriptDependenciesSorter.add(new ScriptDependency("A"));
scriptDependenciesSorter.add(new ScriptDependency("B"));
assertThat(scriptDependenciesSorter.getScriptDependenciesOrderered(),
scriptsReturnedAre("A", "B"));
}
@Test(expected = UnsupportedOperationException.class)
public void theDependenciesOrderedCannotBeModified() {
givenAllScriptsRequired();
scriptDependenciesSorter.getScriptDependenciesOrderered().add(
new ScriptDependency("bla"));
}
@Test
public void dependenciesGoesFirst() {
givenAllScriptsRequired();
scriptDependenciesSorter.add(new ScriptDependency("A", Arrays
.asList(new ScriptDependency("B"))));
assertThat(scriptDependenciesSorter.getScriptDependenciesOrderered(),
scriptsReturnedAre("B", "A"));
}
@Test
public void dependenciesAreNotRepeated() {
givenAllScriptsRequired();
scriptDependenciesSorter.add(new ScriptDependency("A", Arrays
.asList(new ScriptDependency("B"))));
scriptDependenciesSorter.add(new ScriptDependency("C", Arrays
.asList(new ScriptDependency("B"))));
scriptDependenciesSorter.add(new ScriptDependency("D"));
assertThat(scriptDependenciesSorter.getScriptDependenciesOrderered(),
scriptsReturnedAre("B", "A", "C", "D"));
}
private Matcher<List<ScriptDependency>> scriptsReturnedAre(String... urls) {
final List<String> urlsList = Arrays.asList(urls);
return new BaseMatcher<List<ScriptDependency>>() {
@Override
public boolean matches(Object object) {
if (object instanceof List) {
List<ScriptDependency> scriptsRequired = (List<ScriptDependency>) object;
List<String> onlyURLs = ScriptDependency
.getOnlyURLs(scriptsRequired);
return onlyURLs.equals(urlsList);
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText("must return " + urlsList);
}
};
}
private void givenAllScriptsRequired() {
scriptDependenciesSorter = new ScriptDependenciesSorter();
}
}

View file

@ -1,91 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.not;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
public class ScriptDependencyTest {
private ScriptDependency script;
private String url;
private List<ScriptDependency> dependencies;
private void givenScript() {
url = "blabla/zkau/web/js/yui/2.7.0/selector/selector-min.js";
dependencies = new ArrayList<ScriptDependency>();
dependencies.add(new ScriptDependency("blabla/blabla/bla.js"));
script = new ScriptDependency(url, dependencies);
}
@Test
public void aScriptHasAURL() {
givenScript();
assertThat(script.getURL(), equalTo(url));
}
@Test(expected = IllegalArgumentException.class)
public void theURLMustBeNotNull() {
new ScriptDependency(null);
}
@Test(expected = IllegalArgumentException.class)
public void theURLMustBeNotEmpty() {
new ScriptDependency("");
}
@Test(expected = IllegalArgumentException.class)
public void noDependenciesCanBeNull() {
List<ScriptDependency> list = new ArrayList<ScriptDependency>();
list.add(null);
new ScriptDependency("bla", list);
}
@Test
public void aScriptCanHaveDependencies() {
givenScript();
assertThat(script.getDependsOn(), equalTo(dependencies));
}
@Test(expected = UnsupportedOperationException.class)
public void theDependenciesCannotBeModified() {
givenScript();
script.getDependsOn().clear();
}
@Test
public void twoScriptsAreEqualsIfHaveTheSameURL() {
givenScript();
ScriptDependency scriptDependencyWithSameURL = new ScriptDependency(url);
assertThat(scriptDependencyWithSameURL, equalTo(script));
assertThat(scriptDependencyWithSameURL.hashCode(), equalTo(script
.hashCode()));
assertThat(new ScriptDependency(url + "b"), not(equalTo(script)));
}
}

View file

@ -1,108 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.matchers.JUnitMatchers.each;
import static org.junit.matchers.JUnitMatchers.hasItem;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Test;
public class ScriptExtractionTest {
@Test(expected = IllegalArgumentException.class)
public void aClassWithoutScriptRequiredAnnotationIsNotIncluded() {
ScriptDependenciesSorter.extractFrom(String.class);
}
@Test
public void onlyPublicStringFieldsAreIncluded() {
List<ScriptDependency> scripts = ScriptDependenciesSorter
.extractFrom(ScriptsDeclarationsExample.class);
assertThat(scripts.size(), equalTo(2));
assertThat(scripts,
hasItem(withURL(ScriptsDeclarationsExample.EXAMPLE_A)));
}
@Test
public void testIncludesDependencies() {
List<ScriptDependency> scripts = ScriptDependenciesSorter
.extractFrom(ScriptsDeclarationsExample.class);
assertThat(scripts, each(withDependencies(ScriptIncludedExample.base,
ScriptIncludedExample.other)));
}
private Matcher<ScriptDependency> withDependencies(final String... urls) {
final Set<String> urlsSet = new HashSet<String>(Arrays.asList(urls));
return new BaseMatcher<ScriptDependency>() {
@Override
public boolean matches(Object object) {
if (object instanceof ScriptDependency) {
ScriptDependency dependency = (ScriptDependency) object;
Set<String> urls = new HashSet<String>();
for (ScriptDependency s : dependency.getDependsOn()) {
urls.add(s.getURL());
}
return urlsSet.equals(urls);
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText("depends on "
+ Arrays.toString(urls));
}
};
}
private Matcher<ScriptDependency> withURL(final String url) {
return new BaseMatcher<ScriptDependency>() {
@Override
public boolean matches(Object dependency) {
if (dependency instanceof ScriptDependency) {
ScriptDependency d = (ScriptDependency) dependency;
return d.getURL().equals(url);
}
return false;
}
@Override
public void describeTo(Description description) {
description.appendText("it has url:" + url);
}
};
}
}

View file

@ -1,30 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
@ScriptsRequiredDeclaration
public class ScriptIncludedExample {
public static final String base = "blabla/bla/base.js";
public static final String other = "othare/other.js";
}

View file

@ -1,37 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.util.script;
@ScriptsRequiredDeclaration(dependsOn = ScriptIncludedExample.class)
public class ScriptsDeclarationsExample {
public static final String EXAMPLE_A = "/project-a/blabla/a.js";
public static final String EXAMPLE_B = "/project-a/blabla/b.js";
private static String EXAMPLE_NOT_INCLUDED = "/project-a/blablaadsf/a.js";
public static int NOT_INCLUDED_BECAUSE_IS_NOT_STRING = 4;
public String NOT_INCLUDED_BECAUSE_IS_NOT_STATIC = "balbla/bladsfafa/ba.js";
}

View file

@ -49,6 +49,20 @@
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.1.2</version>
<executions>
<execution>
<id>default</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
@ -171,6 +185,16 @@
<groupId>jasperreports</groupId>
<artifactId>jasperreports</artifactId>
</dependency>
<!-- GPL Jasperreport Component for ZK -->
<dependency>
<groupId>com.igalia.java.zk.components</groupId>
<artifactId>jasperreportcomponent</artifactId>
</dependency>
<!-- GPL Jasperreport Component for ZK -->
<dependency>
<groupId>com.igalia.java.zk.components</groupId>
<artifactId>jfreechartengine</artifactId>
</dependency>
<!-- Gettext commons -->
<dependency>
<groupId>org.xnap.commons</groupId>
@ -298,12 +322,12 @@
</dependency>
<!-- ZK Timeplot -->
<dependency>
<groupId>org.zkoss.zkforge.timeline</groupId>
<groupId>org.zkoss.zkforge</groupId>
<artifactId>timelinez</artifactId>
</dependency>
<dependency>
<groupId>org.zkoss.zkforge</groupId>
<artifactId>timeplotz-modified</artifactId>
<artifactId>timeplotz</artifactId>
</dependency>
</dependencies>
</project>

View file

@ -414,6 +414,7 @@ public class CustomMenuController extends Div implements IMenuItemsRegister {
setDeselectedClass(button);
button.addEventListener(Events.ON_CLICK, doNotCallTwice(button,
eventListener));
button.setMold("trendy");
insertionPoint.appendChild(button);
insertionPoint.appendChild(separator());
return button;

View file

@ -31,6 +31,21 @@ public class EffortDurationBox extends Textbox {
return (EffortDuration) getTargetValue();
}
@Override
protected Object marshall(Object value) {
return coerceToString(value);
}
@Override
protected Object unmarshall(Object value) {
EffortDuration result = EffortDuration
.parseFromFormattedString((String) value);
if (result == null) {
return EffortDuration.zero();
}
return result;
}
@Override
protected Object coerceFromString(String value) throws WrongValueException {
EffortDuration result = EffortDuration.parseFromFormattedString(value);

View file

@ -29,6 +29,8 @@ import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.zkoss.ganttz.util.ComponentsFinder;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
@ -48,6 +50,7 @@ import org.zkoss.zul.Radio;
import org.zkoss.zul.Textbox;
import org.zkoss.zul.Timebox;
import org.zkoss.zul.api.Checkbox;
import org.zkoss.zul.api.Column;
/**
* Utilities class. <br />
@ -57,6 +60,8 @@ import org.zkoss.zul.api.Checkbox;
*/
public class Util {
private static final Log LOG = LogFactory.getLog(Util.class);
private Util() {
}
@ -615,4 +620,13 @@ public class Util {
}
}
public static void setSort(Column column, String sortSpec) {
try {
column.setSort(sortSpec);
} catch (Exception e) {
LOG.error("failed to set sort property for: " + column + " with: "
+ sortSpec, e);
}
}
}

View file

@ -1,38 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.common.components;
import org.zkoss.zkex.zul.Jasperreport;
/**
* Extends ZK Jasperreport component to offer access to encodedSrc() method
*
* @author Diego Pino Garcia <dpino@igalia.com>
*
*/
public class ExtendedJasperreport extends Jasperreport {
public String getEncodedSrc() {
return super.getEncodedSrc();
}
}

View file

@ -497,6 +497,8 @@ public class LimitingResourcesPanel extends HtmlMacroComponent {
private void refreshQueueComponents() {
queueListComponent.invalidate();
queueListComponent.afterCompose();
queueListComponent.refreshQueues();
rebuildDependencies();
}
private class PaginatorFilter implements IDetailItemFilter {
@ -651,4 +653,7 @@ public class LimitingResourcesPanel extends HtmlMacroComponent {
return previousInterval;
}
public String getWidgetClass() {
return "limitingresources.LimitingResourcesPanel";
}
}

View file

@ -23,6 +23,7 @@ package org.navalplanner.web.limitingresources;
import static org.navalplanner.web.I18nHelper._;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
@ -54,6 +55,7 @@ import org.zkoss.ganttz.util.MenuBuilder.ItemAction;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zk.ui.sys.ContentRenderer;
import org.zkoss.zul.Div;
import org.zkoss.zul.impl.XulElement;
@ -516,4 +518,10 @@ public class QueueComponent extends XulElement implements
}
}
public void renderProperties(ContentRenderer renderer) throws IOException{
super.renderProperties(renderer);
render(renderer, "_resourceName", getResourceName());
}
}

View file

@ -33,8 +33,8 @@ 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.HtmlMacroComponent;
import org.zkoss.zk.ui.ext.AfterCompose;
import org.zkoss.zul.impl.XulElement;
/**
* Component to include a list of {@link LimitingResourceQueue} inside the {@link LimitingResourcesPanel}
@ -42,7 +42,7 @@ import org.zkoss.zk.ui.ext.AfterCompose;
* @author Lorenzo Tilve Álvaro <ltilve@igalia.com>
* @author Diego Pino Garcia <dpino@igalia.com>
*/
public class QueueListComponent extends HtmlMacroComponent implements
public class QueueListComponent extends XulElement implements
AfterCompose {
private final LimitingResourcesPanel limitingResourcesPanel;
@ -107,6 +107,12 @@ public class QueueListComponent extends HtmlMacroComponent implements
queueComponent.removeQueueElement(element);
}
public void refreshQueues() {
for (QueueComponent each: fromQueueToComponent.values()) {
each.invalidate();
}
}
public void refreshQueue(LimitingResourceQueue queue) {
QueueComponent queueComponent = fromQueueToComponent.get(queue);
queueComponent.setLimitingResourceQueue(queue);

View file

@ -373,7 +373,7 @@ public class AssignedTaskQualityFormsToOrderElementController extends
// Add static headers
Column columnName = new Column();
columnName.setLabel(_("Name"));
columnName.setSort("auto=(name)");
Util.setSort(columnName, "auto=(name)");
columnName.setSortDirection("ascending");
columns.appendChild(columnName);

View file

@ -81,7 +81,6 @@ import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zkex.zul.LayoutRegion;
import org.zkoss.zul.Button;
import org.zkoss.zul.Combobox;
import org.zkoss.zul.Comboitem;
@ -89,6 +88,7 @@ import org.zkoss.zul.Div;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.LayoutRegion;
import org.zkoss.zul.ListModel;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
@ -409,7 +409,7 @@ public class AdvancedAllocationController extends GenericForwardComposer {
private static final int VERTICAL_MAX_ELEMENTS = 25;
private IMessagesForUser messages;
private LayoutRegion insertionPointTimetracker;
private Component insertionPointTimetracker;
private Div insertionPointLeftPanel;
private LayoutRegion insertionPointRightPanel;
@ -649,7 +649,7 @@ public class AdvancedAllocationController extends GenericForwardComposer {
}
});
timeTrackerComponent = new TimeTrackerComponentWithoutColumns(
timeTracker, "timeTracker");
timeTracker, "timetrackerheader");
timeTrackedTableWithLeftPane = new TimeTrackedTableWithLeftPane<Row, Row>(
getDataSource(), getColumnsForLeft(), getLeftRenderer(),
getRightRenderer(), timeTracker);

View file

@ -419,7 +419,7 @@ public abstract class AllocationRow {
private void setUnknownResourcesPerDay() {
this.editedValue = null;
this.intendedResourcesPerDayInput.setValue(null);
this.intendedResourcesPerDayInput.setValue((BigDecimal) null);
clearRealResourcesPerDay();
}

View file

@ -735,7 +735,7 @@ public class FormBinder {
private void resetStateForResourcesPerDayInputsWhenDoingRecommendedAllocation() {
if (allResourcesPerDay.isDisabled()) {
allResourcesPerDay.setValue(null);
allResourcesPerDay.setValue((BigDecimal) null);
AllocationRow.unknownResourcesPerDay(rows);
} else {
allResourcesPerDay.setValue(BigDecimal.ZERO);

View file

@ -56,8 +56,6 @@ import org.zkoss.ganttz.extensions.IContextWithPlannerTask;
import org.zkoss.ganttz.timetracker.ICellForDetailItemRenderer;
import org.zkoss.ganttz.timetracker.IConvertibleToColumn;
import org.zkoss.ganttz.timetracker.OnColumnsRowRenderer;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
import org.zkoss.ganttz.util.script.IScriptsRegister;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
@ -136,16 +134,6 @@ public class ResourceAllocationController extends GenericForwardComposer {
private Window editTaskWindow;
public static void registerNeededScripts() {
getScriptsRegister()
.register(ScriptsRequiredByAdvancedAllocation.class);
}
private static IScriptsRegister getScriptsRegister() {
return OnZKDesktopRegistry.getLocatorFor(IScriptsRegister.class)
.retrieve();
}
private EditTaskController editTaskController;
public void setEditTaskController(EditTaskController editTaskController) {

View file

@ -1,37 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.allocation;
import org.zkoss.ganttz.util.script.ScriptsRequiredDeclaration;
/**
* Represents the scripts required by advance allocation<br />
* @author Óscar González Fernández <ogonzalez@igalia.com>
*/
@ScriptsRequiredDeclaration
public class ScriptsRequiredByAdvancedAllocation {
private ScriptsRequiredByAdvancedAllocation() {
}
public static final String ADVANDED_ALLOCATION = "/js/advanceAllocations.js";
}

View file

@ -464,11 +464,8 @@ public abstract class ChartFiller implements IChartFiller {
finish = getThursdayOfThisWeek(finish);
}
String min = start.toString("yyyyMMdd");
String max = finish.toString("yyyyMMdd");
timeGeometry.setMin(Integer.valueOf(min));
timeGeometry.setMax(Integer.valueOf(max));
timeGeometry.setMin(start.toDateTimeAtStartOfDay().toDate());
timeGeometry.setMax(finish.toDateTimeAtStartOfDay().toDate());
timeGeometry.setAxisLabelsPlacement("bottom");
// Remove year separators
timeGeometry.setGridColor("#FFFFFF");
@ -650,7 +647,7 @@ public abstract class ChartFiller implements IChartFiller {
HttpServletRequest request = (HttpServletRequest) Executions
.getCurrent().getNativeRequest();
return CallbackServlet.registerAndCreateURLFor(request,
graphicSpecificationCreator,
graphicSpecificationCreator, false,
DisposalMode.WHEN_NO_LONGER_REFERENCED);
}

View file

@ -42,10 +42,7 @@ import org.springframework.context.annotation.Scope;
import org.zkoss.ganttz.IPredicate;
import org.zkoss.ganttz.Planner;
import org.zkoss.ganttz.extensions.ICommandOnTask;
import org.zkoss.ganttz.resourceload.ScriptsRequiredByResourceLoadPanel;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
import org.zkoss.ganttz.util.script.IScriptsRegister;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
@ -92,12 +89,6 @@ public class CompanyPlanningController implements Composer {
private MultipleTabsPlannerController tabsController;
public CompanyPlanningController() {
getScriptsRegister().register(ScriptsRequiredByResourceLoadPanel.class);
}
private IScriptsRegister getScriptsRegister() {
return OnZKDesktopRegistry.getLocatorFor(IScriptsRegister.class)
.retrieve();
}
private Combobox cbProgressTypes;
@ -148,6 +139,9 @@ public class CompanyPlanningController implements Composer {
}
cbProgressTypes.setModel(new SimpleListModel(ProgressType.getAll()));
cbProgressTypes.setItemRenderer(new ProgressTypeRenderer());
// FIXME: Select default configuration option
// cbProgressTypes.renderAll();
cbProgressTypes.invalidate();
Comboitem item = findListitemValue(cbProgressTypes,
getProgressTypeFromConfiguration());

View file

@ -23,6 +23,9 @@ package org.navalplanner.web.planner.company;
import static org.navalplanner.web.I18nHelper._;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collection;
@ -96,19 +99,20 @@ 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.Interval;
import org.zkoss.zk.au.out.AuInsertAfter;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zkex.zul.api.South;
import org.zkoss.zul.Button;
import org.zkoss.zul.Checkbox;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Div;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Label;
import org.zkoss.zul.South;
import org.zkoss.zul.Tab;
import org.zkoss.zul.Tabbox;
import org.zkoss.zul.Tabpanel;
@ -300,7 +304,8 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
}
else {
//if the chart is not expanded, we load the data later with a listener
((South) planner.getFellow("graphics")).addEventListener("onOpen",
((South) planner.getFellow("graphics"))
.addEventListener("onOpen",
new EventListener() {
@Override
public void onEvent(Event event) {
@ -323,20 +328,51 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
return configurationDAO.getConfiguration().getDefaultCalendar();
}
private void setupChartAndItsContent(Planner planner,
Tabbox chartComponent) {
private void setupChartAndItsContent(final Planner planner,
final Tabbox chartComponent) {
Timeplot chartLoadTimeplot = createEmptyTimeplot();
Timeplot chartEarnedValueTimeplot = createEmptyTimeplot();
CompanyEarnedValueChartFiller earnedValueChartFiller = new CompanyEarnedValueChartFiller();
earnedValueChartFiller.calculateValues(planner.getTimeTracker()
.getRealInterval());
appendTabpanels(chartComponent, chartLoadTimeplot,
chartEarnedValueTimeplot, earnedValueChartFiller);
appendTabpanels(chartComponent);
appendTab(chartComponent, appendLoadChartAndLegend(new Tabpanel(), chartLoadTimeplot));
setupChart(chartLoadTimeplot, new CompanyLoadChartFiller(), planner);
Chart earnedValueChart = setupChart(chartEarnedValueTimeplot,
earnedValueChartFiller, planner);
setEventListenerConfigurationCheckboxes(earnedValueChart);
chartComponent.getTabs().getLastChild().addEventListener(Events.ON_SELECT, new EventListener() {
public void onEvent(Event event) throws Exception {
createOnDemandEarnedValueTimePlot(chartComponent, planner);
event.getTarget().removeEventListener(Events.ON_SELECT, this);
}
});
}
private void createOnDemandEarnedValueTimePlot(final Tabbox chartComponent, final Planner planner){
transactionService.runOnReadOnlyTransaction(new IOnTransaction<Void>() {
@Override
public Void execute() {
Timeplot chartEarnedValueTimeplot = createEmptyTimeplot();
CompanyEarnedValueChartFiller earnedValueChartFiller = new CompanyEarnedValueChartFiller();
earnedValueChartFiller.calculateValues(planner.getTimeTracker().getRealInterval());
Tabpanel earnedValueTabpanel = new Tabpanel();
appendEarnedValueChartAndLegend(earnedValueTabpanel, chartEarnedValueTimeplot, earnedValueChartFiller);
appendTab(chartComponent, earnedValueTabpanel);
setupChart(chartEarnedValueTimeplot, earnedValueChartFiller, planner);
Writer out = new StringWriter();
try {
earnedValueTabpanel.redraw(out);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Clients.response("aa",
new AuInsertAfter(
chartComponent.getTabpanels().getFirstChild(),
out.toString()
));
return null;
}
});
}
@ -355,21 +391,12 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
chartTabs.setWidth("124px");
}
private void appendTabpanels(Tabbox chartComponent, Timeplot loadChart,
Timeplot chartEarnedValueTimeplot,
CompanyEarnedValueChartFiller earnedValueChartFiller) {
Tabpanels chartTabpanels = new Tabpanels();
private void appendTabpanels(Tabbox chartComponent){
chartComponent.appendChild(new Tabpanels());
}
Tabpanel loadChartPannel = new Tabpanel();
appendLoadChartAndLegend(loadChartPannel, loadChart);
chartTabpanels.appendChild(loadChartPannel);
Tabpanel earnedValueChartPannel = new Tabpanel();
appendEarnedValueChartAndLegend(earnedValueChartPannel,
chartEarnedValueTimeplot, earnedValueChartFiller);
chartTabpanels.appendChild(earnedValueChartPannel);
chartComponent.appendChild(chartTabpanels);
private void appendTab(Tabbox chartComponent, Tabpanel panel){
chartComponent.getTabpanels().appendChild(panel);
}
private void appendEventListenerToDateboxIndicators(
@ -400,7 +427,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
}
}
public static void appendLoadChartAndLegend(Tabpanel loadChartPannel,
public static Tabpanel appendLoadChartAndLegend(Tabpanel loadChartPannel,
Timeplot loadChart) {
Hbox hbox = new Hbox();
hbox.appendChild(getLoadChartLegend());
@ -411,6 +438,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
hbox.appendChild(div);
loadChartPannel.appendChild(hbox);
return loadChartPannel;
}
public static org.zkoss.zk.ui.Component getLoadChartLegend() {
@ -780,7 +808,7 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
chart.getChildren().clear();
chart.invalidate();
String javascript = "zkTasklist.timeplotcontainer_rescroll();";
String javascript = "ganttz.GanttPanel.getInstance().timeplotContainerRescroll()";
Clients.evalJavaScript(javascript);
resetMinimumAndMaximumValueForChart();
@ -809,9 +837,10 @@ public abstract class CompanyPlanningModel implements ICompanyPlanningModel {
ValueGeometry valueGeometry = getValueGeometry();
TimeGeometry timeGeometry = getTimeGeometry(interval);
appendPlotinfo(chart, plotInfoLoad, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoMax, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoOverload, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoMax, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotInfoLoad, valueGeometry, timeGeometry);
chart.setWidth(size + "px");
chart.setHeight("150px");

View file

@ -25,7 +25,6 @@ import static org.navalplanner.web.I18nHelper._;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@ -41,7 +40,6 @@ import org.navalplanner.web.common.components.finders.FilterPair;
import org.navalplanner.web.orders.OrderCRUDController;
import org.navalplanner.web.orders.OrderElementPredicate;
import org.navalplanner.web.planner.advances.AdvanceAssignmentPlanningController;
import org.navalplanner.web.planner.allocation.ResourceAllocationController;
import org.navalplanner.web.planner.calendar.CalendarAllocationController;
import org.navalplanner.web.planner.consolidations.AdvanceConsolidationController;
import org.navalplanner.web.planner.taskedition.EditTaskController;
@ -56,12 +54,10 @@ import org.zkoss.ganttz.extensions.ContextWithPlannerTask;
import org.zkoss.ganttz.extensions.ICommand;
import org.zkoss.ganttz.extensions.IContext;
import org.zkoss.ganttz.extensions.IContextWithPlannerTask;
import org.zkoss.ganttz.resourceload.ScriptsRequiredByResourceLoadPanel;
import org.zkoss.ganttz.timetracker.zoom.ZoomLevel;
import org.zkoss.ganttz.util.LongOperationFeedback;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation;
import org.zkoss.ganttz.util.script.IScriptsRegister;
import org.zkoss.ganttz.util.OnZKDesktopRegistry;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zk.ui.util.Composer;
@ -115,13 +111,6 @@ public class OrderPlanningController implements Composer {
private Textbox filterNameOrderElement;
public OrderPlanningController() {
getScriptsRegister().register(ScriptsRequiredByResourceLoadPanel.class);
ResourceAllocationController.registerNeededScripts();
}
private IScriptsRegister getScriptsRegister() {
return OnZKDesktopRegistry.getLocatorFor(IScriptsRegister.class)
.retrieve();
}
public List<org.navalplanner.business.planner.entities.TaskElement> getCriticalPath() {

View file

@ -1351,7 +1351,7 @@ public abstract class OrderPlanningModel implements IOrderPlanningModel {
chart.getChildren().clear();
chart.invalidate();
String javascript = "zkTasklist.timeplotcontainer_rescroll();";
String javascript = "ganttz.GanttPanel.getInstance().timeplotContainerRescroll()";
Clients.evalJavaScript(javascript);
resetMinimumAndMaximumValueForChart();
@ -1403,13 +1403,15 @@ public abstract class OrderPlanningModel implements IOrderPlanningModel {
TimeGeometry timeGeometry = getTimeGeometry(interval);
// Stacked area: load - otherLoad - max - overload - otherOverload
appendPlotinfo(chart, plotOrderLoad, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotOtherLoad, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotMaxCapacity, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotOrderOverload, valueGeometry,
timeGeometry);
appendPlotinfo(chart, plotOtherOverload, valueGeometry,
timeGeometry);
appendPlotinfo(chart, plotMaxCapacity, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotOrderLoad, valueGeometry, timeGeometry);
appendPlotinfo(chart, plotOtherLoad, valueGeometry, timeGeometry);
chart.setWidth(size + "px");
chart.setHeight("150px");

View file

@ -54,7 +54,6 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.zkoss.ganttz.Planner;
import org.zkoss.ganttz.TabSwitcher;
import org.zkoss.ganttz.TabsRegistry;
import org.zkoss.ganttz.TabsRegistry.IBeforeShowAction;
@ -368,7 +367,6 @@ public class MultipleTabsPlannerController implements Composer,
@Override
@Transactional(readOnly=true)
public void doAfterCompose(org.zkoss.zk.ui.Component comp) {
Planner.registerNeededScripts();
tabsSwitcher = (TabSwitcher) comp;
breadcrumbs = comp.getPage().getFellow("breadcrumbs");
tabsSwitcher.setConfiguration(buildTabsConfiguration());

View file

@ -33,13 +33,14 @@ import org.navalplanner.business.labels.entities.Label;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.ExtendedJasperreport;
import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
import org.zkoss.zul.Datebox;
import org.zkoss.zul.Listbox;
import com.igalia.java.zk.components.JasperreportComponent;
/**
* @author Diego Pino Garcia <dpino@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
@ -110,7 +111,7 @@ public class CompletedEstimatedHoursPerTaskController extends NavalplannerReport
return result;
}
public void showReport(ExtendedJasperreport jasperreport) {
public void showReport(JasperreportComponent jasperreport) {
final Order order = getSelectedOrder();
if (order == null) {
throw new WrongValueException(bandboxSelectOrder,

View file

@ -1,69 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.reports;
import java.util.Map;
import net.sf.jasperreports.engine.JRDataSource;
import org.navalplanner.web.common.components.ExtendedJasperreport;
public class NavalplannerReport implements INavalplannerReport {
private ExtendedJasperreport report;
public NavalplannerReport() {
}
public NavalplannerReport(ExtendedJasperreport report, String reportName) {
if (!reportName.endsWith(".jasper")) {
reportName += ".jasper";
}
report.setSrc(reportName);
setReport(report);
}
public ExtendedJasperreport getReport() {
return report;
}
public void setReport(ExtendedJasperreport report) {
this.report = report;
}
@Override
public String show(String type) {
this.report.setType(type);
String URI = report.getEncodedSrc();
return URI.substring(URI.indexOf("/", 2));
}
public void setParameters(Map parameters) {
report.setParameters(parameters);
}
public void setDatasource(JRDataSource dataSource) {
report.setDatasource(dataSource);
}
}

View file

@ -30,13 +30,15 @@ import java.util.Set;
import net.sf.jasperreports.engine.JRDataSource;
import net.sf.jasperreports.engine.JRParameter;
import org.navalplanner.web.common.components.ExtendedJasperreport;
import org.zkoss.util.Locales;
import org.zkoss.zk.au.out.AuDownload;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.Hbox;
import org.zkoss.zul.Toolbarbutton;
import com.igalia.java.zk.components.JasperreportComponent;
/**
*
* Handles the basic behaviour of a Controller for showing reports
@ -66,22 +68,33 @@ public abstract class NavalplannerReportController extends GenericForwardCompose
private final String DEFAULT_LANG = "en";
public void showReport(ExtendedJasperreport jasperreport) {
public void showReport(JasperreportComponent jasperreport){
final String type = outputFormat.getOutputFormat();
NavalplannerReport report = new NavalplannerReport(jasperreport,
getReportName());
report.setDatasource(getDataSource());
report.setParameters(getParameters());
report.show(type);
// NavalplannerReport report = new NavalplannerReport(jasperreport,
// getReportName());
// report.setDatasource(getDataSource());
// report.setParameters(getParameters());
// report.show(type);
jasperreport.setSrc(getReportName());
jasperreport.setDatasource(getDataSource());
jasperreport.setParameters(getParameters());
jasperreport.setType(type);
String URI = report.show(type);
if (type.equals(HTML)) {
URItext.setStyle("display: none");
Executions.getCurrent().sendRedirect(URI, "_blank");
Executions.getCurrent().sendRedirect(jasperreport.getReportUrl(), "_blank");
} else {
URItext.setStyle("display: inline");
URIlink.setHref(URI);
/*
* We cant use FileDownload.save(<url>) as it creates a new url
* where the resource can't be find so we have to create ourselves
* the download request
* */
Executions.getCurrent().addAuResponse(new AuDownload(jasperreport.getReportUrl()));
URItext.setStyle("display: inline");
URIlink.setHref(jasperreport.getReportUrl());
}
}

View file

@ -1,33 +0,0 @@
/*
* This file is part of NavalPlan
*
* Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e
* Desenvolvemento Tecnolóxico de Galicia
* Copyright (C) 2010-2011 Igalia, S.L.
*
* 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.reports;
import org.navalplanner.web.common.components.ExtendedJasperreport;
public class OrderCostsPerResourceReport extends NavalplannerReport {
public OrderCostsPerResourceReport(ExtendedJasperreport report) {
report.setSrc("orderCostsPerResourceReport.jasper");
setReport(report);
}
}

View file

@ -37,7 +37,6 @@ import org.joda.time.LocalDate;
import org.navalplanner.business.advance.entities.AdvanceType;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.ExtendedJasperreport;
import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
@ -45,6 +44,8 @@ import org.zkoss.zul.Datebox;
import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listitem;
import com.igalia.java.zk.components.JasperreportComponent;
/**
* @author Diego Pino Garcia <dpino@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
@ -210,7 +211,7 @@ public class SchedulingProgressPerOrderController extends NavalplannerReportCont
}
}
public void showReport(ExtendedJasperreport jasperreport) {
public void showReport(JasperreportComponent jasperreport){
checkCannotBeHigher(startingDate, endingDate);
super.showReport(jasperreport);
}

View file

@ -38,7 +38,6 @@ import org.navalplanner.business.materials.entities.MaterialCategory;
import org.navalplanner.business.materials.entities.MaterialStatusEnum;
import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.ExtendedJasperreport;
import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
@ -52,6 +51,8 @@ import org.zkoss.zul.Treeitem;
import org.zkoss.zul.TreeitemRenderer;
import org.zkoss.zul.Treerow;
import com.igalia.java.zk.components.JasperreportComponent;
/**
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
*/
@ -187,7 +188,7 @@ public class TimeLineRequiredMaterialController extends
return result;
}
public void showReport(ExtendedJasperreport jasperreport) {
public void showReport(JasperreportComponent jasperreport){
super.showReport(jasperreport);
}

View file

@ -37,7 +37,6 @@ import org.navalplanner.business.orders.entities.Order;
import org.navalplanner.business.planner.entities.TaskStatusEnum;
import org.navalplanner.business.resources.entities.Criterion;
import org.navalplanner.web.common.Util;
import org.navalplanner.web.common.components.ExtendedJasperreport;
import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.WrongValueException;
@ -46,6 +45,8 @@ import org.zkoss.zul.Listbox;
import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem;
import com.igalia.java.zk.components.JasperreportComponent;
/**
* @author Diego Pino Garcia <dpino@igalia.com>
* @author Susana Montes Pedreira <smontes@wirelessgalicia.com>
@ -133,7 +134,7 @@ public class WorkingArrangementsPerOrderController extends NavalplannerReportCon
return result;
}
public void showReport(ExtendedJasperreport jasperreport) {
public void showReport(JasperreportComponent jasperreport){
if (getSelectedOrder() == null) {
throw new WrongValueException(bdOrder, _("Please, select a project"));
}

Some files were not shown because too many files have changed in this diff Show more