blob: eddebe82a3cc60829f8cffbaf1e7e05071a0f10a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2008 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.tasks.ui;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Calendar;
import java.util.List;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.internal.tasks.core.AbstractTask;
import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants;
import org.eclipse.mylyn.internal.tasks.core.LocalTask;
import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants;
import org.eclipse.mylyn.internal.tasks.ui.Messages;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiMessages;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.internal.tasks.ui.views.TaskListView;
import org.eclipse.mylyn.internal.tasks.ui.views.TaskRepositoriesView;
import org.eclipse.mylyn.internal.tasks.ui.wizards.EditRepositoryWizard;
import org.eclipse.mylyn.internal.tasks.ui.wizards.MultiRepositoryAwareWizard;
import org.eclipse.mylyn.internal.tasks.ui.wizards.NewLocalTaskWizard;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITaskMapping;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.ITask.SynchronizationState;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
import org.eclipse.mylyn.tasks.ui.wizards.TaskRepositoryWizardDialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.browser.IWebBrowser;
import org.eclipse.ui.browser.IWorkbenchBrowserSupport;
import org.eclipse.ui.internal.browser.WebBrowserPreference;
import org.eclipse.ui.internal.browser.WorkbenchBrowserSupport;
/**
* @noextend This class is not intended to be subclassed by clients.
* @noinstantiate This class is not intended to be instantiated by clients.
* @since 2.0
* @author Mik Kersten
* @author Steffen Pingel
* @author Shawn Minto
*/
public class TasksUiUtil {
/**
* Flag that is passed along to the workbench browser support when a task is opened in a browser because no rich
* editor was available.
*
* @see #openTask(String)
*/
public static final int FLAG_NO_RICH_EDITOR = 1 << 17;
/**
* @since 3.0
*/
public static ITask createOutgoingNewTask(String connectorKind, String repositoryUrl) {
Assert.isNotNull(connectorKind);
LocalTask task = TasksUiInternal.createNewLocalTask(null);
task.setAttribute(ITasksCoreConstants.ATTRIBUTE_OUTGOING_NEW_CONNECTOR_KIND, connectorKind);
task.setAttribute(ITasksCoreConstants.ATTRIBUTE_OUTGOING_NEW_REPOSITORY_URL, repositoryUrl);
task.setSynchronizationState(SynchronizationState.OUTGOING_NEW);
return task;
}
/**
* @since 3.0
*/
public static boolean isOutgoingNewTask(ITask task, String connectorKind) {
Assert.isNotNull(task);
Assert.isNotNull(connectorKind);
return connectorKind.equals(task.getAttribute(ITasksCoreConstants.ATTRIBUTE_OUTGOING_NEW_CONNECTOR_KIND));
}
/**
* @since 3.1
*/
public static TaskRepository getOutgoingNewTaskRepository(ITask task) {
Assert.isNotNull(task);
String connectorKind = task.getAttribute(ITasksCoreConstants.ATTRIBUTE_OUTGOING_NEW_CONNECTOR_KIND);
String repositoryUrl = task.getAttribute(ITasksCoreConstants.ATTRIBUTE_OUTGOING_NEW_REPOSITORY_URL);
if (connectorKind != null && repositoryUrl != null) {
return TasksUi.getRepositoryManager().getRepository(connectorKind, repositoryUrl);
}
return null;
}
public static TaskRepository getSelectedRepository() {
return getSelectedRepository(null);
}
/**
* Will use the workbench window's selection if viewer's selection is null
*/
public static TaskRepository getSelectedRepository(StructuredViewer viewer) {
IStructuredSelection selection = null;
if (viewer != null) {
selection = (IStructuredSelection) viewer.getSelection();
}
if (selection == null || selection.isEmpty()) {
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
ISelection windowSelection = window.getSelectionService().getSelection();
if (windowSelection instanceof IStructuredSelection) {
selection = (IStructuredSelection) windowSelection;
}
}
if (selection == null) {
return null;
}
Object element = selection.getFirstElement();
if (element instanceof TaskRepository) {
return (TaskRepository) selection.getFirstElement();
} else if (element instanceof IRepositoryQuery) {
IRepositoryQuery query = (IRepositoryQuery) element;
return TasksUi.getRepositoryManager().getRepository(query.getConnectorKind(), query.getRepositoryUrl());
} else if (element instanceof ITask) {
ITask task = (ITask) element;
return TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(), task.getRepositoryUrl());
} else if (element instanceof IResource) {
IResource resource = (IResource) element;
return TasksUiPlugin.getDefault().getRepositoryForResource(resource);
} else if (element instanceof IAdaptable) {
IAdaptable adaptable = (IAdaptable) element;
IResource resource = (IResource) adaptable.getAdapter(IResource.class);
if (resource != null) {
return TasksUiPlugin.getDefault().getRepositoryForResource(resource);
} else {
ITask task = (ITask) adaptable.getAdapter(AbstractTask.class);
if (task != null) {
ITask rtask = task;
return TasksUi.getRepositoryManager().getRepository(rtask.getConnectorKind(),
rtask.getRepositoryUrl());
}
}
}
// TODO mapping between LogEntry.pliginId and repositories
// TODO handle other selection types
return null;
}
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;
}
public static IEditorPart openEditor(IEditorInput input, String editorId, IWorkbenchPage page) {
if (page == null) {
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (window != null) {
page = window.getActivePage();
}
}
if (page == null) {
StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Unable to open editor for \"" + input //$NON-NLS-1$
+ "\": no active workbench window")); //$NON-NLS-1$
return null;
}
try {
return page.openEditor(input, editorId);
} catch (PartInitException e) {
StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Open for editor failed: " + input //$NON-NLS-1$
+ ", taskId: " + editorId, e)); //$NON-NLS-1$
}
return null;
}
public static int openEditRepositoryWizard(TaskRepository repository) {
AbstractRepositoryConnector connector = TasksUi.getRepositoryManager().getRepositoryConnector(
repository.getConnectorKind());
if (connector == null || !connector.isUserManaged()) {
return Window.CANCEL;
}
try {
EditRepositoryWizard wizard = new EditRepositoryWizard(repository);
Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
if (shell != null && !shell.isDisposed()) {
WizardDialog dialog = new TaskRepositoryWizardDialog(shell, wizard);
dialog.create();
dialog.setBlockOnOpen(true);
if (dialog.open() == Window.CANCEL) {
dialog.close();
return Window.CANCEL;
}
}
if (TaskRepositoriesView.getFromActivePerspective() != null) {
TaskRepositoriesView.getFromActivePerspective().getViewer().refresh();
}
} catch (Exception e) {
StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, e.getMessage(), e));
}
return Window.OK;
}
/**
* @since 3.0
*/
public static boolean openNewLocalTaskEditor(Shell shell, ITaskMapping taskSelection) {
return openNewTaskEditor(shell, new NewLocalTaskWizard(taskSelection), taskSelection);
}
private static boolean openNewTaskEditor(Shell shell, IWizard wizard, ITaskMapping taskSelection) {
WizardDialog dialog = new WizardDialog(shell, wizard);
dialog.setBlockOnOpen(true);
// make sure the wizard has created its pages
dialog.create();
if (!(wizard instanceof MultiRepositoryAwareWizard) && wizard.canFinish()) {
wizard.performFinish();
return true;
}
int result = dialog.open();
return result == Window.OK;
}
/**
* @since 3.0
*/
public static boolean openNewTaskEditor(Shell shell, ITaskMapping taskSelection, TaskRepository taskRepository) {
final IWizard wizard;
List<TaskRepository> repositories = TasksUi.getRepositoryManager().getAllRepositories();
if (taskRepository == null && repositories.size() == 1) {
// only the Local repository connector is available
taskRepository = repositories.get(0);
}
if (taskRepository != null) {
AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(taskRepository.getConnectorKind());
wizard = connectorUi.getNewTaskWizard(taskRepository, taskSelection);
} else {
wizard = TasksUiInternal.createNewTaskWizard(taskSelection);
}
return openNewTaskEditor(shell, wizard, taskSelection);
}
/**
* Either pass in a repository and taskId, or fullUrl, or all of them
*
* @deprecated Use {@link #openTask(String,String,String)} instead
*/
@Deprecated
public static boolean openRepositoryTask(String repositoryUrl, String taskId, String fullUrl) {
return openTask(repositoryUrl, taskId, fullUrl);
}
/**
* @deprecated Use {@link #openTask(TaskRepository,String)} instead
*/
@Deprecated
public static boolean openRepositoryTask(TaskRepository repository, String taskId) {
return openTask(repository, taskId);
}
/**
* @since 3.0
*/
public static boolean openTask(ITask task) {
Assert.isNotNull(task);
IWorkbenchWindow window = PlatformUI.getWorkbench().getActiveWorkbenchWindow();
if (window != null) {
boolean openWithBrowser = !TasksUiPlugin.getDefault().getPreferenceStore().getBoolean(
ITasksUiPreferenceConstants.EDITOR_TASKS_RICH);
if (openWithBrowser) {
openUrl(task.getUrl());
return true;
} else {
TaskRepository taskRepository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(),
task.getRepositoryUrl());
IEditorInput editorInput = new TaskEditorInput(taskRepository, task);
boolean wasOpen = refreshEditorContentsIfOpen(task, editorInput);
if (wasOpen) {
synchronizeTask(taskRepository, task);
return true;
} else {
IWorkbenchPage page = window.getActivePage();
IEditorPart editor = openEditor(editorInput, getTaskEditorId(task), page);
if (editor != null) {
synchronizeTask(taskRepository, task);
return true;
}
}
}
} 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;
}
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.synchronizeTask(connector, task, false, null);
}
}
/**
* Resolves a rich editor for the task if available.
*
* @since 3.0
*/
public static void openTask(String url) {
AbstractTask task = TasksUiInternal.getTaskByUrl(url);
if (task != null && !(task instanceof LocalTask)) {
openTask(task);
} else {
boolean opened = false;
if (url != null) {
AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager()
.getConnectorForRepositoryTaskUrl(url);
if (connector != null) {
String repositoryUrl = connector.getRepositoryUrlFromTaskUrl(url);
if (repositoryUrl != null) {
String id = connector.getTaskIdFromTaskUrl(url);
if (id != null) {
TaskRepository repository = TasksUi.getRepositoryManager().getRepository(
connector.getConnectorKind(), repositoryUrl);
if (repository != null) {
opened = openTask(repository, id);
}
}
}
}
}
if (!opened) {
openUrl(url, 0);
}
}
}
/**
* Either pass in a repository and taskId, or fullUrl, or all of them
*
* @since 3.0
*/
public static boolean openTask(String repositoryUrl, String taskId, String fullUrl) {
AbstractTask task = TasksUiInternal.getTask(repositoryUrl, taskId, fullUrl);
if (task != null) {
return TasksUiUtil.openTask(task);
}
boolean opened = false;
AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getConnectorForRepositoryTaskUrl(
fullUrl);
if (connector != null) {
if (repositoryUrl != null && taskId != null) {
opened = TasksUiInternal.openRepositoryTask(connector.getConnectorKind(), repositoryUrl, taskId);
} else {
repositoryUrl = connector.getRepositoryUrlFromTaskUrl(fullUrl);
taskId = connector.getTaskIdFromTaskUrl(fullUrl);
if (repositoryUrl != null && taskId != null) {
opened = TasksUiInternal.openRepositoryTask(connector.getConnectorKind(), repositoryUrl, taskId);
}
}
}
if (!opened) {
TasksUiUtil.openUrl(fullUrl);
}
return true;
}
/**
* @since 3.0
*/
public static boolean openTask(TaskRepository repository, String taskId) {
Assert.isNotNull(repository);
Assert.isNotNull(taskId);
AbstractTask task = (AbstractTask) TasksUiInternal.getTaskList().getTask(repository.getRepositoryUrl(), taskId);
if (task == null) {
task = TasksUiPlugin.getTaskList().getTaskByKey(repository.getRepositoryUrl(), taskId);
}
if (task != null) {
return TasksUiUtil.openTask(task);
} else {
AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(repository.getConnectorKind());
if (connectorUi != null) {
try {
return TasksUiInternal.openRepositoryTask(connectorUi.getConnectorKind(),
repository.getRepositoryUrl(), taskId);
} catch (Exception e) {
StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN,
"Internal error while opening repository task", e)); //$NON-NLS-1$
}
}
}
return false;
}
/**
* @since 3.0
*
* TODO: move to commons
*/
public static void openUrl(String location) {
openUrl(location, FLAG_NO_RICH_EDITOR);
}
private static void openUrl(String location, int customFlags) {
try {
URL url = null;
if (location != null) {
url = new URL(location);
}
if (WebBrowserPreference.getBrowserChoice() == WebBrowserPreference.EXTERNAL) {
try {
IWorkbenchBrowserSupport support = PlatformUI.getWorkbench().getBrowserSupport();
support.getExternalBrowser().openURL(url);
} catch (Exception e) {
StatusHandler.fail(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not open task url", e)); //$NON-NLS-1$
}
} else {
IWebBrowser browser = null;
int flags = customFlags;
if (WorkbenchBrowserSupport.getInstance().isInternalWebBrowserAvailable()) {
flags |= IWorkbenchBrowserSupport.AS_EDITOR | IWorkbenchBrowserSupport.LOCATION_BAR
| IWorkbenchBrowserSupport.NAVIGATION_BAR;
} else {
flags |= IWorkbenchBrowserSupport.AS_EXTERNAL | IWorkbenchBrowserSupport.LOCATION_BAR
| IWorkbenchBrowserSupport.NAVIGATION_BAR;
}
String generatedId = "org.eclipse.mylyn.web.browser-" + Calendar.getInstance().getTimeInMillis(); //$NON-NLS-1$
browser = WorkbenchBrowserSupport.getInstance().createBrowser(flags, generatedId, null, null);
browser.openURL(url);
}
} catch (PartInitException e) {
MessageDialog.openError(Display.getDefault().getActiveShell(), Messages.TasksUiUtil_Browser_init_error,
Messages.TasksUiUtil_Browser_could_not_be_initiated);
} catch (MalformedURLException e) {
if (location != null && location.trim().equals("")) { //$NON-NLS-1$
MessageDialog.openInformation(Display.getDefault().getActiveShell(), TasksUiMessages.DIALOG_EDITOR,
Messages.TasksUiUtil_No_URL_to_open + location);
} else {
MessageDialog.openInformation(Display.getDefault().getActiveShell(), TasksUiMessages.DIALOG_EDITOR,
Messages.TasksUiUtil_Could_not_open_URL_ + location);
}
}
}
/**
* If task is already open and has incoming, must force refresh in place
*/
private static boolean 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 true;
}
}
}
}
return false;
}
/**
* @since 3.0
*/
public static IViewPart openTasksViewInActivePerspective() {
try {
return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().showView(TaskListView.ID);
} catch (Exception e) {
StatusHandler.log(new Status(IStatus.ERROR, TasksUiPlugin.ID_PLUGIN, "Could not show Task List view", e)); //$NON-NLS-1$
return null;
}
}
}