diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/DynamicDatebox.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/DynamicDatebox.java new file mode 100644 index 000000000..9c15a11e0 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/DynamicDatebox.java @@ -0,0 +1,228 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package org.navalplanner.web.orders; + +import java.text.DateFormat; +import java.util.Date; +import java.util.List; + +import org.navalplanner.business.orders.entities.OrderElement; +import org.zkoss.ganttz.util.ComponentsFinder; +import org.zkoss.util.Locales; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.util.GenericForwardComposer; +import org.zkoss.zul.Datebox; +import org.zkoss.zul.Hbox; +import org.zkoss.zul.Textbox; + +public class DynamicDatebox extends GenericForwardComposer { + + private final OrderElement orderElement; + + final Getter getter; + + final Setter setter; + + private Textbox dateTextBox; + + private Datebox dateBox; + + private DateFormat dateFormat; + + public DynamicDatebox(final OrderElement orderElement, Getter getter, + Setter setter) { + this.orderElement = orderElement; + this.setter = setter; + this.getter = getter; + this.dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locales + .getCurrent()); + } + + public OrderElement getOrderElement() { + return orderElement; + } + + public Datebox getDateBox() { + return dateBox; + } + + public void setDateBox(Datebox dateBox) { + this.dateBox = dateBox; + this.dateBox.setCompact(true); + this.dateBox.setFormat("dd/MM/yyyy"); + } + + /** + * When a text box associated to a datebox is requested to show the datebox, + * the corresponding datebox is shown + * @param component + * the component that has received focus + */ + public void userWantsDateBox(Component component) { + if (component == dateTextBox) { + showDateBox(dateBox, dateTextBox); + } + } + + private void showDateBox(Datebox currentDateBox, Textbox associatedTextBox) { + associatedTextBox.setVisible(false); + currentDateBox.setVisible(true); + currentDateBox.setFocus(true); + currentDateBox.setOpen(true); + } + + /** + * When the dateBox loses focus the corresponding textbox is shown instead. + * @param dateBox + * the component that has lost focus + */ + public void dateBoxHasLostFocus(Datebox currentDateBox) { + if (currentDateBox == dateBox) { + hideDateBox(dateBox, dateTextBox); + } + } + + private void hideDateBox(Datebox dateBoxToDissapear, + Textbox associatedTextBox) { + dateBoxToDissapear.setVisible(false); + associatedTextBox.setVisible(true); + } + + @Override + public void doAfterCompose(Component component) throws Exception { + super.doAfterCompose(component); + findComponents((Hbox) component); + registerListeners(); + updateComponents(); + } + + private void registerListeners() { + registerOnEnterListener(dateTextBox); + registerOnEnterOpenDateBox(dateBox); + registerBlurListener(dateBox); + registerOnChange(dateBox); + } + + private void findComponents(Hbox hbox) { + List children = hbox.getChildren(); + assert children.size() == 2; + + dateTextBox = findTextBoxOfCell(children); + dateBox = findDateBoxOfCell(children); + } + + private static Datebox findDateBoxOfCell(List children) { + return ComponentsFinder.findComponentsOfType(Datebox.class, children) + .get(0); + } + + private static Textbox findTextBoxOfCell(List children) { + return ComponentsFinder.findComponentsOfType(Textbox.class, children) + .get(0); + } + + private void registerOnChange(Component component) { + component.addEventListener("onChange", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + updateBean(); + updateComponents(); + } + }); + } + + private void registerOnEnterListener(final Textbox textBox) { + textBox.addEventListener("onOK", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + userWantsDateBox(textBox); + } + }); + } + + private void registerOnEnterOpenDateBox(final Datebox currentDatebox) { + currentDatebox.addEventListener("onOK", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + currentDatebox.setOpen(true); + } + }); + } + + private void registerBlurListener(final Datebox currentDatebox) { + currentDatebox.addEventListener("onBlur", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + dateBoxHasLostFocus(currentDatebox); + } + }); + } + + public static interface Getter { + /** + * Typical get method that returns a variable. + * @return A variable of type Date. + */ + public Date get(); + } + + public static interface Setter { + /** + * Typical set method to store a variable. + * @param value + * A variable of type Date to be set. + */ + public void set(Date value); + } + + public void updateBean() { + Date date = getDateBox().getValue(); + setter.set(date); + + } + + private void updateComponents() { + getDateBox().setValue(getter.get()); + getDateTextBox().setValue(asString(getter.get())); + } + + private String asString(Date date) { + if (date == null) { + return ""; + } + return dateFormat.format(date); + } + + public Textbox getDateTextBox() { + return dateTextBox; + } + + public void setDateTextBox(Textbox dateTextBox) { + this.dateTextBox = dateTextBox; + } + +} diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java index 1a5ae8253..dd2bfee45 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/OrderElementTreeController.java @@ -170,6 +170,18 @@ public class OrderElementTreeController extends TreeController { } } + private void notifyDateboxCantBeCreated(final String dateboxName, + final String codeOrderElement) { + try { + Messagebox.show(_("the " + dateboxName + + "datebox of the order element " + codeOrderElement + + " could not be created.\n"), + _("Operation cannot be done"), Messagebox.OK, + Messagebox.INFORMATION); + } catch (InterruptedException e) { + } + } + protected void filterByPredicateIfAny() { if (predicate != null) { filterByPredicate(); @@ -309,35 +321,40 @@ public class OrderElementTreeController extends TreeController { } void addInitDateCell(final OrderElement currentOrderElement) { - addCell(Util.bind(new Datebox(), new Util.Getter() { + DynamicDatebox dinamicDatebox = new DynamicDatebox( + currentOrderElement, new DynamicDatebox.Getter() { - @Override - public Date get() { - return currentOrderElement.getInitDate(); - } - }, new Util.Setter() { + @Override + public Date get() { + return currentOrderElement.getInitDate(); + } + }, new DynamicDatebox.Setter() { - @Override - public void set(Date value) { - currentOrderElement.setInitDate(value); - } - })); + @Override + public void set(Date value) { + currentOrderElement.setInitDate(value); + + } + }); + addDateCell(dinamicDatebox, _("init"), currentOrderElement); } void addEndDateCell(final OrderElement currentOrderElement) { - addCell(Util.bind(new Datebox(), new Util.Getter() { + DynamicDatebox dinamicDatebox = new DynamicDatebox( + currentOrderElement, new DynamicDatebox.Getter() { - @Override - public Date get() { - return currentOrderElement.getDeadline(); - } - }, new Util.Setter() { + @Override + public Date get() { + return currentOrderElement.getDeadline(); + } + }, new DynamicDatebox.Setter() { - @Override - public void set(Date value) { - currentOrderElement.setDeadline(value); - } - })); + @Override + public void set(Date value) { + currentOrderElement.setDeadline(value); + } + }); + addDateCell(dinamicDatebox, _("end"), currentOrderElement); } void addHoursCell(final OrderElement currentOrderElement) { @@ -346,6 +363,21 @@ public class OrderElementTreeController extends TreeController { addCell(intboxHours); } + private void addDateCell(final DynamicDatebox dinamicDatebox, + final String dateboxName, + final OrderElement currentOrderElement) { + + Component cell = Executions.getCurrent().createComponents( + "/common/components/dynamicDatebox.zul", null, null); + try { + dinamicDatebox.doAfterCompose(cell); + } catch (Exception e) { + notifyDateboxCantBeCreated(dateboxName, currentOrderElement + .getCode()); + } + addCell(cell); + } + private Intbox buildHoursIntboxFor( final OrderElement currentOrderElement) { Intbox result = new Intbox(); diff --git a/navalplanner-webapp/src/main/webapp/common/components/dynamicDatebox.zul b/navalplanner-webapp/src/main/webapp/common/components/dynamicDatebox.zul new file mode 100644 index 000000000..eb0cced97 --- /dev/null +++ b/navalplanner-webapp/src/main/webapp/common/components/dynamicDatebox.zul @@ -0,0 +1,24 @@ + + + + + +