/* * 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.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.Map.Entry; import org.zkoss.ganttz.adapters.IDisabilityConfiguration; import org.zkoss.ganttz.adapters.PlannerConfiguration; import org.zkoss.ganttz.data.Dependency; import org.zkoss.ganttz.data.GanttDiagramGraph; import org.zkoss.ganttz.data.Position; import org.zkoss.ganttz.data.Task; import org.zkoss.ganttz.data.GanttDiagramGraph.IGraphChangeListener; import org.zkoss.ganttz.extensions.ICommand; import org.zkoss.ganttz.extensions.ICommandOnTask; import org.zkoss.ganttz.extensions.IContext; import org.zkoss.ganttz.timetracker.TimeTracker; import org.zkoss.ganttz.timetracker.TimeTrackerComponent; import org.zkoss.ganttz.timetracker.TimeTrackerComponentWithoutColumns; import org.zkoss.ganttz.timetracker.zoom.ZoomLevel; import org.zkoss.ganttz.util.ComponentsFinder; import org.zkoss.ganttz.util.LongOperationFeedback; import org.zkoss.ganttz.util.OnZKDesktopRegistry; import org.zkoss.ganttz.util.LongOperationFeedback.ILongOperation; import org.zkoss.ganttz.util.script.IScriptsRegister; import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.HtmlMacroComponent; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Button; import org.zkoss.zul.ListModel; import org.zkoss.zul.Separator; import org.zkoss.zul.SimpleListModel; public class Planner extends HtmlMacroComponent { public static void registerNeededScripts() { IScriptsRegister register = getScriptsRegister(); register.register(ScriptsRequiredByPlanner.class); } private static IScriptsRegister getScriptsRegister() { return OnZKDesktopRegistry.getLocatorFor(IScriptsRegister.class) .retrieve(); } 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"); if (values == null) { return false; } return 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 GanttDiagramGraph diagramGraph; private LeftPane leftPane; private GanttPanel ganttPanel; private List> contextualizedGlobalCommands; private CommandContextualized goingDownInLastArrowCommand; private List> commandsOnTasksContextualized; private CommandOnTaskContextualized doubleClickCommand; private FunctionalityExposedForExtensions context; private transient IDisabilityConfiguration disabilityConfiguration; private boolean isShowingCriticalPath = false; private ZoomLevel initialZoomLevel = ZoomLevel.DETAIL_ONE; public Planner() { registerNeededScripts(); } TaskList getTaskList() { if (ganttPanel == null) { return null; } List children = ganttPanel.getChildren(); return ComponentsFinder.findComponentsOfType(TaskList.class, children).get(0); } public int getTaskNumber() { return getTaskList().getTasksNumber(); } public int getAllTasksNumber() { return diagramGraph.getTasks().size(); } public String getContextPath() { return Executions.getCurrent().getContextPath(); } public DependencyList getDependencyList() { if (ganttPanel == null) { return null; } List children = ganttPanel.getChildren(); List found = ComponentsFinder.findComponentsOfType(DependencyList.class, children); if (found.isEmpty()) { return null; } return found.get(0); } public void addTasks(Position position, Collection newTasks) { TaskList taskList = getTaskList(); if (taskList != null && leftPane != null) { taskList.addTasks(position, newTasks); leftPane.addTasks(position, newTasks); } } public void addTask(Position position, Task task) { addTasks(position, Arrays.asList(task)); } void addDependencies(Collection dependencies) { DependencyList dependencyList = getDependencyList(); if (dependencyList == null) { return; } for (DependencyComponent d : getTaskList().asDependencyComponents( dependencies)) { dependencyList.addDependencyComponent(d); } } public ListModel getZoomLevels() { return new SimpleListModel(ZoomLevel.values()); } public void setZoomLevel(final ZoomLevel zoomLevel) { if (ganttPanel == null) { return; } ganttPanel.setZoomLevel(zoomLevel); } public void zoomIncrease() { if (ganttPanel == null) { return; } LongOperationFeedback.execute(ganttPanel, new ILongOperation() { @Override public String getName() { return _("increasing zoom"); } @Override public void doAction() throws Exception { ganttPanel.zoomIncrease(); } }); } public void zoomDecrease() { if (ganttPanel == null) { return; } LongOperationFeedback.execute(ganttPanel, new ILongOperation() { @Override public String getName() { return _("decreasing zoom"); } @Override public void doAction() throws Exception { ganttPanel.zoomDecrease(); } }); } public void setConfiguration(PlannerConfiguration configuration) { if (configuration == null) { return; } this.diagramGraph = new GanttDiagramGraph(configuration .getStartConstraints(), configuration.getEndConstraints(), configuration.isDependenciesConstraintsHavePriority()); FunctionalityExposedForExtensions newContext = new FunctionalityExposedForExtensions( this, configuration, diagramGraph); this.contextualizedGlobalCommands = contextualize(newContext, configuration.getGlobalCommands()); this.commandsOnTasksContextualized = contextualize(newContext, configuration.getCommandsOnTasks()); goingDownInLastArrowCommand = contextualize(newContext, configuration .getGoingDownInLastArrowCommand()); doubleClickCommand = contextualize(newContext, configuration .getDoubleClickCommand()); this.context = newContext; this.disabilityConfiguration = configuration; resettingPreviousComponentsToNull(); newContext.add(configuration.getData()); setupComponents(); setAt("insertionPointLeftPanel", leftPane); leftPane.afterCompose(); setAt("insertionPointRightPanel", ganttPanel); ganttPanel.afterCompose(); leftPane.setGoingDownInLastArrowCommand(goingDownInLastArrowCommand); TimeTrackerComponent timetrackerheader = new TimeTrackerComponentWithoutColumns( ganttPanel.getTimeTracker(), "timetrackerheader"); setAt("insertionPointTimetracker", timetrackerheader); timetrackerheader.afterCompose(); Component chartComponent = configuration.getChartComponent(); if (chartComponent != null) { setAt("insertionPointChart", chartComponent); } if (!configuration.isCriticalPathEnabled()) { Button showCriticalPathButton = (Button) getFellow("showCriticalPath"); showCriticalPathButton.setVisible(false); } } private void resettingPreviousComponentsToNull() { this.ganttPanel = null; this.leftPane = null; } private void setAt(String insertionPointId, Component component) { Component insertionPoint = getFellow(insertionPointId); insertionPoint.getChildren().clear(); insertionPoint.appendChild(component); } private List> contextualize( FunctionalityExposedForExtensions context, List> commands) { List> result = new ArrayList>(); for (ICommandOnTask c : commands) { result.add(contextualize(context, c)); } return result; } 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); } private List> contextualize( IContext context, Collection> commands) { ArrayList> result = new ArrayList>(); for (ICommand command : commands) { result.add(contextualize(context, command)); } return result; } private void setupComponents() { insertGlobalCommands(); this.leftPane = new LeftPane(this.diagramGraph.getTopLevelTasks()); this.ganttPanel = new GanttPanel(this.context, commandsOnTasksContextualized, doubleClickCommand, disabilityConfiguration); Button button = (Button) getFellow("btnPrint"); button.setDisabled(!context.isPrintEnabled()); } @SuppressWarnings("unchecked") private void insertGlobalCommands() { Component toolbar = getToolbar(); Component firstSeparator = getFirstSeparatorFromToolbar(); toolbar.getChildren().removeAll(getBefore(toolbar, firstSeparator)); for (CommandContextualized c : contextualizedGlobalCommands) { toolbar.insertBefore(c.toButton(), firstSeparator); } } @SuppressWarnings("unchecked") private List getBefore(Component parent, Component child) { List children = parent.getChildren(); List result = new ArrayList(); for (Component object : children) { if (object == child) { break; } result.add(object); } return result; } @SuppressWarnings("unchecked") private Component getFirstSeparatorFromToolbar() { Component toolbar = getToolbar(); List children = toolbar.getChildren(); List separators = ComponentsFinder .findComponentsOfType( Separator.class, children); return separators.get(0); } private Component getToolbar() { Component toolbar = getFellow("toolbar"); return toolbar; } void removeTask(Task task) { TaskList taskList = getTaskList(); taskList.remove(task); getDependencyList().taskRemoved(task); leftPane.taskRemoved(task); setHeight(getHeight());// forcing smart update taskList.adjustZoomColumnsHeight(); getDependencyList().redrawDependencies(); } @Override public void afterCompose() { super.afterCompose(); } public TimeTracker getTimeTracker() { return ganttPanel.getTimeTracker(); } private IGraphChangeListener showCriticalPathOnChange = new IGraphChangeListener() { @Override public void execute() { context.showCriticalPath(); } }; private boolean containersExpandedByDefault = false; 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); showCriticalPathButton.setSclass("planner-command clicked"); showCriticalPathButton.setTooltiptext(_("Hide critical path")); } isShowingCriticalPath = !isShowingCriticalPath; } } public void showAllLabels() { Button showAllLabelsButton = (Button) getFellow("showAllLabels"); if (showAllLabelsButton.getSclass().equals( "planner-command show-labels")) { Clients.evalJavaScript("zkTasklist.showAllTooltips();"); showAllLabelsButton .setSclass("planner-command show-labels clicked"); } else { Clients.evalJavaScript("zkTasklist.hideAllTooltips();"); showAllLabelsButton.setSclass("planner-command show-labels"); } } public void showAllResources() { Button showAllLabelsButton = (Button) getFellow("showAllResources"); if (showAllLabelsButton.getSclass().equals( "planner-command show-resources")) { Clients.evalJavaScript("zkTasklist.showResourceTooltips();"); showAllLabelsButton .setSclass("planner-command show-resources clicked"); } else { Clients.evalJavaScript("zkTasklist.hideResourceTooltips();"); showAllLabelsButton.setSclass("planner-command show-resources"); } } public void print() { // Pending to raise print configuration popup. Information retrieved // should be passed as parameter to context print method context.print(); } public ZoomLevel getZoomLevel() { if (ganttPanel == null) { return initialZoomLevel; } return ganttPanel.getTimeTracker().getDetailLevel(); } public void setInitialZoomLevel(final ZoomLevel zoomLevel) { this.initialZoomLevel = zoomLevel; } public boolean areContainersExpandedByDefault() { return containersExpandedByDefault; } public void setAreContainersExpandedByDefault( boolean containersExpandedByDefault) { this.containersExpandedByDefault = containersExpandedByDefault; } }