/******************************************************************************* * Copyright (c) 2004, 2015 Tasktop Technologies and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Tasktop Technologies - initial API and implementation *******************************************************************************/ package org.eclipse.mylyn.internal.tasks.ui; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.MenuManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.window.Window; import org.eclipse.mylyn.commons.ui.CommonImages; import org.eclipse.mylyn.commons.workbench.WorkbenchUtil; import org.eclipse.mylyn.commons.workbench.forms.DatePicker; import org.eclipse.mylyn.commons.workbench.forms.DateSelectionDialog; import org.eclipse.mylyn.internal.tasks.core.AbstractTask; import org.eclipse.mylyn.internal.tasks.core.DateRange; import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; import org.eclipse.mylyn.internal.tasks.core.TaskActivityUtil; import org.eclipse.mylyn.internal.tasks.core.WeekDateRange; import org.eclipse.mylyn.tasks.core.IRepositoryElement; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.swt.widgets.Shell; /** * @author Rob Elves * @author Mik Kersten */ public class ScheduleTaskMenuContributor implements IDynamicSubMenuContributor { private AbstractTask singleTaskSelection; private final List<IRepositoryElement> taskListElementsToSchedule = new ArrayList<IRepositoryElement>(); public MenuManager getSubMenuManager(final List<IRepositoryElement> selectedElements) { singleTaskSelection = null; taskListElementsToSchedule.clear(); final MenuManager subMenuManager = new MenuManager(Messages.ScheduleTaskMenuContributor_Schedule_for); if (selectedElements.size() == 1) { IRepositoryElement selectedElement = selectedElements.get(0); if (selectedElement instanceof ITask) { singleTaskSelection = (AbstractTask) selectedElement; // Tasks artifacts are not able to be scheduled; we'll simply mark them as not supported here String artifactFlag = singleTaskSelection.getAttribute(ITasksCoreConstants.ATTRIBUTE_ARTIFACT); if (Boolean.valueOf(artifactFlag)) { return null; } } } for (IRepositoryElement selectedElement : selectedElements) { if (selectedElement instanceof ITask) { taskListElementsToSchedule.add(selectedElement); } } if (selectionIncludesCompletedTasks()) { Action action = new Action() { @Override public void run() { // ignore } }; action.setText(Messages.ScheduleTaskMenuContributor_Cannot_schedule_completed_tasks); action.setEnabled(false); subMenuManager.add(action); return subMenuManager; } WeekDateRange week = TaskActivityUtil.getCurrentWeek(); int days = 0; for (DateRange day : week.getDaysOfWeek()) { if (day.includes(TaskActivityUtil.getCalendar())) { days++; // Today Action action = createDateSelectionAction(day, CommonImages.SCHEDULE_DAY); subMenuManager.add(action); // Special case: Over scheduled tasks always 'scheduled' for today if (singleTaskSelection != null && isPastReminder(singleTaskSelection)) { action.setChecked(true); } } else if (day.after(TaskActivityUtil.getCalendar())) { days++; // Week Days Action action = createDateSelectionAction(day, null); subMenuManager.add(action); } } // Next week days int toAdd = 7 - days; WeekDateRange nextWeek = TaskActivityUtil.getNextWeek(); for (int x = 0; x < toAdd; x++) { int next = TasksUiPlugin.getTaskActivityManager().getWeekStartDay() + x; if (next > Calendar.SATURDAY) { next = next - Calendar.SATURDAY; } DateRange day = nextWeek.getDayOfWeek(next); Action action = createDateSelectionAction(day, null); subMenuManager.add(action); } subMenuManager.add(new Separator()); // This Week Action action = createDateSelectionAction(week, CommonImages.SCHEDULE_WEEK); subMenuManager.add(action); // Special case: This Week holds previous weeks' scheduled tasks if (isThisWeek(singleTaskSelection)) { // Tasks scheduled for 'someday' float into this week action.setChecked(true); } // Next Week action = createDateSelectionAction(week.next(), null); subMenuManager.add(action); // Two Weeks action = createDateSelectionAction(week.next().next(), null); subMenuManager.add(action); if (singleTaskSelection != null && getScheduledForDate(singleTaskSelection) != null) { // Update Two Weeks DateRange range = getScheduledForDate(singleTaskSelection); if (range.equals(TaskActivityUtil.getNextWeek().next()) || TaskActivityUtil.getNextWeek().next().includes(range)) { action.setChecked(true); } // Future if (getScheduledForDate(singleTaskSelection).after(week.next().next().getEndDate()) && !(getScheduledForDate(singleTaskSelection) instanceof WeekDateRange)) { action = new Action() { @Override public void run() { // ignore } }; action.setChecked(true); action.setText(Messages.ScheduleTaskMenuContributor_Future); subMenuManager.add(action); } } subMenuManager.add(new Separator()); // Date Selection Dialog action = new Action() { @Override public void run() { Calendar theCalendar = TaskActivityUtil.getCalendar(); if (getScheduledForDate(singleTaskSelection) != null) { theCalendar.setTime(getScheduledForDate(singleTaskSelection).getStartDate().getTime()); } Shell shell = null; if (subMenuManager != null && subMenuManager.getMenu() != null && !subMenuManager.getMenu().isDisposed()) { // we should try to use the same shell that the menu was created with // so that it shows up on top of that shell correctly shell = subMenuManager.getMenu().getShell(); } if (shell == null) { shell = WorkbenchUtil.getShell(); } DateSelectionDialog reminderDialog = new DateSelectionDialog(shell, theCalendar, DatePicker.TITLE_DIALOG, false, TasksUiPlugin.getDefault() .getPreferenceStore() .getInt(ITasksUiPreferenceConstants.PLANNING_ENDHOUR)); int result = reminderDialog.open(); if (result == Window.OK) { DateRange range = null; if (reminderDialog.getDate() != null) { range = TaskActivityUtil.getDayOf(reminderDialog.getDate()); } setScheduledDate(range); } } }; action.setText(Messages.ScheduleTaskMenuContributor_Choose_Date_); action.setEnabled(canSchedule()); subMenuManager.add(action); action = new Action() { @Override public void run() { setScheduledDate(null); } }; action.setText(Messages.ScheduleTaskMenuContributor_Not_Scheduled); action.setChecked(false); if (singleTaskSelection != null) { if (getScheduledForDate(singleTaskSelection) == null) { action.setChecked(true); } } subMenuManager.add(action); return subMenuManager; } private boolean isThisWeek(AbstractTask task) { return task != null && task.getScheduledForDate() != null && task.getScheduledForDate() instanceof WeekDateRange && task.getScheduledForDate().isBefore(TaskActivityUtil.getCurrentWeek()); } private boolean selectionIncludesCompletedTasks() { if (singleTaskSelection instanceof AbstractTask) { if ((singleTaskSelection).isCompleted()) { return true; } } if (taskListElementsToSchedule.size() > 0) { for (IRepositoryElement task : taskListElementsToSchedule) { if (task instanceof AbstractTask) { if (((AbstractTask) task).isCompleted()) { return true; } } } } return false; } private Action createDateSelectionAction(final DateRange dateContainer, ImageDescriptor imageDescriptor) { Action action = new Action() { @Override public void run() { setScheduledDate(dateContainer); } }; action.setText(dateContainer.toString()); action.setImageDescriptor(imageDescriptor); action.setEnabled(canSchedule()); DateRange scheduledDate = getScheduledForDate(singleTaskSelection); if (scheduledDate != null) { action.setChecked(dateContainer.equals(scheduledDate)); } return action; } private boolean canSchedule() { if (taskListElementsToSchedule.size() == 0) { return true; } else if (singleTaskSelection instanceof ITask) { return ((!(singleTaskSelection).isCompleted()) || taskListElementsToSchedule.size() > 0); } else { return taskListElementsToSchedule.size() > 0; } } protected void setScheduledDate(DateRange dateContainer) { for (IRepositoryElement element : taskListElementsToSchedule) { if (element instanceof AbstractTask) { AbstractTask task = (AbstractTask) element; TasksUiPlugin.getTaskList().addTaskIfAbsent(task); if (dateContainer != null) { TasksUiPlugin.getTaskActivityManager().setScheduledFor(task, dateContainer); } else { TasksUiPlugin.getTaskActivityManager().setScheduledFor(task, null); } } } } protected DateRange getScheduledForDate(final AbstractTask selectedTask) { if (selectedTask != null) { return selectedTask.getScheduledForDate(); } return null; } private boolean isPastReminder(AbstractTask task) { return TasksUiPlugin.getTaskActivityManager().isPastReminder(task); } }