com.esofthead.mycollab.module.project.view.task.GanttChartTaskContainer.java Source code

Java tutorial

Introduction

Here is the source code for com.esofthead.mycollab.module.project.view.task.GanttChartTaskContainer.java

Source

/**
 * This file is part of mycollab-web.
 *
 * mycollab-web is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * mycollab-web 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with mycollab-web.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.esofthead.mycollab.module.project.view.task;

import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.UUID;

import org.tltv.gantt.Gantt;
import org.tltv.gantt.Gantt.MoveEvent;
import org.tltv.gantt.Gantt.ResizeEvent;
import org.tltv.gantt.client.shared.Step;
import org.tltv.gantt.client.shared.Step.CaptionMode;
import org.vaadin.dialogs.ConfirmDialog;

import com.esofthead.mycollab.common.i18n.GenericI18Enum;
import com.esofthead.mycollab.core.arguments.NumberSearchField;
import com.esofthead.mycollab.core.arguments.SearchRequest;
import com.esofthead.mycollab.module.project.CurrentProjectVariables;
import com.esofthead.mycollab.module.project.ProjectLinkGenerator;
import com.esofthead.mycollab.module.project.ProjectResources;
import com.esofthead.mycollab.module.project.ProjectTypeConstants;
import com.esofthead.mycollab.module.project.domain.SimpleTask;
import com.esofthead.mycollab.module.project.domain.criteria.TaskSearchCriteria;
import com.esofthead.mycollab.module.project.i18n.ProjectCommonI18nEnum;
import com.esofthead.mycollab.module.project.i18n.TaskI18nEnum;
import com.esofthead.mycollab.module.project.service.ProjectTaskService;
import com.esofthead.mycollab.spring.ApplicationContextUtil;
import com.esofthead.mycollab.vaadin.AppContext;
import com.esofthead.mycollab.vaadin.ui.ConfirmDialogExt;
import com.esofthead.mycollab.vaadin.ui.UIConstants;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.shared.ui.datefield.Resolution;
import com.vaadin.ui.DateField;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.NativeSelect;
import com.vaadin.ui.Panel;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;

/**
 * 
 * @author MyCollab Ltd.
 * @since 4.1
 * 
 */
class GanttChartTaskContainer extends VerticalLayout {
    private static final long serialVersionUID = 1L;
    private List<SimpleTask> taskList;

    private Gantt gantt;
    private LinkedHashMap<Step, SimpleTask> stepMap;
    private NativeSelect reso;

    private TaskTableDisplay taskTable;

    private final ProjectTaskService taskService;

    private DateField start;
    private DateField end;

    public GanttChartTaskContainer() {
        taskService = ApplicationContextUtil.getSpringBean(ProjectTaskService.class);
        constructGanttChart();
        Panel controls = createControls();
        this.setStyleName("gantt-view");
        this.addComponent(controls);
        HorizontalLayout mainLayout = new HorizontalLayout();
        mainLayout.setWidth("100%");
        mainLayout.setStyleName("gantt-wrap");
        mainLayout.addComponent(taskTable);
        mainLayout.addComponent(gantt);
        this.addComponent(mainLayout);
    }

    private void constructGanttChart() {
        stepMap = new LinkedHashMap<Step, SimpleTask>();

        taskTable = new TaskTableDisplay(Arrays.asList(TaskTableFieldDef.taskname, TaskTableFieldDef.startdate,
                TaskTableFieldDef.duedate, TaskTableFieldDef.assignee));
        taskTable.setWidth("100%");
        taskTable.setHeightUndefined();
        taskTable.addStyleName("gantt-table");

        gantt = new Gantt();
        gantt.setWidth(100, Unit.PERCENTAGE);
        gantt.setResizableSteps(true);
        gantt.setMovableSteps(true);
        gantt.setVerticalScrollDelegateTarget(taskTable);

        Calendar cal = Calendar.getInstance();
        cal.setTime(new Date());
        cal.add(Calendar.DATE, -14);

        gantt.setStartDate(cal.getTime());
        cal.add(Calendar.DATE, 28);
        gantt.setEndDate(cal.getTime());

        gantt.addMoveListener(new Gantt.MoveListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void onGanttMove(MoveEvent event) {
                // Notification.show("Moved " + event.getStep().getCaption());
                SimpleTask task = stepMap.get(event.getStep());
                Calendar cal = Calendar.getInstance();
                cal.setTime(new Date());

                GregorianCalendar gc = new GregorianCalendar();

                /* check endate after deadline */
                gc.setTimeInMillis(event.getEndDate());
                if (task.getEnddate() != null && task.getEnddate().after(gc.getTime())) {
                    task.setEnddate(null);
                }
                task.setDeadline(gc.getTime());

                gc.setTimeInMillis(event.getStartDate());
                task.setStartdate(gc.getTime());

                taskService.updateWithSession(task, AppContext.getUsername());
                taskTable.setItems(stepMap.values());
            }
        });

        gantt.addResizeListener(new Gantt.ResizeListener() {
            private static final long serialVersionUID = 1L;

            @Override
            public void onGanttResize(ResizeEvent event) {
                // Notification.show("Resized " + event.getStep().getCaption());
                SimpleTask task = stepMap.get(event.getStep());
                Calendar cal = Calendar.getInstance();
                cal.setTime(new Date());

                GregorianCalendar gc = new GregorianCalendar();

                /* check endate after deadline */
                gc.setTimeInMillis(event.getEndDate());
                gc.setTimeInMillis(event.getEndDate());
                if (task.getEnddate() != null && task.getEnddate().after(gc.getTime())) {
                    task.setEnddate(null);
                }
                task.setDeadline(gc.getTime());

                gc.setTimeInMillis(event.getStartDate());
                task.setStartdate(gc.getTime());

                taskService.updateWithSession(task, AppContext.getUsername());
                taskTable.setItems(stepMap.values());
            }
        });
    }

    public void displayChart() {
        updateStepList();
    }

    @SuppressWarnings("unchecked")
    private void updateStepList() {

        TaskSearchCriteria criteria = new TaskSearchCriteria();
        criteria.setProjectid(new NumberSearchField(CurrentProjectVariables.getProjectId()));
        taskList = taskService
                .findPagableListByCriteria(new SearchRequest<TaskSearchCriteria>(criteria, 0, Integer.MAX_VALUE));

        /* Clear current Gantt chart */
        if (stepMap != null) {
            for (Step key : stepMap.keySet()) {
                gantt.removeStep(key);
            }
            stepMap = new LinkedHashMap<Step, SimpleTask>();
        }

        /* Add steps */
        if (!taskList.isEmpty()) {

            for (SimpleTask task : taskList) {

                Date startDate = null;
                Date endDate = null;

                /* Check for date */
                if (task.getActualstartdate() != null) {
                    startDate = task.getActualstartdate();
                } else if (task.getStartdate() != null) {
                    startDate = task.getStartdate();
                }

                if (task.getDeadline() != null) {
                    endDate = task.getDeadline();
                } else if (task.getActualenddate() != null) {
                    endDate = task.getActualenddate();
                }

                /* Add row block if both stardate and endate avalable */
                if (startDate != null && endDate != null && gantt.getStartDate().before(startDate)
                        && gantt.getEndDate().after(startDate)) {
                    Step step = new Step();
                    step.setCaption(tooltipGenerate(task));
                    step.setCaptionMode(CaptionMode.HTML);
                    step.setStartDate(startDate.getTime());
                    step.setEndDate(endDate.getTime());

                    /* Add style for row block */
                    if (task.getPercentagecomplete() != null && 100d == task.getPercentagecomplete()) {
                        step.setBackgroundColor("53C540");
                        step.setStyleName("completed");
                    } else {
                        if ("Pending".equals(task.getStatus())) {
                            step.setBackgroundColor("e2f852");
                        } else if ("Open".equals(task.getStatus())
                                && endDate.before(new GregorianCalendar().getTime())) {
                            step.setBackgroundColor("FC4350");
                        }
                    }
                    stepMap.put(step, task);
                }

            }

            taskTable.setItems(stepMap.values());
        }

        if (stepMap != null) {
            for (Step key : stepMap.keySet()) {
                gantt.addStep(key);
            }
        }

    }

    private String tooltipGenerate(SimpleTask task) {
        String content = "";

        // --------------Item hidden div tooltip----------------
        String randomStrId = UUID.randomUUID().toString();
        String idDivSeverData = "projectOverViewserverdata" + randomStrId + "";
        String idToopTipDiv = "projectOverViewtooltip" + randomStrId + "";
        String idStickyToolTipDiv = "projectOverViewmystickyTooltip" + randomStrId;
        String idtagA = "projectOverViewtagA" + randomStrId;

        String arg0 = ProjectResources.getResourceLink(ProjectTypeConstants.TASK);
        String arg1 = idtagA;
        String arg2 = ProjectLinkGenerator.generateTaskPreviewLink(task.getTaskkey(), task.getProjectShortname());
        String arg3 = "'" + randomStrId + "'";
        String arg4 = "'" + ProjectTypeConstants.TASK + "'";
        String arg5 = "'" + task.getId() + "'";
        String arg6 = "'" + AppContext.getSiteUrl() + "tooltip/'";
        String arg7 = "'" + task.getSaccountid() + "'";
        String arg8 = "'" + AppContext.getSiteUrl() + "'";
        String arg9 = AppContext.getSession().getTimezone();
        String arg10 = "'" + AppContext.getUserLocale().toString() + "'";
        String arg11 = task.getTaskname();

        String arg12 = idStickyToolTipDiv;
        String arg13 = idToopTipDiv;
        String arg14 = idDivSeverData;

        content = AppContext.getMessage(ProjectCommonI18nEnum.TOOLTIP_GANTT_CHART_TITLE, arg0, arg1, arg2, arg3,
                arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12, arg13, arg14);
        return content;
    }

    private Panel createControls() {

        Panel panel = new Panel();
        panel.setWidth(100, Unit.PERCENTAGE);

        HorizontalLayout controls = new HorizontalLayout();
        controls.setSpacing(true);
        controls.setMargin(true);
        panel.setContent(controls);

        start = new DateField(AppContext.getMessage(TaskI18nEnum.FORM_START_DATE));
        start.setValue(gantt.getStartDate());
        start.setResolution(Resolution.DAY);
        start.setImmediate(true);
        start.addValueChangeListener(startDateValueChangeListener);

        end = new DateField(AppContext.getMessage(TaskI18nEnum.FORM_END_DATE));
        end.setValue(gantt.getEndDate());
        end.setResolution(Resolution.DAY);
        end.setImmediate(true);
        end.addValueChangeListener(endDateValueChangeListener);

        reso = new NativeSelect("Resolution");
        reso.setNullSelectionAllowed(false);
        reso.addItem(org.tltv.gantt.client.shared.Resolution.Hour);
        reso.addItem(org.tltv.gantt.client.shared.Resolution.Day);
        reso.addItem(org.tltv.gantt.client.shared.Resolution.Week);
        reso.setValue(gantt.getResolution());
        reso.setImmediate(true);
        reso.addValueChangeListener(resolutionValueChangeListener);

        controls.addComponent(start);
        controls.addComponent(end);
        controls.addComponent(reso);
        panel.setStyleName(UIConstants.THEME_NO_BORDER);

        return panel;
    }

    private ValueChangeListener startDateValueChangeListener = new ValueChangeListener() {
        private static final long serialVersionUID = 1L;

        @Override
        public void valueChange(ValueChangeEvent event) {
            gantt.setStartDate((Date) event.getProperty().getValue());
            updateStepList();
        }
    };

    private ValueChangeListener endDateValueChangeListener = new ValueChangeListener() {
        private static final long serialVersionUID = 1L;

        @Override
        public void valueChange(ValueChangeEvent event) {
            gantt.setEndDate((Date) event.getProperty().getValue());
            updateStepList();
        }
    };

    private ValueChangeListener resolutionValueChangeListener = new ValueChangeListener() {
        private static final long serialVersionUID = 1L;

        @Override
        public void valueChange(ValueChangeEvent event) {
            org.tltv.gantt.client.shared.Resolution res = (org.tltv.gantt.client.shared.Resolution) event
                    .getProperty().getValue();
            if (validateResolutionChange(res)) {
                gantt.setResolution(res);
            }
        }
    };

    private boolean validateResolutionChange(final org.tltv.gantt.client.shared.Resolution res) {
        long max = 4 * 7 * 24 * 60 * 60000L;
        if (res == org.tltv.gantt.client.shared.Resolution.Hour
                && (gantt.getEndDate().getTime() - gantt.getStartDate().getTime()) > max) {

            // revert to previous resolution
            setResolution(gantt.getResolution());

            // make user to confirm hour resolution, if the timeline range is
            // more than one week long.

            ConfirmDialogExt.show(UI.getCurrent(), AppContext.getMessage(GenericI18Enum.WINDOW_WARNING_TITLE),
                    "Timeline range is a quite long for hour resolution. Rendering may be slow. Continue anyway?",
                    AppContext.getMessage(GenericI18Enum.BUTTON_YES),
                    AppContext.getMessage(GenericI18Enum.BUTTON_NO), new ConfirmDialog.Listener() {
                        private static final long serialVersionUID = 1L;

                        @Override
                        public void onClose(final ConfirmDialog dialog) {
                            if (dialog.isConfirmed()) {

                                setResolution(res);
                                gantt.setResolution(res);

                            }
                        }
                    });
            return false;
        }
        return true;
    }

    private void setResolution(org.tltv.gantt.client.shared.Resolution resolution) {
        reso.removeValueChangeListener(resolutionValueChangeListener);
        try {
            reso.setValue(resolution);
        } finally {
            reso.addValueChangeListener(resolutionValueChangeListener);
        }
    }

}