/******************************************************************************* * Copyright (c) 2004, 2016 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 * Steve Elsemore - fix for bug 296963 * Atlassian - fix for bug 319699 *******************************************************************************/ package org.eclipse.mylyn.internal.tasks.ui.util; import java.net.MalformedURLException; import java.net.SocketTimeoutException; import java.net.URL; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.core.commands.Command; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.commands.NotEnabledException; import org.eclipse.core.commands.NotHandledException; import org.eclipse.core.commands.ParameterizedCommand; import org.eclipse.core.commands.common.NotDefinedException; import org.eclipse.core.commands.operations.IUndoContext; import org.eclipse.core.commands.operations.ObjectUndoContext; import org.eclipse.core.expressions.EvaluationContext; import org.eclipse.core.expressions.IEvaluationContext; import org.eclipse.core.runtime.Assert; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IAdaptable; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.ProgressMonitorWrapper; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.jface.dialogs.IDialogConstants; import org.eclipse.jface.dialogs.IDialogSettings; import org.eclipse.jface.dialogs.IInputValidator; import org.eclipse.jface.dialogs.InputDialog; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.preference.IPreferenceStore; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.ITreeSelection; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.TreeViewer; import org.eclipse.jface.window.Window; import org.eclipse.jface.wizard.IWizard; import org.eclipse.mylyn.commons.core.CoreUtil; import org.eclipse.mylyn.commons.core.StatusHandler; import org.eclipse.mylyn.commons.identity.core.Account; import org.eclipse.mylyn.commons.ui.CommonImages; import org.eclipse.mylyn.commons.ui.CommonUiUtil; import org.eclipse.mylyn.commons.workbench.WorkbenchUtil; import org.eclipse.mylyn.internal.monitor.ui.MonitorUiPlugin; import org.eclipse.mylyn.internal.tasks.core.AbstractTask; import org.eclipse.mylyn.internal.tasks.core.AbstractTaskCategory; import org.eclipse.mylyn.internal.tasks.core.AbstractTaskContainer; import org.eclipse.mylyn.internal.tasks.core.DateRange; import org.eclipse.mylyn.internal.tasks.core.ITaskJobFactory; import org.eclipse.mylyn.internal.tasks.core.ITaskList; import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; import org.eclipse.mylyn.internal.tasks.core.LocalRepositoryConnector; import org.eclipse.mylyn.internal.tasks.core.LocalTask; import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery; import org.eclipse.mylyn.internal.tasks.core.TaskActivityUtil; import org.eclipse.mylyn.internal.tasks.core.TaskCategory; import org.eclipse.mylyn.internal.tasks.core.TaskList; import org.eclipse.mylyn.internal.tasks.core.UncategorizedTaskContainer; import org.eclipse.mylyn.internal.tasks.core.UnsubmittedTaskContainer; import org.eclipse.mylyn.internal.tasks.core.data.TaskDataState; import org.eclipse.mylyn.internal.tasks.core.sync.SynchronizationScheduler; import org.eclipse.mylyn.internal.tasks.core.sync.SynchronizationScheduler.Synchronizer; import org.eclipse.mylyn.internal.tasks.core.util.TasksCoreUtil; import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants; import org.eclipse.mylyn.internal.tasks.ui.OpenRepositoryTaskJob; import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView; import org.eclipse.mylyn.internal.tasks.ui.wizards.MultiRepositoryAwareWizard; import org.eclipse.mylyn.internal.tasks.ui.wizards.NewAttachmentWizardDialog; import org.eclipse.mylyn.internal.tasks.ui.wizards.NewTaskWizardInternal; import org.eclipse.mylyn.internal.tasks.ui.wizards.QueryWizardDialog; import org.eclipse.mylyn.internal.tasks.ui.wizards.TaskAttachmentWizard; import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector; import org.eclipse.mylyn.tasks.core.IRepositoryElement; import org.eclipse.mylyn.tasks.core.IRepositoryManager; import org.eclipse.mylyn.tasks.core.IRepositoryPerson; import org.eclipse.mylyn.tasks.core.IRepositoryQuery; import org.eclipse.mylyn.tasks.core.ITask; import org.eclipse.mylyn.tasks.core.ITask.PriorityLevel; import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState; import org.eclipse.mylyn.tasks.core.ITaskMapping; import org.eclipse.mylyn.tasks.core.RepositoryStatus; import org.eclipse.mylyn.tasks.core.TaskRepository; import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentSource; import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler; import org.eclipse.mylyn.tasks.core.data.ITaskDataWorkingCopy; import org.eclipse.mylyn.tasks.core.data.TaskAttachmentMapper; import org.eclipse.mylyn.tasks.core.data.TaskAttribute; import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper; import org.eclipse.mylyn.tasks.core.data.TaskCommentMapper; import org.eclipse.mylyn.tasks.core.data.TaskData; import org.eclipse.mylyn.tasks.core.data.TaskHistory; import org.eclipse.mylyn.tasks.core.data.TaskRevision; import org.eclipse.mylyn.tasks.core.data.TaskRevision.Change; import org.eclipse.mylyn.tasks.core.sync.SynchronizationJob; import org.eclipse.mylyn.tasks.core.sync.TaskJob; import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; import org.eclipse.mylyn.tasks.ui.TasksUi; import org.eclipse.mylyn.tasks.ui.TasksUiImages; import org.eclipse.mylyn.tasks.ui.TasksUiUtil; import org.eclipse.mylyn.tasks.ui.editors.TaskEditor; import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput; import org.eclipse.osgi.util.NLS; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Shell; import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.IEditorReference; import org.eclipse.ui.ISources; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPage; import org.eclipse.ui.IWorkbenchPart; import org.eclipse.ui.IWorkbenchPreferenceConstants; import org.eclipse.ui.IWorkbenchWindow; import org.eclipse.ui.IWorkingSet; import org.eclipse.ui.PartInitException; import org.eclipse.ui.PlatformUI; import org.eclipse.ui.commands.ICommandService; import org.eclipse.ui.handlers.IHandlerService; import org.eclipse.ui.progress.IProgressConstants2; import org.eclipse.ui.services.IServiceLocator; import org.eclipse.ui.statushandlers.IStatusAdapterConstants; import org.eclipse.ui.statushandlers.StatusAdapter; import org.eclipse.ui.statushandlers.StatusManager; import com.google.common.base.Strings; /** * @author Steffen Pingel */ public class TasksUiInternal { private static SynchronizationScheduler synchronizationScheduler = new SynchronizationScheduler(); private static final TaskDropHandler taskDropHandler = new TaskDropHandler(); /** * @deprecated use SWT.SHEET instead */ @Deprecated public static final int SWT_SHEET = 1 << 28; public static final String ID_MENU_ACTIVE_TASK = "org.eclipse.mylyn.tasks.ui.menus.activeTask"; //$NON-NLS-1$ private static ObjectUndoContext undoContext; public static MultiRepositoryAwareWizard createNewTaskWizard(ITaskMapping taskSelection) { return new NewTaskWizardInternal(taskSelection); } /** * get the connector discovery wizard command. Calling code should check {@link Command#isEnabled()} on return. * * @return the command, or null if it is not available. */ public static Command getConfiguredDiscoveryWizardCommand() { ICommandService service = (ICommandService) PlatformUI.getWorkbench().getService(ICommandService.class); final Command discoveryWizardCommand = service.getCommand("org.eclipse.mylyn.tasks.ui.discoveryWizardCommand"); //$NON-NLS-1$ if (discoveryWizardCommand != null) { IHandlerService handlerService = (IHandlerService) PlatformUI.getWorkbench() .getService(IHandlerService.class); EvaluationContext evaluationContext = createDiscoveryWizardEvaluationContext(handlerService); if (!discoveryWizardCommand.isEnabled()) { // update enabled state in case something has changed (ProxyHandler caches state) discoveryWizardCommand.setEnabled(evaluationContext); } } return discoveryWizardCommand; } public static EvaluationContext createDiscoveryWizardEvaluationContext(IHandlerService handlerService) { EvaluationContext evaluationContext = new EvaluationContext(handlerService.getCurrentState(), Platform.class); // must specify this variable otherwise the PlatformPropertyTester won't work evaluationContext.addVariable("platform", Platform.class); //$NON-NLS-1$ return evaluationContext; } public static ImageDescriptor getPriorityImage(ITask task) { if (task.isCompleted()) { return CommonImages.COMPLETE; } else { return TasksUiImages.getImageDescriptorForPriority(PriorityLevel.fromString(task.getPriority())); } } public static List<TaskEditor> getActiveRepositoryTaskEditors() { List<TaskEditor> repositoryTaskEditors = new ArrayList<TaskEditor>(); IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); for (IWorkbenchWindow window : windows) { IEditorReference[] editorReferences = window.getActivePage().getEditorReferences(); for (IEditorReference editorReference : editorReferences) { try { if (editorReference.getEditorInput() instanceof TaskEditorInput) { TaskEditorInput input = (TaskEditorInput) editorReference.getEditorInput(); if (input.getTask() != null) { IEditorPart editorPart = editorReference.getEditor(false); if (editorPart instanceof TaskEditor) { repositoryTaskEditors.add((TaskEditor) editorPart); } } } } catch (PartInitException e) { // ignore } } } return repositoryTaskEditors; } public static IProgressMonitor getUiMonitor(IProgressMonitor monitor) { return new ProgressMonitorWrapper(monitor) { @Override public void beginTask(final String name, final int totalWork) { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { getWrappedProgressMonitor().beginTask(name, totalWork); } }); } @Override public void done() { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { getWrappedProgressMonitor().done(); } }); } @Override public void subTask(final String name) { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { getWrappedProgressMonitor().subTask(name); } }); } @Override public void worked(final int work) { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { getWrappedProgressMonitor().worked(work); } }); } }; } public static void openEditor(TaskCategory category) { final String name = category.getSummary(); InputDialog dialog = new InputDialog(WorkbenchUtil.getShell(), Messages.TasksUiInternal_Rename_Category_Title, Messages.TasksUiInternal_Rename_Category_Message, name, new IInputValidator() { public String isValid(String newName) { if (newName.trim().length() == 0 || newName.equals(name)) { return ""; //$NON-NLS-1$ } Set<AbstractTaskCategory> categories = TasksUiPlugin.getTaskList().getCategories(); for (AbstractTaskCategory category : categories) { if (newName.equals(category.getSummary())) { return Messages.TasksUiInternal_Rename_Category_Name_already_exists_Error; } } return null; } }); if (dialog.open() == Window.OK) { TasksUiPlugin.getTaskList().renameContainer(category, dialog.getValue()); } } public static void refreshAndOpenTaskListElement(IRepositoryElement element) { if (element instanceof ITask) { final AbstractTask task = (AbstractTask) element; if (task instanceof LocalTask) { TasksUiUtil.openTask(task); } else { String repositoryKind = task.getConnectorKind(); final AbstractRepositoryConnector connector = TasksUi.getRepositoryManager() .getRepositoryConnector(repositoryKind); TaskRepository repository = TasksUi.getRepositoryManager().getRepository(repositoryKind, task.getRepositoryUrl()); if (repository == null) { displayStatus(Messages.TasksUiInternal_Failed_to_open_task, new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, Messages.TasksUiInternal_No_repository_found)); return; } if (connector != null) { boolean opened = false; if (TasksUiPlugin.getTaskDataManager().hasTaskData(task)) { opened = TasksUiUtil.openTask(task); } if (!opened) { if (connector.canSynchronizeTask(repository, task)) { // TODO consider moving this into the editor, i.e. have the editor refresh the task if task data is missing TasksUiInternal.synchronizeTask(connector, task, true, new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { PlatformUI.getWorkbench().getDisplay().asyncExec(new Runnable() { public void run() { TasksUiUtil.openTask(task); } }); } }); } else { TasksUiUtil.openTask(task); } } } } } else if (element instanceof TaskCategory) { TasksUiInternal.openEditor((TaskCategory) element); } else if (element instanceof IRepositoryQuery) { RepositoryQuery query = (RepositoryQuery) element; AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(query.getConnectorKind()); TasksUiInternal.openEditQueryDialog(connectorUi, query); } } public static TaskJob updateRepositoryConfiguration(final TaskRepository taskRepository) { synchronized (taskRepository) { taskRepository.setUpdating(true); } AbstractRepositoryConnector connector = TasksUi.getRepositoryManager() .getRepositoryConnector(taskRepository.getConnectorKind()); final TaskJob job = TasksUiInternal.getJobFactory().createUpdateRepositoryConfigurationJob(connector, taskRepository, null); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { synchronized (taskRepository) { taskRepository.setUpdating(false); } if (job.getStatus() != null) { TasksUiInternal.asyncLogAndDisplayStatus(Messages.TasksUiInternal_Configuration_Refresh_Failed, job.getStatus()); } } }); job.schedule(); return job; } private static void joinIfInTestMode(SynchronizationJob job) { // FIXME the client code should join the job if (CoreUtil.TEST_MODE) { try { job.join(); } catch (InterruptedException e) { throw new RuntimeException(e); } } } public static final Job synchronizeQueries(AbstractRepositoryConnector connector, TaskRepository repository, Set<RepositoryQuery> queries, IJobChangeListener listener, boolean force) { Assert.isTrue(queries.size() > 0); TaskList taskList = TasksUiPlugin.getTaskList(); for (RepositoryQuery query : queries) { query.setSynchronizing(true); } taskList.notifySynchronizationStateChanged(queries); SynchronizationJob job = TasksUiPlugin.getTaskJobFactory().createSynchronizeQueriesJob(connector, repository, queries); job.setUser(force); if (force) { // show the progress in the system task bar if this is a user job (i.e. forced) job.setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE); } if (listener != null) { job.addJobChangeListener(listener); } if (force) { final RepositoryQuery query = queries.iterator().next(); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { if (query.getStatus() != null) { TasksUiInternal.asyncLogAndDisplayStatus(Messages.TasksUiInternal_Query_Synchronization_Failed, query.getStatus()); } } }); } job.schedule(); joinIfInTestMode(job); return job; } /** * For synchronizing a single query. Use synchronize(Set, IJobChangeListener) if synchronizing multiple queries at a * time. */ public static final Job synchronizeQuery(AbstractRepositoryConnector connector, RepositoryQuery repositoryQuery, IJobChangeListener listener, boolean force) { TaskRepository repository = TasksUi.getRepositoryManager().getRepository(repositoryQuery.getConnectorKind(), repositoryQuery.getRepositoryUrl()); return synchronizeQueries(connector, repository, Collections.singleton(repositoryQuery), listener, force); } public static SynchronizationJob synchronizeAllRepositories(boolean force) { SynchronizationJob job = TasksUiPlugin.getTaskJobFactory().createSynchronizeRepositoriesJob(null); job.setUser(force); if (force) { // show the progress in the system task bar if this is a user job (i.e. forced) job.setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE); } job.schedule(); joinIfInTestMode(job); return job; } public static void synchronizeRepositoryInBackground(final TaskRepository repository) { synchronizationScheduler.schedule(repository, new Synchronizer<SynchronizationJob>() { @Override public SynchronizationJob createJob() { return synchronizeRepositoryInternal(repository, false); } }); } public static SynchronizationJob synchronizeRepository(TaskRepository repository, boolean force) { SynchronizationJob job = synchronizeRepositoryInternal(repository, force); synchronizationScheduler.cancel(repository); job.schedule(); return job; } private static SynchronizationJob synchronizeRepositoryInternal(TaskRepository repository, boolean force) { SynchronizationJob job = TasksUiInternal.getJobFactory() .createSynchronizeRepositoriesJob(Collections.singleton(repository)); // do not show in progress view by default job.setSystem(true); job.setUser(force); if (force) { // show the progress in the system task bar if this is a user job (i.e. forced) job.setProperty(IProgressConstants2.SHOW_IN_TASKBAR_ICON_PROPERTY, Boolean.TRUE); } job.setFullSynchronization(false); return job; } public static void synchronizeTaskInBackground(final AbstractRepositoryConnector connector, final ITask task) { synchronizationScheduler.schedule(task, new Synchronizer<Job>() { @Override public Job createJob() { SynchronizationJob job = TasksUiPlugin.getTaskJobFactory().createSynchronizeTasksJob(connector, Collections.singleton(task)); job.setUser(false); job.setSystem(true); return job; } }); } /** * Synchronize a single task. Note that if you have a collection of tasks to synchronize with this connector then * you should call synchronize(Set<Set<AbstractTask> repositoryTasks, ...) * * @param listener * can be null */ public static Job synchronizeTask(AbstractRepositoryConnector connector, ITask task, boolean force, IJobChangeListener listener) { return synchronizeTasks(connector, Collections.singleton(task), force, listener); } /** * @param listener * can be null */ public static Job synchronizeTasks(AbstractRepositoryConnector connector, Set<ITask> tasks, boolean force, IJobChangeListener listener) { ITaskList taskList = TasksUiInternal.getTaskList(); for (ITask task : tasks) { ((AbstractTask) task).setSynchronizing(true); synchronizationScheduler.cancel(task); } ((TaskList) taskList).notifySynchronizationStateChanged(tasks); // TODO notify task list? SynchronizationJob job = TasksUiPlugin.getTaskJobFactory().createSynchronizeTasksJob(connector, tasks); job.setUser(force); job.setSystem(!force); job.setPriority(Job.DECORATE); if (listener != null) { job.addJobChangeListener(listener); } if (force && tasks.size() == 1) { final ITask task = tasks.iterator().next(); job.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { if (task instanceof AbstractTask && ((AbstractTask) task).getStatus() != null) { TasksUiInternal.asyncLogAndDisplayStatus(Messages.TasksUiInternal_Task_Synchronization_Failed, ((AbstractTask) task).getStatus()); } } }); } job.schedule(); joinIfInTestMode(job); return job; } public static ITaskJobFactory getJobFactory() { return TasksUiPlugin.getTaskJobFactory(); } public static NewAttachmentWizardDialog openNewAttachmentWizard(Shell shell, TaskRepository taskRepository, ITask task, TaskAttribute taskAttribute, TaskAttachmentWizard.Mode mode, AbstractTaskAttachmentSource source) { TaskAttachmentWizard attachmentWizard = new TaskAttachmentWizard(taskRepository, task, taskAttribute); attachmentWizard.setSource(source); attachmentWizard.setMode(mode); NewAttachmentWizardDialog dialog = new NewAttachmentWizardDialog(shell, attachmentWizard, false); dialog.setBlockOnOpen(false); dialog.create(); dialog.open(); return dialog; } private static MessageDialog createDialog(Shell shell, String title, String message, int type) { return new MessageDialog(shell, title, null, message, type, new String[] { IDialogConstants.OK_LABEL }, 0); } private static void displayStatus(Shell shell, final String title, final IStatus status, boolean showLinkToErrorLog) { // avoid blocking ui when in test mode if (CoreUtil.TEST_MODE) { StatusHandler.log(status); return; } if (status instanceof RepositoryStatus && ((RepositoryStatus) status).isHtmlMessage()) { WebBrowserDialog.openAcceptAgreement(shell, title, status.getMessage(), ((RepositoryStatus) status).getHtmlMessage()); } else { String message = status.getMessage(); if (message == null || message.trim().length() == 0) { message = Messages.TasksUiInternal_An_unknown_error_occurred; } if (message.length() > 256) { message = message.substring(0, 256) + "..."; //$NON-NLS-1$ } if (showLinkToErrorLog) { message += "\n\n" + Messages.TasksUiInternal_See_error_log_for_details; //$NON-NLS-1$ } switch (status.getSeverity()) { case IStatus.CANCEL: case IStatus.INFO: createDialog(shell, title, message, MessageDialog.INFORMATION).open(); break; case IStatus.WARNING: createDialog(shell, title, message, MessageDialog.WARNING).open(); break; case IStatus.ERROR: default: createDialog(shell, title, message, MessageDialog.ERROR).open(); break; } } } public static void asyncDisplayStatus(final String title, final IStatus status) { Display display = PlatformUI.getWorkbench().getDisplay(); if (!display.isDisposed()) { display.asyncExec(new Runnable() { public void run() { displayStatus(title, status); } }); } else { StatusHandler.log(status); } } public static void asyncLogAndDisplayStatus(final String title, final IStatus status) { Display display = PlatformUI.getWorkbench().getDisplay(); if (!display.isDisposed()) { display.asyncExec(new Runnable() { public void run() { logAndDisplayStatus(title, status); } }); } else { StatusHandler.log(status); } } public static void logAndDisplayStatus(final String title, final IStatus status) { StatusHandler.log(status); IWorkbench workbench = PlatformUI.getWorkbench(); if (workbench != null && !workbench.getDisplay().isDisposed()) { displayStatus(WorkbenchUtil.getShell(), title, status, false); } } public static void displayStatus(final String title, final IStatus status) { IWorkbench workbench = PlatformUI.getWorkbench(); if (workbench != null && !workbench.getDisplay().isDisposed()) { displayStatus(WorkbenchUtil.getShell(), title, status, false); } else { StatusHandler.log(status); } } /** * Creates a new local task and schedules for today * * @param summary * if null DEFAULT_SUMMARY (New Task) used. */ public static LocalTask createNewLocalTask(String summary) { if (summary == null) { summary = LocalRepositoryConnector.DEFAULT_SUMMARY; } TaskList taskList = TasksUiPlugin.getTaskList(); LocalTask newTask = new LocalTask("" + taskList.getNextLocalTaskId(), summary); //$NON-NLS-1$ newTask.setPriority(PriorityLevel.P3.toString()); TasksUiInternal.getTaskList().addTask(newTask); scheduleNewTask(newTask); TaskListView view = TaskListView.getFromActivePerspective(); AbstractTaskCategory category = getSelectedCategory(view); if (view != null && view.getDrilledIntoCategory() != null && view.getDrilledIntoCategory() != category) { MessageDialog.openInformation(Display.getCurrent().getActiveShell(), Messages.TasksUiInternal_Create_Task, MessageFormat.format(Messages.TasksUiInternal_The_new_task_will_be_added_to_the_X_container, UncategorizedTaskContainer.LABEL)); } newTask.setAttribute(ITasksCoreConstants.PROPERTY_NEW_UNSAVED_TASK, Boolean.TRUE.toString()); taskList.addTask(newTask, category); return newTask; } /** * Schedules the new task according to the Tasks UI preferences * * @param newTask * the task to schedule */ public static void scheduleNewTask(LocalTask newTask) { IPreferenceStore preferenceStore = TasksUiPlugin.getDefault().getPreferenceStore(); String preference = preferenceStore.getString(ITasksUiPreferenceConstants.SCHEDULE_NEW_TASKS_FOR); DateRange dateRange = getNewTaskScheduleDateRange(preference); TasksUiPlugin.getTaskActivityManager().scheduleNewTask(newTask, dateRange); } private static DateRange getNewTaskScheduleDateRange(String preference) { switch (preference) { case ITasksUiPreferenceConstants.SCHEDULE_NEW_TASKS_FOR_NOT_SCHEDULED: return null; case ITasksUiPreferenceConstants.SCHEDULE_NEW_TASKS_FOR_TODAY: return TaskActivityUtil.getCurrentWeek().getToday(); case ITasksUiPreferenceConstants.SCHEDULE_NEW_TASKS_FOR_TOMORROW: return TaskActivityUtil.getCurrentWeek().getToday().next(); case ITasksUiPreferenceConstants.SCHEDULE_NEW_TASKS_FOR_THIS_WEEK: return TaskActivityUtil.getCurrentWeek(); } return TaskActivityUtil.getCurrentWeek(); } public static AbstractTaskCategory getSelectedCategory(TaskListView view) { Object selectedObject = null; if (view != null) { selectedObject = ((IStructuredSelection) view.getViewer().getSelection()).getFirstElement(); } if (selectedObject instanceof TaskCategory) { return (TaskCategory) selectedObject; } else if (selectedObject instanceof ITask) { ITask task = (ITask) selectedObject; AbstractTaskContainer container = TaskCategory.getParentTaskCategory(task); if (container instanceof TaskCategory) { return (TaskCategory) container; } else if (view != null && view.getDrilledIntoCategory() instanceof TaskCategory) { return (TaskCategory) view.getDrilledIntoCategory(); } } else if (view != null && view.getDrilledIntoCategory() instanceof TaskCategory) { return (TaskCategory) view.getDrilledIntoCategory(); } return TasksUiPlugin.getTaskList().getDefaultCategory(); } public static Set<AbstractTaskContainer> getContainersFromWorkingSet(Set<IWorkingSet> containers) { Set<AbstractTaskContainer> allTaskContainersInWorkingSets = new HashSet<AbstractTaskContainer>(); for (IWorkingSet workingSet : containers) { IAdaptable[] elements = workingSet.getElements(); for (IAdaptable adaptable : elements) { if (adaptable instanceof AbstractTaskContainer) { allTaskContainersInWorkingSets.add(((AbstractTaskContainer) adaptable)); } } } return allTaskContainersInWorkingSets; } /** * @param connectorUi * - repository connector ui * @param query * - repository query * @return - true if dialog was opened successfully and not canceled, false otherwise * @since 3.0 */ public static boolean openEditQueryDialog(AbstractRepositoryConnectorUi connectorUi, final IRepositoryQuery query) { try { TaskRepository repository = TasksUi.getRepositoryManager().getRepository(query.getConnectorKind(), query.getRepositoryUrl()); if (repository == null) { return false; } IWizard wizard = connectorUi.getQueryWizard(repository, query); Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(); if (wizard != null && shell != null && !shell.isDisposed()) { QueryWizardDialog dialog = new QueryWizardDialog(shell, wizard) { private static final String DIALOG_SETTINGS = "EditQueryWizardWizard"; //$NON-NLS-1$ @Override protected IDialogSettings getDialogBoundsSettings() { IDialogSettings settings = TasksUiPlugin.getDefault().getDialogSettings(); String settingsSectionId = DIALOG_SETTINGS + '.' + query.getRepositoryUrl(); IDialogSettings section = settings.getSection(settingsSectionId); if (section == null) { section = settings.addNewSection(settingsSectionId); } return section; } }; dialog.create(); dialog.setBlockOnOpen(true); if (dialog.open() == Window.CANCEL) { return false; } else { return true; } } } catch (Exception e) { StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Failed to open query dialog", e)); //$NON-NLS-1$ } return false; } public static ITaskList getTaskList() { return TasksUiPlugin.getTaskList(); } public static boolean isAnimationsEnabled() { IPreferenceStore store = PlatformUI.getPreferenceStore(); return store.getBoolean(IWorkbenchPreferenceConstants.ENABLE_ANIMATIONS); } public static boolean hasValidUrl(ITask task) { return isValidUrl(task.getUrl()); } public static boolean isValidUrl(String url) { if (url != null && !url.equals("") && !url.equals("http://") && !url.equals("https://")) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ try { new URL(url); return true; } catch (MalformedURLException e) { return false; } } return false; } /** * @deprecated use {@link #closeTaskEditorInAllPages(ITask, boolean)} */ @Deprecated public static void closeEditorInActivePage(ITask task, boolean save) { Assert.isNotNull(task); IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window == null) { return; } IWorkbenchPage page = window.getActivePage(); if (page == null) { return; } TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); IEditorInput input = new TaskEditorInput(taskRepository, task); IEditorPart editor = page.findEditor(input); if (editor != null) { page.closeEditor(editor, save); } } public static void closeTaskEditorInAllPages(ITask task, boolean save) { Assert.isNotNull(task); TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); IEditorInput input = new TaskEditorInput(taskRepository, task); IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); for (IWorkbenchWindow window : windows) { IWorkbenchPage[] pages = window.getPages(); for (IWorkbenchPage page : pages) { IEditorPart editor = page.findEditor(input); if (editor != null) { page.closeEditor(editor, save); } } } } public static boolean hasLocalCompletionState(ITask task) { TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); AbstractRepositoryConnector connector = TasksUi.getRepositoryManager() .getRepositoryConnector(task.getConnectorKind()); return connector.hasLocalCompletionState(taskRepository, task); } /** * Utility method to get the best parenting possible for a dialog. If there is a modal shell create it so as to * avoid two modal dialogs. If not then return the shell of the active workbench window. If neither can be found * return null. * <p> * <b>Note: Applied from patch on bug 99472.</b> * * @return Shell or <code>null</code> * @deprecated Use {@link WorkbenchUtil#getShell()} instead */ @Deprecated public static Shell getShell() { return WorkbenchUtil.getShell(); } public static TaskData createTaskData(TaskRepository taskRepository, ITaskMapping initializationData, ITaskMapping selectionData, IProgressMonitor monitor) throws CoreException { AbstractRepositoryConnector connector = TasksUi.getRepositoryManager() .getRepositoryConnector(taskRepository.getConnectorKind()); AbstractTaskDataHandler taskDataHandler = connector.getTaskDataHandler(); TaskAttributeMapper mapper = taskDataHandler.getAttributeMapper(taskRepository); TaskData taskData = new TaskData(mapper, taskRepository.getConnectorKind(), taskRepository.getRepositoryUrl(), ""); //$NON-NLS-1$ boolean result = taskDataHandler.initializeTaskData(taskRepository, taskData, initializationData, monitor); if (!result) { throw new CoreException(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Initialization of task failed. The provided data is insufficient.")); //$NON-NLS-1$ } if (selectionData != null) { connector.getTaskMapping(taskData).merge(selectionData); } return taskData; } public static void createAndOpenNewTask(TaskData taskData) throws CoreException { ITask task = TasksUiUtil.createOutgoingNewTask(taskData.getConnectorKind(), taskData.getRepositoryUrl()); AbstractRepositoryConnector connector = TasksUi.getRepositoryManager() .getRepositoryConnector(taskData.getConnectorKind()); ITaskMapping mapping = connector.getTaskMapping(taskData); String summary = mapping.getSummary(); if (!Strings.isNullOrEmpty(summary)) { task.setSummary(summary); } String taskKind = mapping.getTaskKind(); if (!Strings.isNullOrEmpty(taskKind)) { task.setTaskKind(taskKind); } UnsubmittedTaskContainer unsubmitted = TasksUiPlugin.getTaskList() .getUnsubmittedContainer(taskData.getRepositoryUrl()); if (unsubmitted != null) { TasksUiPlugin.getTaskList().addTask(task, unsubmitted); } ITaskDataWorkingCopy workingCopy = TasksUi.getTaskDataManager().createWorkingCopy(task, taskData); workingCopy.save(null, null); TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(taskData.getConnectorKind(), taskData.getRepositoryUrl()); connector.updateNewTaskFromTaskData(taskRepository, task, taskData); TaskRepository localTaskRepository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); TaskEditorInput editorInput = new TaskEditorInput(localTaskRepository, task); TasksUiUtil.openEditor(editorInput, TaskEditor.ID_EDITOR, null); } public static boolean openTask(TaskRepository repository, String taskId, TaskOpenListener listener) { AbstractTask task = getTaskFromTaskList(repository, taskId); if (task != null) { // task is known, open in task editor return openKnownTaskInEditor(task, taskId, listener); } else { // search for task AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind()); if (connectorUi != null) { try { return openRepositoryTask(connectorUi.getConnectorKind(), repository.getRepositoryUrl(), taskId, listener); } catch (Exception e) { StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Internal error while opening repository task", e)); //$NON-NLS-1$ } } } return false; } public static boolean openTaskByIdOrKey(TaskRepository repository, String taskIdOrKey, TaskOpenListener listener) { AbstractTask task = getTaskFromTaskList(repository, taskIdOrKey); if (task != null) { // task is known, open in task editor return openKnownTaskInEditor(task, taskIdOrKey, listener); } else { // search for task AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind()); if (connectorUi != null) { try { return openRepositoryTaskByIdOrKey(connectorUi.getConnectorKind(), repository.getRepositoryUrl(), taskIdOrKey, listener); } catch (Exception e) { StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Internal error while opening repository task", e)); //$NON-NLS-1$ } } } return false; } private static boolean openKnownTaskInEditor(AbstractTask task, String taskIdOrKey, TaskOpenListener listener) { TaskOpenEvent event = TasksUiInternal.openTask(task, taskIdOrKey); if (listener != null && event != null) { listener.taskOpened(event); } return event != null; } private static AbstractTask getTaskFromTaskList(TaskRepository repository, String taskIdOrKey) { Assert.isNotNull(repository); Assert.isNotNull(taskIdOrKey); AbstractTask task = (AbstractTask) TasksUiInternal.getTaskList().getTask(repository.getRepositoryUrl(), taskIdOrKey); if (task == null) { task = TasksUiPlugin.getTaskList().getTaskByKey(repository.getRepositoryUrl(), taskIdOrKey); } return task; } public static TaskOpenEvent openTask(ITask task, String taskId) { Assert.isNotNull(task); IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); boolean openWithBrowser = !TasksUiPlugin.getDefault() .getPreferenceStore() .getBoolean(ITasksUiPreferenceConstants.EDITOR_TASKS_RICH); if (openWithBrowser && !(task instanceof LocalTask)) { TasksUiUtil.openWithBrowser(taskRepository, task); return new TaskOpenEvent(taskRepository, task, taskId, null, true); } else { IEditorInput editorInput = getTaskEditorInput(taskRepository, task); IEditorPart editor = refreshEditorContentsIfOpen(task, editorInput); if (editor != null) { synchronizeTask(taskRepository, task); return new TaskOpenEvent(taskRepository, task, taskId, editor, false); } else { IWorkbenchPage page = window.getActivePage(); editor = TasksUiUtil.openEditor(editorInput, getTaskEditorId(task), page); if (editor != null) { synchronizeTask(taskRepository, task); return new TaskOpenEvent(taskRepository, task, taskId, editor, false); } } } } else { StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Unable to open editor for \"" //$NON-NLS-1$ + task.getSummary() + "\": no active workbench window")); //$NON-NLS-1$ } return null; } private static IEditorInput getTaskEditorInput(TaskRepository repository, ITask task) { Assert.isNotNull(task); Assert.isNotNull(repository); AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(task.getConnectorKind()); IEditorInput editorInput = connectorUi.getTaskEditorInput(repository, task); if (editorInput != null) { return editorInput; } else { return new TaskEditorInput(repository, task); } } private static String getTaskEditorId(final ITask task) { String taskEditorId = TaskEditor.ID_EDITOR; if (task != null) { ITask repositoryTask = task; AbstractRepositoryConnectorUi repositoryUi = TasksUiPlugin .getConnectorUi(repositoryTask.getConnectorKind()); String customTaskEditorId = repositoryUi.getTaskEditorId(repositoryTask); if (customTaskEditorId != null) { taskEditorId = customTaskEditorId; } } return taskEditorId; } /** * If task is already open and has incoming, must force refresh in place */ private static IEditorPart refreshEditorContentsIfOpen(ITask task, IEditorInput editorInput) { if (task != null) { if (task.getSynchronizationState() == SynchronizationState.INCOMING || task.getSynchronizationState() == SynchronizationState.CONFLICT) { for (TaskEditor editor : TasksUiInternal.getActiveRepositoryTaskEditors()) { if (editor.getEditorInput().equals(editorInput)) { editor.refreshPages(); editor.getEditorSite().getPage().activate(editor); return editor; } } } } return null; } private static void synchronizeTask(TaskRepository taskRepository, ITask task) { if (task instanceof LocalTask) { return; } AbstractRepositoryConnector connector = TasksUi.getRepositoryManager() .getRepositoryConnector(task.getConnectorKind()); if (connector.canSynchronizeTask(taskRepository, task)) { TasksUiInternal.synchronizeTaskInBackground(connector, task); } } public static boolean openRepositoryTask(String connectorKind, String repositoryUrl, String id) { return openRepositoryTask(connectorKind, repositoryUrl, id, null); } /** * Only override if task should be opened by a custom editor, default behavior is to open with a rich editor, * falling back to the web browser if not available. * * @return true if the task was successfully opened */ public static boolean openRepositoryTask(String connectorKind, String repositoryUrl, String id, TaskOpenListener listener) { return openRepositoryTask(connectorKind, repositoryUrl, id, listener, 0); } /** * Only override if task should be opened by a custom editor, default behavior is to open with a rich editor, * falling back to the web browser if not available. * * @return true if the task was successfully opened */ public static boolean openRepositoryTask(String connectorKind, String repositoryUrl, String id, TaskOpenListener listener, long timestamp) { String taskUrl = getTaskUrl(connectorKind, repositoryUrl, id); if (taskUrl == null) { return false; } IWorkbenchWindow window = getWorkbenchWindow(); if (window == null) { return false; } IWorkbenchPage page = window.getActivePage(); OpenRepositoryTaskJob job = new OpenRepositoryTaskJob(connectorKind, repositoryUrl, id, taskUrl, timestamp, page); job.setListener(listener); job.schedule(); return true; } /** * Opens a task with a given search string that can be a task id or task key. * * @return true if the task was successfully opened */ public static boolean openRepositoryTaskByIdOrKey(String connectorKind, String repositoryUrl, String idOrKey, TaskOpenListener listener) { String taskUrl = getTaskUrl(connectorKind, repositoryUrl, idOrKey); if (taskUrl == null) { return false; } IWorkbenchWindow window = getWorkbenchWindow(); if (window == null) { return false; } IWorkbenchPage page = window.getActivePage(); OpenRepositoryTaskJob job = new OpenRepositoryTaskJob(page, connectorKind, repositoryUrl, idOrKey, taskUrl); job.setListener(listener); job.schedule(); return true; } private static IWorkbenchWindow getWorkbenchWindow() { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window == null) { IWorkbenchWindow[] windows = PlatformUI.getWorkbench().getWorkbenchWindows(); if (windows != null && windows.length > 0) { window = windows[0]; } } return window; } private static String getTaskUrl(String connectorKind, String repositoryUrl, String idOrKey) { IRepositoryManager repositoryManager = TasksUi.getRepositoryManager(); AbstractRepositoryConnector connector = repositoryManager.getRepositoryConnector(connectorKind); return connector.getTaskUrl(repositoryUrl, idOrKey); } /** * @since 3.0 */ public static boolean openTaskInBackground(ITask task, boolean bringToTop) { IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow(); if (window != null) { IEditorPart activeEditor = null; IWorkbenchPart activePart = null; IWorkbenchPage activePage = window.getActivePage(); if (activePage != null) { activeEditor = activePage.getActiveEditor(); activePart = activePage.getActivePart(); } boolean opened = TasksUiUtil.openTask(task); if (opened && activePage != null) { if (!bringToTop && activeEditor != null) { activePage.bringToTop(activeEditor); } if (activePart != null) { activePage.activate(activePart); } } return opened; } else { StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Unable to open editor for \"" //$NON-NLS-1$ + task.getSummary() + "\": no active workbench window")); //$NON-NLS-1$ } return false; } /** * Returns text masking the &-character from decoration as an accelerator in SWT labels. * * @deprecated Use {@link CommonUiUtil#toLabel(String)} instead */ @Deprecated public static String escapeLabelText(String text) { return CommonUiUtil.toLabel(text); } public static void preservingSelection(final TreeViewer viewer, Runnable runnable) { final ISelection selection = viewer.getSelection(); runnable.run(); if (selection != null) { ISelection newSelection = viewer.getSelection(); if ((newSelection == null || newSelection.isEmpty()) && !(selection == null || selection.isEmpty())) { // delay execution to ensure that any delayed tree updates such as expand all have been processed and the selection is revealed properly Display.getDefault().asyncExec(new Runnable() { public void run() { viewer.setSelection(selection, true); } }); } else if (newSelection instanceof ITreeSelection && !newSelection.isEmpty()) { viewer.reveal(((ITreeSelection) newSelection).getFirstElement()); } } } public static String getFormattedDuration(long duration, boolean includeSeconds) { long seconds = duration / 1000; long minutes = 0; long hours = 0; // final long SECOND = 1000; final long MIN = 60; final long HOUR = MIN * 60; String formatted = ""; //$NON-NLS-1$ String hour = ""; //$NON-NLS-1$ String min = ""; //$NON-NLS-1$ String sec = ""; //$NON-NLS-1$ if (seconds >= HOUR) { hours = seconds / HOUR; if (hours == 1) { hour = hours + Messages.TasksUiInternal__hour_; } else if (hours > 1) { hour = hours + Messages.TasksUiInternal__hours_; } seconds -= hours * HOUR; minutes = seconds / MIN; if (minutes == 1) { min = minutes + Messages.TasksUiInternal__minute_; } else if (minutes != 1) { min = minutes + Messages.TasksUiInternal__minutes_; } seconds -= minutes * MIN; if (seconds == 1) { sec = seconds + Messages.TasksUiInternal__second; } else if (seconds > 1) { sec = seconds + Messages.TasksUiInternal__seconds; } formatted += hour + min; if (includeSeconds) { formatted += sec; } } else if (seconds >= MIN) { minutes = seconds / MIN; if (minutes == 1) { min = minutes + Messages.TasksUiInternal__minute_; } else if (minutes != 1) { min = minutes + Messages.TasksUiInternal__minutes_; } seconds -= minutes * MIN; if (seconds == 1) { sec = seconds + Messages.TasksUiInternal__second; } else if (seconds > 1) { sec = seconds + Messages.TasksUiInternal__seconds; } formatted += min; if (includeSeconds) { formatted += sec; } } else { if (seconds == 1) { sec = seconds + Messages.TasksUiInternal__second; } else if (seconds > 1) { sec = seconds + Messages.TasksUiInternal__seconds; } if (includeSeconds) { formatted += sec; } } return formatted; } public static AbstractTask getTask(String repositoryUrl, String taskId, String fullUrl) { AbstractTask task = null; if (repositoryUrl != null && taskId != null) { task = (AbstractTask) TasksUiInternal.getTaskList().getTask(repositoryUrl, taskId); } if (task == null && fullUrl != null) { task = TasksUiInternal.getTaskByUrl(fullUrl); } if (task == null && repositoryUrl != null && taskId != null) { task = TasksUiPlugin.getTaskList().getTaskByKey(repositoryUrl, taskId); } return task; } /** * Searches for a task whose URL matches * * @return first task with a matching URL. */ public static AbstractTask getTaskByUrl(String taskUrl) { return TasksCoreUtil.getTaskByUrl(TasksUiPlugin.getTaskList(), TasksUi.getRepositoryManager(), taskUrl); } public static boolean isTaskUrl(String taskUrl) { Assert.isNotNull(taskUrl); List<TaskRepository> repositories = TasksUiPlugin.getRepositoryManager().getAllRepositories(); for (TaskRepository repository : repositories) { if (taskUrl.startsWith(repository.getUrl())) { return true; } } return false; } /** * Cleans text for use as the text of an action to ensure that it is displayed properly. * * @return the cleaned text * @deprecated use {@link CommonUiUtil#toMenuLabel(String)} instead */ @Deprecated public static String cleanTextForAction(String label) { return CommonUiUtil.toMenuLabel(label); } public static void executeCommand(IServiceLocator serviceLocator, String commandId, String title, Object object, Event event) throws NotEnabledException { IHandlerService service = (IHandlerService) serviceLocator.getService(IHandlerService.class); if (service != null) { ICommandService commandService = (ICommandService) serviceLocator.getService(ICommandService.class); if (commandService != null) { Command command = commandService.getCommand(commandId); if (command != null) { try { if (object != null) { IEvaluationContext context = service.createContextSnapshot(false); context.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, new StructuredSelection(object)); service.executeCommandInContext(new ParameterizedCommand(command, null), event, context); } else { service.executeCommand(commandId, event); } } catch (ExecutionException e) { TasksUiInternal.displayStatus(title, new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Command execution failed", e)); //$NON-NLS-1$ } catch (NotDefinedException e) { TasksUiInternal.displayStatus(title, new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, NLS.bind("The command with the id ''{0}'' is not defined.", commandId), e)); //$NON-NLS-1$ } catch (NotHandledException e) { TasksUiInternal.displayStatus(title, new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, NLS.bind("The command with the id ''{0}'' is not bound.", commandId), e)); //$NON-NLS-1$ } } else { TasksUiInternal.displayStatus(title, new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, NLS.bind("The command with the id ''{0}'' does not exist.", commandId))); //$NON-NLS-1$ } } else { TasksUiInternal .displayStatus(title, new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, NLS.bind( "Command service is not available to execute command with the id ''{0}''.", //$NON-NLS-1$ commandId), new Exception())); } } else { TasksUiInternal.displayStatus(title, new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, NLS.bind("Handler service is not available to execute command with the id ''{0}''.", //$NON-NLS-1$ commandId), new Exception())); } } public static void activateTaskThroughCommand(ITask task) { try { TasksUiInternal.executeCommand(PlatformUI.getWorkbench(), "org.eclipse.mylyn.tasks.ui.command.activateSelectedTask", Messages.TasksUiInternal_Activate_Task, //$NON-NLS-1$ task, null); } catch (NotEnabledException e) { StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, NLS.bind("Failed to activate task ''{0}''.", task.getSummary()), e)); //$NON-NLS-1$ } } public static long getActiveTime(ITask task) { if (TasksUiInternal.isActivityTrackingEnabled()) { return TasksUiPlugin.getTaskActivityManager().getElapsedTime(task); } return 0; } public static String getTaskPrefix(String connectorKind) { AbstractRepositoryConnector connector = TasksUiPlugin.getConnector(connectorKind); if (connector != null) { String prefix = connector.getTaskIdPrefix(); // work around short prefixes which are not separated by space, e.g. "#" for Trac return (prefix.length() > 1) ? prefix + " " : prefix; //$NON-NLS-1$ } return ""; //$NON-NLS-1$ } public static void displayFrameworkError(String message) { RuntimeException exception = new RuntimeException(message); if (!CoreUtil.TEST_MODE) { StatusAdapter status = new StatusAdapter( new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, message, exception)); status.setProperty(IStatusAdapterConstants.TITLE_PROPERTY, "Framework Error"); //$NON-NLS-1$ StatusManager.getManager().handle(status, StatusManager.SHOW | StatusManager.LOG | StatusManager.BLOCK); } throw exception; } public static String getAuthenticatedUrl(TaskRepository repository, IRepositoryElement element) { Assert.isNotNull(repository); Assert.isNotNull(element); IRepositoryManager repositoryManager = TasksUi.getRepositoryManager(); AbstractRepositoryConnector connector = repositoryManager.getRepositoryConnector(repository.getConnectorKind()); if (connector != null) { URL authenticatedUrl = connector.getAuthenticatedUrl(repository, element); if (authenticatedUrl != null) { return authenticatedUrl.toString(); } else { String url = element.getUrl(); if (TasksUiInternal.isValidUrl(url)) { return url; } } } return null; } public static TaskRepository getRepository(IRepositoryElement element) { IRepositoryManager repositoryManager = TasksUi.getRepositoryManager(); TaskRepository repository = null; if (element instanceof ITask) { repository = repositoryManager.getRepository(((ITask) element).getConnectorKind(), ((ITask) element).getRepositoryUrl()); } else if (element instanceof IRepositoryQuery) { repository = repositoryManager.getRepository(((IRepositoryQuery) element).getConnectorKind(), ((IRepositoryQuery) element).getRepositoryUrl()); } return repository; } /** * Returns all the tasks in the given selection, or an empty list if the selection contains no tasks. */ public static List<ITask> getTasksFromSelection(ISelection selection) { Assert.isNotNull(selection); if (selection.isEmpty()) { return Collections.emptyList(); } List<ITask> tasks = new ArrayList<ITask>(); if (selection instanceof IStructuredSelection) { for (Object element : ((IStructuredSelection) selection).toList()) { ITask task = null; if (element instanceof ITask) { task = (ITask) element; } else if (element instanceof IAdaptable) { IAdaptable adaptable = (IAdaptable) element; task = (ITask) adaptable.getAdapter(ITask.class); } if (task != null) { tasks.add(task); } } } return tasks; } public static boolean shouldShowIncoming(ITask task) { SynchronizationState state = task.getSynchronizationState(); if ((state == SynchronizationState.INCOMING && !Boolean.valueOf(task.getAttribute(ITasksCoreConstants.ATTRIBUTE_TASK_SUPPRESS_INCOMING))) || state == SynchronizationState.INCOMING_NEW || state == SynchronizationState.CONFLICT) { return true; } return false; } public static TaskData computeTaskData(TaskData taskData, TaskHistory history, String revisionId, IProgressMonitor monitor) throws CoreException { TaskData newTaskData = TaskDataState.createCopy(taskData); List<TaskRevision> revisions = history.getRevisions(); Collections.reverse(revisions); TaskRevision lastRevision = null; for (TaskRevision revision : revisions) { for (Change change : revision.getChanges()) { TaskAttribute attribute = newTaskData.getRoot().getAttribute(change.getAttributeId()); if (attribute != null) { attribute.setValue(change.getRemoved()); } } // only apply changes up to this revision if (revisionId.equals(revision.getId())) { lastRevision = revision; break; } } if (lastRevision != null && lastRevision.getDate() != null) { // remove attachments and comments that are newer than lastRevision List<TaskAttribute> attributes = new ArrayList<TaskAttribute>( newTaskData.getRoot().getAttributes().values()); for (TaskAttribute attribute : attributes) { if (TaskAttribute.TYPE_COMMENT.equals(attribute.getMetaData().getType())) { TaskCommentMapper mapper = TaskCommentMapper.createFrom(attribute); if (mapper.getCreationDate() != null && mapper.getCreationDate().after(lastRevision.getDate())) { newTaskData.getRoot().removeAttribute(attribute.getId()); } } else if (TaskAttribute.TYPE_ATTACHMENT.equals(attribute.getMetaData().getType())) { TaskAttachmentMapper mapper = TaskAttachmentMapper.createFrom(attribute); if (mapper.getCreationDate() != null && mapper.getCreationDate().after(lastRevision.getDate())) { newTaskData.getRoot().removeAttribute(attribute.getId()); } } } } return newTaskData; } public static boolean canGetTaskHistory(ITask task) { TaskRepository repository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl()); AbstractRepositoryConnector connector = TasksUi.getRepositoryManager() .getRepositoryConnector(repository.getConnectorKind()); return connector.canGetTaskHistory(repository, task); } public static Account getAccount(TaskAttribute attribute) { Account account; if (TaskAttribute.TYPE_PERSON.equals(attribute.getMetaData().getType())) { IRepositoryPerson person = attribute.getTaskData().getAttributeMapper().getRepositoryPerson(attribute); account = Account.id(person.getPersonId()).name(person.getName()); } else { account = Account.id(attribute.getValue()); } TaskRepository repository = attribute.getTaskData().getAttributeMapper().getTaskRepository(); return account.kind(repository.getConnectorKind()).url(repository.getRepositoryUrl()); } public static boolean isActivityTrackingEnabled() { return TasksUiPlugin.getTaskActivityMonitor().isEnabled() && MonitorUiPlugin.getDefault().isActivityTrackingEnabled(); } public static TaskDropHandler getTaskDropHandler() { return taskDropHandler; } public static ImageDescriptor getIconFromStatusOfQuery(RepositoryQuery query) { ImageDescriptor image; boolean showError = false; Throwable exception = query.getStatus().getException(); showError = (query.getLastSynchronizedTimeStamp().equals("<never>") //$NON-NLS-1$ && ((RepositoryStatus.ERROR_IO == query.getStatus().getCode() && exception != null && exception instanceof SocketTimeoutException) || // // only when we change SocketTimeout or Eclipse.org change there timeout for long running Queries (RepositoryStatus.ERROR_NETWORK) == query.getStatus().getCode() && query.getStatus().getMessage().equals("Http error: Internal Server Error"))); //$NON-NLS-1$ if (showError) { image = CommonImages.OVERLAY_SYNC_ERROR; } else { image = CommonImages.OVERLAY_SYNC_WARNING; } return image; } public static synchronized IUndoContext getUndoContext() { if (undoContext == null) { undoContext = new ObjectUndoContext(new Object(), "Tasks Context"); //$NON-NLS-1$ } return undoContext; } /** * Deletes the given task from the Task List, the Task Context Store, and the Task Data Manager. * * @param task * the task to delete */ public static void deleteTask(ITask task) { TasksUiInternal.getTaskList().deleteTask(task); TasksUiPlugin.getContextStore().deleteContext(task); try { TasksUiPlugin.getTaskDataManager().deleteTaskData(task); } catch (CoreException e) { StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Failed to delete task data", e)); //$NON-NLS-1$ } } }