/* * 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 <http://www.gnu.org/licenses/>. */ package org.libreplan.web.templates; import static org.libreplan.web.I18nHelper._; import static org.libreplan.web.planner.tabs.MultipleTabsPlannerController.BREADCRUMBS_SEPARATOR; import java.util.List; import javax.annotation.Resource; import org.libreplan.business.calendars.entities.BaseCalendar; import org.libreplan.business.common.exceptions.ValidationException; import org.libreplan.business.orders.entities.OrderElement; import org.libreplan.business.templates.entities.OrderElementTemplate; import org.libreplan.business.templates.entities.OrderTemplate; import org.libreplan.web.common.ConstraintChecker; import org.libreplan.web.common.IMessagesForUser; import org.libreplan.web.common.Level; import org.libreplan.web.common.MessagesForUser; import org.libreplan.web.common.OnlyOneVisible; import org.libreplan.web.common.Util; import org.libreplan.web.common.entrypoints.EntryPointsHandler; import org.libreplan.web.common.entrypoints.IURLHandlerRegistry; import org.libreplan.web.planner.tabs.IGlobalViewEntryPoints; import org.libreplan.web.templates.advances.AdvancesAssignmentComponent; import org.libreplan.web.templates.criterionrequirements.CriterionRequirementTemplateComponent; import org.libreplan.web.templates.historicalAssignment.OrderElementHistoricalAssignmentComponent; import org.libreplan.web.templates.historicalStatistics.OrderElementHistoricalStatisticsComponent; import org.libreplan.web.templates.labels.LabelsAssignmentToTemplateComponent; import org.libreplan.web.templates.materials.MaterialAssignmentTemplateComponent; import org.libreplan.web.templates.quality.QualityFormAssignerComponent; import org.libreplan.web.tree.TreeComponent; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.context.annotation.Scope; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.WrongValueException; import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.util.GenericForwardComposer; import org.zkoss.zkplus.spring.SpringUtil; import org.zkoss.zul.Constraint; import org.zkoss.zul.Grid; import org.zkoss.zul.Image; import org.zkoss.zul.Label; import org.zkoss.zul.Messagebox; import org.zkoss.zul.Tab; import org.zkoss.zul.Tabpanel; import org.zkoss.zul.Textbox; import org.zkoss.zul.Tree; import org.zkoss.zul.Window; /** * @author Óscar González Fernández <ogonzalez@igalia.com> */ @org.springframework.stereotype.Component @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class OrderTemplatesController extends GenericForwardComposer implements IOrderTemplatesControllerEntryPoints { private IOrderTemplatesModel model; private OnlyOneVisible cachedOnlyOneVisible; private Window listWindow; private Window editWindow; private Textbox name; private IMessagesForUser messagesForUser; private Component messagesContainer; private TreeComponent treeComponent; private EditTemplateWindowController editTemplateController; @Resource private IGlobalViewEntryPoints globalView; @Autowired private IURLHandlerRegistry handlerRegistry; public OrderTemplatesController() { model = (IOrderTemplatesModel) SpringUtil.getBean("orderTemplatesModel"); } @Override public void doAfterCompose(Component comp) throws Exception { super.doAfterCompose(comp); messagesForUser = new MessagesForUser(messagesContainer); getVisibility().showOnly(listWindow); final EntryPointsHandler<IOrderTemplatesControllerEntryPoints> handler = handlerRegistry.getRedirectorFor(IOrderTemplatesControllerEntryPoints.class); handler.register(this, page); setBreadcrumbs(comp); } public List<OrderElementTemplate> getTemplates() { return model.getRootTemplates(); } private OnlyOneVisible getVisibility() { if (cachedOnlyOneVisible == null) { cachedOnlyOneVisible = new OnlyOneVisible(listWindow, editWindow); } return cachedOnlyOneVisible; } public OrderElementTemplate getTemplate() { return model.getTemplate(); } @Override public void goToCreateTemplateFrom(OrderElement orderElement) { model.createTemplateFrom(orderElement); showEditWindow(); } public void goToEditForm(OrderElementTemplate template) { model.initEdit(template); showEditWindow(); } private void showEditWindow() { // openTemplateTree is not called if it's the first tab shown bindTemplatesTreeWithModel(); bindAdvancesComponentWithCurrentTemplate(); bindMaterialsControllerWithCurrentTemplate(); bindCriterionRequirementControllerWithCurrentTemplate(); bindLabelsControllerWithCurrentTemplate(); bindQualityFormWithCurrentTemplate(); bindEditTemplateWindowWithController(); bindHistoricalArragenmentWithCurrentTemplate(); bindHistoricalStatisticsWithCurrentTemplate(); show(editWindow); } private <T extends Component> T findAtEditWindow(String id, Class<T> type) { return type.cast(editWindow.getFellow(id)); } private void bindAdvancesComponentWithCurrentTemplate() { AdvancesAssignmentComponent c = findAtEditWindow("advancesAssignment", AdvancesAssignmentComponent.class); c.useModel(model); } private void bindMaterialsControllerWithCurrentTemplate() { MaterialAssignmentTemplateComponent c = findAtEditWindow("listOrderElementMaterials", MaterialAssignmentTemplateComponent.class); c.getController().openWindow(model.getTemplate()); } private void bindCriterionRequirementControllerWithCurrentTemplate() { CriterionRequirementTemplateComponent c = findAtEditWindow("listOrderElementCriterionRequirements", CriterionRequirementTemplateComponent.class); c.getController().openWindow(model); } private void bindLabelsControllerWithCurrentTemplate() { LabelsAssignmentToTemplateComponent c = findAtEditWindow("listOrderElementLabels", LabelsAssignmentToTemplateComponent.class); c.getController().openWindow(model); } private void bindQualityFormWithCurrentTemplate() { QualityFormAssignerComponent c = findAtEditWindow("assignedQualityForms", QualityFormAssignerComponent.class); c.useModel(model); } private void bindEditTemplateWindowWithController() { Window editTemplateWindow = (Window) editWindow.getFellow("editTemplateWindow"); editTemplateController = EditTemplateWindowController.bindTo(model, editTemplateWindow); } private void bindHistoricalArragenmentWithCurrentTemplate() { OrderElementHistoricalAssignmentComponent c = (OrderElementHistoricalAssignmentComponent) editWindow.getFellow("historicalAssignment"); c.useModel(model, globalView); } private void bindHistoricalStatisticsWithCurrentTemplate() { OrderElementHistoricalStatisticsComponent c = (OrderElementHistoricalStatisticsComponent) editWindow.getFellow("historicalStatistics"); c.useModel(model); } public boolean isTemplateTreeDisabled() { return model.isTemplateTreeDisabled(); } private void show(Component window) { Util.reloadBindings(window); getVisibility().showOnly(window); } public void showEditionFor(OrderElementTemplate template) { editTemplateController.open(template); } public void saveAndExit() { if (isAllValid()) { try { model.confirmSave(); messagesForUser.showMessage(Level.INFO, _("Template saved")); show(listWindow); } catch (ValidationException e) { messagesForUser.showInvalidValues(e); } } } public void cancel() { show(listWindow); } public void saveAndContinue() { if (isAllValid()) { try { model.confirmSave(); model.initEdit(getTemplate()); bindTemplatesTreeWithModel(); messagesForUser.showMessage(Level.INFO, _("Template saved")); } catch (ValidationException e) { messagesForUser.showInvalidValues(e); } } } private boolean isAllValid() { // Validate template name ConstraintChecker.isValid(editWindow); name = (Textbox) editWindow.getFellowIfAny("name"); if ((name != null) && (!name.isValid())) { selectTab("tabGeneralData"); showInvalidWorkReportTypeName(); return false; } if (model.getTemplate().isOrderTemplate()) { OrderTemplate orderTemplate = (OrderTemplate) model.getTemplate(); if (orderTemplate.getCalendar() == null) { throw new WrongValueException(editWindow.getFellow("calendar"), _("calendar not specified")); } } return true; } private void selectTab(String str) { Tab tab = (Tab) editWindow.getFellowIfAny(str); if (tab != null) { tab.setSelected(true); } } private void showInvalidWorkReportTypeName() { try { model.validateTemplateName(name.getValue()); } catch (IllegalArgumentException e) { throw new WrongValueException(name, _(e.getMessage())); } } private void setBreadcrumbs(Component comp) { Component breadcrumbs = comp.getPage().getFellow("breadcrumbs"); if (breadcrumbs.getChildren() != null) { breadcrumbs.getChildren().clear(); } breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR)); breadcrumbs.appendChild(new Label(_("Planning"))); breadcrumbs.appendChild(new Image(BREADCRUMBS_SEPARATOR)); breadcrumbs.appendChild(new Label(_("Templates"))); } /** * Ensures that the tree component is correctly initialized. * It's called from templates.zul page when selecting the tab. * <p> * Please not that this method is not called if the first tab shown is the templates tree tab. * </p> */ public void openTemplateTree() { if (treeComponent == null) { final TemplatesTreeController treeController = new TemplatesTreeController(model, this); treeComponent = (TreeComponent) editWindow.getFellow("orderElementTree"); treeComponent.useController(treeController); controlSelectionWithOnClick(getTreeFrom(treeComponent)); treeController.setReadOnly(false); setTreeRenderer(treeComponent); } bindTemplatesTreeWithModel(); } private void bindTemplatesTreeWithModel() { if (treeComponent == null) { // If the tree is not initialized yet no bind has to be done return; } treeComponent.getController().bindModelIfNeeded(); } private Tree getTreeFrom(TreeComponent treeComponent) { return (Tree) treeComponent.getFellowIfAny("tree"); } private void controlSelectionWithOnClick(final Tree tree) { // Undo the work done by this event to be able to control it from the ON_CLICK event tree.addEventListener(Events.ON_SELECT, event -> tree.clearSelection()); } private void setTreeRenderer(TreeComponent orderElementsTree) { final Tree tree = (Tree) orderElementsTree.getFellowIfAny("tree"); tree.setItemRenderer(orderElementsTree.getController().getRenderer()); } public Constraint validateTemplateName() { return (comp, value) -> { try { model.validateTemplateName((String) value); } catch (IllegalArgumentException e) { throw new WrongValueException(comp, _(e.getMessage())); } }; } /** * Pop up confirm remove dialog. * * @param template */ public void confirmDelete(OrderElementTemplate template) { if (Messagebox.show( _("Delete template. Are you sure?"), _("Confirm"), Messagebox.OK | Messagebox.CANCEL, Messagebox.QUESTION) == Messagebox.OK) { if (this.model.hasNotApplications(template)) { this.model.confirmDelete(template); Grid gridOrderTemplates = (Grid) listWindow.getFellowIfAny("listing"); if (gridOrderTemplates != null) { Util.reloadBindings(gridOrderTemplates); } } else { messagesForUser.showMessage(Level.ERROR, _("Template cannot be removed because it has applications")); } } } public boolean isContainer() { return model.getTemplate() != null && !model.getTemplate().isLeaf(); } public void reloadBudget() { Tabpanel tabPanel = (Tabpanel) editWindow.getFellow("tabPanelGeneralData"); Util.reloadBindings(tabPanel); } public String getMoneyFormat() { return Util.getMoneyFormat(); } public boolean isOrderTemplate() { return model.getTemplate() != null && model.getTemplate().isOrderTemplate(); } public BaseCalendar getCalendar() { return isOrderTemplate() ? ((OrderTemplate) model.getTemplate()).getCalendar() : null; } public void setCalendar(BaseCalendar calendar) { if (isOrderTemplate()) { ((OrderTemplate) model.getTemplate()).setCalendar(calendar); } } }