From f3dee6c31345518a0e7c016f45b9462c96d7cf9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93scar=20Gonz=C3=A1lez=20Fern=C3=A1ndez?= Date: Tue, 4 Jan 2011 17:00:44 +0100 Subject: [PATCH] [Bug #778] Fix bug Add hours group column by pulling up order element's implementation up. FEA: ItEr67S04BugFixing --- .../orders/OrderElementTreeController.java | 326 ++--------------- .../web/templates/TemplatesTreeComponent.java | 9 + .../templates/TemplatesTreeController.java | 31 ++ .../navalplanner/web/tree/TreeController.java | 329 +++++++++++++++++- 4 files changed, 397 insertions(+), 298 deletions(-) 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 8036d314b..c78b6513a 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 @@ -24,7 +24,6 @@ import static org.navalplanner.web.I18nHelper._; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -45,8 +44,6 @@ import org.navalplanner.business.templates.entities.OrderElementTemplate; import org.navalplanner.web.common.IMessagesForUser; import org.navalplanner.web.common.Level; import org.navalplanner.web.common.Util; -import org.navalplanner.web.common.Util.Getter; -import org.navalplanner.web.common.Util.Setter; import org.navalplanner.web.common.components.bandboxsearch.BandboxMultipleSearch; import org.navalplanner.web.common.components.bandboxsearch.BandboxSearch; import org.navalplanner.web.common.components.finders.FilterPair; @@ -61,7 +58,6 @@ 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.KeyEvent; import org.zkoss.zul.Button; import org.zkoss.zul.Constraint; import org.zkoss.zul.Datebox; @@ -392,13 +388,6 @@ public class OrderElementTreeController extends TreeController { } } - private enum Navigation { - LEFT, UP, RIGHT, DOWN; - public static Navigation getIntentFrom(KeyEvent keyEvent) { - return values()[keyEvent.getKeyCode() - 37]; - } - } - private Map orderElementCodeTextboxes = new HashMap(); public Map getOrderElementCodeTextboxes() { @@ -407,204 +396,8 @@ public class OrderElementTreeController extends TreeController { public class OrderElementTreeitemRenderer extends Renderer { - private class KeyboardNavigationHandler { - - private Map> navigableElementsByRow = new HashMap>(); - - void register(final InputElement inputElement) { - inputElement.setCtrlKeys("#up#down"); - registerNavigableElement(inputElement); - inputElement.addEventListener("onCtrlKey", new EventListener() { - private Treerow treerow = getCurrentTreeRow(); - - @Override - public void onEvent(Event event) throws Exception { - Navigation navigation = Navigation - .getIntentFrom((KeyEvent) event); - moveFocusTo(inputElement, navigation, treerow); - } - }); - } - - private void registerNavigableElement(InputElement inputElement) { - Treerow treeRow = getCurrentTreeRow(); - if (!navigableElementsByRow.containsKey(treeRow)) { - navigableElementsByRow.put(treeRow, - new ArrayList()); - } - navigableElementsByRow.get(treeRow).add(inputElement); - } - - private void moveFocusTo(InputElement inputElement, - Navigation navigation, Treerow treerow) { - List boxes = getNavigableElements(treerow); - int position = boxes.indexOf(inputElement); - - switch (navigation) { - case UP: - focusGoUp(treerow, position); - break; - case DOWN: - focusGoDown(treerow, position); - break; - case LEFT: - if (position == 0) { - focusGoUp(treerow, boxes.size() - 1); - } else { - if (boxes.get(position - 1).isDisabled()) { - moveFocusTo(boxes.get(position - 1), - Navigation.LEFT, treerow); - } else { - boxes.get(position - 1).focus(); - } - } - break; - case RIGHT: - if (position == boxes.size() - 1) { - focusGoDown(treerow, 0); - } else { - if (boxes.get(position + 1).isDisabled()) { - moveFocusTo(boxes.get(position + 1), - Navigation.RIGHT, treerow); - } else { - boxes.get(position + 1).focus(); - } - } - break; - } - } - - private void focusGoUp(Treerow treerow, int position) { - Treeitem parent = (Treeitem) treerow.getParent(); - @SuppressWarnings("unchecked") - List treeItems = parent.getParent().getChildren(); - int myPosition = parent.indexOf(); - - if (myPosition > 0) { - // the current node is not the first brother - Treechildren treechildren = treeItems.get(myPosition - 1) - .getTreechildren(); - if (treechildren == null - || treechildren.getChildren().size() == 0) { - // the previous brother doesn't have children, - // or it has children but they are unloaded - Treerow upTreerow = treeItems.get(myPosition - 1) - .getTreerow(); - - focusCorrectBox(upTreerow, position, Navigation.LEFT); - } - else { - // we have to move to the last child of the previous - // brother - Treerow upTreerow = findLastTreerow(treeItems - .get(myPosition - 1)); - - while (!upTreerow.isVisible()) { - upTreerow = ((Treeitem) upTreerow - .getParent().getParent().getParent()) - .getTreerow(); - } - - focusCorrectBox(upTreerow, position, Navigation.LEFT); - } - } - else { - // the node is the first brother - if (parent.getParent().getParent() instanceof Treeitem) { - // the node has a parent, so we move up to it - Treerow upTreerow = ((Treeitem) parent.getParent() - .getParent()).getTreerow(); - - focusCorrectBox(upTreerow, position, Navigation.LEFT); - } - } - } - - private Treerow findLastTreerow(Treeitem item) { - if (item.getTreechildren() == null) { - return item.getTreerow(); - } - @SuppressWarnings("unchecked") - List children = item.getTreechildren().getChildren(); - Treeitem lastchild = children.get(children.size() - 1); - - return findLastTreerow(lastchild); - } - - private void focusGoDown(Treerow treerow, int position) { - Treeitem parent = (Treeitem) treerow.getParent(); - focusGoDown(parent, position, false); - } - - private void focusGoDown(Treeitem parent, int position, - boolean skipChildren) { - if (parent.getTreechildren() == null || skipChildren) { - // Moving from a node to its brother - @SuppressWarnings("unchecked") - List treeItems = parent.getParent().getChildren(); - int myPosition = parent.indexOf(); - - if (myPosition < treeItems.size() - 1) { - // the current node is not the last one - Treerow downTreerow = treeItems.get(myPosition + 1) - .getTreerow(); - - focusCorrectBox(downTreerow, position, Navigation.RIGHT); - } else { - // the node is the last brother - if (parent.getParent().getParent() instanceof Treeitem) { - focusGoDown((Treeitem) parent.getParent() - .getParent(), position, true); - } - } - } else { - // Moving from a parent node to its children - Treechildren treechildren = parent.getTreechildren(); - - if (treechildren.getChildren().size() == 0) { - // the children are unloaded yet - focusGoDown(parent, position, true); - return; - } - Treerow downTreerow = ((Treeitem) treechildren - .getChildren().get(0)).getTreerow(); - - if (!downTreerow.isVisible()) { - // children are loaded but not visible - focusGoDown(parent, position, true); - return; - } - - focusCorrectBox(downTreerow, position, Navigation.RIGHT); - } - } - - private void focusCorrectBox(Treerow treerow, int position, - Navigation whereIfDisabled) { - List boxes = getNavigableElements(treerow); - - if (boxes.get(position).isDisabled()) { - moveFocusTo(boxes.get(position), whereIfDisabled, treerow); - } - else { - boxes.get(position).focus(); - } - } - - private List getNavigableElements(Treerow row) { - if (!navigableElementsByRow.containsKey(row)) { - return Collections.emptyList(); - } - return Collections.unmodifiableList(navigableElementsByRow - .get(row)); - } - - } - private Map hoursIntBoxByOrderElement = new HashMap(); - private KeyboardNavigationHandler navigationHandler = new KeyboardNavigationHandler(); - public OrderElementTreeitemRenderer() { } @@ -635,7 +428,6 @@ public class OrderElementTreeController extends TreeController { textBox.setDisabled(true); } addCell(cssClass, textBox); - navigationHandler.register(textBox); } @Override @@ -684,7 +476,6 @@ public class OrderElementTreeController extends TreeController { } addCell(textBoxCode); - navigationHandler.register(textBoxCode); orderElementCodeTextboxes.put(orderElement, textBoxCode); } @@ -708,7 +499,6 @@ public class OrderElementTreeController extends TreeController { dinamicDatebox.setDisabled(true); } addDateCell(dinamicDatebox, _("init")); - navigationHandler.register(dinamicDatebox.getDateTextBox()); } void addEndDateCell(final OrderElement currentOrderElement) { @@ -730,90 +520,6 @@ public class OrderElementTreeController extends TreeController { dinamicDatebox.setDisabled(true); } addDateCell(dinamicDatebox, _("end")); - navigationHandler.register(dinamicDatebox - .getDateTextBox()); - } - - void addHoursCell(final OrderElement currentOrderElement) { - Intbox intboxHours = buildHoursIntboxFor(currentOrderElement); - hoursIntBoxByOrderElement.put(currentOrderElement, intboxHours); - if (readOnly) { - intboxHours.setDisabled(true); - } - - Treecell cellHours = addCell(intboxHours); - setReadOnlyHoursCell(currentOrderElement, intboxHours, cellHours); - navigationHandler.register(intboxHours); - } - - private void addDateCell(final DynamicDatebox dinamicDatebox, final String dateboxName) { - - Component cell = Executions.getCurrent().createComponents( - "/common/components/dynamicDatebox.zul", null, null); - try { - dinamicDatebox.doAfterCompose(cell); - } catch (Exception e) { - throw new RuntimeException(e); - } - registerFocusEvent(dinamicDatebox.getDateTextBox()); - addCell(cell); - } - - private Intbox buildHoursIntboxFor( - final OrderElement currentOrderElement) { - Intbox result = new Intbox(); - if (currentOrderElement instanceof OrderLine) { - OrderLine orderLine = (OrderLine) currentOrderElement; - Util.bind(result, getHoursGetterFor(currentOrderElement), - getHoursSetterFor(orderLine)); - result.setConstraint(getHoursConstraintFor(orderLine)); - } else { - // If it's a container hours cell is not editable - Util.bind(result, getHoursGetterFor(currentOrderElement)); - } - return result; - } - - private Getter getHoursGetterFor( - final OrderElement currentOrderElement) { - return new Util.Getter() { - @Override - public Integer get() { - return currentOrderElement.getWorkHours(); - } - }; - } - - private Constraint getHoursConstraintFor(final OrderLine orderLine) { - return new Constraint() { - @Override - public void validate(Component comp, Object value) - throws WrongValueException { - if (!orderLine.isTotalHoursValid((Integer) value)) { - throw new WrongValueException( - comp, - _("Value is not valid, taking into account the current list of HoursGroup")); - } - } - }; - } - - private Setter getHoursSetterFor(final OrderLine orderLine) { - return new Util.Setter() { - @Override - public void set(Integer value) { - orderLine.setWorkHours(value); - List parentNodes = getModel().getParents( - orderLine); - // Remove the last element because it's an - // Order node, not an OrderElement - parentNodes.remove(parentNodes.size() - 1); - for (OrderElement node : parentNodes) { - Intbox intbox = hoursIntBoxByOrderElement.get(node); - intbox.setValue(node.getWorkHours()); - } - } - }; } @Override @@ -973,8 +679,7 @@ public class OrderElementTreeController extends TreeController { if ((!readOnly) && (orderElement instanceof OrderLine)) { if (orderElement.getHoursGroups().size() > 1) { boxHours.setReadonly(true); - tc - .setTooltiptext(_("Not editable for containing more that an hours group.")); + tc.setTooltiptext(_("Not editable for containing more that an hours group.")); } else { boxHours.setReadonly(false); tc.setTooltiptext(""); @@ -1060,4 +765,33 @@ public class OrderElementTreeController extends TreeController { } } + @Override + protected IHoursGroupHandler getHoursGroupHandler() { + return new IHoursGroupHandler() { + + @Override + public boolean hasMoreThanOneHoursGroup(OrderElement element) { + return element.getHoursGroups().size() > 1; + } + + @Override + public boolean isTotalHoursValid(OrderElement line, Integer value) { + return ((OrderLine) line).isTotalHoursValid(value); + } + + @Override + public Integer getWorkHoursFor(OrderElement element) { + return element.getWorkHours(); + } + + @Override + public void setWorkHours(OrderElement element, Integer value) { + if (element instanceof OrderLine) { + OrderLine line = (OrderLine) element; + line.setWorkHours(value); + } + } + }; + } + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeComponent.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeComponent.java index 91d2c9893..f12fafccf 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeComponent.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeComponent.java @@ -88,6 +88,15 @@ public class TemplatesTreeComponent extends TreeComponent { renderer.addInitCell(currentElement); } + }); + result.add(new TemplatesTreeColumn(_("Hours"), "hours") { + + @Override + protected void doCell(TemplatesTreeRenderer renderer, + Treeitem item, OrderElementTemplate currentElement) { + renderer.addHoursCell(currentElement); + } + }); result.add(new TemplatesTreeColumn( _("Deadline (days since beggining project)"), diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeController.java index fe09cfa45..73608ccd8 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplatesTreeController.java @@ -25,6 +25,7 @@ import org.apache.commons.lang.StringUtils; import org.hibernate.validator.ClassValidator; import org.navalplanner.business.orders.entities.SchedulingState; import org.navalplanner.business.templates.entities.OrderElementTemplate; +import org.navalplanner.business.templates.entities.OrderLineTemplate; import org.navalplanner.web.common.Util; import org.navalplanner.web.common.Util.Getter; import org.navalplanner.web.common.Util.Setter; @@ -225,4 +226,34 @@ public class TemplatesTreeController extends // we do nothing, since there isn't an hours box in this tree } + @Override + protected IHoursGroupHandler getHoursGroupHandler() { + return new IHoursGroupHandler() { + + @Override + public boolean hasMoreThanOneHoursGroup(OrderElementTemplate element) { + return element.getHoursGroups().size() > 1; + } + + @Override + public boolean isTotalHoursValid(OrderElementTemplate line, + Integer value) { + return ((OrderLineTemplate) line).isTotalHoursValid(value); + } + + @Override + public Integer getWorkHoursFor(OrderElementTemplate element) { + return element.getWorkHours(); + } + + @Override + public void setWorkHours(OrderElementTemplate element, Integer value) { + if (element instanceof OrderLineTemplate) { + OrderLineTemplate line = (OrderLineTemplate) element; + line.setWorkHours(value); + } + } + }; + } + } diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/tree/TreeController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/tree/TreeController.java index f980932b9..1deb594b7 100644 --- a/navalplanner-webapp/src/main/java/org/navalplanner/web/tree/TreeController.java +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/tree/TreeController.java @@ -21,9 +21,13 @@ package org.navalplanner.web.tree; import static org.navalplanner.web.I18nHelper._; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.apache.commons.logging.Log; @@ -39,22 +43,29 @@ import org.navalplanner.web.common.IMessagesForUser; import org.navalplanner.web.common.Level; import org.navalplanner.web.common.MessagesForUser; import org.navalplanner.web.common.Util; +import org.navalplanner.web.common.Util.Getter; +import org.navalplanner.web.common.Util.Setter; +import org.navalplanner.web.orders.DynamicDatebox; import org.navalplanner.web.orders.SchedulingStateToggler; import org.navalplanner.web.tree.TreeComponent.Column; import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.DropEvent; 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; import org.zkoss.zul.Button; +import org.zkoss.zul.Constraint; import org.zkoss.zul.Intbox; import org.zkoss.zul.RendererCtrl; import org.zkoss.zul.Textbox; import org.zkoss.zul.Tree; import org.zkoss.zul.TreeModel; 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; @@ -310,9 +321,210 @@ public abstract class TreeController> extends return (children.get(children.size() - 1).equals(element)); } + private enum Navigation { + LEFT, UP, RIGHT, DOWN; + public static Navigation getIntentFrom(KeyEvent keyEvent) { + return values()[keyEvent.getKeyCode() - 37]; + } + } + public abstract class Renderer implements TreeitemRenderer, RendererCtrl { + private class KeyboardNavigationHandler { + + private Map> navigableElementsByRow = new HashMap>(); + + void register(final InputElement inputElement) { + inputElement.setCtrlKeys("#up#down"); + registerNavigableElement(inputElement); + inputElement.addEventListener("onCtrlKey", new EventListener() { + private Treerow treerow = getCurrentTreeRow(); + + @Override + public void onEvent(Event event) throws Exception { + Navigation navigation = Navigation + .getIntentFrom((KeyEvent) event); + moveFocusTo(inputElement, navigation, treerow); + } + }); + } + + private void registerNavigableElement(InputElement inputElement) { + Treerow treeRow = getCurrentTreeRow(); + if (!navigableElementsByRow.containsKey(treeRow)) { + navigableElementsByRow.put(treeRow, + new ArrayList()); + } + navigableElementsByRow.get(treeRow).add(inputElement); + } + + private void moveFocusTo(InputElement inputElement, + Navigation navigation, Treerow treerow) { + List boxes = getNavigableElements(treerow); + int position = boxes.indexOf(inputElement); + + switch (navigation) { + case UP: + focusGoUp(treerow, position); + break; + case DOWN: + focusGoDown(treerow, position); + break; + case LEFT: + if (position == 0) { + focusGoUp(treerow, boxes.size() - 1); + } else { + if (boxes.get(position - 1).isDisabled()) { + moveFocusTo(boxes.get(position - 1), + Navigation.LEFT, treerow); + } else { + boxes.get(position - 1).focus(); + } + } + break; + case RIGHT: + if (position == boxes.size() - 1) { + focusGoDown(treerow, 0); + } else { + if (boxes.get(position + 1).isDisabled()) { + moveFocusTo(boxes.get(position + 1), + Navigation.RIGHT, treerow); + } else { + boxes.get(position + 1).focus(); + } + } + break; + } + } + + private void focusGoUp(Treerow treerow, int position) { + Treeitem parent = (Treeitem) treerow.getParent(); + @SuppressWarnings("unchecked") + List treeItems = parent.getParent().getChildren(); + int myPosition = parent.indexOf(); + + if (myPosition > 0) { + // the current node is not the first brother + Treechildren treechildren = treeItems.get(myPosition - 1) + .getTreechildren(); + if (treechildren == null + || treechildren.getChildren().size() == 0) { + // the previous brother doesn't have children, + // or it has children but they are unloaded + Treerow upTreerow = treeItems.get(myPosition - 1) + .getTreerow(); + + focusCorrectBox(upTreerow, position, Navigation.LEFT); + } else { + // we have to move to the last child of the previous + // brother + Treerow upTreerow = findLastTreerow(treeItems + .get(myPosition - 1)); + + while (!upTreerow.isVisible()) { + upTreerow = ((Treeitem) upTreerow.getParent() + .getParent().getParent()).getTreerow(); + } + + focusCorrectBox(upTreerow, position, Navigation.LEFT); + } + } else { + // the node is the first brother + if (parent.getParent().getParent() instanceof Treeitem) { + // the node has a parent, so we move up to it + Treerow upTreerow = ((Treeitem) parent.getParent() + .getParent()).getTreerow(); + + focusCorrectBox(upTreerow, position, Navigation.LEFT); + } + } + } + + private Treerow findLastTreerow(Treeitem item) { + if (item.getTreechildren() == null) { + return item.getTreerow(); + } + @SuppressWarnings("unchecked") + List children = item.getTreechildren().getChildren(); + Treeitem lastchild = children.get(children.size() - 1); + + return findLastTreerow(lastchild); + } + + private void focusGoDown(Treerow treerow, int position) { + Treeitem parent = (Treeitem) treerow.getParent(); + focusGoDown(parent, position, false); + } + + private void focusGoDown(Treeitem parent, int position, + boolean skipChildren) { + if (parent.getTreechildren() == null || skipChildren) { + // Moving from a node to its brother + @SuppressWarnings("unchecked") + List treeItems = parent.getParent().getChildren(); + int myPosition = parent.indexOf(); + + if (myPosition < treeItems.size() - 1) { + // the current node is not the last one + Treerow downTreerow = treeItems.get(myPosition + 1) + .getTreerow(); + + focusCorrectBox(downTreerow, position, Navigation.RIGHT); + } else { + // the node is the last brother + if (parent.getParent().getParent() instanceof Treeitem) { + focusGoDown((Treeitem) parent.getParent() + .getParent(), position, true); + } + } + } else { + // Moving from a parent node to its children + Treechildren treechildren = parent.getTreechildren(); + + if (treechildren.getChildren().size() == 0) { + // the children are unloaded yet + focusGoDown(parent, position, true); + return; + } + Treerow downTreerow = ((Treeitem) treechildren + .getChildren().get(0)).getTreerow(); + + if (!downTreerow.isVisible()) { + // children are loaded but not visible + focusGoDown(parent, position, true); + return; + } + + focusCorrectBox(downTreerow, position, Navigation.RIGHT); + } + } + + private void focusCorrectBox(Treerow treerow, int position, + Navigation whereIfDisabled) { + List boxes = getNavigableElements(treerow); + + if (boxes.get(position).isDisabled()) { + moveFocusTo(boxes.get(position), whereIfDisabled, treerow); + } else { + boxes.get(position).focus(); + } + } + + private List getNavigableElements(Treerow row) { + if (!navigableElementsByRow.containsKey(row)) { + return Collections.emptyList(); + } + return Collections.unmodifiableList(navigableElementsByRow + .get(row)); + } + + } + + private Map hoursIntBoxByElement = new HashMap(); + + private KeyboardNavigationHandler navigationHandler = new KeyboardNavigationHandler(); + private Treerow currentTreeRow; public Treerow getCurrentTreeRow() { @@ -336,6 +548,20 @@ public abstract class TreeController> extends }); } + protected void addDateCell(final DynamicDatebox dinamicDatebox, + final String dateboxName) { + + Component cell = Executions.getCurrent().createComponents( + "/common/components/dynamicDatebox.zul", null, null); + try { + dinamicDatebox.doAfterCompose(cell); + } catch (Exception e) { + throw new RuntimeException(e); + } + addCell(cell); + registerListeners(dinamicDatebox.getDateTextBox()); + } + protected Treecell addCell(Component... components) { return addCell(null, components); } @@ -347,14 +573,19 @@ public abstract class TreeController> extends } for (Component component : components) { cell.appendChild(component); - if(component instanceof InputElement) { - registerFocusEvent((InputElement) component); + if (component instanceof InputElement) { + registerListeners((InputElement) component); } } currentTreeRow.appendChild(cell); return cell; } + private void registerListeners(InputElement associatedInput) { + registerFocusEvent(associatedInput); + navigationHandler.register(associatedInput); + } + @Override public void render(final Treeitem item, Object data) throws Exception { item.setValue(data); @@ -478,6 +709,87 @@ public abstract class TreeController> extends protected abstract void addDescriptionCell(final T element); + public void addHoursCell(final T currentElement) { + Intbox intboxHours = buildHoursIntboxFor(currentElement); + hoursIntBoxByElement.put(currentElement, intboxHours); + if (readOnly) { + intboxHours.setDisabled(true); + } + Treecell cellHours = addCell(intboxHours); + setReadOnlyHoursCell(currentElement, intboxHours, cellHours); + } + + private void setReadOnlyHoursCell(T element, + Intbox boxHours, Treecell tc) { + if (!readOnly && isLine(element)) { + if (getHoursGroupHandler().hasMoreThanOneHoursGroup(element)) { + boxHours.setReadonly(true); + tc.setTooltiptext(_("Not editable for containing more that an hours group.")); + } else { + boxHours.setReadonly(false); + tc.setTooltiptext(""); + } + } + } + + private Intbox buildHoursIntboxFor(final T element) { + Intbox result = new Intbox(); + if (isLine(element)) { + Util.bind(result, getHoursGetterFor(element), + getHoursSetterFor(element)); + result.setConstraint(getHoursConstraintFor(element)); + } else { + // If it's a container hours cell is not editable + Util.bind(result, getHoursGetterFor(element)); + } + return result; + } + + private Getter getHoursGetterFor(final T element) { + return new Util.Getter() { + @Override + public Integer get() { + return getHoursGroupHandler().getWorkHoursFor(element); + } + }; + } + + private Setter getHoursSetterFor(final T element) { + return new Util.Setter() { + @Override + public void set(Integer value) { + getHoursGroupHandler().setWorkHours(element, value); + List parentNodes = getModel().getParents(element); + // Remove the last element because it's an + // Order node, not an OrderElement + parentNodes.remove(parentNodes.size() - 1); + for (T node : parentNodes) { + Intbox intbox = hoursIntBoxByElement.get(node); + intbox.setValue(getHoursGroupHandler().getWorkHoursFor(node)); + } + } + }; + } + + private Constraint getHoursConstraintFor(final T line) { + return new Constraint() { + @Override + public void validate(Component comp, Object value) + throws WrongValueException { + if (!getHoursGroupHandler().isTotalHoursValid(line, ((Integer) value))) { + throw new WrongValueException( + comp, + _("Value is not valid, taking into account the current list of HoursGroup")); + } + } + + }; + } + + private boolean isLine(T element) { + return element.getChildren().isEmpty(); + } + protected abstract void addOperationsCell(final Treeitem item, final T currentElement); @@ -624,6 +936,19 @@ public abstract class TreeController> extends this.columns = columns; } + public interface IHoursGroupHandler { + + boolean hasMoreThanOneHoursGroup(T element); + + boolean isTotalHoursValid(T line, Integer value); + + Integer getWorkHoursFor(T element); + + void setWorkHours(T element, Integer value); + } + + protected abstract IHoursGroupHandler getHoursGroupHandler(); + /** * Disable control buttons (new, up, down, indent, unindent, delete) */