diff --git a/AUTHORS.rst b/AUTHORS.rst index 47c6f704c..08b60279b 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -7,9 +7,11 @@ LibrePlan Team -------------- * Jeroen Baten +* Edwin Zuijdendorp * Bjørn Vos -* Vova Perebykivskiy -* Міша Гожда +* Philippe Poumaroux +* Vova Perebykivskyi +* Paul Luchyn Previous Team Members @@ -30,6 +32,8 @@ Previous Team Members * Óscar González Fernández * Pablo Fernández de la Cigoña Nóvoa * Farruco Sanjurjo Arcay +* Misha Gozda +* Bogdan Bodnarjuk - @@ -127,7 +126,7 @@ Steps: @@ -167,8 +166,8 @@ charge to manage users interaction with report interface and call the proper methods to generate the report itself and show it to the user. There is already a controller called ``LibrePlanReportController`` which -implements most of the stuff needed for report controllers. So, controllers for -new reports are going to extend this class and re-implement some methods. +implements most of the stuff needed for report controllers. +So, controllers for new reports are going to extend this class and re-implement some methods. Steps: @@ -335,8 +334,7 @@ Steps: layout and save it with the name of the new report ``resourcesListReport.jrxml`` in the same folder. - This will allow us to keep coherence between reports in regard to design, - header, footer, etc. + This will allow us to keep coherence between reports in regard to design, header, footer, etc. * Set report name to ``resourcesList``. @@ -381,18 +379,24 @@ with other LibrePlan reports like header and footer. The result in iReport would be something similar to the screenshot. .. figure:: img/ireport-resources-list-report.png - :alt: iRerpot screenshot for Resources List report +:alt: iRerpot screenshot for Resources List report :width: 100% - iReport screenshot for Resources List report + iReport screenshot for Resources List report -You can even check the XML ``resourcesListReport.jrxml`` that should have + You can even check the XML ``resourcesListReport.jrxml`` that should have something similar to the following content: :: - + + @@ -419,7 +423,7 @@ something similar to the following content: - + @@ -552,27 +556,25 @@ Steps: } Then if you run LibrePlan and go to the new menu entry called *Resources List* -in *Reports* you will be able to generate a report with the resources added as -example data. The report still lacks a good design and format, but at least you -are able to see how the basic functionality of JasperReports in LibrePlan is -integrated. The next step will be to show real data in the report getting it -from database. +in *Reports* you will be able to generate a report with the resources added as example data. +The report still lacks a good design and format, but at least you +are able to see how the basic functionality of JasperReports in LibrePlan is integrated. +The next step will be to show real data in the report getting it from database. .. figure:: img/resources-list-report-example-data-pdf.png - :alt: Resources List report with example data in PDF format +:alt: Resources List report with example data in PDF format :width: 100% - Resources List report with example data in PDF format + Resources List report with example data in PDF format Show real data from database ---------------------------- -Now you need to query database and get information about resources. In order to -follow LibrePlan architecture you are going to create a model that will be in -charge to retrieve information from database, process it if needed and return -the information to the controller. Then controller will send this information to -JasperReports in order to generate the report with real data. +Now you need to query database and get information about resources. +In order to follow LibrePlan architecture you are going to create a model that will be in +charge to retrieve information from database, process it if needed and return the information to the controller. +Then controller will send this information to JasperReports in order to generate the report with real data. Steps: @@ -828,8 +830,8 @@ Steps: } * Modify report file ``resourcesListReport.jrxml`` with iReport to add the new - parameter and show it in some part of the report layout. You could use iReport - for this task, or, for example, add the following lines in XML file:: + parameter and show it in some part of the report layout. + You could use iReport for this task, or, for example, add the following lines in XML file:: diff --git a/doc/src/technical/howto-develop-a-use-case-in-libreplan.rst b/doc/src/technical/howto-develop-a-use-case-in-libreplan.rst index e665153bd..b4529700c 100644 --- a/doc/src/technical/howto-develop-a-use-case-in-libreplan.rst +++ b/doc/src/technical/howto-develop-a-use-case-in-libreplan.rst @@ -602,7 +602,7 @@ content: + apply="org.libreplan.web.planner.allocation.stretches.StretchesFunctionTemplateCRUDController"> @@ -680,7 +680,7 @@ The basis for implementing MVC pattern in ZK is ``apply`` attribute. Your page defines a component ``Window`` with an ``apply`` attribute assigned:: + apply="org.libreplan.web.planner.allocation.stretches.StretchesFunctionTemplateCRUDController"> It links this ``Window`` component with a ``.java`` file, thereby the Java class will be able to access and manipulate components defined inside ``window`` tag. @@ -766,7 +766,7 @@ For this example you will create a new controller :: - package org.libreplan.web.planner.allocation.streches; + package org.libreplan.web.planner.allocation.stretches; ... @@ -1253,7 +1253,7 @@ folder: * ``IStretchesFunctionTemplateModel.java``:: - package org.libreplan.web.planner.allocation.streches; + package org.libreplan.web.planner.allocation.stretches; ... @@ -1263,7 +1263,7 @@ folder: * ``StretchesFunctionTemplateModel.java``:: - package org.libreplan.web.planner.allocation.streches; + package org.libreplan.web.planner.allocation.stretches; ... diff --git a/doc/src/technical/uml-analysis.xmi b/doc/src/technical/uml-analysis.xmi index 96c32d1bb..aa9a69720 100644 --- a/doc/src/technical/uml-analysis.xmi +++ b/doc/src/technical/uml-analysis.xmi @@ -196,7 +196,7 @@ - + @@ -245,8 +245,8 @@ - - + + @@ -257,13 +257,13 @@ - + - + @@ -278,12 +278,12 @@ - + - + @@ -454,7 +454,7 @@ - + @@ -1251,7 +1251,7 @@ - + @@ -1291,7 +1291,7 @@ - + @@ -1574,7 +1574,7 @@ - + @@ -1586,7 +1586,7 @@ - + @@ -1802,10 +1802,10 @@ - + - + @@ -1954,10 +1954,10 @@ - + - + @@ -2692,7 +2692,7 @@ - + diff --git a/doc/src/user/en/15-3-work-progress-per-project.rst b/doc/src/user/en/15-3-work-progress-per-project.rst index e69b909a9..38b082e7d 100644 --- a/doc/src/user/en/15-3-work-progress-per-project.rst +++ b/doc/src/user/en/15-3-work-progress-per-project.rst @@ -19,7 +19,7 @@ There are several mandatory parameters. They are: * **Reference date**. It is the date which is wanted to have as reference to make the comparison with the planned foreseen status of the project at that date with the real performance of the project at that date according. *The default value for this field is the current date*. - * **Progres type**. It is the progress type it is wanted to be used to measure the projects progress. In the application a project can be measured simultaneously with different progress types, and the one selected with the pulldown component by the user is the one used for calculating the report data. The default value for the *progress type* is *spread*, which is a special progress type consisting of using the preferred way of measuring the progress configured in each WBS element. + * **Progress type**. It is the progress type it is wanted to be used to measure the projects progress. In the application a project can be measured simultaneously with different progress types, and the one selected with the pulldown component by the user is the one used for calculating the report data. The default value for the *progress type* is *spread*, which is a special progress type consisting of using the preferred way of measuring the progress configured in each WBS element. With regard to the optional fields, they are the following: diff --git a/doc/src/user/en/20-acerca-de.rst b/doc/src/user/en/20-acerca-de.rst index e9d6991f6..864e5c915 100644 --- a/doc/src/user/en/20-acerca-de.rst +++ b/doc/src/user/en/20-acerca-de.rst @@ -43,6 +43,21 @@ Written by LibrePlan Team -------------- +* Jeroen Baten +* Edwin Zuijdendorp +* Bjørn Vos +* Philippe Poumaroux +* Vova Perebykivskyi +* Paul Luchyn + +Previous Team Members +--------------------- + +* Fernando Bellas Permuy +* José María Casanova Crespo +* Óscar González Fernández +* Pablo Fernández de la Cigoña Nóvoa +* Farruco Sanjurjo Arcay * Cristina Alvariño Pérez * Jacobo Aragunde Pérez * Nacho Barrientos Arias @@ -53,15 +68,8 @@ LibrePlan Team * Diego Pino García * Manuel Rego Casasnovas * Lorenzo Tilve Álvaro - -Previous Team Members ---------------------- - -* Fernando Bellas Permuy -* José María Casanova Crespo -* Óscar González Fernández -* Pablo Fernández de la Cigoña Nóvoa -* Farruco Sanjurjo Arcay +* Misha Gozda +* Bogdan Bodnarjuk Translators ----------- @@ -106,10 +114,10 @@ Public funding Inside the global scope that LibrePlan is designed for regarding planning management, a project was developed to solve some common polanning problems. This project is partially financed by Xunta de Galicia, Ministerio de Industria, Turismo e Comercio, and by the European Union, Fondo Europeo de Desenvolvemento Rexional. .. figure:: images/logos.png - :scale: 100 +:scale: 100 This project was part of Plan Avanza: .. figure:: images/avanza.png - :scale: 100 +:scale: 100 diff --git a/doc/src/user/en/21-communications.rst b/doc/src/user/en/21-communications.rst new file mode 100644 index 000000000..41a248464 --- /dev/null +++ b/doc/src/user/en/21-communications.rst @@ -0,0 +1,9 @@ +Subcontractor work description +############################### + +It is possible to keep this field empty. + +But if you do, you could get errors in communication functionality when multiple emtpy fields exist. + +We recommend to always use a unique work description. + diff --git a/doc/src/user/en/lsr.css b/doc/src/user/en/lsr.css index 81e4c1669..ced6c967a 100644 --- a/doc/src/user/en/lsr.css +++ b/doc/src/user/en/lsr.css @@ -10,7 +10,6 @@ body { background: #ffffff; color: black; margin: 2em; -/* padding: 0em 2em; */ } p.topic-title { @@ -19,7 +18,7 @@ p.topic-title { table.docinfo { text-align: left; - margin: 2em 0em; + margin: 2em 0; } a[href] { @@ -78,18 +77,18 @@ p.rubric { h1.title { color: #003a6b; font-size: 250%; - margin-bottom: 0em; + margin-bottom: 0; } h2.subtitle { color: #003a6b; - border-bottom: 0px; + border-bottom: 0; } h1, h2, h3, h4, h5, h6 { color: #555; background-color: transparent; - margin: 0em; + margin: 0; padding-top: 0.5em; } @@ -138,7 +137,7 @@ dd { div.admonition, div.note, div.tip, div.caution, div.important, div.warning { margin: 2em 2em; - padding: 0em 1em; + padding: 0 1em; border-top: 1px solid #aaa; border-left: 1px solid #aaa; border-bottom: 2px solid #555; @@ -180,7 +179,7 @@ table.docutils { border: 1px solid gray; border-collapse: collapse; width: 100%; - margin: 1.5em 0em; + margin: 1.5em 0; } table.docutils caption { @@ -198,8 +197,8 @@ table.docutils th { div.sidebar { width: 33%; float: right; - margin: 0em 2em; - padding: 0em 1em; + margin: 0 2em; + padding: 0 1em; border-top: 1px solid #aaa; border-left: 1px solid #aaa; border-bottom: 2px solid #555; @@ -207,45 +206,45 @@ div.sidebar { } p.sidebar-title { - margin-bottom: 0em; + margin-bottom: 0; color: #003a6b; border-bottom: 1px solid #aaa; font-weight: bold; } p.sidebar-subtitle { - margin-top: 0em; + margin-top: 0; font-style: italic; color: #003a6b; } div.figure { - text-align: center; + text-align: center; } div.figure img { - background: #f8f8f8; - padding: 0.25em; - border: 1px solid #888; - border-radius: 5px; - -moz-border-radius: 5px; - -webkit-border-radius: 5px; + background: #f8f8f8; + padding: 0.25em; + border: 1px solid #888; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; } div.figure img:hover { - background: #e0e0e0; + background: #e0e0e0; } div.figure p.caption { - text-align: center; - margin-top: 0.1em; - font-style: italic; - color: #444; + text-align: center; + margin-top: 0.1em; + font-style: italic; + color: #444; } pre.literal-block { - padding: 0.15em; - background: #f8f8f8; - border: 1px solid #dfdfdf; - border-left: 0.25em solid #dfdfdf + padding: 0.15em; + background: #f8f8f8; + border: 1px solid #dfdfdf; + border-left: 0.25em solid #dfdfdf } diff --git a/ganttzk/pom.xml b/ganttzk/pom.xml index 3ce4f474d..b07aabe21 100644 --- a/ganttzk/pom.xml +++ b/ganttzk/pom.xml @@ -1,6 +1,6 @@ + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4.0.0 @@ -37,6 +37,7 @@ + org.apache.maven.plugins maven-source-plugin @@ -50,6 +51,7 @@ + @@ -89,17 +91,19 @@ org.apache.commons commons-collections4 - + org.zkoss.zk zul + org.zkoss.zk zkplus + org.zkoss.zk zk @@ -123,6 +127,7 @@ easymock test + org.easymock easymockclassextension diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/CommandContextualized.java b/ganttzk/src/main/java/org/zkoss/ganttz/CommandContextualized.java index c75db4723..4fac7b3d7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/CommandContextualized.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/CommandContextualized.java @@ -24,17 +24,11 @@ package org.zkoss.ganttz; import org.apache.commons.lang3.StringUtils; import org.zkoss.ganttz.extensions.ICommand; import org.zkoss.ganttz.extensions.IContext; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zul.Button; class CommandContextualized { - public static CommandContextualized create(ICommand command, IContext context) { - return new CommandContextualized(command, context); - } - private final ICommand command; private final IContext context; @@ -46,6 +40,10 @@ class CommandContextualized { this.context = context; } + public static CommandContextualized create(ICommand command, IContext context) { + return new CommandContextualized<>(command, context); + } + public void doAction() { command.doAction(context); } @@ -66,12 +64,7 @@ class CommandContextualized { if ( command.isDisabled() ) { result.setDisabled(true); } else { - result.addEventListener(Events.ON_CLICK, new EventListener() { - @Override - public void onEvent(Event event) { - doAction(); - } - }); + result.addEventListener(Events.ON_CLICK, event -> doAction()); } button = result; diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/CommandOnTaskContextualized.java b/ganttzk/src/main/java/org/zkoss/ganttz/CommandOnTaskContextualized.java index 21ebf9c7c..bb343d3c1 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/CommandOnTaskContextualized.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/CommandOnTaskContextualized.java @@ -29,29 +29,33 @@ import org.zkoss.ganttz.extensions.ICommandOnTask; import org.zkoss.ganttz.extensions.IContext; import org.zkoss.ganttz.extensions.IContextWithPlannerTask; import org.zkoss.ganttz.util.MenuBuilder.ItemAction; -import org.zkoss.zk.ui.event.Event; public class CommandOnTaskContextualized { - public static CommandOnTaskContextualized create(ICommandOnTask commandOnTask, - IDomainAndBeansMapper mapper, IContext context) { - - return new CommandOnTaskContextualized(commandOnTask, mapper, context); - } - private final ICommandOnTask commandOnTask; private final IContext context; private final IDomainAndBeansMapper mapper; - private CommandOnTaskContextualized(ICommandOnTask commandOnTask, IDomainAndBeansMapper mapper, + private CommandOnTaskContextualized(ICommandOnTask commandOnTask, + IDomainAndBeansMapper mapper, IContext context) { + this.commandOnTask = commandOnTask; this.mapper = mapper; this.context = context; } + public static CommandOnTaskContextualized create(ICommandOnTask commandOnTask, + IDomainAndBeansMapper mapper, + IContext context) { + + return new CommandOnTaskContextualized<>(commandOnTask, mapper, context); + } + + + public void doAction(TaskComponent taskComponent) { doAction( ContextRelativeToOtherComponent.makeRelativeTo(context, taskComponent), @@ -82,12 +86,7 @@ public class CommandOnTaskContextualized { } ItemAction toItemAction() { - return new ItemAction() { - @Override - public void onEvent(TaskComponent choosen, Event event) { - doAction(choosen); - } - }; + return (chosen, event) -> doAction(chosen); } public String getIcon() { @@ -95,8 +94,7 @@ public class CommandOnTaskContextualized { } public boolean accepts(TaskComponent taskComponent) { - T domainObject = domainObjectFor(taskComponent.getTask()); - return commandOnTask.isApplicableTo(domainObject); + return commandOnTask.isApplicableTo(domainObjectFor(taskComponent.getTask())); } public IDomainAndBeansMapper getMapper() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java b/ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java index 04ca965e3..7a9bf251e 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/DependencyList.java @@ -27,8 +27,6 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.zkoss.ganttz.data.Dependency; import org.zkoss.ganttz.data.DependencyType; import org.zkoss.ganttz.data.Task; @@ -39,6 +37,7 @@ import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.ganttz.util.MenuBuilder; import org.zkoss.ganttz.util.MenuBuilder.ItemAction; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.ext.AfterCompose; import org.zkoss.zul.Menupopup; @@ -51,8 +50,8 @@ import org.zkoss.zul.impl.XulElement; */ public class DependencyList extends XulElement implements AfterCompose { - private final class ChangeTypeAction implements - ItemAction { + private final class ChangeTypeAction implements ItemAction { + private final DependencyType type; private ChangeTypeAction(DependencyType type) { @@ -60,32 +59,28 @@ public class DependencyList extends XulElement implements AfterCompose { } @Override - public void onEvent(final DependencyComponent choosen, Event event) { - boolean canBeAdded = context.changeType(choosen.getDependency(), - type); - if (!canBeAdded) { + public void onEvent(final DependencyComponent chosen, Event event) { + boolean canBeAdded = context.changeType(chosen.getDependency(), type); + + if ( !canBeAdded ) { warnUser(_("The specified dependency is not allowed")); } } private void warnUser(String message) { - try { - Messagebox.show(message, null, Messagebox.OK, - Messagebox.EXCLAMATION, 0, null); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + Messagebox.show(message, null, Messagebox.OK, Messagebox.EXCLAMATION, 0, null); } } - private final class DependencyVisibilityToggler implements - PropertyChangeListener { + private final class DependencyVisibilityToggler implements PropertyChangeListener { + private final Task source; + private final Task destination; + private final DependencyComponent dependencyComponent; - private DependencyVisibilityToggler(Task source, Task destination, - DependencyComponent dependencyComponent) { + private DependencyVisibilityToggler(Task source, Task destination, DependencyComponent dependencyComponent) { this.source = source; this.destination = destination; this.dependencyComponent = dependencyComponent; @@ -93,16 +88,17 @@ public class DependencyList extends XulElement implements AfterCompose { @Override public void propertyChange(PropertyChangeEvent evt) { - if (!evt.getPropertyName().equals("visible")) { + if ( !"visible".equals(evt.getPropertyName()) ) { return; } - if (dependencyMustBeVisible() != isDependencyNowVisible()) { + + if ( dependencyMustBeVisible() != isDependencyNowVisible() ) { toggleDependencyExistence(dependencyMustBeVisible()); } } void toggleDependencyExistence(boolean visible) { - if (visible) { + if ( visible ) { appendChild(dependencyComponent); dependencyComponent.afterCompose(); addContextMenu(dependencyComponent); @@ -120,8 +116,6 @@ public class DependencyList extends XulElement implements AfterCompose { } } - private static final Log LOG = LogFactory.getLog(DependencyList.class); - private transient IZoomLevelChangedListener listener; private final FunctionalityExposedForExtensions context; @@ -135,33 +129,32 @@ public class DependencyList extends XulElement implements AfterCompose { } private List getDependencyComponents() { - List children = getChildren(); - return ComponentsFinder - .findComponentsOfType(DependencyComponent.class, children); + List children = getChildren(); + return ComponentsFinder.findComponentsOfType(DependencyComponent.class, children); } void addDependencyComponent(final DependencyComponent dependencyComponent) { TaskComponent source = dependencyComponent.getSource(); TaskComponent destination = dependencyComponent.getDestination(); - DependencyVisibilityToggler visibilityToggler = new DependencyVisibilityToggler( - source.getTask(), destination.getTask(), dependencyComponent); - source.getTask().addVisibilityPropertiesChangeListener( - visibilityToggler); - destination.getTask().addVisibilityPropertiesChangeListener( - visibilityToggler); + + DependencyVisibilityToggler visibilityToggler = + new DependencyVisibilityToggler(source.getTask(), destination.getTask(), dependencyComponent); + + source.getTask().addVisibilityPropertiesChangeListener(visibilityToggler); + destination.getTask().addVisibilityPropertiesChangeListener(visibilityToggler); dependencyComponent.setVisibilityChangeListener(visibilityToggler); - boolean dependencyMustBeVisible = visibilityToggler - .dependencyMustBeVisible(); + + boolean dependencyMustBeVisible = visibilityToggler.dependencyMustBeVisible(); visibilityToggler.toggleDependencyExistence(dependencyMustBeVisible); - if (dependencyMustBeVisible) { + + if ( dependencyMustBeVisible ) { dependencyComponent.redrawDependency(); } } private void addContextMenu(DependencyComponent dependencyComponent) { - Menupopup contextMenu = dependencyComponent.hasLimitingTasks() ? - getLimitingContextMenu() - : getContextMenu(); + Menupopup contextMenu = dependencyComponent.hasLimitingTasks() ? getLimitingContextMenu() : getContextMenu(); + dependencyComponent.setContext(contextMenu); } @@ -169,8 +162,7 @@ public class DependencyList extends XulElement implements AfterCompose { return (GanttPanel) getParent(); } - public void setDependencyComponents( - List dependencyComponents) { + void setDependencyComponents(List dependencyComponents) { for (DependencyComponent dependencyComponent : dependencyComponents) { addDependencyComponent(dependencyComponent); } @@ -178,11 +170,13 @@ public class DependencyList extends XulElement implements AfterCompose { @Override public void afterCompose() { - if (listener == null) { + if ( listener == null ) { + + /* Do not replace it with lambda */ listener = new IZoomLevelChangedListener() { @Override public void zoomLevelChanged(ZoomLevel detailLevel) { - if (!isInPage()) { + if ( !isInPage() ) { return; } for (DependencyComponent dependencyComponent : getDependencyComponents()) { @@ -190,14 +184,15 @@ public class DependencyList extends XulElement implements AfterCompose { } } }; + getTimeTracker().addZoomListener(listener); } + addContextMenu(); } private boolean isInPage() { - return getParent() != null && getGanttPanel() != null - && getGanttPanel().getParent() != null; + return getParent() != null && getGanttPanel() != null && getGanttPanel().getParent() != null; } private TimeTracker getTimeTracker() { @@ -211,54 +206,39 @@ public class DependencyList extends XulElement implements AfterCompose { } private Menupopup getLimitingContextMenu() { - if (limitingContextMenu == null) { - MenuBuilder contextMenuBuilder = MenuBuilder - .on(getPage(), getDependencyComponents()).item(_("Erase"), + if ( limitingContextMenu == null ) { + + MenuBuilder contextMenuBuilder = + MenuBuilder.on(getPage(), getDependencyComponents()).item( + _("Erase"), "/common/img/ico_borrar.png", - new ItemAction() { - @Override - public void onEvent( - final DependencyComponent choosen, - Event event) { - context - .removeDependency(choosen.getDependency()); - } - }); + (chosen, event) -> context.removeDependency(chosen.getDependency())); + limitingContextMenu = contextMenuBuilder.create(); } + return limitingContextMenu; } private Menupopup getContextMenu() { - if (contextMenu == null) { - MenuBuilder contextMenuBuilder = MenuBuilder - .on(getPage(), getDependencyComponents()).item(_("Erase"), + if ( contextMenu == null ) { + + MenuBuilder contextMenuBuilder = + MenuBuilder.on(getPage(), getDependencyComponents()).item( + _("Erase"), "/common/img/ico_borrar.png", - new ItemAction() { - @Override - public void onEvent( - final DependencyComponent choosen, - Event event) { - context - .removeDependency(choosen.getDependency()); - } - }); + ((chosen, event) -> context.removeDependency(chosen.getDependency()))); - contextMenuBuilder.item(_("Set End-Start"), null, - new ChangeTypeAction( - DependencyType.END_START)); + contextMenuBuilder.item(_("Set End-Start"), null, new ChangeTypeAction(DependencyType.END_START)); - contextMenuBuilder.item(_("Set Start-Start"), null, - new ChangeTypeAction( - DependencyType.START_START)); + contextMenuBuilder.item(_("Set Start-Start"), null, new ChangeTypeAction(DependencyType.START_START)); - contextMenuBuilder.item(_("Set End-End"), null, - new ChangeTypeAction( - DependencyType.END_END)); + contextMenuBuilder.item(_("Set End-End"), null, new ChangeTypeAction(DependencyType.END_END)); contextMenu = contextMenuBuilder.create(); } + return contextMenu; } @@ -266,48 +246,45 @@ public class DependencyList extends XulElement implements AfterCompose { return getGanttPanel().getTimeTrackerComponent(); } - public void redrawDependencies() { + void redrawDependencies() { redrawDependencyComponents(getDependencyComponents()); } - public void redrawDependencyComponents( - List dependencyComponents) { + private void redrawDependencyComponents(List dependencyComponents) { for (DependencyComponent dependencyComponent : dependencyComponents) { dependencyComponent.redrawDependency(); } } - public void taskRemoved(Task task) { - for (DependencyComponent dependencyComponent : DependencyList.this - .getDependencyComponents()) { - if (dependencyComponent.contains(task)) { + void taskRemoved(Task task) { + for (DependencyComponent dependencyComponent : DependencyList.this.getDependencyComponents()) { + if ( dependencyComponent.contains(task) ) { removeDependencyComponent(dependencyComponent); } } } public void remove(Dependency dependency) { - for (DependencyComponent dependencyComponent : DependencyList.this - .getDependencyComponents()) { - if (dependencyComponent.hasSameSourceAndDestination(dependency)) { + for (DependencyComponent dependencyComponent : DependencyList.this.getDependencyComponents()) { + if ( dependencyComponent.hasSameSourceAndDestination(dependency) ) { removeDependencyComponent(dependencyComponent); } } } private void removeDependencyComponent(DependencyComponent dependencyComponent) { - //remove the visibility listener attached to the tasks + // Remove the visibility listener attached to the tasks TaskComponent source = dependencyComponent.getSource(); TaskComponent destination = dependencyComponent.getDestination(); - PropertyChangeListener listener = - dependencyComponent.getVisibilityChangeListener(); + PropertyChangeListener listener = dependencyComponent.getVisibilityChangeListener(); + source.getTask().removeVisibilityPropertiesChangeListener(listener); destination.getTask().removeVisibilityPropertiesChangeListener(listener); - //remove other change listeners + // Remove other change listeners dependencyComponent.removeChangeListeners(); - //remove the dependency itself + // Remove the dependency itself this.removeChild(dependencyComponent); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java index 8f62483da..23e74d03d 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/FunctionalityExposedForExtensions.java @@ -50,7 +50,7 @@ import org.zkoss.ganttz.data.TaskLeaf; import org.zkoss.ganttz.data.criticalpath.CriticalPathCalculator; import org.zkoss.ganttz.extensions.IContext; import org.zkoss.ganttz.timetracker.TimeTracker; -import org.zkoss.ganttz.timetracker.zoom.IDetailItemModificator; +import org.zkoss.ganttz.timetracker.zoom.IDetailItemModifier; import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState; import org.zkoss.ganttz.util.Interval; import org.zkoss.zk.ui.Component; @@ -174,11 +174,17 @@ public class FunctionalityExposedForExtensions implements IContext { } private final Planner planner; + private final IAdapterToTaskFundamentalProperties adapter; + private final IStructureNavigator navigator; - private final OneToOneMapper mapper = new OneToOneMapper(); + + private final OneToOneMapper mapper = new OneToOneMapper<>(); + private final GanttZKDiagramGraph diagramGraph; + private TimeTracker timeTracker; + private final PlannerConfiguration configuration; public FunctionalityExposedForExtensions( @@ -190,8 +196,8 @@ public class FunctionalityExposedForExtensions implements IContext { this.navigator = configuration.getNavigator(); this.diagramGraph = diagramGraph; - final IDetailItemModificator firstLevelModificators = configuration.getFirstLevelModificators(); - final IDetailItemModificator secondLevelModificators = configuration.getSecondLevelModificators(); + final IDetailItemModifier firstLevelModifiers = configuration.getFirstLevelModifiers(); + final IDetailItemModifier secondLevelModifiers = configuration.getSecondLevelModifiers(); Calendar calendarRightNow = Calendar.getInstance(); LocalDate localDateRightNow = LocalDate.fromCalendarFields(calendarRightNow); @@ -201,19 +207,18 @@ public class FunctionalityExposedForExtensions implements IContext { this.timeTracker = new TimeTracker( new Interval(TimeTrackerState.year(initDate.getYear()), TimeTrackerState.year(endDate.getYear())), planner.getZoomLevel(), - firstLevelModificators, - secondLevelModificators, + firstLevelModifiers, + secondLevelModifiers, planner); } /** - * @param insertionPosition the position in which to register the task at top level. + * @param position the position in which to register the task at top level. * It can be null * @param accumulatedDependencies * @param data - * @param parent * - * @return + * @return {@link Task} */ private Task buildAndRegister(Position position, List> accumulatedDependencies, T data) { accumulatedDependencies.addAll(adapter.getOutcomingDependencies(data)); @@ -226,8 +231,7 @@ public class FunctionalityExposedForExtensions implements IContext { int i = 0; for (T child : navigator.getChildren(data)) { - container.add(buildAndRegister(position.down(container, i), - accumulatedDependencies, child)); + container.add(buildAndRegister(position.down(container, i), accumulatedDependencies, child)); i++; } @@ -349,9 +353,8 @@ public class FunctionalityExposedForExtensions implements IContext { private DomainDependency toDomainDependency(Dependency bean) { T source = mapper.findAssociatedDomainObject(bean.getSource()); T destination = mapper.findAssociatedDomainObject(bean.getDestination()); - DomainDependency dep = DomainDependency.createDependency(source, destination, bean.getType()); - return dep; + return DomainDependency.createDependency(source, destination, bean.getType()); } public void addDependency(Dependency dependency) { @@ -383,9 +386,8 @@ public class FunctionalityExposedForExtensions implements IContext { } /** - * Substitutes the dependency for a new one with the same source and - * destination but with the specified type. If the new dependency cannot be - * added, the old one remains. + * Substitutes the dependency for a new one with the same source and destination but with the specified type. + * If the new dependency cannot be added, the old one remains. * * @param dependency * @param type diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/GanttPanel.java b/ganttzk/src/main/java/org/zkoss/ganttz/GanttPanel.java index 335dfe229..d554443c5 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/GanttPanel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/GanttPanel.java @@ -60,56 +60,60 @@ public class GanttPanel extends XulElement implements AfterCompose { CommandOnTaskContextualized doubleClickCommand, IDisabilityConfiguration disabilityConfiguration, FilterAndParentExpandedPredicates predicate) { + this.planner = planner; - FunctionalityExposedForExtensions context = (FunctionalityExposedForExtensions) planner - .getContext(); + FunctionalityExposedForExtensions context = (FunctionalityExposedForExtensions) planner.getContext(); + if (planner.isShowingCriticalPath()) { context.showCriticalPath(); } + this.diagramGraph = context.getDiagramGraph(); - timeTrackerComponent = timeTrackerForGanttPanel(context - .getTimeTracker()); + timeTrackerComponent = timeTrackerForGanttPanel(context.getTimeTracker()); + appendChild(timeTrackerComponent); dependencyList = new DependencyList(context); - tasksLists = TaskList.createFor(context, doubleClickCommand, - commandsOnTasksContextualized, disabilityConfiguration, - predicate); + + tasksLists = TaskList.createFor( + context, doubleClickCommand, commandsOnTasksContextualized, disabilityConfiguration, predicate); + appendChild(tasksLists); appendChild(dependencyList); } - private TimeTrackerComponent timeTrackerForGanttPanel( - TimeTracker timeTracker) { + private TimeTrackerComponent timeTrackerForGanttPanel(TimeTracker timeTracker) { return new TimeTrackerComponent(timeTracker) { @Override protected void scrollHorizontalPercentage(int daysDisplacement) { - response("scroll_horizontal", new AuInvoke(GanttPanel.this, - "scroll_horizontal", "" + daysDisplacement)); + + response( + "scroll_horizontal", + new AuInvoke(GanttPanel.this, "scroll_horizontal", Integer.toString(daysDisplacement))); + moveCurrentPositionScroll(); } // FIXME: this is quite awful, it should be simple @Override protected void moveCurrentPositionScroll() { - // get the previous data. + // Get the previous data. LocalDate previousStart = getPreviousStart(); - // get the current data - int diffDays = getTimeTrackerComponent().getDiffDays( - previousStart); + // Get the current data + int diffDays = getTimeTrackerComponent().getDiffDays(previousStart); double pixelPerDay = getTimeTrackerComponent().getPixelPerDay(); - response("move_scroll", new AuInvoke(GanttPanel.this, - "move_scroll", "" + diffDays, "" + pixelPerDay)); + response("move_scroll", new AuInvoke(GanttPanel.this, "move_scroll", + Integer.toString(diffDays), + Double.toString(pixelPerDay))); } protected void updateCurrentDayScroll() { - double previousPixelPerDay = getTimeTracker().getMapper() - .getPixelsPerDay() - .doubleValue(); + double previousPixelPerDay = getTimeTracker().getMapper().getPixelsPerDay().doubleValue(); - response("update_day_scroll", new AuInvoke(GanttPanel.this, - "update_day_scroll", "" + previousPixelPerDay)); + response( + "update_day_scroll", + new AuInvoke(GanttPanel.this, "update_day_scroll", Double.toString(previousPixelPerDay))); } @@ -119,14 +123,16 @@ public class GanttPanel extends XulElement implements AfterCompose { @Override public void afterCompose() { tasksLists.afterCompose(); - dependencyList.setDependencyComponents(tasksLists - .asDependencyComponents(diagramGraph.getVisibleDependencies())); + + dependencyList.setDependencyComponents( + tasksLists.asDependencyComponents(diagramGraph.getVisibleDependencies())); + timeTrackerComponent.afterCompose(); dependencyList.afterCompose(); savePreviousData(); + if (planner.isExpandAll()) { - FunctionalityExposedForExtensions context = (FunctionalityExposedForExtensions) planner - .getContext(); + FunctionalityExposedForExtensions context = (FunctionalityExposedForExtensions) planner.getContext(); context.expandAll(); } @@ -141,6 +147,7 @@ public class GanttPanel extends XulElement implements AfterCompose { for (Task task : this.tasksLists.getAllTasks()) { task.updateTooltipText(); } + for (TaskComponent taskComponent : this.tasksLists.getTaskComponents()) { taskComponent.invalidate(); } @@ -195,12 +202,7 @@ public class GanttPanel extends XulElement implements AfterCompose { private void registerZoomLevelChangedListener() { if (zoomLevelChangedListener == null) { - zoomLevelChangedListener = new IZoomLevelChangedListener() { - @Override - public void zoomLevelChanged(ZoomLevel detailLevel) { - adjustZoomColumnsHeight(); - } - }; + zoomLevelChangedListener = detailLevel -> adjustZoomColumnsHeight(); getTimeTracker().addZoomListener(zoomLevelChangedListener); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/IDatesMapper.java b/ganttzk/src/main/java/org/zkoss/ganttz/IDatesMapper.java index a9a7473ec..051116aa1 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/IDatesMapper.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/IDatesMapper.java @@ -28,7 +28,7 @@ import org.zkoss.ganttz.util.Interval; public interface IDatesMapper { - final long MILISECONDS_PER_HOUR = 3600000; + long MILISECONDS_PER_HOUR = 3600000; int toPixels(LocalDate date); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/LeftPane.java b/ganttzk/src/main/java/org/zkoss/ganttz/LeftPane.java index e2ed9375a..3acf7f6d4 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/LeftPane.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/LeftPane.java @@ -31,14 +31,13 @@ import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlMacroComponent; /** - * LeftPane of the planner. Responsible of showing global commands and the - * leftTasksTree
+ * LeftPane of the planner. Responsible of showing global commands and the leftTasksTree + *
+ * * @author Óscar González Fernández */ public class LeftPane extends HtmlMacroComponent { - private final List topLevelTasks; - private LeftTasksTree leftTasksTree; private final IDisabilityConfiguration disabilityConfiguration; @@ -47,16 +46,14 @@ public class LeftPane extends HtmlMacroComponent { private Planner planner; - public void setGoingDownInLastArrowCommand( - CommandContextualized goingDownInLastArrowCommand) { - this.leftTasksTree - .setGoingDownInLastArrowCommand(goingDownInLastArrowCommand); + public void setGoingDownInLastArrowCommand(CommandContextualized goingDownInLastArrowCommand) { + this.leftTasksTree.setGoingDownInLastArrowCommand(goingDownInLastArrowCommand); } public LeftPane(IDisabilityConfiguration disabilityConfiguration, - Planner planner, - FilterAndParentExpandedPredicates predicate) { - this.topLevelTasks = planner.getDiagramGraph().getTopLevelTasks(); + Planner planner, + FilterAndParentExpandedPredicates predicate) { + this.disabilityConfiguration = disabilityConfiguration; this.predicate = predicate; this.planner = planner; @@ -65,15 +62,14 @@ public class LeftPane extends HtmlMacroComponent { @Override public void afterCompose() { super.afterCompose(); - leftTasksTree = new LeftTasksTree(disabilityConfiguration, planner, - predicate); + + leftTasksTree = new LeftTasksTree(disabilityConfiguration, planner, predicate); getContainer().appendChild(leftTasksTree); leftTasksTree.afterCompose(); } private Component getContainer() { - Component container = getFellow("listdetails_container"); - return container; + return getFellow("listdetails_container"); } public void taskRemoved(Task task) { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTree.java b/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTree.java index 142c75903..4b1989c1a 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTree.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTree.java @@ -23,39 +23,32 @@ package org.zkoss.ganttz; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; +import java.util.Collections; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.Set; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.zkoss.ganttz.LeftTasksTreeRow.ILeftTasksTreeNavigator; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.data.Position; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.data.TaskContainer; import org.zkoss.ganttz.data.TaskContainer.IExpandListener; -import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.ganttz.util.MutableTreeModel; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.HtmlMacroComponent; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zul.Tree; -import org.zkoss.zul.TreeModel; -import org.zkoss.zul.Treecell; import org.zkoss.zul.Treeitem; import org.zkoss.zul.TreeitemRenderer; /** - * Tree element to display tasks structure in the planning Gantt
+ * Tree element to display tasks structure in the planning Gantt. + *
* * @author Óscar González Fernández * @author Manuel Rego Casasnovas @@ -63,258 +56,8 @@ import org.zkoss.zul.TreeitemRenderer; */ public class LeftTasksTree extends HtmlMacroComponent { - private final class TaskBeanRenderer implements TreeitemRenderer { - private Map expandListeners = new HashMap(); - - public void render(final Treeitem item, Object data) throws Exception { - Task task = (Task) data; - item.setOpen(isOpened(task)); - - if ( task instanceof TaskContainer ) { - - final TaskContainer container = (TaskContainer) task; - - IExpandListener expandListener = new IExpandListener() { - - @Override - public void expandStateChanged(boolean isNowExpanded) { - item.setOpen(isNowExpanded); - } - }; - - expandListeners.put(container, expandListener); - container.addExpandListener(expandListener); - - } - LeftTasksTreeRow leftTasksTreeRow = LeftTasksTreeRow - .create(disabilityConfiguration, task, new TreeNavigator(tasksTreeModel, task), planner); - - if ( task.isContainer() ) { - expandWhenOpened((TaskContainer) task, item); - } - Component row; - if ( disabilityConfiguration.isTreeEditable() ) { - row = Executions.getCurrent().createComponents( - "~./ganttz/zul/leftTasksTreeRow.zul", item, null); - } else { - row = Executions.getCurrent().createComponents( - "~./ganttz/zul/leftTasksTreeRowLabels.zul", item, null); - } - leftTasksTreeRow.doAfterCompose(row); - detailsForBeans.put(task, leftTasksTreeRow); - deferredFiller.isBeingRendered(task, item); - } - - private void expandWhenOpened(final TaskContainer taskBean, Treeitem item) { - item.addEventListener("onOpen", new EventListener() { - @Override - public void onEvent(Event event) { - OpenEvent openEvent = (OpenEvent) event; - taskBean.setExpanded(openEvent.isOpen()); - } - }); - } - - } - - public boolean isOpened(Task task) { - return task.isLeaf() || task.isExpanded(); - } - - private static final class DetailsForBeans { - - private Map map = new HashMap(); - - private Set focusRequested = new HashSet(); - - public void put(Task task, LeftTasksTreeRow leftTasksTreeRow) { - map.put(task, leftTasksTreeRow); - if (focusRequested.contains(task)) { - focusRequested.remove(task); - leftTasksTreeRow.receiveFocus(); - } - } - - public void requestFocusFor(Task task) { - focusRequested.add(task); - } - - public LeftTasksTreeRow get(Task taskbean) { - return map.get(taskbean); - } - - } - private DetailsForBeans detailsForBeans = new DetailsForBeans(); - private final class TreeNavigator implements ILeftTasksTreeNavigator { - private final int[] pathToNode; - private final Task task; - - private TreeNavigator(TreeModel treemodel, Task task) { - this.task = task; - this.pathToNode = tasksTreeModel.getPath(tasksTreeModel.getRoot(), - task); - } - - @Override - public LeftTasksTreeRow getAboveRow() { - Task parent = getParent(pathToNode); - int lastPosition = pathToNode[pathToNode.length - 1]; - if (lastPosition != 0) { - return getChild(parent, lastPosition - 1); - } else if (tasksTreeModel.getRoot() != parent) { - return getDetailFor(parent); - } - return null; - } - - private LeftTasksTreeRow getChild(Task parent, int position) { - Task child = tasksTreeModel.getChild(parent, position); - return getDetailFor(child); - } - - private LeftTasksTreeRow getDetailFor(Task child) { - return detailsForBeans.get(child); - } - - @Override - public LeftTasksTreeRow getBelowRow() { - if (isExpanded() && hasChildren()) { - return getChild(task, 0); - } - for (ChildAndParent childAndParent : group(task, tasksTreeModel - .getParents(task))) { - if (childAndParent.childIsNotLast()) { - return getDetailFor(childAndParent.getNextToChild()); - } - } - // it's the last one, it has none below - return null; - } - - public List group(Task origin, List parents) { - ArrayList result = new ArrayList(); - Task child = origin; - Task parent; - ListIterator listIterator = parents.listIterator(); - while (listIterator.hasNext()) { - parent = listIterator.next(); - result.add(new ChildAndParent(child, parent)); - child = parent; - } - return result; - } - - private class ChildAndParent { - private final Task parent; - - private final Task child; - - private Integer positionOfChildCached; - - private ChildAndParent(Task child, Task parent) { - this.parent = parent; - this.child = child; - } - - public Task getNextToChild() { - return tasksTreeModel - .getChild(parent, getPositionOfChild() + 1); - } - - public boolean childIsNotLast() { - return getPositionOfChild() < numberOfChildrenForParent() - 1; - } - - private int numberOfChildrenForParent() { - return tasksTreeModel.getChildCount(parent); - } - - private int getPositionOfChild() { - if (positionOfChildCached != null) { - return positionOfChildCached; - } - int[] path = tasksTreeModel.getPath(parent, child); - return positionOfChildCached = path[path.length - 1]; - } - } - - private boolean hasChildren() { - return task.isContainer() && task.getTasks().size() > 0; - } - - private boolean isExpanded() { - return task.isContainer() && task.isExpanded(); - } - - private Task getParent(int[] path) { - Task current = tasksTreeModel.getRoot(); - for (int i = 0; i < path.length - 1; i++) { - current = tasksTreeModel.getChild(current, path[i]); - } - return current; - } - - } - - /** - * This class is a workaround for an issue with zk {@link Tree}. Once the - * tree is created, adding a node with children is troublesome. Only the top - * element is added to the tree, although the element has children. The Tree - * discards the adding event for the children because the parent says it's - * not loaded. This is the condition that is not satisfied:
- * if(parent != null && - (!(parent instanceof Treeitem) || ((Treeitem)parent).isLoaded())){
- * This problem is present in zk 3.6.1 at least. - * @author Óscar González Fernández - * @see Tree#onTreeDataChange - */ - private class DeferredFiller { - - private Set pendingToAddChildren = new HashSet(); - - public void addParentOfPendingToAdd(Task parent) { - pendingToAddChildren.add(parent); - } - - public void isBeingRendered(final Task parent, final Treeitem item) { - if (!pendingToAddChildren.contains(parent)) { - return; - } - markLoaded(item); - fillModel(parent, 0, parent.getTasks(), false); - pendingToAddChildren.remove(parent); - } - - private void markLoaded(Treeitem item) { - try { - Method method = getSetLoadedMethod(); - method.invoke(item, true); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - private Method setLoadedMethod = null; - - private Method getSetLoadedMethod() { - if (setLoadedMethod != null) { - return setLoadedMethod; - } - try { - Method method = Treeitem.class.getDeclaredMethod("setLoaded", - Boolean.TYPE); - method.setAccessible(true); - return setLoadedMethod = method; - } catch (Exception e) { - throw new RuntimeException(e); - } - } - } - - private static Log LOG = LogFactory.getLog(LeftTasksTree.class); - private final DeferredFiller deferredFiller = new DeferredFiller(); private final List tasks; @@ -329,67 +72,376 @@ public class LeftTasksTree extends HtmlMacroComponent { private FilterAndParentExpandedPredicates predicate; - private final List visibleTasks = new ArrayList(); + private final List visibleTasks = new ArrayList<>(); private Planner planner; public LeftTasksTree(IDisabilityConfiguration disabilityConfiguration, - Planner planner, - FilterAndParentExpandedPredicates predicate) { + Planner planner, + FilterAndParentExpandedPredicates predicate) { + this.disabilityConfiguration = disabilityConfiguration; this.tasks = planner.getTaskList().getAllTasks(); this.predicate = predicate; this.planner = planner; } + @Override + public void afterCompose() { + setClass("listdetails"); + super.afterCompose(); + tasksTree = (Tree) getFellow("tasksTree"); + tasksTreeModel = MutableTreeModel.create(Task.class); + fillModel(tasks, true); + tasksTree.setModel(tasksTreeModel); + tasksTree.setItemRenderer(getTaskBeanRenderer()); + + /* Force call overridden render() */ + try { + if ( !tasks.isEmpty() ) { + getTaskBeanRenderer().render(new Treeitem(""), tasks.get(0), 0); + } + } catch (Exception e) { + e.printStackTrace(); + } + + } + + private final class TaskBeanRenderer implements TreeitemRenderer { + @Override + public void render(final Treeitem treeitem, Task o, int i) throws Exception { + Task task = o; + treeitem.setOpen(isOpened(task)); + + if ( task instanceof TaskContainer ) { + + final TaskContainer container = (TaskContainer) task; + + IExpandListener expandListener = new IExpandListener() { + @Override + public void expandStateChanged(boolean isNowExpanded) { + treeitem.setOpen(isNowExpanded); + } + }; + + container.addExpandListener(expandListener); + + } + + LeftTasksTreeRow leftTasksTreeRow = + LeftTasksTreeRow.create(disabilityConfiguration, task, new TreeNavigator(task), planner); + + if ( task.isContainer() ) { + expandWhenOpened((TaskContainer) task, treeitem); + } + + /* Clear existing Treerows */ + if ( !treeitem.getChildren().isEmpty() ) { + treeitem.getChildren().clear(); + } + + Component row = disabilityConfiguration.isTreeEditable() + ? Executions + .getCurrent() + .createComponents("~./ganttz/zul/leftTasksTreeRow.zul", treeitem, null) + : Executions + .getCurrent() + .createComponents("~./ganttz/zul/leftTasksTreeRowLabels.zul", treeitem, null); + + leftTasksTreeRow.doAfterCompose(row); + detailsForBeans.put(task, leftTasksTreeRow); + deferredFiller.isBeingRendered(task, treeitem); + } + + private void expandWhenOpened(final TaskContainer taskBean, Treeitem item) { + item.addEventListener("onOpen", event -> { + OpenEvent openEvent = (OpenEvent) event; + taskBean.setExpanded(openEvent.isOpen()); + }); + } + } + + private TaskBeanRenderer getTaskBeanRenderer() { + return new TaskBeanRenderer(); + } + + public boolean isOpened(Task task) { + return task.isLeaf() || task.isExpanded(); + } + + private static final class DetailsForBeans { + + private Map map = new HashMap<>(); + + private Set focusRequested = new HashSet<>(); + + public void put(Task task, LeftTasksTreeRow leftTasksTreeRow) { + map.put(task, leftTasksTreeRow); + + if ( focusRequested.contains(task) ) { + focusRequested.remove(task); + leftTasksTreeRow.receiveFocus(); + } + } + + public void requestFocusFor(Task task) { + focusRequested.add(task); + } + + public LeftTasksTreeRow get(Task taskbean) { + return map.get(taskbean); + } + + } + + private final class TreeNavigator implements ILeftTasksTreeNavigator { + + private final int[] pathToNode; + + private final Task task; + + private TreeNavigator(Task task) { + this.task = task; + this.pathToNode = tasksTreeModel.getPath(tasksTreeModel.getRoot(), task); + } + + @Override + public LeftTasksTreeRow getAboveRow() { + Task parent = getParent(pathToNode); + int lastPosition = pathToNode[pathToNode.length - 1]; + + if ( lastPosition != 0 ) { + return getChild(parent, lastPosition - 1); + } else if ( tasksTreeModel.getRoot() != parent ) { + return getDetailFor(parent); + } + + return null; + } + + private LeftTasksTreeRow getChild(Task parent, int position) { + return getDetailFor(tasksTreeModel.getChild(parent, position)); + } + + private LeftTasksTreeRow getDetailFor(Task child) { + return detailsForBeans.get(child); + } + + @Override + public LeftTasksTreeRow getBelowRow() { + if ( isExpanded() && hasChildren() ) { + return getChild(task, 0); + } + + for (ChildAndParent childAndParent : group(task, tasksTreeModel.getParents(task))) { + if ( childAndParent.childIsNotLast() ) { + return getDetailFor(childAndParent.getNextToChild()); + } + } + + // It's the last one, it has none below + return null; + } + + public List group(Task origin, List parents) { + ArrayList result = new ArrayList<>(); + Task child = origin; + + for (Task parent : parents) { + result.add(new ChildAndParent(child, parent)); + child = parent; + } + + return result; + } + + private class ChildAndParent { + + private final Task parent; + + private final Task child; + + private Integer positionOfChildCached; + + private ChildAndParent(Task child, Task parent) { + this.parent = parent; + this.child = child; + } + + public Task getNextToChild() { + return tasksTreeModel.getChild(parent, getPositionOfChild() + 1); + } + + public boolean childIsNotLast() { + return getPositionOfChild() < numberOfChildrenForParent() - 1; + } + + private int numberOfChildrenForParent() { + return tasksTreeModel.getChildCount(parent); + } + + private int getPositionOfChild() { + if ( positionOfChildCached != null ) { + return positionOfChildCached; + } + + int[] path = tasksTreeModel.getPath(parent, child); + + positionOfChildCached = path[path.length - 1]; + + return positionOfChildCached; + } + } + + private boolean hasChildren() { + return task.isContainer() && !task.getTasks().isEmpty(); + } + + private boolean isExpanded() { + return task.isContainer() && task.isExpanded(); + } + + private Task getParent(int[] path) { + Task current = tasksTreeModel.getRoot(); + + for (int i = 0; i < path.length - 1; i++) { + current = tasksTreeModel.getChild(current, path[i]); + } + + return current; + } + + } + + /** + * This class is a workaround for an issue with zk {@link Tree}. + * Once the tree is created, adding a node with children is troublesome. + * Only the top element is added to the tree, although the element has children. + * The Tree discards the adding event for the children because the parent says it's not loaded. + * + * This is the condition that is not satisfied: + *
+ * + * if( parent != null && (!(parent instanceof Treeitem) || ((Treeitem) parent).isLoaded()) ) { + * // ... + * } + * + *
+ * + * This problem is present in zk 3.6.1 at least. + * + * @author Óscar González Fernández + * @see Tree#onTreeDataChange + */ + private class DeferredFiller { + + private Set pendingToAddChildren = new HashSet<>(); + + private Method setLoadedMethod = null; + + public void addParentOfPendingToAdd(Task parent) { + pendingToAddChildren.add(parent); + } + + public void isBeingRendered(final Task parent, final Treeitem item) { + if ( !pendingToAddChildren.contains(parent) ) { + return; + } + + markLoaded(item); + fillModel(parent, 0, parent.getTasks(), false); + pendingToAddChildren.remove(parent); + } + + private void markLoaded(Treeitem item) { + try { + Method method = getSetLoadedMethod(); + method.invoke(item, true); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private Method getSetLoadedMethod() { + if ( setLoadedMethod != null ) { + return setLoadedMethod; + } + + try { + Method method = Treeitem.class.getDeclaredMethod("setLoaded", Boolean.TYPE); + method.setAccessible(true); + setLoadedMethod = method; + + return setLoadedMethod; + + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + private void fillModel(Collection tasks, boolean firstTime) { fillModel(this.tasksTreeModel.getRoot(), 0, tasks, firstTime); } - private void fillModel(Task parent, Integer insertionPosition, - Collection children, final boolean firstTime) { - if (predicate.isFilterContainers()) { + private void fillModel(Task parent, + Integer insertionPosition, + Collection children, + final boolean firstTime) { + + if ( predicate.isFilterContainers() ) { parent = this.tasksTreeModel.getRoot(); } - if (firstTime) { + if ( firstTime ) { + for (Task node : children) { - if (predicate.accpetsFilterPredicateAndContainers(node)) { - if (!visibleTasks.contains(node)) { + + if ( predicate.accpetsFilterPredicateAndContainers(node) ) { + + if ( !visibleTasks.contains(node) ) { this.tasksTreeModel.add(parent, node); visibleTasks.add(node); } + } else { - if (visibleTasks.contains(node)) { + + if ( visibleTasks.contains(node) ) { this.tasksTreeModel.remove(node); visibleTasks.remove(node); } } - if (node.isContainer()) { + if ( node.isContainer() ) { fillModel(node, 0, node.getTasks(), firstTime); } } } else { + for (Task node : children) { - if (node.isContainer()) { - if (predicate.accpetsFilterPredicateAndContainers(node)) { - if (!visibleTasks.contains(node)) { + + if ( node.isContainer() ) { + + if ( predicate.accpetsFilterPredicateAndContainers(node) ) { + + if ( !visibleTasks.contains(node) ) { this.deferredFiller.addParentOfPendingToAdd(node); } } } } - // the node must be added after, so the multistepTreeFiller is - // ready + + // The node must be added after, so the multistepTreeFiller is ready for (Task node : children) { - if (predicate.accpetsFilterPredicateAndContainers(node)) { - if (!visibleTasks.contains(node)) { - this.tasksTreeModel.add(parent, insertionPosition, - Arrays.asList(node)); + + if ( predicate.accpetsFilterPredicateAndContainers(node) ) { + + if ( !visibleTasks.contains(node) ) { + this.tasksTreeModel.add(parent, insertionPosition, Collections.singletonList(node)); visibleTasks.add(node); } + } else { if (visibleTasks.contains(node)) { this.tasksTreeModel.remove(node); @@ -411,7 +463,7 @@ public class LeftTasksTree extends HtmlMacroComponent { private void removeTaskAndAllChildren(List visibleTasks, Task task) { visibleTasks.remove(task); - if (task.isContainer()) { + if ( task.isContainer() ) { for (Task node : task.getTasks()) { removeTaskAndAllChildren(visibleTasks, node); } @@ -422,38 +474,25 @@ public class LeftTasksTree extends HtmlMacroComponent { tasksTreeModel.remove(taskRemoved); } - @Override - public void afterCompose() { - setClass("listdetails"); - super.afterCompose(); - tasksTree = (Tree) getFellow("tasksTree"); - tasksTreeModel = MutableTreeModel.create(Task.class); - fillModel(tasks, true); - tasksTree.setModel(tasksTreeModel); - tasksTree.setTreeitemRenderer(new TaskBeanRenderer()); - } - void addTask(Position position, Task task) { - if (position.isAppendToTop()) { - fillModel(Arrays.asList(task), false); + if ( position.isAppendToTop() ) { + fillModel(Collections.singletonList(task), false); detailsForBeans.requestFocusFor(task); } else { - List toAdd = Arrays.asList(task); - fillModel(position.getParent(), position.getInsertionPosition(), - toAdd, false); + List toAdd = Collections.singletonList(task); + fillModel(position.getParent(), position.getInsertionPosition(), toAdd, false); } } public void addTasks(Position position, Collection newTasks) { Task root = tasksTreeModel.getRoot(); - if (position.isAppendToTop()) { + + if ( position.isAppendToTop() ) { fillModel(root, tasksTreeModel.getChildCount(root), newTasks, false); - } else if (position.isAtTop()) { - fillModel(root, - position.getInsertionPosition(), newTasks, false); + } else if ( position.isAtTop() ) { + fillModel(root, position.getInsertionPosition(), newTasks, false); } else { - fillModel(position.getParent(), position.getInsertionPosition(), - newTasks, false); + fillModel(position.getParent(), position.getInsertionPosition(), newTasks, false); } } @@ -461,8 +500,7 @@ public class LeftTasksTree extends HtmlMacroComponent { return goingDownInLastArrowCommand; } - public void setGoingDownInLastArrowCommand( - CommandContextualized goingDownInLastArrowCommand) { + public void setGoingDownInLastArrowCommand(CommandContextualized goingDownInLastArrowCommand) { this.goingDownInLastArrowCommand = goingDownInLastArrowCommand; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTreeRow.java b/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTreeRow.java index ba6d9475e..cef49182f 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTreeRow.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/LeftTasksTreeRow.java @@ -39,16 +39,12 @@ import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.data.GanttDate; -import org.zkoss.ganttz.data.ITaskFundamentalProperties.IModifications; -import org.zkoss.ganttz.data.ITaskFundamentalProperties.IUpdatablePosition; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.util.Locales; import org.zkoss.zk.ui.Component; 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.event.KeyEvent; import org.zkoss.zk.ui.util.GenericForwardComposer; @@ -56,10 +52,10 @@ import org.zkoss.zul.Constraint; import org.zkoss.zul.Datebox; import org.zkoss.zul.Textbox; import org.zkoss.zul.Treecell; -import org.zkoss.zul.api.Div; -import org.zkoss.zul.api.Hlayout; -import org.zkoss.zul.api.Label; -import org.zkoss.zul.api.Treerow; +import org.zkoss.zul.Div; +import org.zkoss.zul.Hlayout; +import org.zkoss.zul.Label; +import org.zkoss.zul.Treerow; import static org.zkoss.ganttz.i18n.I18nHelper._; @@ -74,6 +70,7 @@ import static org.zkoss.ganttz.i18n.I18nHelper._; public class LeftTasksTreeRow extends GenericForwardComposer { public interface ILeftTasksTreeNavigator { + LeftTasksTreeRow getBelowRow(); LeftTasksTreeRow getAboveRow(); @@ -287,7 +284,11 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private enum Navigation { - LEFT, UP, RIGHT, DOWN; + LEFT, + UP, + RIGHT, + DOWN; + public static Navigation getIntentFrom(KeyEvent keyEvent) { return values()[keyEvent.getKeyCode() - 37]; } @@ -332,15 +333,15 @@ public class LeftTasksTreeRow extends GenericForwardComposer { int position = textBoxes.indexOf(textbox); switch (navigation) { case UP: - focusGoUp(position); - break; + focusGoUp(position); + break; case DOWN: - focusGoDown(position); - break; + focusGoDown(position); + break; default: - throw new RuntimeException("case not covered: " + navigation); + throw new RuntimeException("case not covered: " + navigation); } } @@ -394,7 +395,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private void findComponents(Treerow row) { - List rowChildren = row.getChildren(); + List rowChildren = row.getChildren(); List treeCells = ComponentsFinder.findComponentsOfType(Treecell.class, rowChildren); assert treeCells.size() == 4; @@ -405,7 +406,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private static Textbox findTextBoxOfCell(Treecell treecell) { - List children = treecell.getChildren(); + List children = treecell.getChildren(); return ComponentsFinder.findComponentsOfType(Textbox.class, children).get(0); } @@ -418,54 +419,26 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private void registerKeyboardListener(final Textbox textBox) { - textBox.addEventListener("onCtrlKey", new EventListener() { - - @Override - public void onEvent(Event event) { - userWantsToMove(textBox, (KeyEvent) event); - } - }); + textBox.addEventListener("onCtrlKey", event -> userWantsToMove(textBox, (KeyEvent) event)); } private void registerOnChange(final Component component) { - component.addEventListener("onChange", new EventListener() { - - @Override - public void onEvent(Event event) { - updateBean(component); - } - }); + component.addEventListener("onChange", event -> updateBean(component)); } private void registerOnChangeDatebox(final Datebox datebox, final Textbox textbox) { - datebox.addEventListener("onChange", new EventListener() { - - @Override - public void onEvent(Event event) { - textbox.setValue(dateFormat.format(datebox.getValue())); - updateBean(textbox); - } + datebox.addEventListener("onChange", event -> { + textbox.setValue(dateFormat.format(datebox.getValue())); + updateBean(textbox); }); } private void registerOnEnterListener(final Textbox textBox) { - textBox.addEventListener("onOK", new EventListener() { - - @Override - public void onEvent(Event event) { - userWantsDateBox(textBox); - } - }); + textBox.addEventListener("onOK", event -> userWantsDateBox(textBox)); } private void registerOnEnterOpenDateBox(final Datebox datebox) { - datebox.addEventListener("onOK", new EventListener() { - - @Override - public void onEvent(Event event) { - datebox.setOpen(true); - } - }); + datebox.addEventListener("onOK", event -> datebox.setOpen(true)); } private void findComponentsForStartDateCell(Treecell treecell) { @@ -485,7 +458,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private void findComponentsForStatusCell(Treecell treecell) { - List children = treecell.getChildren(); + List children = treecell.getChildren(); Hlayout hlayout = ComponentsFinder.findComponentsOfType(Hlayout.class, children).get(0); @@ -496,13 +469,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { } private void registerBlurListener(final Datebox datebox) { - datebox.addEventListener("onBlur", new EventListener() { - - @Override - public void onEvent(Event event) { - dateBoxHasLostFocus(datebox); - } - }); + datebox.addEventListener("onBlur", event -> dateBoxHasLostFocus(datebox)); } public void updateBean(Component updatedComponent) { @@ -518,13 +485,7 @@ public class LeftTasksTreeRow extends GenericForwardComposer { try { final Date begin = dateFormat.parse(getStartDateTextBox().getValue()); - task.doPositionModifications(new IModifications() { - - @Override - public void doIt(IUpdatablePosition position) { - position.moveTo(GanttDate.createFrom(begin)); - } - }); + task.doPositionModifications(position -> position.moveTo(GanttDate.createFrom(begin))); } catch (ParseException e) { // Do nothing as textbox is rested in the next sentence } @@ -562,12 +523,8 @@ public class LeftTasksTreeRow extends GenericForwardComposer { nameLabel.setTooltiptext(task.getName()); nameLabel.setSclass("clickable-rows"); - nameLabel.addEventListener(Events.ON_CLICK, new EventListener() { - @Override - public void onEvent(Event arg0) throws Exception { - Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode()); - } - }); + nameLabel.addEventListener(Events.ON_CLICK, + arg0 -> Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode())); startDateLabel.setValue(asString(task.getBeginDate().toDayRoundedDate())); endDateLabel.setValue(asString(task.getEndDate().toDayRoundedDate())); @@ -627,17 +584,17 @@ public class LeftTasksTreeRow extends GenericForwardComposer { switch (status) { case MARGIN_EXCEEDED: - cssClass = "status-red"; - break; + cssClass = "status-red"; + break; case WITHIN_MARGIN: - cssClass = "status-orange"; - break; + cssClass = "status-orange"; + break; case AS_PLANNED: default: - cssClass = "status-green"; + cssClass = "status-green"; } return cssClass; @@ -645,12 +602,9 @@ public class LeftTasksTreeRow extends GenericForwardComposer { private void onProjectStatusClick(Component statucComp) { if ( !disabilityConfiguration.isTreeEditable() ) { - statucComp.addEventListener(Events.ON_CLICK, new EventListener() { - @Override - public void onEvent(Event arg0) throws Exception { - Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode()); - } - }); + statucComp.addEventListener( + Events.ON_CLICK, + arg0 -> Executions.getCurrent().sendRedirect("/planner/index.zul;order=" + task.getProjectCode())); } } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java index 9f0a702a5..771cbe4f4 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/Planner.java @@ -23,16 +23,15 @@ package org.zkoss.ganttz; import static org.zkoss.ganttz.i18n.I18nHelper._; - +import java.util.ArrayList; +import java.util.Collections; +import java.util.Collection; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; -import java.util.List; -import java.util.Collection; -import java.util.Collections; -import java.util.ArrayList; import org.apache.commons.logging.Log; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; @@ -56,7 +55,6 @@ import org.zkoss.ganttz.util.LongOperationFeedback; import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation; import org.zkoss.ganttz.util.ProfilingLogFactory; import org.zkoss.ganttz.util.WeakReferencedListeners; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.au.AuRequest; import org.zkoss.zk.au.AuService; import org.zkoss.zk.mesg.MZk; @@ -64,8 +62,6 @@ 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.zul.Button; @@ -74,57 +70,17 @@ import org.zkoss.zul.Listbox; import org.zkoss.zul.Listitem; import org.zkoss.zul.SimpleListModel; import org.zkoss.zul.South; -import org.zkoss.zul.api.Combobox; +import org.zkoss.zul.Combobox; public class Planner extends HtmlMacroComponent { private static final Log PROFILING_LOG = ProfilingLogFactory.getLog(Planner.class); - public static boolean guessContainersExpandedByDefaultGivenPrintParameters(Map printParameters) { - return guessContainersExpandedByDefault(convertToURLParameters(printParameters)); - } + private static int PIXELS_PER_TASK_LEVEL = 21; - private static Map convertToURLParameters(Map printParameters) { - Map result = new HashMap<>(); - for (Entry each : printParameters.entrySet()) { - result.put(each.getKey(), new String[] { each.getValue() }); - } + private static int PIXELS_PER_CHARACTER = 5; - return result; - } - - public static boolean guessContainersExpandedByDefault(Map queryURLParameters) { - String[] values = queryURLParameters.get("expanded"); - - return values != null && toLowercaseSet(values).contains("all"); - } - - public static boolean guessShowAdvancesByDefault(Map queryURLParameters) { - String[] values = queryURLParameters.get("advances"); - - return values != null && toLowercaseSet(values).contains("all"); - } - - public static boolean guessShowReportedHoursByDefault(Map queryURLParameters) { - String[] values = queryURLParameters.get("reportedHours"); - - return values != null && toLowercaseSet(values).contains("all"); - } - - public static boolean guessShowMoneyCostBarByDefault(Map queryURLParameters) { - String[] values = queryURLParameters.get("moneyCostBar"); - - return values != null && toLowercaseSet(values).contains("all"); - } - - private static Set toLowercaseSet(String[] values) { - Set result = new HashSet<>(); - for (String each : values) { - result.add(each.toLowerCase()); - } - - return result; - } + private String EXPAND_ALL_BUTTON = "expandAll"; private GanttZKDiagramGraph diagramGraph; @@ -134,6 +90,8 @@ public class Planner extends HtmlMacroComponent { private List> contextualizedGlobalCommands; + private CommandContextualized goingDownInLastArrowCommand; + private List> commandsOnTasksContextualized; private CommandOnTaskContextualized doubleClickCommand; @@ -165,16 +123,102 @@ public class Planner extends HtmlMacroComponent { private WeakReferencedListeners chartVisibilityListeners = WeakReferencedListeners.create(); - public Planner() { + private IGraphChangeListener showCriticalPathOnChange = new IGraphChangeListener() { + @Override + public void execute() { + context.showCriticalPath(); + } + }; + + private IGraphChangeListener showAdvanceOnChange = new IGraphChangeListener() { + @Override + public void execute() { + context.showAdvances(); + } + }; + + private IGraphChangeListener showReportedHoursOnChange = new IGraphChangeListener() { + @Override + public void execute() { + context.showReportedHours(); + } + }; + + private IGraphChangeListener showMoneyCostBarOnChange = new IGraphChangeListener() { + @Override + public void execute() { + context.showMoneyCostBar(); + } + }; + + private boolean containersExpandedByDefault = false; + + private boolean shownAdvanceByDefault = false; + + private boolean shownReportedHoursByDefault = false; + + private boolean shownMoneyCostBarByDefault = false; + + private FilterAndParentExpandedPredicates predicate; + + private boolean visibleChart; + + public Planner() {} + + public static boolean guessContainersExpandedByDefaultGivenPrintParameters(Map printParameters) { + return guessContainersExpandedByDefault(convertToURLParameters(printParameters)); + } + + private static Map convertToURLParameters(Map printParameters) { + Map result = new HashMap<>(); + for (Entry each : printParameters.entrySet()) { + result.put(each.getKey(), new String[] { each.getValue() }); + } + + return result; + } + + public static boolean guessContainersExpandedByDefault(Map queryURLParameters) { + String[] values = queryURLParameters.get("expanded"); + + return values != null && toLowercaseSet(values).contains("all"); + + } + + public static boolean guessShowAdvancesByDefault(Map queryURLParameters) { + String[] values = queryURLParameters.get("advances"); + + return values != null && toLowercaseSet(values).contains("all"); + + } + + public static boolean guessShowReportedHoursByDefault(Map queryURLParameters) { + String[] values = queryURLParameters.get("reportedHours"); + + return values != null && toLowercaseSet(values).contains("all"); + + } + + public static boolean guessShowMoneyCostBarByDefault(Map queryURLParameters) { + String[] values = queryURLParameters.get("moneyCostBar"); + + return values != null && toLowercaseSet(values).contains("all"); + + } + + private static Set toLowercaseSet(String[] values) { + Set result = new HashSet<>(); + for (String each : values) { + result.add(each.toLowerCase()); + } + + return result; } TaskList getTaskList() { - if ( ganttPanel == null ) { - return null; - } - List children = ganttPanel.getChildren(); - - return ComponentsFinder.findComponentsOfType(TaskList.class, children).get(0); + return ganttPanel == null + ? null + : ComponentsFinder.findComponentsOfType(TaskList.class, ganttPanel.getChildren()).get(0); } public int getTaskNumber() { @@ -186,20 +230,19 @@ public class Planner extends HtmlMacroComponent { } private int calculateMinimumWidthForTaskNameColumn(boolean expand, List tasks) { + IDomainAndBeansMapper mapper = getContext().getMapper(); int widest = 0; - for(Task task : tasks) { + for (Task task : tasks) { int numberOfAncestors = mapper.findPositionFor(task).getAncestors().size(); int numberOfCharacters = task.getName().length(); - int PIXELS_PER_TASK_LEVEL = 21; - int PIXELS_PER_CHARACTER = 5; widest = Math.max( widest, numberOfCharacters * PIXELS_PER_CHARACTER + numberOfAncestors * PIXELS_PER_TASK_LEVEL); - if( expand && !task.isLeaf() ) { + if ( expand && !task.isLeaf() ) { widest = Math.max(widest, calculateMinimumWidthForTaskNameColumn(expand, task.getTasks())); } } @@ -220,7 +263,7 @@ public class Planner extends HtmlMacroComponent { return null; } - List children = ganttPanel.getChildren(); + List children = ganttPanel.getChildren(); List found = ComponentsFinder.findComponentsOfType(DependencyList.class, children); if ( found.isEmpty() ) { @@ -232,6 +275,7 @@ public class Planner extends HtmlMacroComponent { public void addTasks(Position position, Collection newTasks) { TaskList taskList = getTaskList(); + if ( taskList != null && leftPane != null ) { taskList.addTasks(position, newTasks); leftPane.addTasks(position, newTasks); @@ -244,6 +288,7 @@ public class Planner extends HtmlMacroComponent { void addDependencies(Collection dependencies) { DependencyList dependencyList = getDependencyList(); + if ( dependencyList == null ) { return; } @@ -253,21 +298,23 @@ public class Planner extends HtmlMacroComponent { } } - public ListModel getZoomLevels() { + public ListModel getZoomLevels() { ZoomLevel[] selectableZoomlevels = { ZoomLevel.DETAIL_ONE, ZoomLevel.DETAIL_TWO, ZoomLevel.DETAIL_THREE, ZoomLevel.DETAIL_FOUR, - ZoomLevel.DETAIL_FIVE }; + ZoomLevel.DETAIL_FIVE + }; - return new SimpleListModel(selectableZoomlevels); + return new SimpleListModel<>(selectableZoomlevels); } public void setZoomLevel(final ZoomLevel zoomLevel, int scrollLeft) { if ( ganttPanel == null ) { return; } + this.zoomLevel = zoomLevel; ganttPanel.setZoomLevel(zoomLevel, scrollLeft); } @@ -294,6 +341,7 @@ public class Planner extends HtmlMacroComponent { if ( ganttPanel == null ) { return; } + LongOperationFeedback.execute(ganttPanel, new ILongOperation() { @Override public String getName() { @@ -328,18 +376,22 @@ public class Planner extends HtmlMacroComponent { new FunctionalityExposedForExtensions<>(this, configuration, diagramGraph); addGraphChangeListenersFromConfiguration(configuration); + this.contextualizedGlobalCommands = contextualize(newContext, configuration.getGlobalCommands()); + this.commandsOnTasksContextualized = contextualize(newContext, configuration.getCommandsOnTasks()); - CommandContextualized goingDownInLastArrowCommand = - contextualize(newContext, configuration.getGoingDownInLastArrowCommand()); + goingDownInLastArrowCommand = contextualize(newContext, configuration.getGoingDownInLastArrowCommand()); doubleClickCommand = contextualize(newContext, configuration.getDoubleClickCommand()); + this.context = newContext; this.disabilityConfiguration = configuration; + resettingPreviousComponentsToNull(); long timeAddingData = System.currentTimeMillis(); newContext.add(configuration.getData()); + PROFILING_LOG.debug("It took to add data: " + (System.currentTimeMillis() - timeAddingData) + " ms"); long timeSetupingAndAddingComponents = System.currentTimeMillis(); setupComponents(); @@ -356,6 +408,7 @@ public class Planner extends HtmlMacroComponent { timetrackerheader.afterCompose(); Component chartComponent = configuration.getChartComponent(); + if ( chartComponent != null ) { setAt("insertionPointChart", chartComponent); } @@ -366,11 +419,11 @@ public class Planner extends HtmlMacroComponent { } if ( !configuration.isExpandAllEnabled() ) { - Button expandAllButton = (Button) getFellow("expandAll"); + Button expandAllButton = (Button) getFellow(EXPAND_ALL_BUTTON); expandAllButton.setVisible(false); } - if ( !configuration.isFlattenTreeEnabled() ) { + if (!configuration.isFlattenTreeEnabled()) { Button flattenTree = (Button) getFellow("flattenTree"); flattenTree.setVisible(false); } @@ -390,22 +443,26 @@ public class Planner extends HtmlMacroComponent { this.visibleChart = configuration.isExpandPlanningViewCharts(); ((South) getFellow("graphics")).setOpen(this.visibleChart); - PROFILING_LOG.debug( - "It took doing the setup of components and adding them: " + - (System.currentTimeMillis() - timeSetupingAndAddingComponents) + " ms"); + if (!visibleChart) { + ((South) getFellow("graphics")).setTitle(_("Graphics are disabled")); + } - setAuService(new AuService(){ + PROFILING_LOG.debug("it took doing the setup of components and adding them: " + + (System.currentTimeMillis() - timeSetupingAndAddingComponents) + " ms"); + + setAuService(new AuService() { public boolean service(AuRequest request, boolean everError){ String command = request.getCommand(); int zoomindex; int scrollLeft; - if ( command.equals("onZoomLevelChange") ){ + if ( "onZoomLevelChange".equals(command) ) { zoomindex= (Integer) retrieveData(request, "zoomindex"); scrollLeft = (Integer) retrieveData(request, "scrollLeft"); - setZoomLevel((ZoomLevel)((Listbox)getFellow("listZoomLevels")) - .getModel().getElementAt(zoomindex), scrollLeft); + setZoomLevel( + (ZoomLevel)((Listbox) getFellow("listZoomLevels")).getModel().getElementAt(zoomindex), + scrollLeft); return true; } @@ -413,7 +470,7 @@ public class Planner extends HtmlMacroComponent { return false; } - private Object retrieveData(AuRequest request, String key){ + 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 }); @@ -434,9 +491,8 @@ public class Planner extends HtmlMacroComponent { insertionPoint.appendChild(component); } - private List> contextualize( - FunctionalityExposedForExtensions context, List> commands) { - + private List> contextualize(FunctionalityExposedForExtensions context, + List> commands) { List> result = new ArrayList<>(); for (ICommandOnTask c : commands) { result.add(contextualize(context, c)); @@ -445,18 +501,14 @@ public class Planner extends HtmlMacroComponent { return result; } - private CommandOnTaskContextualized contextualize( - FunctionalityExposedForExtensions context, ICommandOnTask commandOnTask) { + private CommandOnTaskContextualized contextualize(FunctionalityExposedForExtensions context, + ICommandOnTask commandOnTask) { return CommandOnTaskContextualized.create(commandOnTask, context.getMapper(), context); } private CommandContextualized contextualize(IContext context, ICommand command) { - if (command == null) { - return null; - } - - return CommandContextualized.create(command, context); + return command == null ? null : CommandContextualized.create(command, context); } private List> contextualize( @@ -510,6 +562,7 @@ public class Planner extends HtmlMacroComponent { // Comparison through icon as name is internationalized if ( c.getCommand().isPlannerCommand() ) { + // FIXME Avoid hard-coding the number of planner commands // At this moment we have 2 planner commands: reassign and adapt planning if ( plannerToolbar.getChildren().size() < 2 ) { @@ -535,10 +588,7 @@ public class Planner extends HtmlMacroComponent { taskList.remove(task); getDependencyList().taskRemoved(task); leftPane.taskRemoved(task); - - // forcing smart update - setHeight(getHeight()); - + setHeight(getHeight());// forcing smart update ganttPanel.adjustZoomColumnsHeight(); getDependencyList().redrawDependencies(); } @@ -549,14 +599,10 @@ public class Planner extends HtmlMacroComponent { listZoomLevels = (Listbox) getFellow("listZoomLevels"); Component westContainer = getFellow("taskdetailsContainer"); - westContainer.addEventListener(Events.ON_SIZE, new EventListener() { - @Override - public void onEvent(Event event) { - Clients.evalJavaScript("ganttz.TaskList.getInstance().legendResize();"); - } - - }); + westContainer.addEventListener( + Events.ON_SIZE, + event -> Clients.evalJavaScript("ganttz.TaskList.getInstance().legendResize();")); } @@ -564,60 +610,14 @@ public class Planner extends HtmlMacroComponent { return ganttPanel.getTimeTracker(); } - private IGraphChangeListener showCriticalPathOnChange = new IGraphChangeListener() { - - @Override - public void execute() { - context.showCriticalPath(); - } - }; - - private IGraphChangeListener showAdvanceOnChange = new IGraphChangeListener() { - - @Override - public void execute() { - context.showAdvances(); - } - }; - - private IGraphChangeListener showReportedHoursOnChange = new IGraphChangeListener() { - - @Override - public void execute() { - context.showReportedHours(); - } - }; - - private IGraphChangeListener showMoneyCostBarOnChange = new IGraphChangeListener() { - - @Override - public void execute() { - context.showMoneyCostBar(); - } - }; - - private boolean containersExpandedByDefault = false; - - private boolean shownAdvanceByDefault = false; - - private boolean shownReportedHoursByDefault = false; - - private boolean shownMoneyCostBarByDefault = false; - - private FilterAndParentExpandedPredicates predicate; - - private boolean visibleChart; - public void showCriticalPath() { Button showCriticalPathButton = (Button) getFellow("showCriticalPath"); - if ( disabilityConfiguration.isCriticalPathEnabled() ) { if ( isShowingCriticalPath ) { context.hideCriticalPath(); diagramGraph.removePostGraphChangeListener(showCriticalPathOnChange); showCriticalPathButton.setSclass("planner-command"); showCriticalPathButton.setTooltiptext(_("Show critical path")); - } else { context.showCriticalPath(); diagramGraph.addPostGraphChangeListener(showCriticalPathOnChange); @@ -638,10 +638,9 @@ public class Planner extends HtmlMacroComponent { public void showAdvances() { Button showAdvancesButton = (Button) getFellow("showAdvances"); if ( disabilityConfiguration.isAdvancesEnabled() ) { - Combobox progressTypesCombo = (Combobox) getFellow("cbProgressTypes"); - if ( isShowingAdvances ) { + if ( isShowingAdvances ) { context.hideAdvances(); diagramGraph.removePostGraphChangeListener(showAdvanceOnChange); showAdvancesButton.setSclass("planner-command"); @@ -650,40 +649,39 @@ public class Planner extends HtmlMacroComponent { if ( progressTypesCombo.getItemCount() > 0 ) { progressTypesCombo.setSelectedIndex(0); } - } else { context.showAdvances(); diagramGraph.addPostGraphChangeListener(showAdvanceOnChange); showAdvancesButton.setSclass("planner-command clicked"); showAdvancesButton.setTooltiptext(_("Hide progress")); } + isShowingAdvances = !isShowingAdvances; } } public void showReportedHours() { Button showReportedHoursButton = (Button) getFellow("showReportedHours"); - if ( disabilityConfiguration.isReportedHoursEnabled() ) { + if ( isShowingReportedHours ) { context.hideReportedHours(); diagramGraph.removePostGraphChangeListener(showReportedHoursOnChange); showReportedHoursButton.setSclass("planner-command"); showReportedHoursButton.setTooltiptext(_("Show reported hours")); - } else { context.showReportedHours(); diagramGraph.addPostGraphChangeListener(showReportedHoursOnChange); showReportedHoursButton.setSclass("planner-command clicked"); showReportedHoursButton.setTooltiptext(_("Hide reported hours")); } + isShowingReportedHours = !isShowingReportedHours; } } public void showMoneyCostBar() { Button showMoneyCostBarButton = (Button) getFellow("showMoneyCostBar"); - if ( disabilityConfiguration.isMoneyCostBarEnabled() ) { if ( isShowingMoneyCostBar ) { context.hideMoneyCostBar(); @@ -696,6 +694,7 @@ public class Planner extends HtmlMacroComponent { showMoneyCostBarButton.setSclass("planner-command clicked"); showMoneyCostBarButton.setTooltiptext(_("Hide money cost bar")); } + isShowingMoneyCostBar = !isShowingMoneyCostBar; } } @@ -709,6 +708,7 @@ public class Planner extends HtmlMacroComponent { Clients.evalJavaScript("ganttz.TaskList.getInstance().showAllTaskLabels()"); showAllLabelsButton.setSclass("planner-command show-labels clicked"); } + isShowingLabels = !isShowingLabels; } @@ -721,6 +721,7 @@ public class Planner extends HtmlMacroComponent { Clients.evalJavaScript("ganttz.TaskList.getInstance().showResourceTooltips()"); showAllLabelsButton.setSclass("planner-command show-resources clicked"); } + isShowingResources = !isShowingResources; } @@ -731,11 +732,9 @@ public class Planner extends HtmlMacroComponent { } public ZoomLevel getZoomLevel() { - if ( ganttPanel == null ) { - return zoomLevel != null ? zoomLevel : ZoomLevel.DETAIL_ONE; - } - - return ganttPanel.getTimeTracker().getDetailLevel(); + return ganttPanel == null + ? zoomLevel != null ? zoomLevel : ZoomLevel.DETAIL_ONE + : ganttPanel.getTimeTracker().getDetailLevel(); } public void setInitialZoomLevel(final ZoomLevel zoomLevel) { @@ -755,7 +754,7 @@ public class Planner extends HtmlMacroComponent { } public boolean showAdvancesRightNow() { - return (areShownAdvancesByDefault() || isShowingAdvances); + return areShownAdvancesByDefault() || isShowingAdvances; } public void setAreShownAdvancesByDefault(boolean shownAdvanceByDefault) { @@ -772,7 +771,7 @@ public class Planner extends HtmlMacroComponent { } public boolean showReportedHoursRightNow() { - return (areShownReportedHoursByDefault() || isShowingReportedHours); + return areShownReportedHoursByDefault() || isShowingReportedHours; } public void setAreShownMoneyCostBarByDefault(boolean shownMoneyCostBarByDefault) { @@ -784,13 +783,13 @@ public class Planner extends HtmlMacroComponent { } public boolean showMoneyCostBarRightNow() { - return (areShownMoneyCostBarByDefault() || isShowingMoneyCostBar); + return areShownMoneyCostBarByDefault() || isShowingMoneyCostBar; } public void expandAll() { - Button expandAllButton = (Button) getFellow("expandAll"); - + Button expandAllButton = (Button) getFellow(EXPAND_ALL_BUTTON); if ( disabilityConfiguration.isExpandAllEnabled() ) { + if ( isExpandAll ) { context.collapseAll(); expandAllButton.setSclass("planner-command"); @@ -799,25 +798,26 @@ public class Planner extends HtmlMacroComponent { expandAllButton.setSclass("planner-command clicked"); } } + isExpandAll = !isExpandAll; } public void expandAllAlways() { - Button expandAllButton = (Button) getFellow("expandAll"); + Button expandAllButton = (Button) getFellow(EXPAND_ALL_BUTTON); if ( disabilityConfiguration.isExpandAllEnabled() ) { - context.expandAll(); - expandAllButton.setSclass("planner-command clicked"); + context.expandAll(); + expandAllButton.setSclass("planner-command clicked"); } } public void updateSelectedZoomLevel() { ganttPanel.getTimeTracker().setZoomLevel(zoomLevel); - Listitem selectedItem = (Listitem) listZoomLevels.getItems().get(zoomLevel.ordinal()); + Listitem selectedItem = listZoomLevels.getItems().get(zoomLevel.ordinal()); listZoomLevels.setSelectedItem(selectedItem); listZoomLevels.invalidate(); } - public IContext getContext() { + public IContext getContext() { return context; } @@ -838,17 +838,18 @@ public class Planner extends HtmlMacroComponent { public void flattenTree() { Button flattenTreeButton = (Button) getFellow("flattenTree"); - if ( disabilityConfiguration.isFlattenTreeEnabled() ) { - if ( isFlattenTree ) { + if (isFlattenTree) { predicate.setFilterContainers(false); flattenTreeButton.setSclass("planner-command"); } else { predicate.setFilterContainers(true); flattenTreeButton.setSclass("planner-command clicked"); } + setTaskListPredicate(predicate); } + isFlattenTree = !isFlattenTree; Clients.evalJavaScript("ganttz.Planner.getInstance().adjustScrollableDimensions()"); } @@ -859,12 +860,7 @@ public class Planner extends HtmlMacroComponent { public void changeChartVisibility(boolean visible) { visibleChart = visible; - chartVisibilityListeners.fireEvent(new IListenerNotification() { - @Override - public void doNotify(IChartVisibilityChangedListener listener) { - listener.chartVisibilityChanged(visibleChart); - } - }); + chartVisibilityListeners.fireEvent(listener -> listener.chartVisibilityChanged(visibleChart)); } public boolean isVisibleChart() { @@ -914,8 +910,9 @@ public class Planner extends HtmlMacroComponent { return null; } + @Override public String getWidgetClass(){ - return getDefinition().getDefaultWidgetClass(); + return getDefinition().getDefaultWidgetClass(this); } public List getCriticalPath() { @@ -926,17 +923,19 @@ public class Planner extends HtmlMacroComponent { TaskList taskList = getTaskList(); if ( taskList != null ) { taskList.updateCompletion(progressType); - // FIXME Bug #1270 + for (TaskComponent each : taskList.getTaskComponents()) { each.invalidate(); } } } - public TaskComponent getTaskComponentRelatedTo(org.zkoss.ganttz.data.Task task) { + public TaskComponent getTaskComponentRelatedTo(Task task) { TaskList taskList = getTaskList(); if ( taskList != null ) { + for (TaskComponent each : taskList.getTaskComponents()) { + if ( each.getTask().equals(task) ) { return each; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java b/ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java index e9b98b2ef..1c1699a22 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TabsRegistry.java @@ -29,16 +29,14 @@ import java.util.Map; import org.zkoss.ganttz.extensions.ITab; import org.zkoss.ganttz.util.IMenuItemsRegister; import org.zkoss.zk.ui.Component; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; public class TabsRegistry { - private List tabs = new ArrayList(); + private List tabs = new ArrayList<>(); private final Component parent; - private Map fromTabToMenuKey = new HashMap(); + private Map fromTabToMenuKey = new HashMap<>(); private IMenuItemsRegister menu; @@ -52,14 +50,10 @@ public class TabsRegistry { } public interface IBeforeShowAction { - public void doAction(); + void doAction(); } - private static final IBeforeShowAction DO_NOTHING = new IBeforeShowAction() { - @Override - public void doAction() { - } - }; + private static final IBeforeShowAction DO_NOTHING = () -> {}; public void show(ITab tab) { show(tab, DO_NOTHING); @@ -101,23 +95,10 @@ public class TabsRegistry { } } - public void showFirst() { - if (!tabs.isEmpty()) { - show(tabs.get(0)); - } - } - public void registerAtMenu(IMenuItemsRegister menu) { this.menu = menu; for (final ITab t : tabs) { - Object key = menu.addMenuItem(t.getName(), t.getCssClass(), - new EventListener() { - - @Override - public void onEvent(Event event) { - show(t); - } - }); + Object key = menu.addMenuItem(t.getName(), t.getCssClass(), event -> show(t)); fromTabToMenuKey.put(t, key); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java index 07cab2efd..9a721613b 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TaskComponent.java @@ -21,6 +21,7 @@ package org.zkoss.ganttz; +import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import java.util.Date; @@ -34,6 +35,8 @@ import org.joda.time.Duration; import org.joda.time.LocalDate; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.data.GanttDate; +import org.zkoss.ganttz.data.ITaskFundamentalProperties.IModifications; +import org.zkoss.ganttz.data.ITaskFundamentalProperties.IUpdatablePosition; import org.zkoss.ganttz.data.Milestone; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.data.Task.IReloadResourcesTextRequested; @@ -62,9 +65,12 @@ import org.zkoss.zul.Div; public class TaskComponent extends Div implements AfterCompose { private static final int HEIGHT_PER_TASK = 10; + private static final int CONSOLIDATED_MARK_HALF_WIDTH = 3; + private static final int HALF_DEADLINE_MARK = 3; + private String FUNCTION_RESIZE = "resizeCompletion2Advance"; protected final IDisabilityConfiguration disabilityConfiguration; @@ -76,6 +82,18 @@ public class TaskComponent extends Div implements AfterCompose { private PropertyChangeListener showingMoneyCostBarPropertyListener; + private IReloadResourcesTextRequested reloadResourcesTextRequested; + + private String _color; + + private boolean isTopLevel; + + private final Task task; + + private transient PropertyChangeListener propertiesListener; + + private String progressType; + public static TaskComponent asTaskComponent(Task task, IDisabilityConfiguration disabilityConfiguration, boolean isTopLevel) { @@ -99,8 +117,6 @@ public class TaskComponent extends Div implements AfterCompose { return asTaskComponent(task, disabilityConfiguration, true); } - private IReloadResourcesTextRequested reloadResourcesTextRequested; - public TaskComponent(Task task, IDisabilityConfiguration disabilityConfiguration) { setHeight(HEIGHT_PER_TASK + "px"); setContext("idContextMenuTaskAssignment"); @@ -108,9 +124,7 @@ public class TaskComponent extends Div implements AfterCompose { setClass(calculateCSSClass()); setId(UUID.randomUUID().toString()); this.disabilityConfiguration = disabilityConfiguration; - - IConstraintViolationListener taskViolationListener = - Constraint.onlyOnZKExecution(new IConstraintViolationListener() { + IConstraintViolationListener taskViolationListener = Constraint.onlyOnZKExecution(new IConstraintViolationListener() { @Override public void constraintViolated(Constraint constraint, GanttDate value) { @@ -124,32 +138,38 @@ public class TaskComponent extends Div implements AfterCompose { }); this.task.addConstraintViolationListener(taskViolationListener, Mode.RECEIVE_PENDING); - reloadResourcesTextRequested = () -> { - if ( canShowResourcesText() ) { - smartUpdate("resourcesText", getResourcesText()); + + reloadResourcesTextRequested = new IReloadResourcesTextRequested() { + @Override + public void reloadResourcesTextRequested() { + if ( canShowResourcesText() ) { + smartUpdate("resourcesText", getResourcesText()); + } + + String cssClass = calculateCSSClass(); + + response("setClass", new AuInvoke(TaskComponent.this, "setClass", cssClass)); + + // FIXME: Refactor to another listener + updateDeadline(); + invalidate(); } - String cssClass = calculateCSSClass(); - - response("setClass", new AuInvoke(TaskComponent.this, "setClass", cssClass)); - - // FIXME: Refactor to another listener - updateDeadline(); - invalidate(); }; this.task.addReloadListener(reloadResourcesTextRequested); - setAuService(new AuService(){ + setAuService(new AuService() { - public boolean service(AuRequest request, boolean everError){ + 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"))); + ta.doUpdatePosition(toInteger(retrieveData(request, "left")) + ); Events.postEvent(new Event(getId(), ta, request.getData())); @@ -181,7 +201,7 @@ public class TaskComponent extends Div implements AfterCompose { return ((Number) valueFromRequestData).intValue(); } - private TaskComponent retrieveTaskComponent(AuRequest request){ + private TaskComponent retrieveTaskComponent(AuRequest request) { final TaskComponent ta = (TaskComponent) request.getComponent(); if ( ta == null ) { @@ -191,7 +211,7 @@ public class TaskComponent extends Div implements AfterCompose { return ta; } - private Object retrieveData(AuRequest request, String key){ + 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 }); @@ -240,15 +260,25 @@ public class TaskComponent extends Div implements AfterCompose { public final void afterCompose() { updateProperties(); if ( propertiesListener == null ) { - propertiesListener = evt -> updateProperties(); + + propertiesListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + updateProperties(); + } + }; } this.task.addFundamentalPropertiesChangeListener(propertiesListener); if ( showingAdvancePropertyListener == null ) { - showingAdvancePropertyListener = evt -> { - if ( isInPage() && !(task instanceof Milestone) ) { - updateCompletionAdvance(); + + showingAdvancePropertyListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ( isInPage() && !(task instanceof Milestone) ) { + updateCompletionAdvance(); + } } }; } @@ -256,9 +286,13 @@ public class TaskComponent extends Div implements AfterCompose { this.task.addAdvancesPropertyChangeListener(showingAdvancePropertyListener); if ( showingReportedHoursPropertyListener == null ) { - showingReportedHoursPropertyListener = evt -> { - if ( isInPage() && !(task instanceof Milestone) ) { - updateCompletionReportedHours(); + + showingReportedHoursPropertyListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ( isInPage() && !(task instanceof Milestone) ) { + updateCompletionReportedHours(); + } } }; } @@ -266,9 +300,13 @@ public class TaskComponent extends Div implements AfterCompose { this.task.addReportedHoursPropertyChangeListener(showingReportedHoursPropertyListener); if ( showingMoneyCostBarPropertyListener == null ) { - showingMoneyCostBarPropertyListener = evt -> { - if ( isInPage() && !(task instanceof Milestone) ) { - updateCompletionMoneyCostBar(); + + showingMoneyCostBarPropertyListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if ( isInPage() && !(task instanceof Milestone) ) { + updateCompletionMoneyCostBar(); + } } }; } @@ -276,7 +314,14 @@ public class TaskComponent extends Div implements AfterCompose { this.task.addMoneyCostBarPropertyChangeListener(showingMoneyCostBarPropertyListener); if ( criticalPathPropertyListener == null ) { - criticalPathPropertyListener = evt -> updateClass(); + + criticalPathPropertyListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + updateClass(); + } + + }; } this.task.addCriticalPathPropertyChangeListener(criticalPathPropertyListener); @@ -291,15 +336,6 @@ public class TaskComponent extends Div implements AfterCompose { return true; } - private String _color; - - private boolean isTopLevel; - - private final Task task; - private transient PropertyChangeListener propertiesListener; - - private String progressType; - public TaskRow getRow() { if ( getParent() == null ) { throw new IllegalStateException( @@ -337,9 +373,16 @@ public class TaskComponent extends Div implements AfterCompose { void doUpdatePosition(int leftX) { GanttDate startBeforeMoving = this.task.getBeginDate(); final LocalDate newPosition = getMapper().toDate(leftX); - this.task.doPositionModifications(position -> position.moveTo(GanttDate.createFrom(newPosition))); + + this.task.doPositionModifications(new IModifications() { + @Override + public void doIt(IUpdatablePosition position) { + position.moveTo(GanttDate.createFrom(newPosition)); + } + }); boolean remainsInOriginalPosition = this.task.getBeginDate().equals(startBeforeMoving); + if ( remainsInOriginalPosition ) { updateProperties(); } @@ -372,20 +415,18 @@ public class TaskComponent extends Div implements AfterCompose { } } - /* - * We override the method of renderProperties to put the color property as part - * of the style - */ + /* 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()); setWidgetAttribute("movingTasksEnabled", ((Boolean)isMovingTasksEnabled()).toString()); setWidgetAttribute("resizingTasksEnabled", ((Boolean)isResizingTasksEnabled()).toString()); - /* We can't use setStyle because of restrictions - * involved with UiVisualizer#getResponses and the - * smartUpdate method (when the request is asynchronous) */ + /* 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"); render(renderer, "_labelsText", getLabelsText()); @@ -395,10 +436,7 @@ public class TaskComponent extends Div implements AfterCompose { super.renderProperties(renderer); } - /* - * We send a response to the client to create the arrow we are going to use - * to create the dependency - */ + /* We send a response to the client to create the arrow we are going to use to create the dependency */ public void addDependency() { response("depkey", new AuInvoke(this, "addDependency")); @@ -540,9 +578,9 @@ public class TaskComponent extends Div implements AfterCompose { if ( task.isShowingAdvances() ) { int startPixels = this.task.getBeginDate().toPixels(getMapper()); String widthAdvancePercentage = pixelsFromStartUntil(startPixels, this.task.getAdvanceBarEndDate()) + "px"; - response(null, new AuInvoke(this, "resizeCompletion2Advance", widthAdvancePercentage)); + response(null, new AuInvoke(this, FUNCTION_RESIZE, widthAdvancePercentage)); } else { - response(null, new AuInvoke(this, "resizeCompletion2Advance", "0px")); + response(null, new AuInvoke(this, FUNCTION_RESIZE, "0px")); } } @@ -553,9 +591,9 @@ public class TaskComponent extends Div implements AfterCompose { String widthAdvancePercentage = pixelsFromStartUntil(startPixels, this.task.getAdvanceBarEndDate(progressType)) + "px"; - response(null, new AuInvoke(this, "resizeCompletion2Advance", widthAdvancePercentage)); + response(null, new AuInvoke(this, FUNCTION_RESIZE, widthAdvancePercentage)); } else { - response(null, new AuInvoke(this, "resizeCompletion2Advance", "0px")); + response(null, new AuInvoke(this, FUNCTION_RESIZE, "0px")); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TaskEditFormComposer.java b/ganttzk/src/main/java/org/zkoss/ganttz/TaskEditFormComposer.java index 6e74d1f86..a63c1f24f 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TaskEditFormComposer.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TaskEditFormComposer.java @@ -33,11 +33,7 @@ import org.zkoss.zk.ui.util.GenericForwardComposer; import org.zkoss.zul.Datebox; import org.zkoss.zul.Textbox; -public class TaskEditFormComposer extends GenericForwardComposer { - - public TaskEditFormComposer() { - - } +public class TaskEditFormComposer extends GenericForwardComposer { private Task currentTask; @@ -53,19 +49,22 @@ public class TaskEditFormComposer extends GenericForwardComposer { private Textbox notes; + public TaskEditFormComposer() { + + } + @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); } - public void init(Component openRelativeTo, Task task) { + public void init(Task task) { this.currentTask = task; this.taskDTO = toDTO(task); updateComponentValuesForTask(taskDTO); } - private void updateComponentValuesForTask( - TaskDTO taskDTO) { + private void updateComponentValuesForTask(TaskDTO taskDTO) { name.setValue(taskDTO.name); startDateBox.setValue(taskDTO.beginDate); endDateBox.setValue(taskDTO.endDate); @@ -96,10 +95,15 @@ public class TaskEditFormComposer extends GenericForwardComposer { * @author Manuel Rego Casasnovas */ public static class TaskDTO { + public String name; + public Date beginDate; + public Date endDate; + public Date deadlineDate; + public String notes; } @@ -122,18 +126,12 @@ public class TaskEditFormComposer extends GenericForwardComposer { return localDate.toDateTimeAtStartOfDay().toDate(); } - private void copyFromDTO(final TaskDTO taskDTO, Task currentTask, - boolean copyDates) { + private void copyFromDTO(final TaskDTO taskDTO, Task currentTask, boolean copyDates) { currentTask.setName(taskDTO.name); if (copyDates) { - currentTask.doPositionModifications(new IModifications() { - - @Override - public void doIt(IUpdatablePosition position) { - position.setBeginDate(GanttDate - .createFrom(taskDTO.beginDate)); - position.resizeTo(GanttDate.createFrom(taskDTO.endDate)); - } + currentTask.doPositionModifications(position -> { + position.setBeginDate(GanttDate.createFrom(taskDTO.beginDate)); + position.resizeTo(GanttDate.createFrom(taskDTO.endDate)); }); } currentTask.setNotes(taskDTO.notes); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java b/ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java index d01c04d48..65ee93f1c 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/TaskList.java @@ -23,16 +23,6 @@ package org.zkoss.ganttz; import static org.zkoss.ganttz.i18n.I18nHelper._; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.WeakHashMap; - import org.apache.commons.lang3.math.Fraction; import org.joda.time.LocalDate; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; @@ -48,15 +38,23 @@ import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener; 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.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.ext.AfterCompose; import org.zkoss.zul.Menupopup; import org.zkoss.zul.impl.XulElement; +import java.util.HashSet; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.WeakHashMap; +import java.util.HashMap; +import java.util.Set; +import java.util.Collection; +import java.util.Collections; + /** - * Component to show the list of task in the planner + * Component to show the list of task in the planner. + * * @author Javier Moran Rua */ public class TaskList extends XulElement implements AfterCompose { @@ -79,6 +77,10 @@ public class TaskList extends XulElement implements AfterCompose { private Map taskComponentByTask; + private Map autoRemovedListers = new WeakHashMap<>(); + + private Map contextMenus = new HashMap<>(); + public TaskList( FunctionalityExposedForExtensions context, CommandOnTaskContextualized doubleClickCommand, @@ -114,15 +116,13 @@ public class TaskList extends XulElement implements AfterCompose { IDisabilityConfiguration disabilityConfiguration, FilterAndParentExpandedPredicates predicate) { - TaskList result = new TaskList( + return new TaskList( context, doubleClickCommand, context.getDiagramGraph().getTopLevelTasks(), commandsOnTasksContextualized, disabilityConfiguration, predicate); - - return result; } public List asDependencyComponents(Collection dependencies) { @@ -137,11 +137,11 @@ public class TaskList extends XulElement implements AfterCompose { } public DependencyComponent asDependencyComponent(Dependency dependency) { - return asDependencyComponents(Arrays.asList(dependency)).get(0); + return asDependencyComponents(Collections.singletonList(dependency)).get(0); } - private synchronized void addTaskComponent(TaskRow beforeThis, final TaskComponent taskComponent, - boolean relocate) { + private synchronized void addTaskComponent( + TaskRow beforeThis, final TaskComponent taskComponent, boolean relocate) { insertBefore(taskComponent.getRow(), beforeThis); addContextMenu(taskComponent); @@ -163,7 +163,7 @@ public class TaskList extends XulElement implements AfterCompose { currentTotalTasks.addAll(insertionPosition, newTasks); } - // if the position is children of some already existent task when + // If the position is children of some already existent task when // reloading it will be added if the predicate tells so reload(true); } @@ -182,13 +182,7 @@ public class TaskList extends XulElement implements AfterCompose { if ( doubleClickCommand == null ) { return; } - taskComponent.addEventListener("onDoubleClick", new EventListener() { - - @Override - public void onEvent(Event event) { - doubleClickCommand.doAction(taskComponent); - } - }); + taskComponent.addEventListener("onDoubleClick", event -> doubleClickCommand.doAction(taskComponent)); } private void addContextMenu(final TaskComponent taskComponent) { @@ -262,20 +256,12 @@ public class TaskList extends XulElement implements AfterCompose { return result; } - private Map autoRemovedListers = new WeakHashMap<>(); - private void addExpandListenerTo(TaskContainer container) { if ( autoRemovedListers.containsKey(container) ) { return; } - IExpandListener expandListener = new IExpandListener() { - - @Override - public void expandStateChanged(boolean isNowExpanded) { - reload(true); - } - }; + IExpandListener expandListener = (isNowExpanded -> reload(true)); container.addExpandListener(expandListener); autoRemovedListers.put(container, expandListener); @@ -283,6 +269,7 @@ public class TaskList extends XulElement implements AfterCompose { private void registerZoomLevelChangedListener() { if ( zoomLevelChangedListener == null ) { + /* Do not replace it with lambda */ zoomLevelChangedListener = new IZoomLevelChangedListener() { @Override public void zoomLevelChanged(ZoomLevel detailLevel) { @@ -301,25 +288,20 @@ public class TaskList extends XulElement implements AfterCompose { return interval.getStart().plusDays(daysInto); } - private Map contextMenus = new HashMap<>(); - private Menupopup getContextMenuFor(TaskComponent taskComponent) { if ( contextMenus.get(taskComponent) == null ) { MenuBuilder menuBuilder = MenuBuilder.on(getPage(), getTaskComponents()); if ( disabilityConfiguration.isAddingDependenciesEnabled() ) { - menuBuilder.item(_("Add Dependency"), "/common/img/ico_dependency.png", - new ItemAction() { - @Override - public void onEvent(TaskComponent choosen, Event event) { - choosen.addDependency(); - } - }); + + menuBuilder.item( + _("Add Dependency"), "/common/img/ico_dependency.png", + (chosen, event) -> chosen.addDependency()); } for (CommandOnTaskContextualized command : commandsOnTasksContextualized) { if ( command.accepts(taskComponent) ) { - menuBuilder.item(command.getName(), command.getIcon(), command.toItemAction()); + menuBuilder.item(command.getName(), command.getIcon(), command.toItemAction()); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/DomainDependency.java b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/DomainDependency.java index ea14c47b5..2f7b35af7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/DomainDependency.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/DomainDependency.java @@ -33,12 +33,26 @@ import org.zkoss.ganttz.data.IDependency; /** * Represents a dependency in the domain. + * * @author Óscar González Fernández */ public class DomainDependency implements IDependency { private static final Log LOG = LogFactory.getLog(DomainDependency.class); + private final T source; + + private final T destination; + + private final DependencyType type; + + private DomainDependency(T source, T destination, DependencyType type) { + super(); + this.source = source; + this.destination = destination; + this.type = type; + } + public static List toDependencies( IDomainAndBeansMapper mapper, Collection> dependencies) { @@ -55,20 +69,7 @@ public class DomainDependency implements IDependency { } public static DomainDependency createDependency(T source, T destination, DependencyType type) { - return new DomainDependency(source, destination, type); - } - - private final T source; - - private final T destination; - - private final DependencyType type; - - private DomainDependency(T source, T destination, DependencyType type) { - super(); - this.source = source; - this.destination = destination; - this.type = type; + return new DomainDependency<>(source, destination, type); } public T getSource() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java index 90e023373..47a5fc473 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/adapters/PlannerConfiguration.java @@ -40,12 +40,12 @@ import org.zkoss.ganttz.extensions.ICommand; import org.zkoss.ganttz.extensions.ICommandOnTask; import org.zkoss.ganttz.extensions.IContext; import org.zkoss.ganttz.extensions.IContextWithPlannerTask; -import org.zkoss.ganttz.timetracker.zoom.IDetailItemModificator; -import org.zkoss.ganttz.timetracker.zoom.SeveralModificators; +import org.zkoss.ganttz.timetracker.zoom.IDetailItemModifier; +import org.zkoss.ganttz.timetracker.zoom.SeveralModifiers; import org.zkoss.zk.ui.Component; /** - * A object that defines several extension points for gantt planner + * A object that defines several extension points for gantt planner. * * @author Óscar González Fernández * @author Manuel Rego Casasnovas @@ -68,7 +68,7 @@ public class PlannerConfiguration implements IDisabilityConfiguration { @Override public void doAction(IContext context) { - // do nothing + // Do nothing } @Override @@ -97,7 +97,7 @@ public class PlannerConfiguration implements IDisabilityConfiguration { @Override public void doAction(IContextWithPlannerTask context, T task) { - // do nothing + // Do nothing } @Override @@ -165,11 +165,9 @@ public class PlannerConfiguration implements IDisabilityConfiguration { private boolean treeEditable = true; - // private String identifier = null; + private IDetailItemModifier firstLevelModifiers = SeveralModifiers.empty(); - private IDetailItemModificator firstLevelModificators = SeveralModificators.empty(); - - private IDetailItemModificator secondLevelModificators = SeveralModificators.empty(); + private IDetailItemModifier secondLevelModifiers = SeveralModifiers.empty(); private List reloadChartListeners = new ArrayList<>(); @@ -395,20 +393,20 @@ public class PlannerConfiguration implements IDisabilityConfiguration { return renamingTasksEnabled; } - public IDetailItemModificator getSecondLevelModificators() { - return secondLevelModificators; + public IDetailItemModifier getSecondLevelModifiers() { + return secondLevelModifiers; } - public void setSecondLevelModificators(IDetailItemModificator... secondLevelModificators) { - this.secondLevelModificators = SeveralModificators.create(secondLevelModificators); + public void setSecondLevelModifiers(IDetailItemModifier... secondLevelModifiers) { + this.secondLevelModifiers = SeveralModifiers.create(secondLevelModifiers); } - public IDetailItemModificator getFirstLevelModificators() { - return firstLevelModificators; + public IDetailItemModifier getFirstLevelModifiers() { + return firstLevelModifiers; } - public void setFirstLevelModificators(IDetailItemModificator... firstLevelModificators) { - this.firstLevelModificators = SeveralModificators.create(firstLevelModificators); + public void setFirstLevelModifiers(IDetailItemModifier... firstLevelModifiers) { + this.firstLevelModifiers = SeveralModifiers.create(firstLevelModifiers); } public void addReloadChartListener(IReloadChartListener reloadChartListener) { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java index 302f54146..086156365 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/Task.java @@ -126,14 +126,7 @@ public abstract class Task implements ITaskFundamentalProperties { @Override public void doPositionModifications(final IModifications modifications) { - fundamentalProperties.doPositionModifications(new IModifications() { - - @Override - public void doIt(IUpdatablePosition p) { - modifications.doIt(position); - - } - }); + fundamentalProperties.doPositionModifications(p -> modifications.doIt(position)); } private final IUpdatablePosition position = new IUpdatablePosition() { @@ -174,12 +167,7 @@ public abstract class Task implements ITaskFundamentalProperties { private IUpdatablePosition getFundamentalPropertiesPosition() { final IUpdatablePosition[] result = new IUpdatablePosition[1]; - fundamentalProperties.doPositionModifications(new IModifications() { - @Override - public void doIt(IUpdatablePosition position) { - result[0] = position; - } - }); + fundamentalProperties.doPositionModifications(position1 -> result[0] = position1); return result[0]; } @@ -342,12 +330,7 @@ public abstract class Task implements ITaskFundamentalProperties { return; } - doPositionModifications(new IModifications() { - @Override - public void doIt(IUpdatablePosition position) { - position.resizeTo(GanttDate.createFrom(date)); - } - }); + doPositionModifications(position1 -> position1.resizeTo(GanttDate.createFrom(date))); } public void removed() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/TaskContainer.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/TaskContainer.java index e26aa6f6c..1001312c3 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/TaskContainer.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/TaskContainer.java @@ -37,18 +37,18 @@ import org.zkoss.zk.ui.util.Clients; */ public class TaskContainer extends Task { - public TaskContainer(ITaskFundamentalProperties fundamentalProperties, - boolean expanded) { + public TaskContainer(ITaskFundamentalProperties fundamentalProperties, boolean expanded) { super(fundamentalProperties); this.expanded = expanded; } public interface IExpandListener { - public void expandStateChanged(boolean isNowExpanded); + void expandStateChanged(boolean isNowExpanded); } private static List removeNulls(Collection elements) { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); + for (T e : elements) { if (e != null) { result.add(e); @@ -57,22 +57,19 @@ public class TaskContainer extends Task { return result; } - private static > T getSmallest( - Collection elements) { + private static > T getSmallest(Collection elements) { return Collections.min(removeNulls(elements)); } - private static > T getBiggest( - Collection elements) { + private static > T getBiggest(Collection elements) { return Collections.max(removeNulls(elements)); } - private List tasks = new ArrayList(); + private List tasks = new ArrayList<>(); private boolean expanded = false; - private WeakReferencedListeners expandListeners = WeakReferencedListeners - .create(); + private WeakReferencedListeners expandListeners = WeakReferencedListeners.create(); public void addExpandListener(IExpandListener expandListener) { expandListeners.addListener(expandListener); @@ -89,17 +86,20 @@ public class TaskContainer extends Task { } private List getEndDates() { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); + for (Task task : tasks) { result.add(task.getEndDate()); } + return result; } public GanttDate getBiggestDateFromChildren() { - if (tasks.isEmpty()) { + if ( tasks.isEmpty() ) { return getEndDate(); } + return getBiggest(getEndDates()); } @@ -111,9 +111,11 @@ public class TaskContainer extends Task { @Override public void setVisible(boolean visible) { super.setVisible(visible); - if (!this.expanded) { + + if ( !this.expanded ) { return; } + for (Task task : tasks) { task.setVisible(true); } @@ -133,6 +135,7 @@ public class TaskContainer extends Task { } }); } + refreshTooltips(); } @@ -171,10 +174,12 @@ public class TaskContainer extends Task { @Override public List getAllTaskLeafs() { - List result = new ArrayList(); + List result = new ArrayList<>(); + for (Task task : tasks) { result.addAll(task.getAllTaskLeafs()); } + return result; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadLevel.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadLevel.java index ad8f575e6..b719c8e51 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadLevel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadLevel.java @@ -23,6 +23,9 @@ package org.zkoss.ganttz.data.resourceload; import org.apache.commons.lang3.Validate; +/** + * Represents level of load of some {@link Resource}. + */ public class LoadLevel { public enum Category { @@ -56,6 +59,7 @@ public class LoadLevel { }; protected abstract boolean contains(int percentage); + public static Category categoryFor(int percentage) { for (Category category : values()) { if ( category.contains(percentage) ) { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadTimeLine.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadTimeLine.java index 2b89e0dfa..b826534b5 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadTimeLine.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/LoadTimeLine.java @@ -37,30 +37,17 @@ public class LoadTimeLine { @SuppressWarnings("unchecked") private static final Comparator nullSafeComparator = new NullComparator<>(false); - public static Comparator byStartAndEndDate() { - return new Comparator() { - @Override - public int compare(LoadTimeLine o1, LoadTimeLine o2) { - int result = nullSafeComparator.compare(o1.getStartPeriod(), o2.getStartPeriod()); - - if ( result == 0 ) { - return nullSafeComparator.compare(o1.getEndPeriod(), o2.getEndPeriod()); - } - - return result; - - } - }; - } - private final String conceptName; + private final List loadPeriods; private final TimeLineRole timeLineRole; + private final String type; private final List children; + public LoadTimeLine(String conceptName, List loadPeriods, TimeLineRole role) { @@ -101,6 +88,22 @@ public class LoadTimeLine { } + public static Comparator byStartAndEndDate() { + return new Comparator() { + @Override + public int compare(LoadTimeLine o1, LoadTimeLine o2) { + int result = nullSafeComparator.compare(o1.getStartPeriod(), o2.getStartPeriod()); + + if ( result == 0 ) { + return nullSafeComparator.compare(o1.getEndPeriod(), o2.getEndPeriod()); + } + + return result; + + } + }; + } + public List getLoadPeriods() { return loadPeriods; } @@ -122,11 +125,7 @@ public class LoadTimeLine { } public GanttDate getStartPeriod() { - if ( isEmpty() ) { - return null; - } - - return getFirst().getStart(); + return isEmpty() ? null : getFirst().getStart(); } public boolean isEmpty() { @@ -134,11 +133,7 @@ public class LoadTimeLine { } public GanttDate getEndPeriod() { - if ( isEmpty() ) { - return null; - } - - return getLast().getEnd(); + return isEmpty() ? null : getLast().getEnd(); } public String getType() { @@ -192,7 +187,7 @@ public class LoadTimeLine { } public boolean hasChildren() { - return (!children.isEmpty()); + return !children.isEmpty(); } public List getChildren() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java index 54f9b2f61..7f72a7622 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/data/resourceload/TimeLineRole.java @@ -21,8 +21,6 @@ package org.zkoss.ganttz.data.resourceload; -import org.zkoss.ganttz.i18n.I18nHelper; - /** * @author Susana Montes Pedreira */ @@ -39,7 +37,7 @@ public class TimeLineRole { } public boolean isVisibleScheduled() { - return type != null ? type.isVisibleScheduled() : false; + return type != null && type.isVisibleScheduled(); } public T getEntity() { @@ -55,7 +53,10 @@ public class TimeLineRole { */ public enum TimeLineRoleEnum { - NONE(_("None")), WORKER(_("Worker")), ORDER(_("Project")), TASK(_("Task")) { + NONE(_("None")), + WORKER(_("Worker")), + ORDER(_("Project")), + TASK(_("Task")) { @Override public boolean isVisibleScheduled() { return true; @@ -63,19 +64,19 @@ public class TimeLineRole { }, CRITERION(_("Criterion")); + private String name; + + TimeLineRoleEnum(String name) { + this.name = name; + } + /** - * Forces to mark the string as needing translation + * Forces to mark the string as needing translation. */ private static String _(String string) { return string; } - private String name; - - private TimeLineRoleEnum(String name) { - this.name = name; - } - public static TimeLineRoleEnum create(String name) { TimeLineRoleEnum requiredTimeLineRole = TimeLineRoleEnum.NONE; if (name != null) { @@ -88,8 +89,9 @@ public class TimeLineRole { return requiredTimeLineRole; } + @Override public String toString() { - return I18nHelper._(this.name); + return _(this.name); } public boolean isVisibleScheduled() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/extensions/ICommand.java b/ganttzk/src/main/java/org/zkoss/ganttz/extensions/ICommand.java index 186ad8412..2e0dcefea 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/extensions/ICommand.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/extensions/ICommand.java @@ -23,25 +23,24 @@ package org.zkoss.ganttz.extensions; /** - * An action that can be applied to the planner and it's wanted to be available - * to the user
+ * An action that can be applied to the planner and it's wanted to be available to the user
* * @author Óscar González Fernández * @author Manuel Rego Casasnovas */ public interface ICommand { - public String getName(); + String getName(); - public void doAction(IContext context); + void doAction(IContext context); - public String getImage(); + String getImage(); boolean isDisabled(); /** - * Describes if a command is for the planner toolbar. Otherwise it'll be - * inserted in the common toolbar. + * Describes if a command is for the planner toolbar. + * Otherwise it will be inserted in the common toolbar. */ boolean isPlannerCommand(); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/i18n/I18nHelper.java b/ganttzk/src/main/java/org/zkoss/ganttz/i18n/I18nHelper.java index 2bbed8892..bfa327554 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/i18n/I18nHelper.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/i18n/I18nHelper.java @@ -34,7 +34,7 @@ public class I18nHelper { private static HashMap localesCache = new HashMap<>(); public static I18n getI18n() { - if ( localesCache.keySet().contains(Locales.getCurrent()) ) { + if (localesCache.keySet().contains(Locales.getCurrent())) { return localesCache.get(Locales.getCurrent()); } @@ -48,7 +48,15 @@ public class I18nHelper { return i18n; } - // TODO refactor symbol _ + + + //TODO It should be changed since JDK9. + /** + * Use of '_' as an identifier might not be supported in releases after Java SE 8. + * + * @param str + * @return Text depends on locale + */ public static String _(String str) { return getI18n().tr(str); } @@ -65,8 +73,7 @@ public class I18nHelper { return getI18n().tr(text, o1, o2, o3); } - public static String _(String text, Object o1, Object o2, Object o3, - Object o4) { + public static String _(String text, Object o1, Object o2, Object o3, Object o4) { return getI18n().tr(text, o1, o2, o3, o4); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IFilterChangedListener.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IFilterChangedListener.java index 47207786a..b7e675bd7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IFilterChangedListener.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IFilterChangedListener.java @@ -23,6 +23,6 @@ package org.zkoss.ganttz.resourceload; public interface IFilterChangedListener { - public void filterChanged(boolean filter); + void filterChanged(boolean filter); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IPaginationFilterChangedListener.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IPaginationFilterChangedListener.java index 8006de012..b0bee8ea1 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IPaginationFilterChangedListener.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/IPaginationFilterChangedListener.java @@ -23,6 +23,6 @@ package org.zkoss.ganttz.resourceload; public interface IPaginationFilterChangedListener { - public void filterChanged(int initialPosition); + void filterChanged(int initialPosition); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ISeeScheduledOfListener.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ISeeScheduledOfListener.java index 990951456..d943327c7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ISeeScheduledOfListener.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ISeeScheduledOfListener.java @@ -25,6 +25,6 @@ import org.zkoss.ganttz.data.resourceload.LoadTimeLine; public interface ISeeScheduledOfListener { - public void seeScheduleOf(LoadTimeLine taskLine); + void seeScheduleOf(LoadTimeLine taskLine); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java index f084d21a2..81d9e5c07 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadComponent.java @@ -36,11 +36,7 @@ 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.MenuBuilder; -import org.zkoss.ganttz.util.MenuBuilder.ItemAction; import org.zkoss.ganttz.util.WeakReferencedListeners; -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; @@ -48,38 +44,54 @@ import org.zkoss.zul.impl.XulElement; /** * This class wraps ResourceLoad data inside an specific HTML Div component. + * * @author Lorenzo Tilve Álvaro + * @author Vova Perebykivskyi */ public class ResourceLoadComponent extends XulElement { - public static ResourceLoadComponent create(TimeTracker timeTracker, - LoadTimeLine loadLine) { - return new ResourceLoadComponent(timeTracker, loadLine); - } - private final LoadTimeLine loadLine; - private final TimeTracker timeTracker; - private transient IZoomLevelChangedListener zoomChangedListener; - private WeakReferencedListeners scheduleListeners = WeakReferencedListeners - .create(); - private ResourceLoadComponent(final TimeTracker timeTracker, - final LoadTimeLine loadLine) { + private final TimeTracker timeTracker; + + private transient IZoomLevelChangedListener zoomChangedListener; + + private WeakReferencedListeners scheduleListeners = WeakReferencedListeners.create(); + + private Map contextMenus = new HashMap<>(); + + private ResourceLoadComponent(final TimeTracker timeTracker, final LoadTimeLine loadLine) { this.loadLine = loadLine; this.timeTracker = timeTracker; createChildren(loadLine, timeTracker.getMapper()); + + /* Do not replace it with lambda */ zoomChangedListener = new IZoomLevelChangedListener() { + /** + * In general it is working like, on every zoomChanged : + * 1. Remove all LoadLines ( divs ). + * 2. Create new ones ( for selected zoom mode ). + * 3. Redraw insertionPointRightPanel component ( Div ). + */ @Override public void zoomLevelChanged(ZoomLevel detailLevel) { getChildren().clear(); createChildren(loadLine, timeTracker.getMapper()); + if ( !getFellows().isEmpty() ) { + getFellow("insertionPointRightPanel").invalidate(); + } invalidate(); } }; + this.timeTracker.addZoomListener(zoomChangedListener); } + public static ResourceLoadComponent create(TimeTracker timeTracker, LoadTimeLine loadLine) { + return new ResourceLoadComponent(timeTracker, loadLine); + } + private void createChildren(final LoadTimeLine loadLine, IDatesMapper mapper) { List
divs = createDivsForPeriods(mapper, loadLine.getLoadPeriods()); for (Div div : divs) { @@ -95,71 +107,50 @@ public class ResourceLoadComponent extends XulElement { } private void addDoubleClickAction(final Div div, final LoadTimeLine loadLine) { - div.addEventListener("onDoubleClick", new EventListener() { - @Override - public void onEvent(Event event) { - schedule(loadLine); - } - }); + div.addEventListener("onDoubleClick", event -> schedule(loadLine)); } - private void addContextMenu(final List
divs, final Div div, - final LoadTimeLine loadLine) { + private void addContextMenu(final List
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. + * in 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) { - try { - getContextMenuFor(divs, div, loadLine).open(div); - } catch (Exception e) { - e.printStackTrace(); - } + * non-null page is required by MenuBuilder or a NullPointerException will be raised. + */ + + div.addEventListener("onRightClick", event -> { + try { + getContextMenuFor(divs, div, loadLine).open(div); + } catch (Exception e) { + e.printStackTrace(); } }); } public void schedule(final LoadTimeLine taskLine) { - - scheduleListeners - .fireEvent(new IListenerNotification() { - @Override - public void doNotify(ISeeScheduledOfListener listener) { - listener.seeScheduleOf(taskLine); - } - }); + scheduleListeners.fireEvent(listener -> listener.seeScheduleOf(taskLine)); } - public void addSeeScheduledOfListener( - ISeeScheduledOfListener seeScheduledOfListener) { + public void addSeeScheduledOfListener(ISeeScheduledOfListener seeScheduledOfListener) { scheduleListeners.addListener(seeScheduledOfListener); } - private Map contextMenus = new HashMap(); - - private Menupopup getContextMenuFor(final List
divs, final Div div, - final LoadTimeLine loadLine) { + private Menupopup getContextMenuFor(final List
divs, final Div div, final LoadTimeLine loadLine) { if (contextMenus.get(div) == null) { MenuBuilder
menuBuilder = MenuBuilder.on(getPage(), divs); - menuBuilder.item(_("See resource allocation"), - "/common/img/ico_allocation.png", new ItemAction
() { - @Override - public void onEvent(Div choosen, Event event) { - schedule(loadLine); - } - }); + menuBuilder.item( + _("See resource allocation"), + "/common/img/ico_allocation.png", + (chosen, event) -> schedule(loadLine)); Menupopup result = menuBuilder.createWithoutSettingContext(); contextMenus.put(div, result); + return result; } @@ -174,52 +165,56 @@ public class ResourceLoadComponent extends XulElement { return loadLine.getType(); } + LoadTimeLine getLoadLine() { + return loadLine; + } - private static List
createDivsForPeriods(IDatesMapper datesMapper, - List loadPeriods) { - List
result = new ArrayList
(); + private static List
createDivsForPeriods(IDatesMapper datesMapper, List loadPeriods) { + List
result = new ArrayList<>(); for (LoadPeriod loadPeriod : loadPeriods) { result.add(createDivForPeriod(datesMapper, loadPeriod)); } return result; } - private static Div createDivForPeriod(IDatesMapper datesMapper, - LoadPeriod loadPeriod) { + private static Div createDivForPeriod(IDatesMapper datesMapper, LoadPeriod loadPeriod) { Div result = new Div(); - result.setClass(String.format("taskassignmentinterval %s", loadPeriod - .getLoadLevel().getCategory())); + result.setClass(String.format("taskassignmentinterval %s", loadPeriod.getLoadLevel().getCategory())); + + String load = _("Load: {0}%", loadPeriod.getLoadLevel().getPercentage()) + ", "; - String load = _("Load: {0}%", loadPeriod.getLoadLevel().getPercentage()) - + ", "; if (loadPeriod.getLoadLevel().getPercentage() == Integer.MAX_VALUE) { load = ""; } - result.setTooltiptext(load - + _("available effort: {0}, assigned effort: {1}", - loadPeriod.getAvailableEffort(), - loadPeriod.getAssignedEffort())); + + result.setTooltiptext( + load + + _("available effort: {0}, assigned effort: {1}", + loadPeriod.getAvailableEffort(), + loadPeriod.getAssignedEffort())); result.setLeft(forCSS(getStartPixels(datesMapper, loadPeriod))); result.setWidth(forCSS(getWidthPixels(datesMapper, loadPeriod))); + return result; } - private static int getWidthPixels(IDatesMapper datesMapper, - LoadPeriod loadPeriod) { - return Math.max(loadPeriod.getEnd().toPixels(datesMapper) - - getStartPixels(datesMapper, loadPeriod), 0); + private static int getWidthPixels(IDatesMapper datesMapper, LoadPeriod loadPeriod) { + return Math.max(loadPeriod.getEnd().toPixels(datesMapper) - getStartPixels(datesMapper, loadPeriod), 0); } private static String forCSS(int pixels) { return String.format("%dpx", pixels); } - private static int getStartPixels(IDatesMapper datesMapper, - LoadPeriod loadPeriod) { + private static int getStartPixels(IDatesMapper datesMapper, LoadPeriod loadPeriod) { return loadPeriod.getStart().toPixels(datesMapper); } + /** + * It is drawing chart on right pane for each ResourceLoad row. + */ + @Override protected void renderProperties(ContentRenderer renderer) throws IOException{ render(renderer, "_resourceLoadName", getResourceLoadName()); render(renderer, "_resourceLoadType", getResourceLoadType()); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java index 0b5b321a8..77fa98c20 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadLeftPane.java @@ -24,65 +24,106 @@ package org.zkoss.ganttz.resourceload; import static org.zkoss.ganttz.i18n.I18nHelper._; import java.util.ArrayList; -import java.util.Iterator; import java.util.List; +import java.util.HashSet; import org.zkoss.ganttz.data.resourceload.LoadTimeLine; import org.zkoss.ganttz.util.MutableTreeModel; import org.zkoss.ganttz.util.WeakReferencedListeners; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlMacroComponent; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.OpenEvent; -import org.zkoss.zul.Button; -import org.zkoss.zul.Div; -import org.zkoss.zul.Label; -import org.zkoss.zul.Popup; import org.zkoss.zul.Treecell; -import org.zkoss.zul.Treechildren; import org.zkoss.zul.Treeitem; import org.zkoss.zul.TreeitemRenderer; import org.zkoss.zul.Treerow; -import org.zkoss.zul.api.Tree; +import org.zkoss.zul.Button; +import org.zkoss.zul.Div; +import org.zkoss.zul.Label; +import org.zkoss.zul.Tree; +import org.zkoss.zul.Treechildren; +/** + * Works with left pane of Resource Load page. Also works with right pane ( a little bit ). + * + * @author Óscar González Fernández + * @author Manuel Rego Casasnovas + * @author Susana Montes Pedreira + * @author Lorenzo Tilve + * @author Jacobo Aragunde Pérez + * @author Vova Perebykivskyi + */ public class ResourceLoadLeftPane extends HtmlMacroComponent { private MutableTreeModel modelForTree; + private final ResourceLoadList resourceLoadList; - private WeakReferencedListeners scheduleListeners = WeakReferencedListeners - .create(); + private WeakReferencedListeners scheduleListeners = WeakReferencedListeners.create(); - public ResourceLoadLeftPane( -MutableTreeModel modelForTree, - ResourceLoadList resourceLoadList) { + /** + * {@link ResourceLoadLeftPane#onOpenEventQueue}, {@link OnOpenEvent} and proceedOnOpenEventQueue() + * were created because of problem: + * after migration from ZK5 to ZK8 onOpen event had been calling before render(). + * It produced a problem. + * On onOpen event we are calculating closest items to treeItem. + * render() was not called so, treeItem row had no value. + * It made calculatedClosedItems(treeItem).isEmpty() to return true, even if it is not! + * + * http://forum.zkoss.org/question/101294/event-before-render-treeitem/ + */ + private OnOpenEvent onOpenEventQueue = null; + + /** + * Made to know if {@link LoadTimeLine} was rendered. + */ + private HashSet renderedLines; + + + public ResourceLoadLeftPane(MutableTreeModel modelForTree, ResourceLoadList resourceLoadList) { this.resourceLoadList = resourceLoadList; this.modelForTree = modelForTree; + this.renderedLines = new HashSet<>(); } - @Override public void afterCompose() { super.afterCompose(); + getContainerTree().setModel(modelForTree); - getContainerTree().setTreeitemRenderer(getRendererForTree()); + getContainerTree().setItemRenderer(getRendererForTree()); + + /* Force call overridden render() */ + try { + if ( !this.resourceLoadList.getChildren().isEmpty() ) { + getRendererForTree().render( + new Treeitem(""), + ((ResourceLoadComponent) this.resourceLoadList.getFirstChild()).getLoadLine(), + 0); + } + } catch (Exception e) { + e.printStackTrace(); + } } private TreeitemRenderer getRendererForTree() { return new TreeitemRenderer() { @Override - public void render(Treeitem item, Object data) - { - LoadTimeLine line = (LoadTimeLine) data; - item.setOpen(false); - item.setValue(line); + public void render(Treeitem treeitem, Object o, int index) throws Exception { + LoadTimeLine line = (LoadTimeLine) o; + treeitem.setOpen(false); + treeitem.setValue(line); Treerow row = new Treerow(); Treecell cell = new Treecell(); Component component = createComponent(line); - item.appendChild(row); + + /* Clear existing Treerows */ + if ( !treeitem.getChildren().isEmpty() ) { + treeitem.getChildren().clear(); + } + + treeitem.appendChild(row); row.appendChild(cell); appendOperations(cell, line); @@ -90,70 +131,86 @@ MutableTreeModel modelForTree, cell.appendChild(component); collapse(line); - addExpandedListener(item, line); + addExpandedListener(treeitem, line); row.setSclass("resourceload-leftpanel-row"); + + if ( onOpenEventQueue != null ) { + processOnOpenEventQueue(); + } + + renderedLines.add(line); } - private void appendOperations(final Treecell cell, - final LoadTimeLine line) { - if (line.getRole().isVisibleScheduled()) { + private void processOnOpenEventQueue() { + if ( onOpenEventQueue.event.isOpen() ) { + List closed = calculatedClosedItems(onOpenEventQueue.treeitem); + expand(onOpenEventQueue.line, closed); + } else { + collapse(onOpenEventQueue.line); + } + + /* + * When queue processed, clean object, to make it kind of "unique" or "one time only". + */ + onOpenEventQueue = null; + } + + private void appendOperations(final Treecell cell, final LoadTimeLine line) { + if ( line.getRole().isVisibleScheduled() ) { appendButtonPlan(cell, line); } } - private void appendButtonPlan(final Treecell cell, - final LoadTimeLine taskLine) { + private void appendButtonPlan(final Treecell cell, final LoadTimeLine taskLine) { Button buttonPlan = new Button(); buttonPlan.setSclass("icono"); buttonPlan.setImage("/common/img/ico_planificador1.png"); buttonPlan.setHoverImage("/common/img/ico_planificador.png"); buttonPlan.setTooltiptext(_("See scheduling")); - buttonPlan.addEventListener("onClick", new EventListener() { - @Override - public void onEvent(Event event) { - schedule(taskLine); - } - }); + buttonPlan.addEventListener("onClick", event -> schedule(taskLine)); + cell.appendChild(buttonPlan); } + /** + * Do not replace it with lambda. + */ public void schedule(final LoadTimeLine taskLine) { - - scheduleListeners - .fireEvent(new IListenerNotification() { + scheduleListeners.fireEvent( + new WeakReferencedListeners.IListenerNotification() { @Override - public void doNotify( - ISeeScheduledOfListener listener) { + public void doNotify(ISeeScheduledOfListener listener) { listener.seeScheduleOf(taskLine); } }); } - private void addExpandedListener(final Treeitem item, - final LoadTimeLine line) { - item.addEventListener("onOpen", new EventListener() { - @Override - public void onEvent(Event event) { - OpenEvent openEvent = (OpenEvent) event; - if (openEvent.isOpen()) { - List closed = calculatedClosedItems(item); - expand(line, closed); - } else { - collapse(line); + private void addExpandedListener(final Treeitem item, final LoadTimeLine line) { + item.addEventListener("onOpen", event -> { + OpenEvent openEvent = (OpenEvent) event; + + if ( openEvent.isOpen() ) { + + onOpenEventQueue = new OnOpenEvent(item, line, openEvent); + + /* If line was rendered than we need to call expand manually */ + if ( renderedLines.contains(line) ) { + processOnOpenEventQueue(); } + + } else { + collapse(line); } }); } private Component createComponent(LoadTimeLine line) { - return isTopLevel(line) ? createFirstLevel(line) - : createSecondLevel(line); + return isTopLevel(line) ? createFirstLevel(line) : createSecondLevel(line); } private boolean isTopLevel(LoadTimeLine line) { - int[] path = modelForTree.getPath(modelForTree.getRoot(), line); - return path.length == 0; + return modelForTree.getPath(modelForTree.getRoot(), line).length == 0; } }; } @@ -167,40 +224,45 @@ MutableTreeModel modelForTree, } private List calculatedClosedItems(Treeitem item) { - List result = new ArrayList(); + List result = new ArrayList<>(); Treechildren treeChildren = item.getTreechildren(); - if (treeChildren != null) { - List myTreeItems = (List) treeChildren - .getChildren(); - Iterator iterator = myTreeItems.iterator(); - while (iterator.hasNext()) { - Treeitem child = (Treeitem) iterator.next(); - if (!child.isOpen()) { + + if ( treeChildren != null ) { + + List myTreeItems = treeChildren.getChildren(); + for (Treeitem child : myTreeItems) { + + if ( !child.isOpen() ) { result.addAll(getLineChildrenBy(child)); } else { result.addAll(calculatedClosedItems(child)); } } } + return result; } private List getLineChildrenBy(Treeitem item) { - List result = new ArrayList(); + List result = new ArrayList<>(); LoadTimeLine line = getLineByTreeitem(item); - if (line != null) { + + if ( line != null ) { result.addAll(line.getAllChildren()); } + return result; } private LoadTimeLine getLineByTreeitem(Treeitem child) { - LoadTimeLine line = null; + LoadTimeLine line; + try { - line = (LoadTimeLine) child.getValue(); + line = child.getValue(); } catch (Exception e) { return null; } + return line; } @@ -211,12 +273,14 @@ MutableTreeModel modelForTree, private Component createFirstLevel(LoadTimeLine main) { Div result = createLabelWithName(main); result.setSclass("firstlevel"); + return result; } private Component createSecondLevel(LoadTimeLine loadTimeLine) { Div result = createLabelWithName(loadTimeLine); result.setSclass("secondlevel"); + return result; } @@ -224,20 +288,32 @@ MutableTreeModel modelForTree, Div result = new Div(); Label label = new Label(); final String conceptName = main.getConceptName(); + label.setValue(conceptName); result.appendChild(label); + return result; } - private static Popup createPopup(Div parent, String originalValue) { - Popup result = new Popup(); - result.appendChild(new Label(originalValue)); - parent.appendChild(result); - return result; - } - - public void addSeeScheduledOfListener( - ISeeScheduledOfListener seeScheduledOfListener) { + public void addSeeScheduledOfListener(ISeeScheduledOfListener seeScheduledOfListener) { scheduleListeners.addListener(seeScheduledOfListener); } + + /** + * Info about onOpenEvent. + */ + private class OnOpenEvent { + + private LoadTimeLine line; + + private Treeitem treeitem; + + private OpenEvent event; + + OnOpenEvent(Treeitem treeitem, LoadTimeLine line, OpenEvent event) { + this.line = line; + this.treeitem = treeitem; + this.event = event; + } + } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadList.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadList.java index 8418da53f..9d1cc4bc3 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadList.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourceLoadList.java @@ -40,27 +40,26 @@ import org.zkoss.zul.impl.XulElement; /** * Component to include a list of ResourceLoads inside the ResourcesLoadPanel. + * * @author Lorenzo Tilve Álvaro + * @author Vova Perebykivskyi */ public class ResourceLoadList extends XulElement { - private final IZoomLevelChangedListener zoomListener; + private Map fromTimeLineToComponent = new HashMap<>(); - private Map fromTimeLineToComponent = new HashMap(); - - public ResourceLoadList(TimeTracker timeTracker, - MutableTreeModel timelinesTree) { - zoomListener = adjustTimeTrackerSizeListener(); + public ResourceLoadList(TimeTracker timeTracker, MutableTreeModel timelinesTree) { + IZoomLevelChangedListener zoomListener = adjustTimeTrackerSizeListener(); timeTracker.addZoomListener(zoomListener); LoadTimeLine current = timelinesTree.getRoot(); - List toInsert = new ArrayList(); + List toInsert = new ArrayList<>(); fill(timelinesTree, current, toInsert); insertAsComponents(timeTracker, toInsert); } - private void fill(MutableTreeModel timelinesTree, - LoadTimeLine current, List result) { + private void fill(MutableTreeModel timelinesTree, LoadTimeLine current, List result) { final int length = timelinesTree.getChildCount(current); + for (int i = 0; i < length; i++) { LoadTimeLine child = timelinesTree.getChild(current, i); result.add(child); @@ -70,41 +69,48 @@ public class ResourceLoadList extends XulElement { private IZoomLevelChangedListener adjustTimeTrackerSizeListener() { return new IZoomLevelChangedListener() { - @Override public void zoomLevelChanged(ZoomLevel detailLevel) { - response(null, new AuInvoke(ResourceLoadList.this, - "adjustTimeTrackerSize")); - response(null, new AuInvoke(ResourceLoadList.this, - "adjustResourceLoadRows")); + response(null, new AuInvoke(ResourceLoadList.this, "adjustTimeTrackerSize")); + response(null, new AuInvoke(ResourceLoadList.this, "adjustResourceLoadRows")); } }; } - private void insertAsComponents(TimeTracker timetracker, - List children) { + private void insertAsComponents(TimeTracker timetracker, List children) { for (LoadTimeLine loadTimeLine : children) { - ResourceLoadComponent component = ResourceLoadComponent.create( - timetracker, loadTimeLine); + ResourceLoadComponent component = ResourceLoadComponent.create(timetracker, loadTimeLine); appendChild(component); fromTimeLineToComponent.put(loadTimeLine, component); } } + /** + * On Resources Load page it will collapse inherited resources. + * + * @param line + */ public void collapse(LoadTimeLine line) { for (LoadTimeLine l : line.getAllChildren()) { getComponentFor(l).detach(); } + /* In ZK8, after detaching component, component will be still visible, so we need to redraw it */ + this.invalidate(); + Clients.evalJavaScript(getWidgetClass() + ".getInstance().recalculateTimeTrackerHeight();"); } private ResourceLoadComponent getComponentFor(LoadTimeLine l) { - ResourceLoadComponent resourceLoadComponent = fromTimeLineToComponent - .get(l); - return resourceLoadComponent; + return fromTimeLineToComponent.get(l); } + /** + * On Resources Load page it will expand inherited resources. + * + * @param line + * @param closed + */ public void expand(LoadTimeLine line, List closed) { ResourceLoadComponent parentComponent = getComponentFor(line); Component nextSibling = parentComponent.getNextSibling(); @@ -118,19 +124,21 @@ public class ResourceLoadList extends XulElement { nextSibling = child; } + /* In ZK8, after detaching component, component will be still visible, so we need to redraw it */ + this.invalidate(); + Clients.evalJavaScript(getWidgetClass() + ".getInstance().recalculateTimeTrackerHeight();"); } private List getChildrenReverseOrderFor(LoadTimeLine line) { List childrenOf = line.getAllChildren(); Collections.reverse(childrenOf); + return childrenOf; } - public void addSeeScheduledOfListener( - ISeeScheduledOfListener seeScheduledOfListener) { - for (Entry entry : fromTimeLineToComponent - .entrySet()) { + public void addSeeScheduledOfListener(ISeeScheduledOfListener seeScheduledOfListener) { + for (Entry entry : fromTimeLineToComponent.entrySet()) { entry.getValue().addSeeScheduledOfListener(seeScheduledOfListener); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java index 0244acc6a..9e0b7750b 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/resourceload/ResourcesLoadPanel.java @@ -38,25 +38,24 @@ import org.zkoss.ganttz.util.LongOperationFeedback; import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation; import org.zkoss.ganttz.util.MutableTreeModel; import org.zkoss.ganttz.util.WeakReferencedListeners; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.au.out.AuInvoke; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlMacroComponent; -import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; import org.zkoss.zul.Button; import org.zkoss.zul.Comboitem; import org.zkoss.zul.ListModel; 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; +import org.zkoss.zul.Combobox; +import org.zkoss.zul.Listbox; +import org.zkoss.zul.South; +import org.zkoss.zul.Div; public class ResourcesLoadPanel extends HtmlMacroComponent { public interface IToolbarCommand { + void doAction(); String getLabel(); @@ -84,17 +83,24 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { private WeakReferencedListeners zoomListeners = WeakReferencedListeners.create(); - private Listbox listZoomLevels; - private final String FILTER_RESOURCES = _("Resources"); + private final String FILTER_CRITERIA = _("Generic allocation criteria"); + + private final String FILTER_BY_NAME_COMBO_COMPONENT = "filterByNameCombo"; + private String feedBackMessage; + private Boolean filterbyResources; private boolean refreshNameFilter = true; + private int filterByNamePosition = 0; + private int numberOfGroupsByName = 10; + private int lastSelectedName = 0; + private final PaginationType paginationType; private WeakReferencedListeners nameFilterListener = @@ -113,12 +119,14 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { private Component secondOptionalFilter; - public ResourcesLoadPanel( - List groups, - TimeTracker timeTracker, - Component componentOnWhichGiveFeedback, - boolean expandResourceLoadViewCharts, - PaginationType paginationType) { + private Combobox filterByNameCombo; + + + public ResourcesLoadPanel(List groups, + TimeTracker timeTracker, + Component componentOnWhichGiveFeedback, + boolean expandResourceLoadViewCharts, + PaginationType paginationType) { this.componentOnWhichGiveFeedback = componentOnWhichGiveFeedback; this.expandResourceLoadViewCharts = expandResourceLoadViewCharts; @@ -141,14 +149,12 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { return timeTracker; } - public ListModel getFilters() { - String[] filters = new String[] { FILTER_RESOURCES, FILTER_CRITERIA }; - - return new SimpleListModel(filters); + public ListModel getFilters() { + return new SimpleListModel<>(new String[] { FILTER_RESOURCES, FILTER_CRITERIA }); } - public void setFilter(String filterby) { - if ( filterby.equals(FILTER_RESOURCES) ) { + public void setFilter(String filterBy) { + if ( filterBy.equals(FILTER_RESOURCES) ) { this.filterbyResources = true; this.feedBackMessage = _("showing resources"); } else { @@ -184,27 +190,23 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } private void applyFilter() { - zoomListeners.fireEvent(new IListenerNotification() { - @Override - public void doNotify(IFilterChangedListener listener) { - listener.filterChanged(getFilter()); - } - }); + zoomListeners.fireEvent(listener -> listener.filterChanged(getFilter())); } public void addFilterListener(IFilterChangedListener listener) { zoomListeners.addListener(listener); } - public ListModel getZoomLevels() { + public ListModel getZoomLevels() { ZoomLevel[] selectableZoomlevels = { ZoomLevel.DETAIL_ONE, ZoomLevel.DETAIL_TWO, ZoomLevel.DETAIL_THREE, ZoomLevel.DETAIL_FOUR, - ZoomLevel.DETAIL_FIVE }; + ZoomLevel.DETAIL_FIVE + }; - return new SimpleListModel(selectableZoomlevels); + return new SimpleListModel<>(selectableZoomlevels); } public void setZoomLevel(final ZoomLevel zoomLevel) { @@ -213,6 +215,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { timeTracker.setZoomLevel(zoomLevel); } + public void zoomIncrease() { savePreviousData(); getTimeTrackerComponent().updateDayScroll(); @@ -265,12 +268,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { private Button asButton(final IToolbarCommand c) { Button result = new Button(); - result.addEventListener(Events.ON_CLICK, new EventListener() { - @Override - public void onEvent(Event event) { - c.doAction(); - } - }); + result.addEventListener(Events.ON_CLICK, event -> c.doAction()); if ( !StringUtils.isEmpty(c.getImage()) ) { result.setImage(c.getImage()); @@ -290,13 +288,12 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } private Component getToolbar() { - Component toolbar = getFellow("toolbar"); - - return toolbar; + return getFellow("toolbar"); } private MutableTreeModel createModelForTree() { MutableTreeModel result = MutableTreeModel.create(LoadTimeLine.class); + for (LoadTimeLine loadTimeLine : this.getGroupsToShow()) { result.addToRoot(loadTimeLine); result = addNodes(result, loadTimeLine); @@ -322,20 +319,21 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { return new TimeTrackerComponent(timeTracker) { @Override protected void scrollHorizontalPercentage(int daysDisplacement) { - response("", new AuInvoke(resourceLoadList, "scroll_horizontal", daysDisplacement + "")); + response("", new AuInvoke(resourceLoadList, "scroll_horizontal", Integer.toString(daysDisplacement))); moveCurrentPositionScroll(); } @Override protected void moveCurrentPositionScroll() { - // get the previous data. + // Get the previous data LocalDate previousStart = getPreviousStart(); - // get the current data + // Get the current data int diffDays = getTimeTrackerComponent().getDiffDays(previousStart); double pixelPerDay = getTimeTrackerComponent().getPixelPerDay(); - response("move_scroll", new AuInvoke(resourceLoadList, "move_scroll", "" + diffDays, "" + pixelPerDay)); + response("move_scroll", new AuInvoke( + resourceLoadList, "move_scroll", Integer.toString(diffDays), Double.toString(pixelPerDay))); } protected void updateCurrentDayScroll() { @@ -343,7 +341,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { response( "update_day_scroll", - new AuInvoke(resourceLoadList, "update_day_scroll", "" + previousPixelPerDay)); + new AuInvoke(resourceLoadList, "update_day_scroll", Double.toString(previousPixelPerDay))); } }; @@ -356,8 +354,10 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { getFellow("insertionPointLeftPanel").appendChild(leftPane); leftPane.afterCompose(); - getFellow("insertionPointRightPanel").appendChild(timeTrackerComponent); - getFellow("insertionPointRightPanel").appendChild(resourceLoadList); + Div insertionPointRightPanel = (Div) getFellow("insertionPointRightPanel"); + insertionPointRightPanel.appendChild(timeTrackerComponent); + insertionPointRightPanel.appendChild(resourceLoadList); + TimeTrackerComponent timeTrackerHeader = createTimeTrackerHeader(); getFellow("insertionPointTimetracker").appendChild(timeTrackerHeader); @@ -374,21 +374,30 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { timeTrackerHeader.afterCompose(); timeTrackerComponent.afterCompose(); - listZoomLevels = (Listbox) getFellow("listZoomLevels"); + Listbox listZoomLevels = (Listbox) getFellow("listZoomLevels"); listZoomLevels.setSelectedIndex(timeTracker.getDetailLevel().ordinal()); + filterByNameCombo = (Combobox) getFellow(FILTER_BY_NAME_COMBO_COMPONENT); + filterByNameCombo.setWidth("85px"); + if ( paginationType == PaginationType.INTERNAL_PAGINATION && refreshNameFilter ) { setupNameFilter(); } else if ( paginationType == PaginationType.NONE ) { - getFellow("filterByNameCombo").setVisible(false); + getFellow(FILTER_BY_NAME_COMBO_COMPONENT).setVisible(false); getFellow("filterByNameLabel").setVisible(false); } getFellow("insertionPointChart").appendChild(loadChart); + this.visibleChart = expandResourceLoadViewCharts; this.visibleChart = expandResourceLoadViewCharts; ((South) getFellow("graphics")).setOpen(this.visibleChart); + + if (!visibleChart) { + ((South) getFellow("graphics")).setTitle(_("Graphics are disabled")); + } + savePreviousData(); } @@ -417,18 +426,14 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { private TimeTrackerComponent createTimeTrackerHeader() { return new TimeTrackerComponent(timeTracker) { - - @Override - protected void scrollHorizontalPercentage(int pixelsDisplacement) { - } + @Override + protected void scrollHorizontalPercentage(int pixelsDisplacement) {} @Override - protected void moveCurrentPositionScroll() { - } + protected void moveCurrentPositionScroll() {} @Override - protected void updateCurrentDayScroll() { - } + protected void updateCurrentDayScroll() {} }; } @@ -438,7 +443,6 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } private void setupNameFilter() { - Combobox filterByNameCombo = (Combobox) getFellow("filterByNameCombo"); filterByNameCombo.getChildren().clear(); int size = groups.size(); @@ -469,7 +473,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { Comboitem lastItem = new Comboitem(); lastItem.setLabel(_("All")); lastItem.setDescription(_("Show all elements")); - lastItem.setValue(new Integer(-1)); + lastItem.setValue(-1); filterByNameCombo.appendChild(lastItem); filterByNameCombo.setSelectedIndex(0); @@ -477,26 +481,28 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } /** - * Returns only the LoadTimeLine objects that have to be show - * according to the name filter. - * @return + * @return only the LoadTimeLine objects that have to be show according to the name filter. */ private List getGroupsToShow() { if ( paginationType != PaginationType.INTERNAL_PAGINATION || filterByNamePosition == -1 ) { return groups; } - boolean condition = (filterByNamePosition + numberOfGroupsByName < groups.size()); + boolean condition = filterByNamePosition + numberOfGroupsByName < groups.size(); int endPosition = condition ? filterByNamePosition + numberOfGroupsByName : groups.size(); return groups.subList(filterByNamePosition, endPosition); } + /** + * Should be public! + * Used in resourcesLoadLayout.zul + */ public void onSelectFilterByName(Combobox comboByName) { - if ( comboByName.getSelectedItemApi() == null ) { + if ( comboByName.getSelectedItem() == null ) { resetComboByName(comboByName); } else { - Integer filterByNamePosition = (Integer) comboByName.getSelectedItemApi().getValue(); + Integer filterByNamePosition = comboByName.getSelectedItem().getValue(); if ( paginationType != PaginationType.NONE ) { this.filterByNamePosition = filterByNamePosition; @@ -523,7 +529,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { public void doAction() { if ( paginationType == PaginationType.INTERNAL_PAGINATION ) { - //if the pagination is internal, we are in charge of repainting the graph + // If the pagination is internal, we are in charge of repainting the graph treeModel = createModelForTree(); timeTrackerComponent = timeTrackerForResourcesLoadPanel(timeTracker); @@ -531,12 +537,7 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { leftPane = new ResourceLoadLeftPane(treeModel, resourceLoadList); } - nameFilterListener.fireEvent(new IListenerNotification() { - @Override - public void doNotify(IPaginationFilterChangedListener listener) { - listener.filterChanged(filterByNamePosition); - } - }); + nameFilterListener.fireEvent(listener -> listener.filterChanged(filterByNamePosition)); afterCompose(); } @@ -549,9 +550,9 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } public void setInternalPaginationDisabled(boolean disabled) { - Combobox combo = ((Combobox) getFellow("filterByNameCombo")); + Combobox combo = (Combobox) getFellow(FILTER_BY_NAME_COMBO_COMPONENT); if ( combo != null && combo.isDisabled() != disabled ) { - filterByNamePosition = disabled? -1 : (Integer) combo.getSelectedItemApi().getValue(); + filterByNamePosition = disabled? -1 : (Integer) combo.getSelectedItem().getValue(); combo.setDisabled(disabled); } } @@ -560,15 +561,12 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { nameFilterListener.addListener(iFilterChangedListener); } + /** + * It should be public! + */ public void changeChartVisibility(boolean visible) { visibleChart = visible; - - chartVisibilityListeners.fireEvent(new IListenerNotification() { - @Override - public void doNotify(IChartVisibilityChangedListener listener) { - listener.chartVisibilityChanged(visibleChart); - } - }); + chartVisibilityListeners.fireEvent(listener -> listener.chartVisibilityChanged(visibleChart)); } public boolean isVisibleChart() { @@ -588,11 +586,9 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { } public Combobox getPaginationFilterCombobox() { - if ( paginationType == PaginationType.EXTERNAL_PAGINATION ) { - return (Combobox) getFellow("filterByNameCombo"); - } - - return null; + return paginationType == PaginationType.EXTERNAL_PAGINATION + ? (Combobox) getFellow(FILTER_BY_NAME_COMBO_COMPONENT) + : null; } public enum PaginationType { @@ -600,14 +596,16 @@ public class ResourcesLoadPanel extends HtmlMacroComponent { * Sets the widget to take care of the pagination of all the LoadTimeLine objects received. */ INTERNAL_PAGINATION, + /** * The widget will only show the combo box but its content has to be configured externally. - * The pagination has to be managed externally too: the widget will show all the LoadTimeLine - * objects received. + * The pagination has to be managed externally too: the widget will show all the LoadTimeLine objects received. */ EXTERNAL_PAGINATION, + /** - * Disables pagination. Shows all the LoadTimeLine objects received. + * Disables pagination. + * Shows all the LoadTimeLine objects received. */ NONE } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/servlets/CallbackServlet.java b/ganttzk/src/main/java/org/zkoss/ganttz/servlets/CallbackServlet.java index 80786f69c..d70276bad 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/servlets/CallbackServlet.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/servlets/CallbackServlet.java @@ -34,11 +34,12 @@ import java.util.concurrent.TimeUnit; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.Validate; -import org.zkoss.web.servlet.http.HttpServlet; + /** * Servlet that allows to register custom responses. It must be declared at diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/IConvertibleToColumn.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/IConvertibleToColumn.java index 9a65d8f95..e21b5ce75 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/IConvertibleToColumn.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/IConvertibleToColumn.java @@ -21,7 +21,7 @@ package org.zkoss.ganttz.timetracker; -import org.zkoss.zul.api.Column; +import org.zkoss.zul.Column; public interface IConvertibleToColumn { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/OnColumnsRowRenderer.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/OnColumnsRowRenderer.java index 83bd4be11..af7c1d396 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/OnColumnsRowRenderer.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/OnColumnsRowRenderer.java @@ -34,15 +34,20 @@ import org.zkoss.zul.RowRenderer; public class OnColumnsRowRenderer implements RowRenderer { + private final List columns; + + private final ICellForDetailItemRenderer cellRenderer; + + private Class type; + public static OnColumnsRowRenderer create(ICellForDetailItemRenderer cellRenderer, Collection columns) { return create(inferGenericType(cellRenderer), cellRenderer, columns); } - public static OnColumnsRowRenderer create(Class type, - ICellForDetailItemRenderer cellRenderer, - Collection columns) { + public static OnColumnsRowRenderer create( + Class type, ICellForDetailItemRenderer cellRenderer, Collection columns) { return new OnColumnsRowRenderer<>(type, cellRenderer, columns); } @@ -95,19 +100,12 @@ public class OnColumnsRowRenderer implements RowRenderer { private static void informCannotBeInferred(ICellForDetailItemRenderer renderer) { throw new IllegalArgumentException( - "the generic type cannot be inferred " + - "if actual type parameters are not declared " + - "or implements the raw interface: " + - renderer.getClass().getName()); + "the generic type cannot be inferred if actual type parameters are not declared " + + "or implements the raw interface: " + renderer.getClass().getName()); } - private final List columns; - private final ICellForDetailItemRenderer cellRenderer; - private Class type; + private OnColumnsRowRenderer(Class type, ICellForDetailItemRenderer cellRenderer, Collection columns) { - private OnColumnsRowRenderer(Class type, - ICellForDetailItemRenderer cellRenderer, - Collection columns) { Validate.notNull(type); Validate.notNull(columns); Validate.notNull(cellRenderer); @@ -119,15 +117,16 @@ public class OnColumnsRowRenderer implements RowRenderer { } @Override - public void render(Row row, Object data) { - if ( !type.isInstance(data) ) { - throw new IllegalArgumentException(data + " is not instance of " + type); + public void render(Row row, Object o, int index) throws Exception { + if ( !type.isInstance(o) ) { + throw new IllegalArgumentException(o + " is not instance of " + type); } for (C item : columns) { - Component child = cellRenderer.cellFor(item, type.cast(data)); + Component child = cellRenderer.cellFor(item, type.cast(o)); child.setParent(row); } } + } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTable.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTable.java index ecd6a88a4..bf1d646b2 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTable.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTable.java @@ -41,8 +41,9 @@ public class TimeTrackedTable extends HtmlMacroComponent { private transient IZoomLevelChangedListener zoomListener; public TimeTrackedTable(Callable> dataSource, - ICellForDetailItemRenderer cellRenderer, - TimeTracker timeTracker) { + ICellForDetailItemRenderer cellRenderer, + TimeTracker timeTracker) { + this.data = dataSource; this.cellRenderer = cellRenderer; this.timeTracker = timeTracker; @@ -56,8 +57,8 @@ public class TimeTrackedTable extends HtmlMacroComponent { this.timeTracker.addZoomListener(zoomListener); } - public ListModel getTableModel() { - return new ListModelList(getData()); + public ListModel getTableModel() { + return new ListModelList<>(getData()); } private List getData() { @@ -69,8 +70,7 @@ public class TimeTrackedTable extends HtmlMacroComponent { } public RowRenderer getRowRenderer() { - return OnColumnsRowRenderer.create(cellRenderer, timeTracker - .getDetailsSecondLevel()); + return OnColumnsRowRenderer.create(cellRenderer, timeTracker.getDetailsSecondLevel()); } public Collection getDetailsSecondLevel() { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTableWithLeftPane.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTableWithLeftPane.java index 73d5ef594..4941c3390 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTableWithLeftPane.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackedTableWithLeftPane.java @@ -33,7 +33,7 @@ import org.zkoss.zul.Columns; import org.zkoss.zul.Grid; import org.zkoss.zul.ListModel; import org.zkoss.zul.ListModelList; -import org.zkoss.zul.api.Column; +import org.zkoss.zul.Column; public class TimeTrackedTableWithLeftPane { @@ -48,10 +48,13 @@ public class TimeTrackedTableWithLeftPane { ICellForDetailItemRenderer leftPaneCellRenderer, ICellForDetailItemRenderer cellRendererForTimeTracker, TimeTracker timeTracker) { + this.dataSource = dataSource; - timeTrackedTable = new TimeTrackedTable( + + timeTrackedTable = new TimeTrackedTable<>( dataForTimeTracker(dataSource), cellRendererForTimeTracker, timeTracker); + timeTrackedTable.setSclass("inner-timetracked-table"); leftPane = new Grid(); zoomLevelListener = new IZoomLevelChangedListener() { @@ -60,28 +63,32 @@ public class TimeTrackedTableWithLeftPane { loadModelForLeftPane(); } }; + timeTracker.addZoomListener(zoomLevelListener); + leftPane.appendChild(createColumns(leftPaneColumns)); - leftPane.setRowRenderer(OnColumnsRowRenderer.create( - leftPaneCellRenderer, leftPaneColumns)); + leftPane.setRowRenderer(OnColumnsRowRenderer.create(leftPaneCellRenderer, leftPaneColumns)); + loadModelForLeftPane(); } - private static Columns createColumns( - Collection convertibleToColumns) { + private static Columns createColumns(Collection convertibleToColumns) { Columns result = new Columns(); + for (Column column : toColumns(convertibleToColumns)) { result.appendChild(column); } + return result; } - private static List toColumns( - Collection convertibleToColumns) { - List columns = new ArrayList(); + private static List toColumns(Collection convertibleToColumns) { + List columns = new ArrayList<>(); + for (IConvertibleToColumn c : convertibleToColumns) { columns.add(c.toColumn()); } + return columns; } @@ -89,12 +96,13 @@ public class TimeTrackedTableWithLeftPane { leftPane.setModel(createModelForLeftPane()); } - private ListModel createModelForLeftPane() { - return new ListModelList(retrieveLeftPaneList()); + private ListModel createModelForLeftPane() { + return new ListModelList<>(retrieveLeftPaneList()); } private List retrieveLeftPaneList() { PairOfLists pair = loadPairOfListsFromCallable(); + return pair.getFirst(); } @@ -106,8 +114,7 @@ public class TimeTrackedTableWithLeftPane { } } - private Callable> dataForTimeTracker( - final Callable> dataSource) { + private Callable> dataForTimeTracker(final Callable> dataSource) { return new Callable>() { @Override @@ -120,10 +127,11 @@ public class TimeTrackedTableWithLeftPane { private boolean afterComposeCalled = false; public TimeTrackedTable getTimeTrackedTable() { - if (!afterComposeCalled) { + if ( !afterComposeCalled ) { timeTrackedTable.afterCompose(); afterComposeCalled = true; } + return timeTrackedTable; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java index e0a5d74a5..96436b6fd 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTracker.java @@ -23,8 +23,6 @@ package org.zkoss.ganttz.timetracker; import static org.zkoss.ganttz.i18n.I18nHelper._; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.Collection; import java.util.Date; @@ -34,16 +32,15 @@ import org.zkoss.ganttz.DatesMapperOnInterval; import org.zkoss.ganttz.IDatesMapper; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.timetracker.zoom.DetailItem; -import org.zkoss.ganttz.timetracker.zoom.IDetailItemModificator; +import org.zkoss.ganttz.timetracker.zoom.IDetailItemModifier; import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener; -import org.zkoss.ganttz.timetracker.zoom.SeveralModificators; +import org.zkoss.ganttz.timetracker.zoom.SeveralModifiers; import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState; import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.Interval; import org.zkoss.ganttz.util.LongOperationFeedback; import org.zkoss.ganttz.util.WeakReferencedListeners; import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation; -import org.zkoss.ganttz.util.WeakReferencedListeners.IListenerNotification; import org.zkoss.zk.ui.Component; public class TimeTracker { @@ -72,9 +69,9 @@ public class TimeTracker { private Interval interval; - private final IDetailItemModificator firstLevelModificator; + private final IDetailItemModifier firstLevelModifier; - private final IDetailItemModificator secondLevelModificator; + private final IDetailItemModifier secondLevelModifier; private final Component componentOnWhichGiveFeedback; @@ -82,46 +79,48 @@ public class TimeTracker { private IDetailItemFilter filter = null; - public IDetailItemFilter getFilter() { - return filter; - } + private Interval realIntervalCached; public TimeTracker(Interval interval, ZoomLevel zoomLevel, Component parent) { - this(interval, zoomLevel, SeveralModificators.empty(), SeveralModificators.empty(), parent); + this(interval, zoomLevel, SeveralModifiers.empty(), SeveralModifiers.empty(), parent); } public TimeTracker(Interval interval, Component componentOnWhichGiveFeedback) { - this(interval, SeveralModificators.empty(), SeveralModificators.empty(), componentOnWhichGiveFeedback); + this(interval, SeveralModifiers.empty(), SeveralModifiers.empty(), componentOnWhichGiveFeedback); } public TimeTracker( Interval interval, - IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator, + IDetailItemModifier firstLevelModifier, + IDetailItemModifier secondLevelModifier, Component componentOnWhichGiveFeedback) { Validate.notNull(interval); - Validate.notNull(firstLevelModificator); - Validate.notNull(secondLevelModificator); + Validate.notNull(firstLevelModifier); + Validate.notNull(secondLevelModifier); Validate.notNull(componentOnWhichGiveFeedback); this.interval = interval; - this.firstLevelModificator = firstLevelModificator; - this.secondLevelModificator = secondLevelModificator; + this.firstLevelModifier = firstLevelModifier; + this.secondLevelModifier = secondLevelModifier; this.componentOnWhichGiveFeedback = componentOnWhichGiveFeedback; } public TimeTracker( Interval interval, ZoomLevel zoomLevel, - IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator, + IDetailItemModifier firstLevelModifier, + IDetailItemModifier secondLevelModifier, Component componentOnWhichGiveFeedback) { - this(interval, firstLevelModificator, secondLevelModificator, componentOnWhichGiveFeedback); + this(interval, firstLevelModifier, secondLevelModifier, componentOnWhichGiveFeedback); detailLevel = zoomLevel; } + public IDetailItemFilter getFilter() { + return filter; + } + public void setFilter(IDetailItemFilter filter) { this.filter = filter; datesMapper = null; @@ -144,11 +143,7 @@ public class TimeTracker { } private Collection filterFirstLevel(Collection firstLevelDetails) { - if ( filter == null ) { - return firstLevelDetails; - } - - return filter.selectsFirstLevel(firstLevelDetails); + return filter == null ? firstLevelDetails : filter.selectsFirstLevel(firstLevelDetails); } public Collection getDetailsSecondLevel() { @@ -160,15 +155,9 @@ public class TimeTracker { } private Collection filterSecondLevel(Collection secondLevelDetails) { - if ( filter == null ) { - return secondLevelDetails; - } - - return filter.selectsSecondLevel(secondLevelDetails); + return filter == null ? secondLevelDetails : filter.selectsSecondLevel(secondLevelDetails); } - private Interval realIntervalCached; - public Interval getRealInterval() { if ( realIntervalCached == null ) { realIntervalCached = getTimeTrackerState().getRealIntervalFor(interval); @@ -178,11 +167,12 @@ public class TimeTracker { } public TimeTrackerState getTimeTrackerState() { - return detailLevel.getTimeTrackerState(firstLevelModificator, secondLevelModificator); + return detailLevel.getTimeTrackerState(firstLevelModifier, secondLevelModifier); } private void fireZoomChanged() { - zoomListeners.fireEvent(new IListenerNotification() { + /* Do not replace it with lambda */ + zoomListeners.fireEvent(new WeakReferencedListeners.IListenerNotification() { @Override public void doNotify(IZoomLevelChangedListener listener) { listener.zoomLevelChanged(detailLevel); @@ -257,13 +247,7 @@ public class TimeTracker { } public void trackPosition(final Task task) { - task.addFundamentalPropertiesChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - updateIntervalIfNeeded(task); - } - }); - + task.addFundamentalPropertiesChangeListener(evt -> updateIntervalIfNeeded(task)); updateIntervalIfNeeded(task); } @@ -319,16 +303,14 @@ public class TimeTracker { } private LocalDate endPlusOneMonth(Task task) { - Date taskEnd = max(task.getEndDate().toDayRoundedDate(), task.getDeadline()); - - return new LocalDate(taskEnd).plusMonths(1); + return new LocalDate(max(task.getEndDate().toDayRoundedDate(), task.getDeadline())).plusMonths(1); } private LocalDate startMinusTwoWeeks(Task task) { - // the deadline could be before the start + // The deadline could be before the start Date start = min(task.getBeginDate().toDayRoundedDate(), task.getDeadline()); - // the last consolidated value could be before the start + // The last consolidated value could be before the start if ( task.getConsolidatedline() != null ) { start = min(start, task.getConsolidatedline().toDayRoundedDate()); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java index b27141c43..9ae3d822d 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponent.java @@ -25,7 +25,6 @@ import java.util.Collection; import org.joda.time.Days; import org.joda.time.LocalDate; -import org.zkoss.ganttz.IDatesMapper; import org.zkoss.ganttz.timetracker.zoom.DetailItem; import org.zkoss.ganttz.timetracker.zoom.IZoomLevelChangedListener; import org.zkoss.ganttz.timetracker.zoom.TimeTrackerState; @@ -35,36 +34,35 @@ import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.HtmlMacroComponent; /** + * Works with time header of some pages. + * * @author Javier Moran Rua */ public abstract class TimeTrackerComponent extends HtmlMacroComponent { private final TimeTracker timeTracker; - private IZoomLevelChangedListener zoomListener; + private final String secondLevelZul; + private String timeTrackerElementId; + private int scrollLeft; public TimeTrackerComponent(TimeTracker timeTracker) { - this(timeTracker, - "~./ganttz/zul/timetracker/timetrackersecondlevel.zul", - "timetracker"); + this(timeTracker, "~./ganttz/zul/timetracker/timetrackersecondlevel.zul", "timetracker"); } - protected TimeTrackerComponent(TimeTracker timeTracker, - String secondLevelZul, String timetrackerId) { + TimeTrackerComponent(TimeTracker timeTracker, String secondLevelZul, String timetrackerId) { this.secondLevelZul = secondLevelZul; this.timeTracker = timeTracker; - zoomListener = new IZoomLevelChangedListener() { - @Override - public void zoomLevelChanged(ZoomLevel detailLevel) { - if (isInPage()) { - recreate(); - changeDetailLevel(getDaysFor(scrollLeft)); - } + IZoomLevelChangedListener zoomListener = detailLevel -> { + if ( isInPage() ) { + recreate(); + changeDetailLevel(getDaysFor(scrollLeft)); } }; + this.timeTracker.addZoomListener(zoomListener); timeTrackerElementId = timetrackerId; } @@ -81,22 +79,24 @@ 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. - * */ + /** + * 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 compose() { super.compose(); + Component fellow = getFellow("firstleveldetails"); addSecondLevels(fellow.getParent()); } private void addSecondLevels(Component parent) { - Executions.getCurrent().createComponents(secondLevelZul, parent, - getAttributes()); + Executions.getCurrent().createComponents(secondLevelZul, parent, getAttributes()); } public ZoomLevel getZoomLevel() { @@ -146,9 +146,9 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent { } public int getDiffDays(LocalDate previousStart) { - // get the current data - IDatesMapper mapper = getTimeTracker().getMapper(); + // Get the current data LocalDate start = getTimeTracker().getRealInterval().getStart(); + return Days.daysBetween(start, previousStart).getDays(); } @@ -166,7 +166,7 @@ public abstract class TimeTrackerComponent extends HtmlMacroComponent { } public String getWidgetClass(){ - return getDefinition().getDefaultWidgetClass(); + return getDefinition().getDefaultWidgetClass(this); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponentWithoutColumns.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponentWithoutColumns.java index 4f91c480a..fc581afd5 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponentWithoutColumns.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/TimeTrackerComponentWithoutColumns.java @@ -21,16 +21,14 @@ package org.zkoss.ganttz.timetracker; /** - * A {@link TimeTrackerComponent} that doesn't show columns as watermark + * A {@link TimeTrackerComponent} that doesn't show columns as watermark. + * * @author Óscar González Fernández */ public class TimeTrackerComponentWithoutColumns extends TimeTrackerComponent { - public TimeTrackerComponentWithoutColumns(TimeTracker timeTracker, - String timeTrackerId) { - super(timeTracker, - "~./ganttz/zul/timetracker/secondlevelwithoutwatermark.zul", - timeTrackerId); + public TimeTrackerComponentWithoutColumns(TimeTracker timeTracker, String timeTrackerId) { + super(timeTracker, "~./ganttz/zul/timetracker/secondlevelwithoutwatermark.zul", timeTrackerId); } @Override @@ -38,14 +36,8 @@ public class TimeTrackerComponentWithoutColumns extends TimeTrackerComponent { } @Override - protected void moveCurrentPositionScroll() { - // TODO Auto-generated method stub - - } + protected void moveCurrentPositionScroll() {} @Override - protected void updateCurrentDayScroll() { - // TODO Auto-generated method stub - - } + protected void updateCurrentDayScroll() {} } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java index 4d8f65299..55dc8e46c 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFiveTimeTrackerState.java @@ -21,57 +21,51 @@ package org.zkoss.ganttz.timetracker.zoom; -import org.joda.time.DateTime; import org.joda.time.Days; import org.joda.time.LocalDate; import org.joda.time.ReadablePeriod; /** - * Zoom level for weeks in the first level and days in the second level + * Zoom level for weeks in the first level and days in the second level. + * * @author Óscar González Fernández * @author Lorenzo Tilve Álvaro */ -public class DetailFiveTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { +public class DetailFiveTimeTrackerState extends TimeTrackerStateWithSubintervalsFitting { private static final int NUMBER_OF_DAYS_MINIMUM = 50; - public static final int FIRST_LEVEL_SIZE = 210; - public static final int SECOND_LEVEL_SIZE = 30; - DetailFiveTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - super(firstLevelModificator, secondLevelModificator); + private static final int FIRST_LEVEL_SIZE = 210; + + private static final int SECOND_LEVEL_SIZE = 30; + + DetailFiveTimeTrackerState( + IDetailItemModifier firstLevelModifier, IDetailItemModifier secondLevelModifier) { + + super(firstLevelModifier, secondLevelModifier); } + @Override public final double daysPerPixel() { - return ((double) 1 / SECOND_LEVEL_SIZE); + return (double) 1 / SECOND_LEVEL_SIZE; } @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(FIRST_LEVEL_SIZE, dateTime - .getWeekOfWeekyear() - + dateTime.toString(", MMM YYYY"), dateTime, dateTime - .plusDays(7)); - } - }; + return dateTime -> new DetailItem( + FIRST_LEVEL_SIZE, + dateTime.getWeekOfWeekyear() + dateTime.toString(", MMM YYYY"), + dateTime, + dateTime.plusDays(7)); } @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(SECOND_LEVEL_SIZE, dateTime - .getDayOfMonth() - + "", dateTime, dateTime.plusDays(1)); - } - }; + return dateTime -> new DetailItem( + SECOND_LEVEL_SIZE, + Integer.toString(dateTime.getDayOfMonth()), + dateTime, + dateTime.plusDays(1)); } @Override @@ -87,11 +81,12 @@ public class DetailFiveTimeTrackerState extends @Override protected LocalDate round(LocalDate date, boolean down) { int dayOfWeek = date.getDayOfWeek(); + if (dayOfWeek == 1) { return date; } - return down ? date.withDayOfWeek(1) : date.withDayOfWeek(1) - .plusWeeks(1); + + return down ? date.withDayOfWeek(1) : date.withDayOfWeek(1).plusWeeks(1); } @Override diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java index a68abe444..394d366e6 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailFourTimeTrackerState.java @@ -31,7 +31,8 @@ import org.joda.time.LocalDate; import org.joda.time.Months; /** - * Zoom level for months and years and weeks in the second level + * Zoom level for months and years and weeks in the second level. + * * @author Óscar González Fernández * @author Lorenzo Tilve Álvaro */ @@ -39,53 +40,39 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { private static final int NUMBER_OF_WEEKS_MINIMUM = 40; - DetailFourTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - super(firstLevelModificator, secondLevelModificator); - } - private static final int SECOND_LEVEL_SIZE = 56; + DetailFourTimeTrackerState( + IDetailItemModifier firstLevelModifier, IDetailItemModifier secondLevelModifier) { + + super(firstLevelModifier, secondLevelModifier); + } + public final double pixelPerDay() { - return (SECOND_LEVEL_SIZE / (double) 7); + return SECOND_LEVEL_SIZE / (double) 7; } public final double daysPerPixel() { - return ((double) 7 / SECOND_LEVEL_SIZE); + return (double) 7 / SECOND_LEVEL_SIZE; } - - private IDetailItemCreator firstLevelCreator; - @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - firstLevelCreator = new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(getSizeMonth(dateTime), dateTime - .toString("MMMM,YYYY"), dateTime, dateTime - .plusMonths(1)); - } - }; - return firstLevelCreator; + return dateTime -> new DetailItem( + getSizeMonth(dateTime), dateTime.toString("MMMM,YYYY"), dateTime, dateTime.plusMonths(1)); } @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { + return dateTime -> { + int daysUntilFirstDayNextWeek = getDaysUntilFirstDayNextWeek(dateTime.toLocalDate()); + int sizeWeek = BigDecimal.valueOf(pixelPerDay() * daysUntilFirstDayNextWeek).intValue(); - @Override - public DetailItem create(DateTime dateTime) { - int daysUntilFirstDayNextWeek = getDaysUntilFirstDayNextWeek(dateTime - .toLocalDate()); - int sizeWeek = new BigDecimal(pixelPerDay() - * daysUntilFirstDayNextWeek).intValue(); - - return new DetailItem(sizeWeek, dateTime.getWeekOfWeekyear() - + "", dateTime, - dateTime.plusDays(daysUntilFirstDayNextWeek)); - } + return new DetailItem( + sizeWeek, + Integer.toString(dateTime.getWeekOfWeekyear()), + dateTime, + dateTime.plusDays(daysUntilFirstDayNextWeek)); }; } @@ -94,8 +81,8 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { if (date.getDayOfMonth() == 1) { return date; } - return down ? date.withDayOfMonth(1) : date.plusMonths(1) - .withDayOfMonth(1); + + return down ? date.withDayOfMonth(1) : date.plusMonths(1).withDayOfMonth(1); } @Override @@ -114,17 +101,18 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { } private int getSizeMonth(DateTime dateTime) { - Calendar cal = new GregorianCalendar(dateTime.getYear(), dateTime - .getMonthOfYear() - 1, dateTime.getDayOfMonth()); + Calendar cal = + new GregorianCalendar(dateTime.getYear(), dateTime.getMonthOfYear() - 1, dateTime.getDayOfMonth()); + // Get the number of days in that month int days = cal.getActualMaximum(Calendar.DAY_OF_MONTH); - return new BigDecimal(pixelPerDay() * days).intValue(); + + return BigDecimal.valueOf(pixelPerDay() * days).intValue(); } @Override protected Iterator getPeriodsFirstLevelGenerator(LocalDate start) { return new LazyGenerator(start) { - @Override protected LocalDate next(LocalDate last) { return last.plus(Months.ONE); @@ -135,14 +123,9 @@ public class DetailFourTimeTrackerState extends TimeTrackerState { @Override protected Iterator getPeriodsSecondLevelGenerator(LocalDate start) { return new LazyGenerator(start) { - @Override protected LocalDate next(LocalDate last) { - if (last.getDayOfWeek() != 1) { - return last.plusDays(getDaysUntilFirstDayNextWeek(last)); - } else { - return last.plusWeeks(1); - } + return last.getDayOfWeek() != 1 ? last.plusDays(getDaysUntilFirstDayNextWeek(last)) : last.plusWeeks(1); } }; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailItem.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailItem.java index 3b470d396..cf2676879 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailItem.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailItem.java @@ -25,42 +25,40 @@ import org.joda.time.DateTime; import org.joda.time.Days; /** - * One of each of the subintervals a time line is divided into + * One of each of the subintervals a time line is divided into. + * * @author Francisco Javier Moran Rúa * @author Lorenzo Tilve Álvaro */ public final class DetailItem { private int size; + private String name; private boolean even; + private boolean bankHoliday; private String bankHolidayWeek; - public String getBankHolidayWeek() { - return bankHolidayWeek; - } - - public void setBankHolidayWeek(String bankHolidayWeek) { - this.bankHolidayWeek = bankHolidayWeek; - } - private boolean currentPeriod; + private int currentDayOffset; private boolean projectStart = false; + private int projectStartOffset = 0; private boolean deadlinePeriod; + private int deadlineOffset; private DateTime startDate; + private DateTime endDate; - public DetailItem(int size, String name, DateTime startDate, - DateTime endDate) { + public DetailItem(int size, String name, DateTime startDate, DateTime endDate) { this(size, name, false); this.startDate = startDate; this.endDate = endDate; @@ -88,32 +86,41 @@ public final class DetailItem { this.currentDayOffset = currentdayoffset; } - public DetailItem(int size, String name, int currentdayoffset, - int deadlineoffset) { + public DetailItem(int size, String name, int currentdayoffset, int deadlineoffset) { this(size, name, currentdayoffset); this.deadlinePeriod = true; this.deadlineOffset = deadlineoffset; } + public String getBankHolidayWeek() { + return bankHolidayWeek; + } + + public void setBankHolidayWeek(String bankHolidayWeek) { + this.bankHolidayWeek = bankHolidayWeek; + } + public void markCurrentDay() { if (this.startDate.isBeforeNow() && this.endDate.isAfterNow()) { - int offsetInPx = Math - .round(((((float) Days.daysBetween(this.startDate, - new DateTime()).getDays()) + (float) 0.5) / ((float) Days - .daysBetween(this.startDate, this.endDate).getDays())) - * this.size); + + int offsetInPx = Math.round( + ( (((float) Days.daysBetween(this.startDate, new DateTime()).getDays()) + (float) 0.5) / + ((float) Days.daysBetween(this.startDate, this.endDate).getDays()) ) + * this.size ); + // 1px per column side, 1px for right border and 1px own bg-width this.markCurrentDay(Math.min(this.size - 4, offsetInPx)); } } public void markProjectStart(DateTime projectStart) { - if (!this.startDate.isAfter(projectStart) - && projectStart.isBefore(endDate)) { - int offsetInPx = Math.round((((float) Days.daysBetween( - this.startDate, projectStart).getDays()) / ((float) Days - .daysBetween(this.startDate, this.endDate).getDays())) - * this.size); + if (!this.startDate.isAfter(projectStart) && projectStart.isBefore(endDate)) { + + int offsetInPx = Math.round( + ( ((float) Days.daysBetween(this.startDate, projectStart).getDays()) / + ((float) Days.daysBetween(this.startDate, this.endDate).getDays()) ) + * this.size); + this.markprojectStart(offsetInPx); } } @@ -121,10 +128,12 @@ public final class DetailItem { public void markDeadlineDay(DateTime maxdeadline) { DateTime deadline = maxdeadline.plusDays(1); if (!this.startDate.isAfter(deadline) && deadline.isBefore(endDate)) { - int offsetInPx = Math.round((((float) Days.daysBetween( - this.startDate, deadline).getDays()) / ((float) Days - .daysBetween(this.startDate, this.endDate).getDays())) - * this.size); + + int offsetInPx = Math.round( + ( ((float) Days.daysBetween(this.startDate, deadline).getDays()) / + ((float) Days.daysBetween(this.startDate, this.endDate).getDays()) ) + * this.size); + // 1px per column side, 1px for right border and 1px own bg-width this.markDeadlineDay(Math.min(this.size - 4, offsetInPx)); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java index 24aa02adc..502af80ed 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailOneTimeTrackerState.java @@ -27,27 +27,26 @@ import org.joda.time.Months; import org.joda.time.ReadablePeriod; import org.joda.time.Years; - /** - * Zoom level with years in the first level and semesters in the second level + * Zoom level with years in the first level and semesters in the second level. + * * @author Francisco Javier Moran Rúa * @author Lorenzo Tilve Álvaro */ -public class DetailOneTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { +public class DetailOneTimeTrackerState extends TimeTrackerStateWithSubintervalsFitting { - public static final Period MINIMUN_PERIOD = PeriodType.YEARS.amount(6); + static final Period MINIMUM_PERIOD = PeriodType.YEARS.amount(6); private static final int FIRST_LEVEL_ITEM_SIZE = 200; + private static final int SECOND_LEVEL_ITEM_SIZE = 100; public final double daysPerPixel() { - return ((double) 365 / FIRST_LEVEL_ITEM_SIZE); + return (double) 365 / FIRST_LEVEL_ITEM_SIZE; } - DetailOneTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - super(firstLevelModificator, secondLevelModificator); + DetailOneTimeTrackerState(IDetailItemModifier firstLevelModifier, IDetailItemModifier secondLevelModifier) { + super(firstLevelModifier, secondLevelModifier); } @Override @@ -62,15 +61,11 @@ public class DetailOneTimeTrackerState extends @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - @Override - public DetailItem create(DateTime start) { - int year = start.getYear(); - DateTime end = new LocalDate(year + 1, 1, 1) - .toDateTimeAtStartOfDay(); - return new DetailItem(FIRST_LEVEL_ITEM_SIZE, start.getYear() - + "", start, end); - } + return start -> { + int year = start.getYear(); + DateTime end = new LocalDate(year + 1, 1, 1).toDateTimeAtStartOfDay(); + + return new DetailItem(FIRST_LEVEL_ITEM_SIZE, Integer.toString(start.getYear()), start, end); }; } @@ -81,15 +76,8 @@ public class DetailOneTimeTrackerState extends @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(SECOND_LEVEL_ITEM_SIZE, - dateTime.getMonthOfYear() == 1 ? "H1" : "H2", dateTime, - dateTime.plusMonths(6)); - } - }; + return dateTime -> new DetailItem( + SECOND_LEVEL_ITEM_SIZE, dateTime.getMonthOfYear() == 1 ? "H1" : "H2", dateTime, dateTime.plusMonths(6)); } @Override @@ -103,12 +91,12 @@ public class DetailOneTimeTrackerState extends } public static LocalDate doYearRound(LocalDate date, boolean down) { - return new LocalDate(date.getYear() + (down?0:1), 1, 1); + return new LocalDate(date.getYear() + (down ? 0 : 1), 1, 1); } @Override protected Period getMinimumPeriod() { - return MINIMUN_PERIOD; + return MINIMUM_PERIOD; } -} +} \ No newline at end of file diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailSixTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailSixTimeTrackerState.java deleted file mode 100644 index 71b8b1d63..000000000 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailSixTimeTrackerState.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * This file is part of LibrePlan - * - * 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 . - */ - -package org.zkoss.ganttz.timetracker.zoom; - -import org.joda.time.DateTime; -import org.joda.time.Days; -import org.joda.time.LocalDate; -import org.joda.time.ReadablePeriod; - -/** - * Zoom level for weeks in the first level and days in the second level - * @author Óscar González Fernández - * @author Lorenzo Tilve Álvaro - */ -public class DetailSixTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { - - private static final int NUMBER_OF_DAYS_MINIMUM = 50; - public static final int FIRST_LEVEL_SIZE = 672; - public static final int SECOND_LEVEL_SIZE = 96; - - DetailSixTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - super(firstLevelModificator, secondLevelModificator); - } - - public final double daysPerPixel() { - return ((double) 1 / SECOND_LEVEL_SIZE); - } - - @Override - protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(FIRST_LEVEL_SIZE, dateTime - .getWeekOfWeekyear() - + dateTime.toString(", MMM YYYY"), dateTime, dateTime - .plusDays(7)); - } - }; - } - - @Override - protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(SECOND_LEVEL_SIZE, dateTime - .getDayOfMonth() - + "", dateTime, dateTime.plusDays(1)); - } - }; - } - - @Override - protected ReadablePeriod getPeriodFirstLevel() { - return Days.days(7); - } - - @Override - protected ReadablePeriod getPeriodSecondLevel() { - return Days.days(1); - } - - @Override - protected LocalDate round(LocalDate date, boolean down) { - int dayOfWeek = date.getDayOfWeek(); - if (dayOfWeek == 1) { - return date; - } - return down ? date.withDayOfWeek(1) : date.withDayOfWeek(1) - .plusWeeks(1); - } - - @Override - protected Period getMinimumPeriod() { - return PeriodType.DAYS.amount(NUMBER_OF_DAYS_MINIMUM); - } - - @Override - protected ZoomLevel getZoomLevel() { - return ZoomLevel.DETAIL_FIVE; - } - - @Override - public int getSecondLevelSize() { - return SECOND_LEVEL_SIZE; - } - -} \ No newline at end of file diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java index 086b73a9f..dd7919359 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailThreeTimeTrackerState.java @@ -28,25 +28,25 @@ import org.joda.time.ReadablePeriod; import org.zkoss.util.Locales; /** - * Zoom level with semesters in the first level and months in the second level + * Zoom level with semesters in the first level and months in the second level. + * * @author Óscar González Fernández * @author Lorenzo Tilve Álvaro */ -public class DetailThreeTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { +public class DetailThreeTimeTrackerState extends TimeTrackerStateWithSubintervalsFitting { private static final int NUMBER_OF_MONTHS_MINIMUM = 30; - DetailThreeTimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - super(firstLevelModificator, secondLevelModificator); - } - private static final int FIRST_LEVEL_SIZE = 300; + protected static final int SECOND_LEVEL_SIZE = 50; + DetailThreeTimeTrackerState(IDetailItemModifier firstLevelModifier, IDetailItemModifier secondLevelModifier) { + super(firstLevelModifier, secondLevelModifier); + } + public final double daysPerPixel() { - return ((double) 182.5 / FIRST_LEVEL_SIZE); + return 182.5 / FIRST_LEVEL_SIZE; } @Override @@ -61,31 +61,22 @@ public class DetailThreeTimeTrackerState extends @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(SECOND_LEVEL_SIZE, - getMonthString(dateTime), - dateTime, dateTime.plusMonths(1)); - } - }; + return dateTime -> new DetailItem( + SECOND_LEVEL_SIZE, getMonthString(dateTime), dateTime, dateTime.plusMonths(1)); } @Override protected LocalDate round(LocalDate date, boolean down) { - if (date.getMonthOfYear() == 1 && date.getDayOfMonth() == 1) { - return date; - } - if (date.getMonthOfYear() == 7 && date.getDayOfMonth() == 1) { + if ( (date.getMonthOfYear() == 1 || date.getMonthOfYear() == 7) && date.getDayOfMonth() == 1) { return date; } + date = date.withDayOfMonth(1); + if (date.getMonthOfYear() < 7) { return down ? date.withMonthOfYear(1) : date.withMonthOfYear(7); } else { - return down ? date.withMonthOfYear(7) : date.plusYears(1) - .withMonthOfYear(1); + return down ? date.withMonthOfYear(7) : date.plusYears(1).withMonthOfYear(1); } } @@ -94,20 +85,13 @@ public class DetailThreeTimeTrackerState extends } private String getYearWithSemesterString(DateTime dateTime) { - return dateTime.getYear() + "," - + (dateTime.getMonthOfYear() < 6 ? "H1" : "H2"); + return dateTime.getYear() + "," + (dateTime.getMonthOfYear() < 6 ? "H1" : "H2"); } @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(FIRST_LEVEL_SIZE, - getYearWithSemesterString(dateTime), dateTime, dateTime - .plusMonths(6)); - } - }; + return dateTime -> new DetailItem( + FIRST_LEVEL_SIZE, getYearWithSemesterString(dateTime), dateTime, dateTime.plusMonths(6)); } @Override diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java index 1c9e57d3b..68497cbfc 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/DetailTwoTimeTrackerState.java @@ -21,38 +21,31 @@ package org.zkoss.ganttz.timetracker.zoom; -import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.Months; import org.joda.time.ReadablePeriod; import org.joda.time.Years; /** - * Zoom level with years in the first level and quarters in the second level + * Zoom level with years in the first level and quarters in the second level. + * * @author Francisco Javier Moran Rúa * @author Lorenzo Tilve Álvaro */ -public class DetailTwoTimeTrackerState extends - TimeTrackerStateWithSubintervalsFitting { +public class DetailTwoTimeTrackerState extends TimeTrackerStateWithSubintervalsFitting { private static final int FIRST_LEVEL_ITEM_SIZE = 400; + private static final int SECOND_LEVEL_ITEM_SIZE = 100; - protected DetailTwoTimeTrackerState( - IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - super(firstLevelModificator, secondLevelModificator); + protected DetailTwoTimeTrackerState(IDetailItemModifier firstLevelModifier, IDetailItemModifier secondLevelModifier) { + super(firstLevelModifier, secondLevelModifier); } @Override protected IDetailItemCreator getDetailItemCreatorFirstLevel() { - return new IDetailItemCreator() { - @Override - public DetailItem create(DateTime dateTime) { - return new DetailItem(FIRST_LEVEL_ITEM_SIZE, dateTime.getYear() - + "", dateTime, dateTime); - } - }; + return dateTime -> + new DetailItem(FIRST_LEVEL_ITEM_SIZE, Integer.toString(dateTime.getYear()), dateTime, dateTime); } @Override @@ -62,14 +55,11 @@ public class DetailTwoTimeTrackerState extends @Override protected IDetailItemCreator getDetailItemCreatorSecondLevel() { - return new IDetailItemCreator() { - @Override - public DetailItem create(DateTime dateTime) { - int quarterNumber = dateTime.getMonthOfYear() / 3 + 1; - String quarterCaption = "Q" + quarterNumber; - return new DetailItem(SECOND_LEVEL_ITEM_SIZE, quarterCaption, - dateTime, dateTime.plusMonths(3)); - } + return dateTime -> { + int quarterNumber = dateTime.getMonthOfYear() / 3 + 1; + String quarterCaption = "Q" + quarterNumber; + + return new DetailItem(SECOND_LEVEL_ITEM_SIZE, quarterCaption, dateTime, dateTime.plusMonths(3)); }; } @@ -85,12 +75,12 @@ public class DetailTwoTimeTrackerState extends @Override protected Period getMinimumPeriod() { - return DetailOneTimeTrackerState.MINIMUN_PERIOD; + return DetailOneTimeTrackerState.MINIMUM_PERIOD; } @Override public double daysPerPixel() { - return ((double) 365 / FIRST_LEVEL_ITEM_SIZE); + return (double) 365 / FIRST_LEVEL_ITEM_SIZE; } @Override diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IDetailItemModificator.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IDetailItemModifier.java similarity index 89% rename from ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IDetailItemModificator.java rename to ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IDetailItemModifier.java index 8f0fbebac..771fb0097 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IDetailItemModificator.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IDetailItemModifier.java @@ -25,8 +25,8 @@ package org.zkoss.ganttz.timetracker.zoom; * @author Óscar González Fernández * */ -public interface IDetailItemModificator { +public interface IDetailItemModifier { - public DetailItem applyModificationsTo(DetailItem item, ZoomLevel z); + DetailItem applyModificationsTo(DetailItem item, ZoomLevel z); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IZoomLevelChangedListener.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IZoomLevelChangedListener.java index 38685af02..680d50c54 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IZoomLevelChangedListener.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/IZoomLevelChangedListener.java @@ -24,6 +24,6 @@ package org.zkoss.ganttz.timetracker.zoom; public interface IZoomLevelChangedListener { - public void zoomLevelChanged(ZoomLevel detailLevel); + void zoomLevelChanged(ZoomLevel detailLevel); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModificators.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModifiers.java similarity index 62% rename from ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModificators.java rename to ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModifiers.java index 42ed2f9b1..688c61b8a 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModificators.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/SeveralModifiers.java @@ -30,33 +30,32 @@ import org.apache.commons.lang3.Validate; /** * @author Óscar González Fernández - * */ -public class SeveralModificators implements IDetailItemModificator { +public class SeveralModifiers implements IDetailItemModifier { - public static IDetailItemModificator empty() { - return new SeveralModificators(Collections. emptyList()); + private final List modifiers; + + public static IDetailItemModifier empty() { + return new SeveralModifiers(Collections.emptyList()); } - public static IDetailItemModificator create(IDetailItemModificator... modificators) { - return new SeveralModificators(Arrays.asList(modificators)); + public static IDetailItemModifier create(IDetailItemModifier... modifiers) { + return new SeveralModifiers(Arrays.asList(modifiers)); } - public static IDetailItemModificator create(Collection modificators) { - return new SeveralModificators(modificators); + public static IDetailItemModifier create(Collection modifiers) { + return new SeveralModifiers(modifiers); } - private final List modificators; - - private SeveralModificators(Collection modificators) { - Validate.noNullElements(modificators); - this.modificators = new ArrayList<>(modificators); + private SeveralModifiers(Collection modifiers) { + Validate.noNullElements(modifiers); + this.modifiers = new ArrayList<>(modifiers); } @Override public DetailItem applyModificationsTo(DetailItem item, ZoomLevel z) { DetailItem result = item; - for (IDetailItemModificator each : modificators) { + for (IDetailItemModifier each : modifiers) { result = each.applyModificationsTo(result, z); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java index 7a5fb8765..e6f8a48bd 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerState.java @@ -47,6 +47,16 @@ import org.zkoss.ganttz.util.Interval; */ public abstract class TimeTrackerState { + private final IDetailItemModifier firstLevelModifier; + + private final IDetailItemModifier secondLevelModifier; + + protected TimeTrackerState(IDetailItemModifier firstLevelModifier, IDetailItemModifier secondLevelModifier) { + + this.firstLevelModifier = firstLevelModifier; + this.secondLevelModifier = secondLevelModifier; + } + public static Date year(int year) { Calendar calendar = Calendar.getInstance(); calendar.clear(); @@ -54,7 +64,7 @@ public abstract class TimeTrackerState { return calendar.getTime(); } - public static abstract class LazyGenerator implements Iterator { + public abstract static class LazyGenerator implements Iterator { private T current; @@ -69,7 +79,9 @@ public abstract class TimeTrackerState { @Override public T next() { - return this.current = next(this.current); + this.current = next(this.current); + + return this.current; } protected abstract T next(T last); @@ -80,27 +92,15 @@ public abstract class TimeTrackerState { } } - protected static final long MILLSECONDS_IN_DAY = 1000 * 60 * 60 * 24; - - // Pending to calculate interval dinamically - protected static final int NUMBER_OF_ITEMS_MINIMUM = 4; - - private final IDetailItemModificator firstLevelModificator; - - private final IDetailItemModificator secondLevelModificator; - - protected TimeTrackerState(IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { - this.firstLevelModificator = firstLevelModificator; - this.secondLevelModificator = secondLevelModificator; - } - - // When applied after setting current day, removes extra data as current day - // or bank holidays, and must proccess the array twice. May be refactorized - private static List markEvens( - Collection items) { + /** + * When applied after setting current day, removes extra data as current day or bank holidays, + * and must process the array twice. + * + * May be refactorized. + */ + private static List markEvens(Collection items) { boolean even = false; - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); for (DetailItem detailItem : items) { detailItem.setEven(even); @@ -120,68 +120,73 @@ public abstract class TimeTrackerState { public Collection getSecondLevelDetails(Interval interval) { if (getZoomLevel() == ZoomLevel.DETAIL_FIVE) { - // Evens are not highlighted in day view + // Events are not highlighted in day view return applyConfiguredModifications( - secondLevelModificator, - createDetailsForSecondLevel(interval), getZoomLevel()); + secondLevelModifier, + createDetailsForSecondLevel(interval), + getZoomLevel()); } else { return markEvens(applyConfiguredModifications( - secondLevelModificator, - createDetailsForSecondLevel(interval), getZoomLevel())); + secondLevelModifier, + createDetailsForSecondLevel(interval), + getZoomLevel())); } } public Collection getFirstLevelDetails(Interval interval) { - return applyConfiguredModifications(firstLevelModificator, - createDetailsForFirstLevel(interval), getZoomLevel()); + return applyConfiguredModifications( + firstLevelModifier, createDetailsForFirstLevel(interval), getZoomLevel()); } - private static List applyConfiguredModifications( - IDetailItemModificator modificator, - Collection detailsItems, ZoomLevel zoomlevel) { - List result = new ArrayList(detailsItems.size()); + private static List applyConfiguredModifications(IDetailItemModifier modifier, + Collection detailsItems, + ZoomLevel zoomlevel) { + + List result = new ArrayList<>(detailsItems.size()); for (DetailItem each : detailsItems) { - result.add(modificator.applyModificationsTo(each, zoomlevel)); + result.add(modifier.applyModificationsTo(each, zoomlevel)); } return result; } private Collection createDetails(Interval interval, - Iterator datesGenerator, - IDetailItemCreator detailItemCreator) { + Iterator datesGenerator, + IDetailItemCreator detailItemCreator) { + + List result = new ArrayList<>(); LocalDate current = interval.getStart(); LocalDate end = interval.getFinish(); - List result = new ArrayList(); + while (current.isBefore(end)) { - result.add(detailItemCreator.create(current - .toDateTimeAtStartOfDay())); + result.add(detailItemCreator.create(current.toDateTimeAtStartOfDay())); assert datesGenerator.hasNext(); current = datesGenerator.next(); } + return result; } - private final Collection createDetailsForFirstLevel( - Interval interval) { + private final Collection createDetailsForFirstLevel(Interval interval) { Interval realInterval = getRealIntervalFor(interval); - return createDetails(realInterval, + + return createDetails( + realInterval, getPeriodsFirstLevelGenerator(realInterval.getStart()), getDetailItemCreatorFirstLevel()); } - protected abstract Iterator getPeriodsFirstLevelGenerator( - LocalDate start); + protected abstract Iterator getPeriodsFirstLevelGenerator(LocalDate start); - private final Collection createDetailsForSecondLevel( - Interval interval) { + private final Collection createDetailsForSecondLevel(Interval interval) { Interval realInterval = getRealIntervalFor(interval); - return createDetails(realInterval, + + return createDetails( + realInterval, getPeriodsSecondLevelGenerator(realInterval.getStart()), getDetailItemCreatorSecondLevel()); } - protected abstract Iterator getPeriodsSecondLevelGenerator( - LocalDate start); + protected abstract Iterator getPeriodsSecondLevelGenerator(LocalDate start); protected abstract IDetailItemCreator getDetailItemCreatorFirstLevel(); @@ -201,6 +206,7 @@ public abstract class TimeTrackerState { return Years.yearsBetween(start, end); } }, + MONTHS { @Override public ReadablePeriod toPeriod(int amount) { @@ -212,6 +218,7 @@ public abstract class TimeTrackerState { return Months.monthsBetween(start, end); } }, + WEEKS { @Override public ReadablePeriod toPeriod(int amount) { @@ -223,6 +230,7 @@ public abstract class TimeTrackerState { return Weeks.weeksBetween(start, end); } }, + DAYS { @Override public ReadablePeriod toPeriod(int amount) { @@ -237,8 +245,7 @@ public abstract class TimeTrackerState { public abstract ReadablePeriod toPeriod(int amount); - public abstract BaseSingleFieldPeriod differenceBetween( - LocalDate start, LocalDate end); + public abstract BaseSingleFieldPeriod differenceBetween(LocalDate start, LocalDate end); public Period amount(int amount) { return new Period(this, amount); @@ -262,18 +269,16 @@ public abstract class TimeTrackerState { } BaseSingleFieldPeriod asPeriod(Interval interval) { - return type.differenceBetween(interval.getStart(), - interval.getFinish()); + return type.differenceBetween(interval.getStart(), interval.getFinish()); } } protected abstract Period getMinimumPeriod(); private Interval ensureMinimumInterval(Interval interval) { - LocalDate newEnd = interval.getStart().plus( - getMinimumPeriod().toPeriod()); - return new Interval(interval.getStart(), Collections.max(asList(newEnd, - interval.getFinish()))); + LocalDate newEnd = interval.getStart().plus(getMinimumPeriod().toPeriod()); + + return new Interval(interval.getStart(), Collections.max(asList(newEnd, interval.getFinish()))); } public Interval getRealIntervalFor(Interval testInterval) { @@ -283,9 +288,8 @@ public abstract class TimeTrackerState { private Interval calculateForAtLeastMinimum(Interval atLeastMinimum) { LocalDate start = round(atLeastMinimum.getStart(), true); LocalDate finish = round(atLeastMinimum.getFinish(), false); - Interval result = new Interval(start.toDateTimeAtStartOfDay().toDate(), - finish.toDateTimeAtStartOfDay().toDate()); - return result; + + return new Interval(start.toDateTimeAtStartOfDay().toDate(), finish.toDateTimeAtStartOfDay().toDate()); } public abstract double daysPerPixel(); diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java index fda2b5a5e..29daddded 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/TimeTrackerStateWithSubintervalsFitting.java @@ -32,11 +32,10 @@ import org.joda.time.ReadablePeriod; */ public abstract class TimeTrackerStateWithSubintervalsFitting extends TimeTrackerState { - protected TimeTrackerStateWithSubintervalsFitting( - IDetailItemModificator firstLevelModificator, - IDetailItemModificator secondLevelModificator) { + protected TimeTrackerStateWithSubintervalsFitting(IDetailItemModifier firstLevelModifier, + IDetailItemModifier secondLevelModifier) { - super(firstLevelModificator, secondLevelModificator); + super(firstLevelModifier, secondLevelModifier); } private final class PeriodicalGenerator extends LazyGenerator { diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java index 7d6e62fad..02cd766f5 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/timetracker/zoom/ZoomLevel.java @@ -23,17 +23,17 @@ package org.zkoss.ganttz.timetracker.zoom; import org.joda.time.Days; import org.joda.time.LocalDate; -import org.zkoss.ganttz.i18n.I18nHelper; + /** + * Describes levels of zooming (time-zooming) on Gantt panel. + * * @author Francisco Javier Moran Rúa */ public enum ZoomLevel { DETAIL_ONE(_("Year")) { @Override - public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + public TimeTrackerState getTimeTrackerState(IDetailItemModifier firstLevel, IDetailItemModifier secondLevel) { return new DetailOneTimeTrackerState(firstLevel, secondLevel); } @@ -42,11 +42,10 @@ public enum ZoomLevel { return days > 950; } }, + DETAIL_TWO(_("Quarter")) { @Override - public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + public TimeTrackerState getTimeTrackerState(IDetailItemModifier firstLevel, IDetailItemModifier secondLevel) { return new DetailTwoTimeTrackerState(firstLevel, secondLevel); } @@ -55,11 +54,10 @@ public enum ZoomLevel { return days > 550; } }, + DETAIL_THREE(_("Month")) { @Override - public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + public TimeTrackerState getTimeTrackerState(IDetailItemModifier firstLevel, IDetailItemModifier secondLevel) { return new DetailThreeTimeTrackerState(firstLevel, secondLevel); } @@ -68,11 +66,10 @@ public enum ZoomLevel { return days > 175; } }, + DETAIL_FOUR(_("Week")) { @Override - public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + public TimeTrackerState getTimeTrackerState(IDetailItemModifier firstLevel, IDetailItemModifier secondLevel) { return new DetailFourTimeTrackerState(firstLevel, secondLevel); } @@ -81,84 +78,63 @@ public enum ZoomLevel { return days > 50; } }, + DETAIL_FIVE(_("Day")) { @Override - public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { + public TimeTrackerState getTimeTrackerState(IDetailItemModifier firstLevel, IDetailItemModifier secondLevel) { return new DetailFiveTimeTrackerState(firstLevel, secondLevel); } - @Override - public boolean isSuitableFor(int days) { - return true; - } - }, - DETAIL_SIX(_("Hour")) { - @Override - public TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel) { - return new DetailSixTimeTrackerState(firstLevel, secondLevel); - } - @Override public boolean isSuitableFor(int days) { return true; } }; + private String internalName; + + ZoomLevel(String name) { + this.internalName = name; + } + /** - * Forces to mark the string as needing translation + * Forces to mark the string as needing translation. */ private static String _(String string) { return string; } - private String internalName; - public String getInternalName() { return internalName; } - private ZoomLevel(String name) { - this.internalName = name; - } - /** - * @return if there is no next, returns this. Otherwise returns - * the next one. + * @return if there is no next, returns this. Otherwise returns the next one. */ public ZoomLevel next() { final int next = ordinal() + 1; - if (next == ZoomLevel.values().length) { - return this; - } - return ZoomLevel.values()[next]; + + return next == ZoomLevel.values().length ? this : ZoomLevel.values()[next]; } /** - * @return if there is no previous, returns this. Otherwise - * returns the previous one. + * @return if there is no previous, returns this. Otherwise returns the previous one. */ public ZoomLevel previous() { - if (ordinal() == 0) { - return this; - } - return ZoomLevel.values()[ordinal() - 1]; + return ordinal() == 0 ? this : ZoomLevel.values()[ordinal() - 1]; } public abstract TimeTrackerState getTimeTrackerState( - IDetailItemModificator firstLevel, - IDetailItemModificator secondLevel); + IDetailItemModifier firstLevel, IDetailItemModifier secondLevel); @Override public String toString() { - return I18nHelper._(internalName); + return _(internalName); } public static ZoomLevel getFromString(String zoomLevelParameter) { ZoomLevel requiredZoomLevel = ZoomLevel.DETAIL_ONE; + if (zoomLevelParameter != null) { for (ZoomLevel z : ZoomLevel.values()) { if (zoomLevelParameter.equals(z.internalName)) { @@ -170,10 +146,10 @@ public enum ZoomLevel { } - public static ZoomLevel getDefaultZoomByDates(LocalDate initDate, - LocalDate endDate) { + public static ZoomLevel getDefaultZoomByDates(LocalDate initDate, LocalDate endDate) { if (initDate != null && endDate != null) { int days = Days.daysBetween(initDate, endDate).getDays(); + for (ZoomLevel each : ZoomLevel.values()) { if (each.isSuitableFor(days)) { return each; diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/ComponentsFinder.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/ComponentsFinder.java index bd3bdb053..a306e36dc 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/ComponentsFinder.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/ComponentsFinder.java @@ -29,7 +29,7 @@ import org.zkoss.zul.Grid; import org.zkoss.zul.Listbox; import org.zkoss.zul.Listitem; import org.zkoss.zul.Row; -import org.zkoss.zul.api.Rows; +import org.zkoss.zul.Rows; /** * Utility methods to find components @@ -40,55 +40,63 @@ public class ComponentsFinder { private ComponentsFinder() { } - public static List findComponentsOfType(Class type, - List children) { - ArrayList result = new ArrayList(); + public static List findComponentsOfType(Class type, List children) { + ArrayList result = new ArrayList<>(); for (Object child : children) { - if (type.isInstance(child)) { + + if ( type.isInstance(child) ) { result.add(type.cast(child)); } } + return result; } - public static Component findById(String id, - List children) { + public static Component findById(String id, List children) { for (Component child : children) { - if (child.getId().equals(id)) { + + if ( child.getId().equals(id) ) { return child; } } + return null; } public static Row findRowByValue(Grid grid, Object needle) { - if (grid == null || needle == null) { + if ( grid == null || needle == null ) { return null; } Rows rows = grid.getRows(); for (Object each : rows.getChildren()) { - if (each instanceof Row) { + + if ( each instanceof Row ) { Row row = (Row) each; Object value = row.getValue(); - if (needle.equals(value)) { + + if ( needle.equals(value) ) { return row; } } } + return null; } public static Listitem findItemByValue(Listbox listbox, Object needle) { - if (listbox == null || needle == null) { + if ( listbox == null || needle == null ) { return null; } + for (Object each : listbox.getItems()) { Listitem item = (Listitem) each; Object value = item.getValue(); - if (needle.toString().equals(value.toString())) { + + if ( needle.toString().equals(value.toString()) ) { return item; } } + return null; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java index 86ebe68db..fcc342342 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/LongOperationFeedback.java @@ -41,8 +41,9 @@ import org.zkoss.zk.ui.util.Clients; /** - * @author Óscar González Fernández + * Handler of long operations ( {@link Clients#showBusy(String)}, {@link Clients#clearBusy()} ). * + * @author Óscar González Fernández */ public class LongOperationFeedback { @@ -61,16 +62,20 @@ public class LongOperationFeedback { } }; - public static void execute(final Component component, final ILongOperation longOperation) { + public static void execute(final Component component, + final ILongOperation longOperation) { + Validate.notNull(component); Validate.notNull(longOperation); - if ( alreadyInside.get() ) { + if (alreadyInside.get()) { dispatchActionDirectly(longOperation); + return; } Clients.showBusy(longOperation.getName()); + executeLater(component, new Runnable() { public void run() { try { @@ -86,13 +91,13 @@ public class LongOperationFeedback { }); } - public static void executeLater(final Component component, final Runnable runnable) { + public static void executeLater(final Component component, + final Runnable runnable) { Validate.notNull(runnable); Validate.notNull(component); - final String eventName = generateEventName(); - component.addEventListener(eventName, new EventListener() { + component.addEventListener(eventName, new EventListener() { @Override public void onEvent(Event event) { try { @@ -131,13 +136,9 @@ public class LongOperationFeedback { } public static IDesktopUpdate and(final IDesktopUpdate... desktopUpdates) { - return new IDesktopUpdate() { - - @Override - public void doUpdate() { - for (IDesktopUpdate each : desktopUpdates) { - each.doUpdate(); - } + return () -> { + for (IDesktopUpdate each : desktopUpdates) { + each.doUpdate(); } }; } @@ -149,50 +150,39 @@ public class LongOperationFeedback { private static final ExecutorService executor = Executors.newCachedThreadPool(); public static IDesktopUpdatesEmitter doNothingEmitter() { - return new IDesktopUpdatesEmitter() { - @Override - public void doUpdate(T value) { - } - }; + return value -> {}; } /** - * Executes a long operation. The background operation can send - * {@link IDesktopUpdate} objects that can update desktop state. Trying to - * update the components in any other way would fail - */ - public static void progressive(final Desktop desktop, final IBackGroundOperation operation) { - progressive(desktop, operation, new IDesktopUpdatesEmitter() { - @Override - public void doUpdate(IDesktopUpdate update) { - update.doUpdate(); - } - }); - } - - /** - * Executes a long operation. The background operation can send - * T objects that can update desktop state. A - * {@link IDesktopUpdatesEmitter} that handle these objects is necessary. + * Executes a long operation. + * The background operation can send {@link IDesktopUpdate} objects that can update desktop state. * Trying to update the components in any other way would fail. */ - public static void progressive( - final Desktop desktop, - final IBackGroundOperation operation, - final IDesktopUpdatesEmitter emitter) { + public static void progressive(final Desktop desktop, + final IBackGroundOperation operation) { + progressive(desktop, operation, (update) -> update.doUpdate()); + } + + /** + * Executes a long operation. + * The background operation can send + * T objects that can update desktop state. + * A {@link IDesktopUpdatesEmitter} that handle these objects is necessary. + * Trying to update the components in any other way would fail. + */ + public static void progressive(final Desktop desktop, + final IBackGroundOperation operation, + final IDesktopUpdatesEmitter emitter) { desktop.enableServerPush(true); - executor.execute(new Runnable() { - - public void run() { - try { - IBackGroundOperation operationWithAsyncUpates = withAsyncUpates(operation, desktop); - operationWithAsyncUpates.doOperation(emitter); - } catch (Exception e) { - LOG.error("error executing background operation", e); - } finally { - desktop.enableServerPush(false); - } + executor.execute(() -> { + try { + IBackGroundOperation operationWithAsyncUpates = withAsyncUpates(operation, desktop); + operationWithAsyncUpates.doOperation(emitter); + } catch (Exception e) { + LOG.error("error executing background operation", e); + } finally { + desktop.enableServerPush(false); } }); } @@ -202,14 +192,14 @@ public class LongOperationFeedback { final Desktop desktop) { return new IBackGroundOperation() { + @Override public void doOperation(IDesktopUpdatesEmitter originalEmitter) { NotBlockingDesktopUpdates notBlockingDesktopUpdates = - new NotBlockingDesktopUpdates(desktop, originalEmitter); + new NotBlockingDesktopUpdates<>(desktop, originalEmitter); Future future = executor.submit(notBlockingDesktopUpdates); - try { backgroundOperation.doOperation(notBlockingDesktopUpdates); } finally { @@ -231,7 +221,9 @@ public class LongOperationFeedback { private static class NotBlockingDesktopUpdates implements IDesktopUpdatesEmitter, Runnable { private BlockingQueue> queue = new LinkedBlockingQueue<>(); + private final IDesktopUpdatesEmitter original; + private final Desktop desktop; NotBlockingDesktopUpdates(Desktop desktop, IDesktopUpdatesEmitter original) { @@ -245,30 +237,28 @@ public class LongOperationFeedback { } void finish() { - queue.add(EndOrValue. end()); + queue.add(EndOrValue.end()); } @Override public void run() { + List batch = new ArrayList<>(); while (true) { batch.clear(); EndOrValue current; - try { current = queue.take(); } catch (InterruptedException e) { throw new RuntimeException(e); } - if ( current.isEnd() ) { + if (current.isEnd()) return; - } - if ( !desktop.isAlive() || !desktop.isServerPushEnabled() ) { + if (!desktop.isAlive() || !desktop.isServerPushEnabled()) return; - } try { Executions.activate(desktop); @@ -279,27 +269,30 @@ public class LongOperationFeedback { try { original.doUpdate(current.getValue()); - while ((current = queue.poll()) != null) { - if ( current.isEnd() ) { + while ((current = queue.poll()) != null) { + if (current.isEnd()) { break; } batch.add(current.getValue()); original.doUpdate(current.getValue()); } + } finally { Executions.deactivate(desktop); } - if ( current != null && current.isEnd() ) { + + if (current != null && current.isEnd()) { return; } + } } } - private static abstract class EndOrValue { + private abstract static class EndOrValue { public static EndOrValue end() { return new End<>(); } @@ -309,6 +302,7 @@ public class LongOperationFeedback { } public abstract boolean isEnd(); + public abstract T getValue() throws UnsupportedOperationException; } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/MenuBuilder.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/MenuBuilder.java index d9569d95c..0e37297d0 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/MenuBuilder.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/MenuBuilder.java @@ -31,32 +31,48 @@ import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.HtmlNativeComponent; import org.zkoss.zk.ui.Page; import org.zkoss.zk.ui.event.Event; -import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.OpenEvent; import org.zkoss.zul.Menuitem; import org.zkoss.zul.Menupopup; import org.zkoss.zul.Menuseparator; -import org.zkoss.zul.impl.api.XulElement; +import org.zkoss.zul.impl.XulElement; +/** + * Create context menu for right-click mouse. + * + * @param + */ public class MenuBuilder { - public static MenuBuilder on(Page page, - Collection elements) { - return new MenuBuilder(page, elements); + private final List elements; + + private final List items = new ArrayList<>(); + + private Component root; + + private T referenced; + + private MenuBuilder(Page page, Collection elements) { + this.elements = new ArrayList<>(elements); + this.root = findVisibleOn(getRoots(page)); } - public static MenuBuilder on(Page page, - T... elements) { + public static MenuBuilder on(Page page, Collection elements) { + return new MenuBuilder<>(page, elements); + } + + public static MenuBuilder on(Page page, T... elements) { return on(page, Arrays.asList(elements)); } - public static interface ItemAction { - - void onEvent(T choosen, Event event); + public interface ItemAction { + void onEvent(T chosen, Event event); } private class Item { + private final String name; + private final String icon; private final ItemAction action; @@ -70,60 +86,50 @@ public class MenuBuilder { Menuitem createMenuItem() { Menuitem result = new Menuitem(); result.setLabel(name); - if (icon != null) { + + if ( icon != null ) { result.setImage(icon); } + return result; } } - private final List elements; - - private final List items = new ArrayList(); - - private Component root; - - private MenuBuilder(Page page, Collection elements) { - this.elements = new ArrayList(elements); - this.root = findVisibleOn(getRoots(page)); - } - private static List getRoots(Page page) { - List result = new ArrayList(); + List result = new ArrayList<>(); Component current = page.getFirstRoot(); + while (current != null) { result.add(current); current = current.getNextSibling(); } + return result; } - private static Component findVisibleOn( - Collection candidates) { + private static Component findVisibleOn(Collection candidates) { for (Component each : candidates) { - if (each.isVisible()) { + if ( each.isVisible() ) { return each; } } - throw new RuntimeException( - "not found visible component on which to attach the menu"); + + throw new RuntimeException("not found visible component on which to attach the menu"); } - public MenuBuilder item(String name, String icon, - ItemAction itemAction) { - if (name == null) { + public MenuBuilder item(String name, String icon, ItemAction itemAction) { + if ( name == null ) { throw new IllegalArgumentException("name cannot be null"); } - if (itemAction == null) { + if ( itemAction == null ) { throw new IllegalArgumentException("itemAction cannot be null"); } items.add(new Item(name, icon, itemAction)); + return this; } - private T referenced; - public Menupopup createWithoutSettingContext() { return create(false); } @@ -134,55 +140,55 @@ public class MenuBuilder { private Menupopup create(boolean setContext) { Menupopup result = new Menupopup(); - result.addEventListener("onOpen", new EventListener() { - @Override - public void onEvent(Event event) { - OpenEvent openEvent = (OpenEvent) event; - referenced = (T) openEvent.getReference(); - } + result.addEventListener("onOpen", event -> { + OpenEvent openEvent = (OpenEvent) event; + referenced = (T) openEvent.getReference(); }); + for (final Item item : items) { - if (!item.name.equals("separator")) { + + if ( !"separator".equals(item.name) ) { Menuitem menuItem = item.createMenuItem(); - menuItem.addEventListener("onClick", new EventListener() { - @Override - public void onEvent(Event event) { - ItemAction action = item.action; - action.onEvent(referenced, event); - } + + menuItem.addEventListener("onClick", event -> { + ItemAction action = item.action; + action.onEvent(referenced, event); }); + result.appendChild(menuItem); } else { Menuseparator separator = new Menuseparator(); result.appendChild(separator); } } + insertInRootComponent(result); - if (setContext) { + + if ( setContext ) { for (T element : elements) { element.setContext(result); } } + return result; } private void insertInRootComponent(Menupopup result) { - ArrayList children = new ArrayList(root - .getChildren()); + ArrayList children = new ArrayList<>(root.getChildren()); Collections.reverse(children); - // the Menupopup cannot be inserted after a HtmlNativeComponent, so we - // try to avoid it - if (children.isEmpty()) { + // The Menupopup cannot be inserted after a HtmlNativeComponent, so we try to avoid it + if ( children.isEmpty() ) { root.appendChild(result); } + for (Component child : children) { - if (!(child instanceof HtmlNativeComponent)) { + if ( !(child instanceof HtmlNativeComponent) ) { root.insertBefore(result, child); return; } } - throw new RuntimeException("all children of " + root - + " are html native"); + + throw new RuntimeException("all children of " + root + " are html native"); } } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/MutableTreeModel.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/MutableTreeModel.java index 1883f5137..52ca692e8 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/MutableTreeModel.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/MutableTreeModel.java @@ -38,25 +38,29 @@ import org.zkoss.zul.event.TreeDataEvent; /** * @author Óscar González Fernández + * @author Vova Perebykivskyi + * @author Bogdan Bodnarjuk */ + public class MutableTreeModel extends AbstractTreeModel { private static final Log LOG = LogFactory.getLog(MutableTreeModel.class); public interface IChildrenExtractor { - public List getChildren(T parent); + List getChildren(T parent); } - private static class Node { + public static class Node { + private T value; - private List> children = new LinkedList>(); + private List> children = new LinkedList<>(); private Node parentNode; - private Node(T value) { + public Node(T value) { this.value = value; } @@ -64,7 +68,8 @@ public class MutableTreeModel extends AbstractTreeModel { for (Node n : nodes) { n.parentNode = this; } - if (position == null) { + + if ( position == null ) { children.addAll(nodes); } else { children.addAll(position, nodes); @@ -73,44 +78,54 @@ public class MutableTreeModel extends AbstractTreeModel { public int[] down(Node node) { ListIterator> listIterator = children.listIterator(); + while (listIterator.hasNext()) { Node current = listIterator.next(); - if (current == node && listIterator.hasNext()) { + + if ( current == node && listIterator.hasNext() ) { int nextIndex = listIterator.nextIndex(); listIterator.remove(); listIterator.next(); listIterator.add(node); + return new int[] { nextIndex - 1, nextIndex }; } } + return new int[] {}; } public int[] up(Node node) { - ListIterator> listIterator = children.listIterator(children - .size()); - while (listIterator.hasPrevious()) { + ListIterator> listIterator = children.listIterator(children.size()); + + while ( listIterator.hasPrevious() ) { Node current = listIterator.previous(); - if (current == node && listIterator.hasPrevious()) { + + if ( current == node && listIterator.hasPrevious() ) { listIterator.remove(); int previousIndex = listIterator.previousIndex(); listIterator.previous(); listIterator.add(current); + return new int[] { previousIndex, previousIndex + 1 }; } } + return new int[] {}; } private void until(LinkedList result, Node parent) { - if (parent.equals(this)) { - return; - } else if (isRoot()) { - // final reached, but parent not found - result.clear(); - } else { - result.add(0, this.parentNode.getIndexOf(this)); - this.parentNode.until(result, parent); + if ( !parent.equals(this) ) { + + if ( isRoot() ) { + + /* Final reached, but parent not found */ + result.clear(); + + } else { + result.add(0, this.parentNode.getIndexOf(this)); + this.parentNode.until(result, parent); + } } } @@ -124,14 +139,16 @@ public class MutableTreeModel extends AbstractTreeModel { } public LinkedList until(Node parent) { - LinkedList result = new LinkedList(); + LinkedList result = new LinkedList<>(); until(result, parent); + return result; } public int remove() { int positionInParent = parentNode.getIndexOf(this); parentNode.children.remove(positionInParent); + return positionInParent; } @@ -143,10 +160,10 @@ public class MutableTreeModel extends AbstractTreeModel { private final Node root; - private transient Map> nodesByDomainObject = new WeakHashMap>(); + private transient Map> nodesByDomainObject = new WeakHashMap<>(); private static Node wrapOne(T object) { - return new Node(object); + return new Node<>(object); } private static List> wrap(T... objects) { @@ -154,14 +171,22 @@ public class MutableTreeModel extends AbstractTreeModel { } private static List> wrap(Collection objects) { - List> result = new ArrayList>(); + List> result = new ArrayList<>(); + for (T o : objects) { result.add(wrapOne(o)); } + return result; } private Node find(Object domainObject) { + for (Map.Entry> item : nodesByDomainObject.entrySet()) { + if ( item.getKey() != null && item.getKey().equals(domainObject) ) { + return item.getValue(); + } + } + return nodesByDomainObject.get(domainObject); } @@ -170,33 +195,65 @@ public class MutableTreeModel extends AbstractTreeModel { } public static MutableTreeModel create(Class type) { - return new MutableTreeModel(type, new Node(null)); + return new MutableTreeModel<>(type, new Node<>(null)); } public static MutableTreeModel create(Class type, T root) { - return new MutableTreeModel(type, wrapOne(root)); + return new MutableTreeModel<>(type, wrapOne(root)); } private MutableTreeModel(Class type, Node root) { super(root); - if (type == null) { + + if ( type == null ) { throw new IllegalArgumentException("type cannot be null"); } nodesByDomainObject.put(unwrap(root), root); this.root = root; } - @Override + /** + * Is some cases it was returning new int[0], but should return new path instead. + * Reason of that: API changes. Before it was looking for child index manually. + * Now it is not looking at all. + * So I decided to return value by our own + * {@link MutableTreeModel#shouldILookForLastValue(Object, Node), {@link #shouldILookForParentValue(Object, Node)}} + * Not to use {@link AbstractTreeModel#getIndexOfChild(Object parent, Object child)}. + */ public int[] getPath(Object parent, Object last) { Node parentNode = find(parent); Node lastNode = find(last); - if (parentNode == null || lastNode == null) { + + if ( shouldILookForParentValue(parent, parentNode) ) { + parentNode = find( ((Node) parent).value ); + } + + if ( shouldILookForLastValue(last, lastNode) ) { + lastNode = find( ((Node) last).value ); + } + + if ( parentNode == null || lastNode == null) { return new int[0]; } List path = lastNode.until(parentNode); + return asIntArray(path); } + private boolean shouldILookForParentValue(Object parent, Node parentNode) { + return parent != null && + parentNode == null && + parent.getClass().toString().contains("Node") && + ((Node) parent).value != null; + } + private boolean shouldILookForLastValue(Object last, Node lastNode) { + return last != null && + lastNode == null && + last.getClass().toString().contains("Node") && + ((Node) last).value != null; + } + + @Override public int[] getPath(Object last) { return getPath(getRoot(), last); } @@ -205,30 +262,33 @@ public class MutableTreeModel extends AbstractTreeModel { T current = getRoot(); for (int i = 0; i < path.length; i++) { int position = path[i]; - if (position >= getChildCount(current)) { + + if ( position >= getChildCount(current) ) { + throw new IllegalArgumentException( - "Failure acessing the path at: " - + stringRepresentationUntil(path, i)); + "Failure acessing the path at: " + stringRepresentationUntil(path, i)); } current = getChild(current, position); } + return current; } private static String stringRepresentationUntil(int[] path, int endExclusive) { - String valid = Arrays.toString(Arrays - .copyOfRange(path, 0, endExclusive)); - String invalid = Arrays.toString(Arrays.copyOfRange(path, endExclusive, - path.length)); + String valid = Arrays.toString(Arrays.copyOfRange(path, 0, endExclusive)); + String invalid = Arrays.toString(Arrays.copyOfRange(path, endExclusive, path.length)); + return valid + "^" + invalid; } private int[] asIntArray(List path) { int[] result = new int[path.size()]; int i = 0; + for (Integer integer : path) { result[i++] = integer; } + return result; } @@ -237,21 +297,74 @@ public class MutableTreeModel extends AbstractTreeModel { return unwrap(root); } + @Override + public T getChild(int[] path){ + T node = getRoot(); + + for (int item : path) { + if (item < 0 || item > _childCount(node)) + return null; + + node = getChild(node, item); + } + + return node; + } + + private int _childCount(T parent) { + return isLeaf(parent) ? 0 : getChildCount(parent); + } + + /** + * Previously index was correct, + * because ZK API was calling {@link AbstractTreeModel#getIndexOfChild(Object, Object)} method. + * Now it is not calling that method and sometimes index could be incorrect. + * So I decided to make --index if it will throw exception. + */ @Override public T getChild(Object parent, int index) { - Node node = find(parent); - return unwrap(node.children.get(index)); + Node node; + + if (parent instanceof MutableTreeModel.Node) { + node = find(((Node) parent).value); + } else { + node = find(parent); + } + + T nodeToReturn; + + try { + nodeToReturn = unwrap(node.children.get(index)); + } catch (IndexOutOfBoundsException e) { + if (parent != null) { + nodeToReturn = unwrap(node.parentNode.children.get(index)); + } else if (index - 1 >= 0) { + nodeToReturn = unwrap(node.children.get(index - 1)); + } else { + throw new IndexOutOfBoundsException("Something wrong with indexes"); + } + } + + return nodeToReturn; } @Override public int getChildCount(Object parent) { - Node node = find(parent); + Node node; + + if (parent instanceof MutableTreeModel.Node) { + node = find(((Node) parent).value); + } else { + node = find(parent); + } + return node.children.size(); } @Override public boolean isLeaf(Object object) { Node node = find(object); + return node.children.isEmpty(); } @@ -265,35 +378,31 @@ public class MutableTreeModel extends AbstractTreeModel { } private IChildrenExtractor noChildrenExtractor() { - return new IChildrenExtractor() { - - @Override - public List getChildren(T parent) { - return Collections.emptyList(); - } - }; + return parent -> Collections.emptyList(); } - private void add(Node parent, Integer position, List> children, - IChildrenExtractor extractor) { - if (children.isEmpty()) { + private void add(Node parent, Integer position, List> children, IChildrenExtractor extractor) { + if ( children.isEmpty() ) { return; } + int indexFrom = position == null ? parent.children.size() : position; int indexTo = indexFrom + children.size() - 1; addWithoutSendingEvents(parent, position, children, extractor); - fireEvent(unwrap(parent), indexFrom, indexTo, - TreeDataEvent.INTERVAL_ADDED); + fireEvent(TreeDataEvent.INTERVAL_ADDED, getPath(parent), indexFrom, indexTo); } - private void addWithoutSendingEvents(Node parent, Integer position, - List> children, IChildrenExtractor extractor) { + private void addWithoutSendingEvents(Node parent, + Integer position, + List> children, + IChildrenExtractor extractor) { + parent.addAll(position, children); addToNodesAndDomainMapping(children); + for (Node each : children) { T value = each.value; - addWithoutSendingEvents(each, 0, - wrap(extractor.getChildren(value)), extractor); + addWithoutSendingEvents(each, 0, wrap(extractor.getChildren(value)), extractor); } } @@ -304,7 +413,7 @@ public class MutableTreeModel extends AbstractTreeModel { } public void add(T parent, T child) { - ArrayList children = new ArrayList(); + ArrayList children = new ArrayList<>(); children.add(child); add(parent, children); } @@ -314,7 +423,7 @@ public class MutableTreeModel extends AbstractTreeModel { T parent = getParent(object); Node parentNode = find(parent); int position = parentNode.getIndexOf(node); - fireEvent(parent, position, position, TreeDataEvent.CONTENTS_CHANGED); + fireEvent(TreeDataEvent.CONTENTS_CHANGED,getPath(parent), position, position); } public void add(T parent, int position, Collection children) { @@ -326,64 +435,64 @@ public class MutableTreeModel extends AbstractTreeModel { add(parentNode, null, wrap(children)); } - public void add(T parent, int position, Collection children, - IChildrenExtractor childrenExtractor) { + public void add(T parent, int position, Collection children, IChildrenExtractor childrenExtractor) { add(find(parent), position, wrap(children), childrenExtractor); } - public void add(T parent, Collection children, - IChildrenExtractor childrenExtractor) { + public void add(T parent, Collection children, IChildrenExtractor childrenExtractor) { add(find(parent), null, wrap(children), childrenExtractor); } public void remove(T node) { Node found = find(node); - if (found.isRoot()) { - throw new IllegalArgumentException(node - + " is root. It can't be removed"); + + if ( found.isRoot() ) { + throw new IllegalArgumentException(node + " is root. It can't be removed"); } + int positionInParent = found.remove(); nodesByDomainObject.remove(node); - fireEvent(unwrap(found.parentNode), positionInParent, positionInParent, - TreeDataEvent.INTERVAL_REMOVED); + fireEvent(TreeDataEvent.INTERVAL_REMOVED, getPath(found.parentNode), positionInParent, positionInParent); } public T getParent(T node) { Node associatedNode = find(node); - if (associatedNode.equals(root)) { + if ( associatedNode.equals(root) ) { throw new IllegalArgumentException(node + " is root"); } + return unwrap(associatedNode.getParent()); } public List getParents(T node) { - ArrayList result = new ArrayList(); + ArrayList result = new ArrayList<>(); + try { T current = node; - while (!isRoot(current)) { + + while ( !isRoot(current) ) { current = getParent(current); result.add(current); } } catch (Exception e) { LOG.error("Trying to get the parent of a removed node", e); } + return result; } public boolean isRoot(T node) { - Node associatedNode = find(node); - return associatedNode.isRoot(); + return find(node).isRoot(); } - public void replace(T nodeToRemove, T nodeToAdd, - IChildrenExtractor childrenExtractor) { + public void replace(T nodeToRemove, T nodeToAdd, IChildrenExtractor childrenExtractor) { T parent = getParent(nodeToRemove); Node parentNode = find(parent); final int insertionPosition = parentNode.getIndexOf(find(nodeToRemove)); remove(nodeToRemove); - if (childrenExtractor != null) { - add(parent, insertionPosition, - Collections.singletonList(nodeToAdd), childrenExtractor); + + if ( childrenExtractor != null ) { + add(parent, insertionPosition, Collections.singletonList(nodeToAdd), childrenExtractor); } else { add(parent, insertionPosition, Collections.singletonList(nodeToAdd)); } @@ -397,7 +506,8 @@ public class MutableTreeModel extends AbstractTreeModel { T parent = getParent(node); Node parentNode = find(parent); int[] changed = parentNode.down(find(node)); - if (changed.length != 0) { + + if ( changed.length != 0 ) { fireRecreationOfInterval(parentNode, changed[0], changed[1]); } } @@ -406,27 +516,21 @@ public class MutableTreeModel extends AbstractTreeModel { T parent = getParent(node); Node parentNode = find(parent); int[] changed = parentNode.up(find(node)); - if (changed.length != 0) { + + if ( changed.length != 0 ) { fireRecreationOfInterval(parentNode, changed[0], changed[1]); } } - private void fireRecreationOfInterval(Node parentNode, int start, - int endInclusive) { - fireEvent(parentNode.value, start, endInclusive, - TreeDataEvent.INTERVAL_REMOVED); - fireEvent(parentNode.value, start, endInclusive, - TreeDataEvent.INTERVAL_ADDED); + private void fireRecreationOfInterval(Node parentNode, int start, int endInclusive) { + fireEvent(TreeDataEvent.INTERVAL_REMOVED,getPath(parentNode.value), start, endInclusive); + fireEvent(TreeDataEvent.INTERVAL_ADDED, getPath(parentNode.value), start, endInclusive); } public boolean isEmpty() { return getChildCount(getRoot()) == 0; } - public boolean hasChildren(T node) { - return getChildCount(node) > 0; - } - public boolean contains(T object) { return find(object) != null; } @@ -435,21 +539,25 @@ public class MutableTreeModel extends AbstractTreeModel { Node parentNode = find(parent); Node childNode = find(child); - return parentNode != null && childNode != null - && childNode.getParent() != null - && childNode.getParent().equals(parentNode); + return parentNode != null && + childNode != null && + childNode.getParent() != null && + childNode.getParent().equals(parentNode); } public List asList() { - List result = new ArrayList(); + List result = new ArrayList<>(); asList(getRoot(), result); + return result; } private void asList(T root, List result) { - List list = new ArrayList(); + List list = new ArrayList<>(); + for (int i = 0; i < getChildCount(root); i++) { final T child = getChild(root, i); + list.add(child); result.add(child); } diff --git a/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java b/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java index 7a90a67f4..628248ff7 100644 --- a/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java +++ b/ganttzk/src/main/java/org/zkoss/ganttz/util/WeakReferencedListeners.java @@ -37,18 +37,19 @@ public class WeakReferencedListeners { } + private LinkedList> listeners = new LinkedList<>(); + + private List> pendingOfNotification = new ArrayList<>(); + + private WeakReferencedListeners() {} + public static WeakReferencedListeners create() { return new WeakReferencedListeners<>(); } - private LinkedList> listeners = new LinkedList<>(); - - private WeakReferencedListeners() { - - } - public enum Mode { - RECEIVE_PENDING, FROM_NOW_ON; + RECEIVE_PENDING, + FROM_NOW_ON } public void addListener(T listener) { @@ -61,11 +62,9 @@ public class WeakReferencedListeners { if ( getActiveListeners().isEmpty() && mode == Mode.RECEIVE_PENDING ) { notifyPendingOfNotificationTo(listener); } - listeners.add(new WeakReference(listener)); + listeners.add(new WeakReference<>(listener)); } - private List> pendingOfNotification = new ArrayList<>(); - private void notifyPendingOfNotificationTo(T listener) { for (IListenerNotification each : pendingOfNotification) { each.doNotify(listener); diff --git a/ganttzk/src/main/resources/metainfo/zk/lang-addon.xml b/ganttzk/src/main/resources/metainfo/zk/lang-addon.xml index fcca06ce0..df6a3790a 100755 --- a/ganttzk/src/main/resources/metainfo/zk/lang-addon.xml +++ b/ganttzk/src/main/resources/metainfo/zk/lang-addon.xml @@ -4,8 +4,7 @@ ganttz xul/html - + @@ -22,22 +21,18 @@ org.zkoss.ganttz.Planner ganttz.Planner ~./ganttz/zul/plannerLayout.zul - - tabSwitcher - org.zkoss.ganttz.TabSwitcher - ~./ganttz/zul/tabSwitcher.zul + tabSwitcher + org.zkoss.ganttz.TabSwitcher + ~./ganttz/zul/tabSwitcher.zul resourcesLoadPanel org.zkoss.ganttz.resourceload.ResourcesLoadPanel - ~./ganttz/zul/resourcesLoadLayout.zul + ~./ganttz/zul/resourcesLoadLayout.zul @@ -47,7 +42,6 @@ default mold/resource-load-list.js - @@ -76,20 +70,17 @@ ganttz.GanttPanel default - mold/gantt-panel.js resourceload - org.zkoss.ganttz.resourceload.ResourceLoadComponent - + org.zkoss.ganttz.resourceload.ResourceLoadComponent ganttz.resourceload.ResourceLoadComponent default mold/resource-load-component.js - @@ -100,7 +91,6 @@ ganttz.TaskRow default - mold/task-row.js @@ -111,7 +101,6 @@ ganttz.TaskComponent default - mold/task-component.js @@ -122,21 +111,17 @@ ganttz.Milestone default - mold/milestone.js - taskcontainer - org.zkoss.ganttz.TaskContainerComponent - + org.zkoss.ganttz.TaskContainerComponent ganttz.TaskContainerComponent default mold/task-container.js - @@ -146,7 +131,6 @@ ganttz.TaskList default - mold/task-list.js @@ -157,24 +141,20 @@ ganttz.DependencyList default - mold/dependency-list.js dependency - org.zkoss.ganttz.DependencyComponent - + org.zkoss.ganttz.DependencyComponent ganttz.DependencyComponent default mold/dependency-component.js - - timetracker org.zkoss.ganttz.timetracker.TimeTrackerComponent @@ -183,9 +163,9 @@ - timeTrackedTable - org.zkoss.ganttz.timetracker.TimeTrackedTable - ~./ganttz/zul/timetracker/timetrackedtable.zul + timeTrackedTable + org.zkoss.ganttz.timetracker.TimeTrackedTable + ~./ganttz/zul/timetracker/timetrackedtable.zul diff --git a/ganttzk/src/main/resources/web/css/jqplot/jquery.jqplot.min.css b/ganttzk/src/main/resources/web/css/jqplot/jquery.jqplot.min.css new file mode 100644 index 000000000..de15fff5b --- /dev/null +++ b/ganttzk/src/main/resources/web/css/jqplot/jquery.jqplot.min.css @@ -0,0 +1 @@ +.jqplot-target{position:relative;color:#666;font-family:"Trebuchet MS",Arial,Helvetica,sans-serif;font-size:1em;}.jqplot-axis{font-size:.75em;}.jqplot-xaxis{margin-top:10px;}.jqplot-x2axis{margin-bottom:10px;}.jqplot-yaxis{margin-right:10px;}.jqplot-y2axis,.jqplot-y3axis,.jqplot-y4axis,.jqplot-y5axis,.jqplot-y6axis,.jqplot-y7axis,.jqplot-y8axis,.jqplot-y9axis,.jqplot-yMidAxis{margin-left:10px;margin-right:10px;}.jqplot-axis-tick,.jqplot-xaxis-tick,.jqplot-yaxis-tick,.jqplot-x2axis-tick,.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick,.jqplot-yMidAxis-tick{position:absolute;white-space:pre;}.jqplot-xaxis-tick{top:0;left:15px;vertical-align:top;}.jqplot-x2axis-tick{bottom:0;left:15px;vertical-align:bottom;}.jqplot-yaxis-tick{right:0;top:15px;text-align:right;}.jqplot-yaxis-tick.jqplot-breakTick{right:-20px;margin-right:0;padding:1px 5px 1px 5px;z-index:2;font-size:1.5em;}.jqplot-y2axis-tick,.jqplot-y3axis-tick,.jqplot-y4axis-tick,.jqplot-y5axis-tick,.jqplot-y6axis-tick,.jqplot-y7axis-tick,.jqplot-y8axis-tick,.jqplot-y9axis-tick{left:0;top:15px;text-align:left;}.jqplot-yMidAxis-tick{text-align:center;white-space:nowrap;}.jqplot-xaxis-label{margin-top:10px;font-size:11pt;position:absolute;}.jqplot-x2axis-label{margin-bottom:10px;font-size:11pt;position:absolute;}.jqplot-yaxis-label{margin-right:10px;font-size:11pt;position:absolute;}.jqplot-yMidAxis-label{font-size:11pt;position:absolute;}.jqplot-y2axis-label,.jqplot-y3axis-label,.jqplot-y4axis-label,.jqplot-y5axis-label,.jqplot-y6axis-label,.jqplot-y7axis-label,.jqplot-y8axis-label,.jqplot-y9axis-label{font-size:11pt;margin-left:10px;position:absolute;}.jqplot-meterGauge-tick{font-size:.75em;color:#999;}.jqplot-meterGauge-label{font-size:1em;color:#999;}table.jqplot-table-legend{margin-top:12px;margin-bottom:12px;margin-left:12px;margin-right:12px;}table.jqplot-table-legend,table.jqplot-cursor-legend{background-color:rgba(255,255,255,0.6);border:1px solid #ccc;position:absolute;font-size:.75em;}td.jqplot-table-legend{vertical-align:middle;}td.jqplot-seriesToggle:hover,td.jqplot-seriesToggle:active{cursor:pointer;}.jqplot-table-legend .jqplot-series-hidden{text-decoration:line-through;}div.jqplot-table-legend-swatch-outline{border:1px solid #ccc;padding:1px;}div.jqplot-table-legend-swatch{width:0;height:0;border-top-width:5px;border-bottom-width:5px;border-left-width:6px;border-right-width:6px;border-top-style:solid;border-bottom-style:solid;border-left-style:solid;border-right-style:solid;}.jqplot-title{top:0;left:0;padding-bottom:.5em;font-size:1.2em;}table.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;}.jqplot-cursor-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-highlighter-tooltip,.jqplot-canvasOverlay-tooltip{border:1px solid #ccc;font-size:.75em;white-space:nowrap;background:rgba(208,208,208,0.5);padding:1px;}.jqplot-point-label{font-size:.75em;z-index:2;}td.jqplot-cursor-legend-swatch{vertical-align:middle;text-align:center;}div.jqplot-cursor-legend-swatch{width:1.2em;height:.7em;}.jqplot-error{text-align:center;}.jqplot-error-message{position:relative;top:46%;display:inline-block;}div.jqplot-bubble-label{font-size:.8em;padding-left:2px;padding-right:2px;color:rgb(20%,20%,20%);}div.jqplot-bubble-label.jqplot-bubble-label-highlight{background:rgba(90%,90%,90%,0.7);}div.jqplot-noData-container{text-align:center;background-color:rgba(96%,96%,96%,0.3);} \ No newline at end of file diff --git a/ganttzk/src/main/resources/web/ganttz/resourceload/leftPane.zul b/ganttzk/src/main/resources/web/ganttz/resourceload/leftPane.zul index 4e803d00d..12b97d99e 100644 --- a/ganttzk/src/main/resources/web/ganttz/resourceload/leftPane.zul +++ b/ganttzk/src/main/resources/web/ganttz/resourceload/leftPane.zul @@ -20,10 +20,10 @@ --> - - - - + + + + \ No newline at end of file diff --git a/ganttzk/src/main/resources/web/ganttz/zul/leftPane.zul b/ganttzk/src/main/resources/web/ganttz/zul/leftPane.zul index 59ff7ff7e..8a0d6e72c 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/leftPane.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/leftPane.zul @@ -20,6 +20,5 @@ --> -
-
+
\ No newline at end of file diff --git a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul index a77490678..7db75bf8f 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTree.zul @@ -20,15 +20,15 @@ --> + signature="java.lang.String _(java.lang.String name)" ?>
- - - - - - - - + + + + + + + +
diff --git a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRow.zul b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRow.zul index 63e0987c3..57430706e 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRow.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRow.zul @@ -20,20 +20,20 @@ --> - - - + + + + - +
diff --git a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRowLabels.zul b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRowLabels.zul index 82a216b58..7cee61311 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRowLabels.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/leftTasksTreeRowLabels.zul @@ -20,20 +20,21 @@ --> - - + - + - + - + - +
diff --git a/ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul b/ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul index ae21cb7ae..5dec45071 100644 --- a/ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul +++ b/ganttzk/src/main/resources/web/ganttz/zul/plannerLayout.zul @@ -18,108 +18,127 @@ You should have received a copy of the GNU Affero General Public License along with this program. If not, see . --> - - - - - + + + + + + + + - - + + - - + -