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 9b8fb8d1d..bb51e17a2 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 @@ -62,7 +62,6 @@ import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zul.Button; import org.zkoss.zul.Constraint; import org.zkoss.zul.Datebox; -import org.zkoss.zul.Messagebox; import org.zkoss.zul.Tab; import org.zkoss.zul.Textbox; import org.zkoss.zul.Treechildren; @@ -77,6 +76,7 @@ import org.zkoss.zul.impl.api.InputElement; * @author Lorenzo Tilve Álvaro * @author Manuel Rego Casasnovas * @author Susana Montes Pedreira + * @author Diego Pino García */ public class OrderElementTreeController extends TreeController { @@ -101,6 +101,8 @@ public class OrderElementTreeController extends TreeController { @Resource private IOrderTemplatesControllerEntryPoints orderTemplates; + private OrderElementOperations operationsForOrderElement; + private final IMessagesForUser messagesForUser; public List getLabels() { @@ -119,6 +121,18 @@ public class OrderElementTreeController extends TreeController { this.orderModel = orderModel; this.orderElementController = orderElementController; this.messagesForUser = messagesForUser; + initializeOperationsForOrderElement(); + } + + /** + * Initializes operationsForOrderTemplate. A reference to variables tree and + * orderTemplates will be set later in doAfterCompose() + */ + private void initializeOperationsForOrderElement() { + operationsForOrderElement = OrderElementOperations.build() + .treeController(this) + .orderModel(this.orderModel) + .orderElementController(this.orderElementController); } public OrderElementController getOrderElementController() { @@ -130,93 +144,36 @@ public class OrderElementTreeController extends TreeController { return orderModel.getOrderElementTreeModel(); } - public void createTemplateFromSelectedOrderElement() { - if (tree.getSelectedCount() == 1) { - createTemplate(getSelectedNode()); - } else { - showSelectAnElementMessageBox(); - } + /** + * Operations for each node + */ + + public void editSelectedElement() { + operationsForOrderElement.editSelectedElement(); } - public void editSelectedOrderElement() { - if (tree.getSelectedCount() == 1) { - showEditionOrderElement(tree.getSelectedItem()); - } else { - showSelectAnElementMessageBox(); - } + public void createTemplateFromSelectedElement() { + operationsForOrderElement.createTemplateFromSelectedElement(); } - public void moveSelectedOrderElementUp() { - if (tree.getSelectedCount() == 1) { - Treeitem item = tree.getSelectedItem(); - up((OrderElement)item.getValue()); - Treeitem brother = (Treeitem) item.getPreviousSibling(); - if (brother != null) { - brother.setSelected(true); - } - } else { - showSelectAnElementMessageBox(); - } + public void moveSelectedElementUp() { + operationsForOrderElement.moveSelectedElementUp(); } - public void moveSelectedOrderElementDown() { - if (tree.getSelectedCount() == 1) { - Treeitem item = tree.getSelectedItem(); - down((OrderElement)item.getValue()); - Treeitem brother = (Treeitem) item.getNextSibling(); - if (brother != null) { - brother.setSelected(true); - } - } else { - showSelectAnElementMessageBox(); - } + public void moveSelectedElementDown() { + operationsForOrderElement.moveSelectedElementDown(); } - public void indentSelectedOrderElement() { - if (tree.getSelectedCount() == 1) { - indent(getSelectedNode()); - } else { - showSelectAnElementMessageBox(); - } + public void indentSelectedElement() { + operationsForOrderElement.indentSelectedElement(); } - public void unindentSelectedOrderElement() { - if (tree.getSelectedCount() == 1) { - unindent(getSelectedNode()); - } else { - showSelectAnElementMessageBox(); - } + public void unindentSelectedElement() { + operationsForOrderElement.unindentSelectedElement(); } - public void deleteSelectedOrderElement() { - if (tree.getSelectedCount() == 1) { - remove(getSelectedNode()); - } else { - showSelectAnElementMessageBox(); - } - } - - private void showSelectAnElementMessageBox() { - try { - Messagebox.show(_("Choose a task " - + "to operate on it")); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - - private boolean isTemplateCreationConfirmed() { - try { - int status = Messagebox - .show( - _("Still not saved changes would be lost." - + " Are you sure you want to go to create a template?"), - "Confirm", Messagebox.YES | Messagebox.NO, - Messagebox.QUESTION); - return Messagebox.YES == status; - } catch (InterruptedException e) { - throw new RuntimeException(e); - } + public void deleteSelectedElement() { + operationsForOrderElement.deleteSelectedElement(); } public void createFromTemplate() { @@ -232,30 +189,6 @@ public class OrderElementTreeController extends TreeController { }); } - private void createTemplate(OrderElement selectedNode) { - if (!isTemplateCreationConfirmed()) { - return; - } - if (!selectedNode.isNewObject()) { - orderTemplates.goToCreateTemplateFrom(selectedNode); - } else { - notifyTemplateCantBeCreated(); - } - } - - private void notifyTemplateCantBeCreated() { - try { - Messagebox - .show( - _("Templates can only be created from already existent tasks.\n" - + "Newly tasks cannot be used."), - _("Operation cannot be done"), Messagebox.OK, - Messagebox.INFORMATION); - } catch (InterruptedException e) { - throw new RuntimeException(e); - } - } - protected void filterByPredicateIfAny() { if (predicate != null) { filterByPredicate(); @@ -324,6 +257,8 @@ public class OrderElementTreeController extends TreeController { templateFinderPopup = (TemplateFinderPopup) comp .getFellow("templateFinderPopupAtTree"); + operationsForOrderElement.tree(tree) + .orderTemplates(this.orderTemplates); } private void appendExpandCollapseButton() { @@ -665,7 +600,7 @@ public class OrderElementTreeController extends TreeController { refreshRow(item); } - private void refreshRow(Treeitem item) { + public void refreshRow(Treeitem item) { try { getRenderer().updateHoursFor((OrderElement) item.getValue()); getRenderer().render(item, item.getValue()); @@ -725,14 +660,13 @@ public class OrderElementTreeController extends TreeController { } @Override - protected void remove(OrderElement element) { + public void remove(OrderElement element) { boolean alreadyInUse = orderModel.isAlreadyInUse(element); if (alreadyInUse) { messagesForUser .showMessage( Level.ERROR, - _( - "You can not remove the task \"{0}\" because of this or any of its children are already in use in some work reports", + _("You can not remove the task \"{0}\" because of this or any of its children are already in use in some work reports", element.getName())); } else { super.remove(element); diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/TreeElementOperationsController.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/TreeElementOperationsController.java new file mode 100644 index 000000000..83316c140 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/orders/TreeElementOperationsController.java @@ -0,0 +1,260 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * Copyright (C) 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.navalplanner.web.orders; + +import static org.navalplanner.web.I18nHelper._; + +import org.navalplanner.business.orders.entities.OrderElement; +import org.navalplanner.web.templates.IOrderTemplatesControllerEntryPoints; +import org.zkoss.zul.Messagebox; +import org.zkoss.zul.Tree; +import org.zkoss.zul.Treeitem; + +/** + * + * @author Diego Pino García + * + * Encapsulates the operations (up, down, indent, unindent, etc) for an + * element of the tree. The element can be an OrderElement or a + * TemplateElement + */ +public abstract class TreeElementOperationsController { + + protected Tree tree; + + public void editSelectedElement() { + if (tree.getSelectedCount() == 1) { + showEditElement(tree.getSelectedItem()); + } else { + showSelectAnElementError(); + } + } + + protected void showSelectAnElementError() { + try { + Messagebox.show(_("Please select a task")); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + protected abstract void showEditElement(Treeitem treeitem); + + public void moveSelectedElementUp() { + if (tree.getSelectedCount() == 1) { + Treeitem item = tree.getSelectedItem(); + up((T)item.getValue()); + Treeitem brother = (Treeitem) item.getPreviousSibling(); + if (brother != null) { + brother.setSelected(true); + } + } else { + showSelectAnElementError(); + } + } + + protected abstract void up(T element); + + public void moveSelectedElementDown() { + if (tree.getSelectedCount() == 1) { + Treeitem item = tree.getSelectedItem(); + down((T)item.getValue()); + Treeitem brother = (Treeitem) item.getNextSibling(); + if (brother != null) { + brother.setSelected(true); + } + } else { + showSelectAnElementError(); + } + } + + protected abstract void down(T element); + + public void indentSelectedElement() { + if (tree.getSelectedCount() == 1) { + indent(getSelectedElement()); + } else { + showSelectAnElementError(); + } + } + + protected abstract T getSelectedElement(); + + protected abstract void indent(T element); + + public void unindentSelectedElement() { + if (tree.getSelectedCount() == 1) { + unindent(getSelectedElement()); + } else { + showSelectAnElementError(); + } + } + + protected abstract void unindent(T element); + + public void deleteSelectedElement() { + if (tree.getSelectedCount() == 1) { + remove(getSelectedElement()); + } else { + showSelectAnElementError(); + } + } + + protected abstract void remove(T element); + +} + +/** + * + * @author Diego Pino García + * + * Implements tree operations for an {@link OrderElement} + * + */ +class OrderElementOperations extends TreeElementOperationsController { + + private OrderElementTreeController treeController; + + private IOrderModel orderModel; + + private OrderElementController orderElementController; + + private IOrderTemplatesControllerEntryPoints orderTemplates; + + public static OrderElementOperations build() { + return new OrderElementOperations(); + } + + private OrderElementOperations() { + + } + + public OrderElementOperations tree(Tree tree) { + super.tree = tree; + return this; + } + + public OrderElementOperations treeController(OrderElementTreeController treeController) { + this.treeController = treeController; + return this; + } + + public OrderElementOperations orderModel(IOrderModel orderModel) { + this.orderModel = orderModel; + return this; + } + + public OrderElementOperations orderElementController(OrderElementController orderElementController) { + this.orderElementController = orderElementController; + return this; + } + + public OrderElementOperations orderTemplates( + IOrderTemplatesControllerEntryPoints orderTemplates) { + this.orderTemplates = orderTemplates; + return this; + } + + @Override + protected OrderElement getSelectedElement() { + return treeController.getSelectedNode(); + } + + @Override + protected void up(OrderElement element) { + treeController.up(element); + } + + @Override + protected void down(OrderElement element) { + treeController.down(element); + } + + @Override + protected void indent(OrderElement element) { + treeController.indent(element); + } + + @Override + protected void unindent(OrderElement element) { + treeController.unindent(element); + } + + @Override + protected void remove(OrderElement element) { + treeController.remove(element); + } + + @Override + protected void showEditElement(Treeitem item) { + OrderElement orderElement = (OrderElement) item.getValue(); + treeController.markModifiedTreeitem(item.getTreerow()); + IOrderElementModel model = orderModel + .getOrderElementModel(orderElement); + orderElementController.openWindow(model); + treeController.refreshRow(item); + } + + public void createTemplateFromSelectedElement() { + if (tree.getSelectedCount() == 1) { + createTemplate(getSelectedElement()); + } else { + showSelectAnElementError(); + } + } + + private void createTemplate(OrderElement element) { + if (element.isNewObject()) { + notifyTemplateCantBeCreated(); + return; + } + if (showConfirmCreateTemplateDialog() == Messagebox.OK) { + orderTemplates.goToCreateTemplateFrom(element); + } + } + + private int showConfirmCreateTemplateDialog() { + try { + return Messagebox + .show(_("Unsaved changes will be lost. Would you like to continue?", + _("Confirm create template"), Messagebox.YES + | Messagebox.NO, Messagebox.QUESTION)); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + private void notifyTemplateCantBeCreated() { + try { + Messagebox.show( + _("Templates can only be created out of existent tasks." + + "You are trying to create a template out of a new task.\n" + + "Please save your project before proceeding."), + _("Operation cannot be done"), Messagebox.OK, + Messagebox.INFORMATION); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + +} \ No newline at end of file diff --git a/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplateElementOperations.java b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplateElementOperations.java new file mode 100644 index 000000000..a36c43779 --- /dev/null +++ b/navalplanner-webapp/src/main/java/org/navalplanner/web/templates/TemplateElementOperations.java @@ -0,0 +1,102 @@ +/* + * This file is part of NavalPlan + * + * Copyright (C) 2009-2010 Fundación para o Fomento da Calidade Industrial e + * Desenvolvemento Tecnolóxico de Galicia + * + * Copyright (C) 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.navalplanner.web.templates; + +import org.navalplanner.business.templates.entities.OrderElementTemplate; +import org.navalplanner.web.orders.TreeElementOperationsController; +import org.zkoss.zul.Tree; +import org.zkoss.zul.Treeitem; + +/** + * + * @author Diego Pino García + * + */ +class TemplateElementOperations extends TreeElementOperationsController { + + private TemplatesTreeController treeController; + + private OrderTemplatesController orderTemplatesController; + + public static TemplateElementOperations build() { + return new TemplateElementOperations(); + } + + private TemplateElementOperations() { + + } + + public TemplateElementOperations tree(Tree tree) { + super.tree = tree; + return this; + } + + public TemplateElementOperations treeController(TemplatesTreeController treeController) { + this.treeController = treeController; + return this; + } + + public TemplateElementOperations orderTemplatesController( + OrderTemplatesController orderTemplatesController) { + this.orderTemplatesController = orderTemplatesController; + return this; + } + + @Override + protected void showEditElement(Treeitem item) { + OrderElementTemplate orderElement = (OrderElementTemplate) item.getValue(); + treeController.markModifiedTreeitem(item.getTreerow()); + orderTemplatesController.showEditionFor(orderElement); + treeController.refreshRow(item); + } + + @Override + protected void up(OrderElementTemplate element) { + treeController.up(element); + } + + @Override + protected void down(OrderElementTemplate element) { + treeController.down(element); + } + + @Override + protected OrderElementTemplate getSelectedElement() { + return treeController.getSelectedNode(); + } + + @Override + protected void indent(OrderElementTemplate element) { + treeController.indent(element); + } + + @Override + protected void unindent(OrderElementTemplate element) { + treeController.unindent(element); + } + + @Override + protected void remove(OrderElementTemplate element) { + treeController.remove(element); + } + +} 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 c0808d7fc..def138393 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 @@ -32,11 +32,13 @@ import org.navalplanner.web.common.Util.Getter; import org.navalplanner.web.common.Util.Setter; import org.navalplanner.web.tree.EntitiesTree; import org.navalplanner.web.tree.TreeController; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zul.Button; import org.zkoss.zul.Intbox; import org.zkoss.zul.Textbox; +import org.zkoss.zul.Treecell; import org.zkoss.zul.Treeitem; /** @@ -50,6 +52,14 @@ public class TemplatesTreeController extends private final OrderTemplatesController orderTemplatesController; + private TemplateElementOperations operationsForOrderTemplate; + + @Override + public void doAfterCompose(Component comp) throws Exception { + super.doAfterCompose(comp); + operationsForOrderTemplate.tree(tree); + } + final class TemplatesTreeRenderer extends Renderer { private final ClassValidator validator = new ClassValidator( @@ -73,13 +83,17 @@ public class TemplatesTreeController extends new EventListener() { @Override public void onEvent(Event event) throws Exception { - orderTemplatesController - .showEditionFor(currentTemplate); + Treeitem item = getTreeitem(event.getTarget()); + operationsForOrderTemplate.showEditElement(item); } }); return result; } + private Treeitem getTreeitem(Component comp) { + return (Treeitem) comp.getParent().getParent().getParent(); + } + @Override protected void addDescriptionCell(final OrderElementTemplate element) { Textbox textBox = Util.bind(new Textbox(), @@ -177,6 +191,17 @@ public class TemplatesTreeController extends super(OrderElementTemplate.class); this.model = model; this.orderTemplatesController = orderTemplatesController; + initializeOperationsForOrderTemplate(); + } + + /** + * Initializes operationsForOrderTemplate. A reference to variable tree is + * needed to be added later in doAfterCompose() + */ + private void initializeOperationsForOrderTemplate() { + operationsForOrderTemplate = TemplateElementOperations.build() + .treeController(this) + .orderTemplatesController(this.orderTemplatesController); } @Override @@ -251,4 +276,43 @@ public class TemplatesTreeController extends }; } -} + public void refreshRow(Treeitem item) { + try { + OrderElementTemplate orderElement = (OrderElementTemplate) item + .getValue(); + getRenderer().updateHoursFor(orderElement); + getRenderer().render(item, orderElement); + } catch (Exception e) { + e.printStackTrace(); + } + } + + /** + * Operations for a node + */ + + public void editSelectedElement() { + operationsForOrderTemplate.editSelectedElement(); + } + + public void moveSelectedElementDown() { + operationsForOrderTemplate.moveSelectedElementDown(); + } + + public void moveSelectedElementUp() { + operationsForOrderTemplate.moveSelectedElementUp(); + } + + public void unindentSelectedElement() { + operationsForOrderTemplate.unindentSelectedElement(); + } + + public void indentSelectedElement() { + operationsForOrderTemplate.indentSelectedElement(); + } + + public void deleteSelectedElement() { + operationsForOrderTemplate.deleteSelectedElement(); + } + +} \ No newline at end of file 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 20d72e013..7294b54c2 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 @@ -99,7 +99,7 @@ public abstract class TreeController> extends } } - protected void indent(T element) { + public void indent(T element) { viewStateSnapshot = TreeViewStateSnapshot.takeSnapshot(tree); getModel().indent(element); filterByPredicateIfAny(); @@ -123,7 +123,7 @@ public abstract class TreeController> extends } } - protected void unindent(T element) { + public void unindent(T element) { viewStateSnapshot = TreeViewStateSnapshot.takeSnapshot(tree); getModel().unindent(element); filterByPredicateIfAny(); @@ -154,8 +154,13 @@ public abstract class TreeController> extends filterByPredicateIfAny(); } - protected T getSelectedNode() { - return type.cast(tree.getSelectedItemApi().getValue()); + public T getSelectedNode() { + Treeitem item = tree.getSelectedItem(); + if (item != null) { + Object value = item.getValue(); + return value != null ? type.cast(value) : null; + } + return null; } public void move(Component dropedIn, Component dragged) { @@ -287,7 +292,7 @@ public abstract class TreeController> extends filterByPredicateIfAny(); } - protected void remove(T element) { + public void remove(T element) { List parentNodes = getModel().getParents(element); getModel().removeNode(element); getRenderer().refreshHoursValueForNodes(parentNodes); @@ -1018,7 +1023,7 @@ public abstract class TreeController> extends protected Set cellsMarkedAsModified = new HashSet(); - protected void markModifiedTreeitem(Treerow item) { + public void markModifiedTreeitem(Treerow item) { Treecell tc = (Treecell) item.getFirstChild(); // Check if marked label has been previously added if (!(tc.getLastChild() instanceof org.zkoss.zul.Label)) { diff --git a/navalplanner-webapp/src/main/webapp/orders/_edition.zul b/navalplanner-webapp/src/main/webapp/orders/_edition.zul index 3fa2ece41..1b8f15c71 100644 --- a/navalplanner-webapp/src/main/webapp/orders/_edition.zul +++ b/navalplanner-webapp/src/main/webapp/orders/_edition.zul @@ -59,7 +59,7 @@ - + diff --git a/navalplanner-webapp/src/main/webapp/orders/components/_orderElementTree.zul b/navalplanner-webapp/src/main/webapp/orders/components/_orderElementTree.zul index fffb0fd8f..0d79dde24 100644 --- a/navalplanner-webapp/src/main/webapp/orders/components/_orderElementTree.zul +++ b/navalplanner-webapp/src/main/webapp/orders/components/_orderElementTree.zul @@ -45,31 +45,32 @@