blob: 4986b3ac567fcd315b4da816d3eb5572a0600be1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 2015 Tasktop Technologies and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* https://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Tasktop Technologies - initial API and implementation
* Eugene Kuleshov - improvements
* David Green - fix for bug 244442
*******************************************************************************/
package org.eclipse.mylyn.tasks.ui;
import java.text.MessageFormat;
import java.util.Collections;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.IWizardPage;
import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery;
import org.eclipse.mylyn.internal.tasks.ui.Messages;
import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin;
import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.IRepositoryElement;
import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.ITaskComment;
import org.eclipse.mylyn.tasks.core.ITaskMapping;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.TaskAttachmentModel;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditor;
import org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput;
import org.eclipse.mylyn.tasks.ui.wizards.ITaskRepositoryPage;
import org.eclipse.mylyn.tasks.ui.wizards.ITaskSearchPage;
import org.eclipse.mylyn.tasks.ui.wizards.TaskAttachmentPage;
import org.eclipse.ui.IEditorInput;
/**
* Extend to provide connector-specific UI extensions. TODO: consider refactoring into extension points
*
* @author Mik Kersten
* @since 2.0
*/
public abstract class AbstractRepositoryConnectorUi {
private static final String LABEL_TASK_DEFAULT = Messages.AbstractRepositoryConnectorUi_Task;
private final boolean customNotificationHandling = false;
private final AbstractRepositoryConnector connector;
/**
* Connectors should provide a one-argument constructor that can be used to pass the connector into the connector UI
* in tests. Connectors must provide a default constructor so that they can be created via extension point.
*
* @param connector
* the task repository connector
* @noreference This method is not intended to be referenced by clients.
*/
public AbstractRepositoryConnectorUi(AbstractRepositoryConnector connector) {
this.connector = connector;
}
public AbstractRepositoryConnectorUi() {
this(null);
}
/**
* @return the unique type of the repository, e.g. "bugzilla"
*/
@NonNull
public abstract String getConnectorKind();
/**
* @param repository
* the repository to edit or {@code null} if creating a new repository
* @since 3.0
*/
@NonNull
public abstract ITaskRepositoryPage getSettingsPage(@Nullable TaskRepository repository);
/**
* @param repository
* @param queryToEdit
* can be null
* @since 3.0
*/
@NonNull
public abstract IWizard getQueryWizard(@NonNull TaskRepository repository, @Nullable IRepositoryQuery query);
/**
* @since 3.0
*/
@NonNull
public abstract IWizard getNewTaskWizard(@NonNull TaskRepository repository, @Nullable ITaskMapping selection);
/**
* Connectors can implement this method if they need to open a wizard dialog before opening a new subtask editor.
*
* @since 3.18
*/
@Nullable
public IWizard getNewSubTaskWizard(@NonNull TaskRepository taskRepository, @NonNull ITask parentTask) {
return null;
}
/**
* Override to return a custom task editor ID. If overriding this method the connector becomes responsible for
* showing the additional pages handled by the default task editor. As of Mylyn 2.0M2 these are the Planning and
* Context pages.
*
* @since 3.0
*/
@NonNull
public String getTaskEditorId(@NonNull ITask repositoryTask) {
return TaskEditor.ID_EDITOR;
}
/**
* Default implementation returns the standard {@link org.eclipse.mylyn.tasks.ui.editors.TaskEditorInput}. Override
* this method to return a custom task editor input. The connector author must ensure the corresponding editor is
* capable of opening this editor input and will likely need to override
* AbstractRepositoryConnectorUi.getTaskEditorId() as well.
*
* @param repository
* - task repository for which to construct an editor
* @param task
* - the task to edit
* @since 3.4
*/
@NonNull
public IEditorInput getTaskEditorInput(@NonNull TaskRepository repository, @NonNull ITask task) {
return new TaskEditorInput(repository, task);
}
public abstract boolean hasSearchPage();
/**
* Contributions to the UI legend.
*
* @deprecated use {@link #getLegendElements()} instead
*/
@Deprecated
@NonNull
public List<ITask> getLegendItems() {
return Collections.emptyList();
}
/**
* Contributions to the UI legend.
*
* @since 3.0
*/
@NonNull
public List<LegendElement> getLegendElements() {
return Collections.emptyList();
}
/**
* @param repositoryTask
* can be null
* @since 3.0
*/
@NonNull
public String getTaskKindLabel(@Nullable ITask task) {
return LABEL_TASK_DEFAULT;
}
/**
* Connector-specific task icons. Not recommended to override unless providing custom icons and kind overlays. For
* connectors that have a decorator that they want to reuse, the connector can maintain a reference to the label
* provider and get the descriptor from the images it returns.
*
* @since 3.0
*/
@Nullable
public ImageDescriptor getImageDescriptor(@NonNull IRepositoryElement element) {
if (element instanceof RepositoryQuery) {
return ((RepositoryQuery) element).getAutoUpdate() ? TasksUiImages.QUERY : TasksUiImages.QUERY_OFFLINE;
} else if (element instanceof ITask) {
ITask task = (ITask) element;
TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(task.getRepositoryUrl());
if (repository != null && connector != null && connector.isOwnedByUser(repository, task)) {
return TasksUiImages.TASK_OWNED;
}
return TasksUiImages.TASK;
} else {
return null;
}
}
/**
* Task kind overlay, recommended to override with connector-specific overlay.
*
* @since 3.0
*/
@Nullable
public ImageDescriptor getTaskKindOverlay(@NonNull ITask task) {
return null;
}
/**
* Connector-specific priority icons. Not recommended to override since priority icons are used elsewhere in the
* Task List UI (e.g. filter selection in view menu).
*
* @since 3.0
*/
@NonNull
public ImageDescriptor getTaskPriorityOverlay(@NonNull ITask task) {
return TasksUiInternal.getPriorityImage(task);
}
/**
* This method is not used anymore.
*
* @return returns null
*/
@Deprecated
@Nullable
public IWizard getAddExistingTaskWizard(@Nullable TaskRepository repository) {
return null;
}
/**
* @since 3.0
*/
@Nullable
public ITaskSearchPage getSearchPage(@NonNull TaskRepository repository, @Nullable IStructuredSelection selection) {
return null;
}
/**
* Override to return a URL that provides the user with an account creation page for the repository
*
* @param taskRepository
* TODO
*/
@Nullable
public String getAccountCreationUrl(@NonNull TaskRepository taskRepository) {
return null;
}
/**
* Override to return a URL that provides the user with an account management page for the repository
*
* @param taskRepository
* TODO
*/
@Nullable
public String getAccountManagementUrl(@NonNull TaskRepository taskRepository) {
return null;
}
/**
* Override to return a URL that provides the user with a history page for the task.
*
* @return a url of a page for the history of the task; null, if no history url is available
* @since 3.0
*/
@Nullable
public String getTaskHistoryUrl(@NonNull TaskRepository taskRepository, @NonNull ITask task) {
return null;
}
/**
* Override to return a specific textual reference to a comment, e.g. by default this method returns
* <code>In reply to comment #12</code> for a reply to comment 12. This text is used when generating replies to
* comments.
*
* @return the reply text with a reference to <code>taskComment</code>; null, if no reference is available
* @since 3.0
*/
@Nullable
public String getReplyText(@NonNull TaskRepository taskRepository, @NonNull ITask task,
@Nullable ITaskComment taskComment, boolean includeTask) {
if (taskComment == null) {
return Messages.AbstractRepositoryConnectorUi_InReplyToDescription;
} else if (includeTask) {
return MessageFormat.format(Messages.AbstractRepositoryConnectorUi_InReplyToTaskAndComment,
task.getTaskKey(), taskComment.getNumber());
} else {
return MessageFormat.format(Messages.AbstractRepositoryConnectorUi_InReplyToComment,
taskComment.getNumber());
}
}
/**
* Returns an array of hyperlinks that link to tasks within <code>text</code>. If <code>index</code> is != -1
* clients may limit the results to hyperlinks found at <code>index</code>. It is legal for clients to always return
* all results.
*
* @param repository
* the task repository, never <code>null</code>
* @param text
* the line of text
* @param index
* the index within <code>text</code>, if -1 return all hyperlinks found in text
* @param textOffset
* the offset of <code>text</code>
* @return an array of hyperlinks, or null if no hyperlinks were found
* @since 2.0
* @deprecated use {@link #findHyperlinks(TaskRepository, ITask, String, int, int)} instead
*/
@Deprecated
@Nullable
public IHyperlink[] findHyperlinks(@NonNull TaskRepository repository, @NonNull String text, int index,
int textOffset) {
return null;
}
/**
* @since 3.0
*/
public boolean hasCustomNotifications() {
return customNotificationHandling;
}
/**
* @since 3.0
* @return true if connector doesn't support non-grouping (flattening) of subtasks
*/
public boolean hasStrictSubtaskHierarchy() {
return false;
}
/**
* @since 3.0
*/
@NonNull
public IWizardPage getTaskAttachmentPage(@NonNull TaskAttachmentModel model) {
return new TaskAttachmentPage(model);
}
/**
* Returns an array of hyperlinks that link to tasks within <code>text</code>. If <code>index</code> is != -1
* clients may limit the results to hyperlinks found at <code>index</code>. It is legal for clients to always return
* all results.
*
* @param repository
* the task repository, never <code>null</code>
* @param task
* the task, can be <code>null</code>
* @param text
* the line of text
* @param index
* the index within <code>text</code>, if -1 return all hyperlinks found in text
* @param textOffset
* the offset of <code>text</code>
* @return an array of hyperlinks, or null if no hyperlinks were found
* @since 3.4
*/
@Nullable
public IHyperlink[] findHyperlinks(@NonNull TaskRepository repository, @Nullable ITask task, @NonNull String text,
int index, int textOffset) {
return findHyperlinks(repository, text, index, textOffset);
}
/**
* @return the {@link AbstractRepositoryConnector } that is associated to this instance
* @since 3.14
*/
public AbstractRepositoryConnector getConnector() {
return connector;
}
}