| /******************************************************************************* |
| * 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 |
| * Kevin Barnes, IBM Corporation - fix for bug 277974 |
| * Robert Munteanu - fix for bug 350771 |
| *******************************************************************************/ |
| |
| package org.eclipse.mylyn.internal.tasks.ui.views; |
| |
| import java.util.ArrayList; |
| import java.util.Calendar; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.List; |
| |
| import org.apache.commons.lang.StringUtils; |
| import org.eclipse.core.runtime.IAdaptable; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.jface.action.LegacyActionTools; |
| import org.eclipse.jface.layout.GridDataFactory; |
| import org.eclipse.jface.resource.ImageDescriptor; |
| import org.eclipse.mylyn.commons.core.DateUtil; |
| import org.eclipse.mylyn.commons.ui.CommonImages; |
| import org.eclipse.mylyn.commons.ui.GradientToolTip; |
| import org.eclipse.mylyn.commons.ui.PlatformUiUtil; |
| import org.eclipse.mylyn.commons.ui.compatibility.CommonFonts; |
| import org.eclipse.mylyn.commons.workbench.forms.ScalingHyperlink; |
| import org.eclipse.mylyn.internal.tasks.core.AbstractTask; |
| import org.eclipse.mylyn.internal.tasks.core.AbstractTaskContainer; |
| import org.eclipse.mylyn.internal.tasks.core.DateRange; |
| import org.eclipse.mylyn.internal.tasks.core.ITasksCoreConstants; |
| import org.eclipse.mylyn.internal.tasks.core.LocalTask; |
| import org.eclipse.mylyn.internal.tasks.core.RepositoryQuery; |
| import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer; |
| import org.eclipse.mylyn.internal.tasks.core.TaskCategory; |
| import org.eclipse.mylyn.internal.tasks.core.UncategorizedTaskContainer; |
| import org.eclipse.mylyn.internal.tasks.core.UnmatchedTaskContainer; |
| import org.eclipse.mylyn.internal.tasks.ui.AbstractTaskListFilter; |
| import org.eclipse.mylyn.internal.tasks.ui.ITasksUiPreferenceConstants; |
| import org.eclipse.mylyn.internal.tasks.ui.TaskScalingHyperlink; |
| import org.eclipse.mylyn.internal.tasks.ui.TasksUiPlugin; |
| import org.eclipse.mylyn.internal.tasks.ui.notifications.TaskListNotifier; |
| import org.eclipse.mylyn.internal.tasks.ui.util.TasksUiInternal; |
| import org.eclipse.mylyn.internal.tasks.ui.views.TaskScheduleContentProvider.StateTaskContainer; |
| 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.ITask.SynchronizationState; |
| import org.eclipse.mylyn.tasks.core.ITaskContainer; |
| import org.eclipse.mylyn.tasks.core.RepositoryStatus; |
| import org.eclipse.mylyn.tasks.core.TaskRepository; |
| import org.eclipse.mylyn.tasks.ui.AbstractRepositoryConnectorUi; |
| import org.eclipse.mylyn.tasks.ui.TaskElementLabelProvider; |
| import org.eclipse.mylyn.tasks.ui.TasksUi; |
| import org.eclipse.mylyn.tasks.ui.TasksUiImages; |
| import org.eclipse.osgi.util.NLS; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.graphics.Color; |
| import org.eclipse.swt.graphics.Image; |
| import org.eclipse.swt.graphics.Point; |
| import org.eclipse.swt.graphics.Rectangle; |
| import org.eclipse.swt.layout.GridData; |
| import org.eclipse.swt.layout.GridLayout; |
| import org.eclipse.swt.widgets.Composite; |
| import org.eclipse.swt.widgets.Control; |
| import org.eclipse.swt.widgets.Event; |
| import org.eclipse.swt.widgets.Label; |
| import org.eclipse.swt.widgets.Scrollable; |
| import org.eclipse.swt.widgets.Table; |
| import org.eclipse.swt.widgets.TableItem; |
| import org.eclipse.swt.widgets.ToolBar; |
| import org.eclipse.swt.widgets.ToolItem; |
| import org.eclipse.swt.widgets.Tree; |
| import org.eclipse.swt.widgets.TreeItem; |
| import org.eclipse.swt.widgets.Widget; |
| import org.eclipse.ui.forms.IFormColors; |
| |
| import com.google.common.base.Strings; |
| import com.ibm.icu.text.DateFormat; |
| import com.ibm.icu.text.SimpleDateFormat; |
| |
| /** |
| * @author Mik Kersten |
| * @author Eric Booth |
| * @author Leo Dos Santos |
| * @author Steffen Pingel |
| */ |
| public class TaskListToolTip extends GradientToolTip { |
| |
| public static interface TaskListToolTipListener { |
| |
| void toolTipHidden(Event event); |
| |
| } |
| |
| private final static int MAX_WIDTH = 600; |
| |
| private final static int X_SHIFT = PlatformUiUtil.getToolTipXShift(); |
| |
| private final static int Y_SHIFT = 1; |
| |
| private IRepositoryElement currentTipElement; |
| |
| private final List<TaskListToolTipListener> listeners = new ArrayList<TaskListToolTipListener>(); |
| |
| private boolean visible; |
| |
| private boolean triggeredByMouse = true; |
| |
| private final Control control; |
| |
| private final Color titleColor; |
| |
| private boolean enabled; |
| |
| public TaskListToolTip(Control control) { |
| super(control); |
| this.control = control; |
| setEnabled(true); |
| setShift(new Point(1, 1)); |
| titleColor = TasksUiPlugin.getDefault().getFormColors(control.getDisplay()).getColor(IFormColors.TITLE); |
| } |
| |
| public void dispose() { |
| hide(); |
| } |
| |
| @Override |
| protected void afterHideToolTip(Event event) { |
| triggeredByMouse = true; |
| visible = false; |
| for (TaskListToolTipListener listener : listeners.toArray(new TaskListToolTipListener[0])) { |
| listener.toolTipHidden(event); |
| } |
| } |
| |
| public void addTaskListToolTipListener(TaskListToolTipListener listener) { |
| listeners.add(listener); |
| } |
| |
| public void removeTaskListToolTipListener(TaskListToolTipListener listener) { |
| listeners.remove(listener); |
| } |
| |
| private IRepositoryElement getTaskListElement(Object hoverObject) { |
| if (hoverObject instanceof ScalingHyperlink) { |
| TaskScalingHyperlink hyperlink = (TaskScalingHyperlink) hoverObject; |
| return hyperlink.getTask(); |
| } else if (hoverObject instanceof Widget) { |
| Object data = ((Widget) hoverObject).getData(); |
| if (data != null) { |
| if (data instanceof ITaskContainer) { |
| return (IRepositoryElement) data; |
| } else if (data instanceof IAdaptable) { |
| return (IRepositoryElement) ((IAdaptable) data).getAdapter(AbstractTaskContainer.class); |
| } |
| } |
| } |
| return null; |
| } |
| |
| private String getTitleText(IRepositoryElement element) { |
| if (element instanceof ScheduledTaskContainer) { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(((ScheduledTaskContainer) element).getShortSummary()); |
| if (!(element instanceof StateTaskContainer)) { |
| Calendar start = ((ScheduledTaskContainer) element).getDateRange().getStartDate(); |
| sb.append(" - "); //$NON-NLS-1$ |
| sb.append(DateFormat.getDateInstance(DateFormat.LONG).format(start.getTime())); |
| } |
| return sb.toString(); |
| } else if (element instanceof IRepositoryQuery) { |
| IRepositoryQuery query = (IRepositoryQuery) element; |
| StringBuilder sb = new StringBuilder(); |
| sb.append(element.getSummary()); |
| sb.append(" ["); //$NON-NLS-1$ |
| sb.append(getRepositoryLabel(query.getConnectorKind(), query.getRepositoryUrl())); |
| sb.append("]"); //$NON-NLS-1$ |
| return sb.toString(); |
| } else if (element instanceof ITask) { |
| return ((ITask) element).getSummary(); |
| } else { |
| return new TaskElementLabelProvider(false).getText(element); |
| } |
| } |
| |
| private String getDetailsText(IRepositoryElement element) { |
| if (element instanceof ScheduledTaskContainer) { |
| ScheduledTaskContainer container = (ScheduledTaskContainer) element; |
| int estimateTotal = 0; |
| long activeTotal = 0; |
| for (ITask child : container.getChildren()) { |
| if (child instanceof AbstractTask) { |
| estimateTotal += ((AbstractTask) child).getEstimatedTimeHours(); |
| activeTotal += TasksUiPlugin.getTaskActivityManager().getElapsedTime(child, |
| container.getDateRange()); |
| } |
| } |
| StringBuilder sb = new StringBuilder(); |
| appendEstimateAndActive(sb, estimateTotal, activeTotal); |
| return sb.toString(); |
| } else if (element instanceof ITask) { |
| ITask task = (ITask) element; |
| StringBuilder sb = new StringBuilder(); |
| AbstractRepositoryConnectorUi connectorUi = TasksUiPlugin.getConnectorUi(task.getConnectorKind()); |
| String kindLabel = null; |
| if (connectorUi != null) { |
| kindLabel = connectorUi.getTaskKindLabel(task); |
| sb.append(kindLabel); |
| } |
| String key = task.getTaskKey(); |
| if (key != null) { |
| sb.append(" "); //$NON-NLS-1$ |
| sb.append(key); |
| } |
| String taskKind = task.getTaskKind(); |
| if (taskKind != null && taskKind.length() > 0 && !taskKind.equals(kindLabel)) { |
| sb.append(" ("); //$NON-NLS-1$ |
| sb.append(taskKind); |
| sb.append(") "); //$NON-NLS-1$ |
| } |
| sb.append(", "); //$NON-NLS-1$ |
| String priorityLabel = task.getAttribute(ITasksCoreConstants.ATTRIBUTE_PRIORITY_LABEL); |
| if (Strings.isNullOrEmpty(priorityLabel)) { |
| priorityLabel = task.getPriority(); |
| } |
| sb.append(priorityLabel); |
| sb.append(" ["); //$NON-NLS-1$ |
| sb.append(getRepositoryLabel(task.getConnectorKind(), task.getRepositoryUrl())); |
| sb.append("]"); //$NON-NLS-1$ |
| return sb.toString(); |
| } else { |
| return null; |
| } |
| } |
| |
| private void appendEstimateAndActive(StringBuilder sb, int estimateTotal, long activeTotal) { |
| sb.append(NLS.bind(Messages.TaskListToolTip_Estimate, estimateTotal)); |
| sb.append("\n"); //$NON-NLS-1$ |
| if (TasksUiInternal.isActivityTrackingEnabled()) { |
| sb.append(NLS.bind(Messages.TaskListToolTip_Active_X, DateUtil.getFormattedDurationShort(activeTotal))); |
| sb.append("\n"); //$NON-NLS-1$ |
| } |
| } |
| |
| private String getRepositoryLabel(String repositoryKind, String repositoryUrl) { |
| TaskRepository repository = TasksUi.getRepositoryManager().getRepository(repositoryKind, repositoryUrl); |
| if (repository != null) { |
| String label = repository.getRepositoryLabel(); |
| if (label.indexOf("//") != -1) { //$NON-NLS-1$ |
| return label.substring((repository.getRepositoryUrl().indexOf("//") + 2)); //$NON-NLS-1$ |
| } |
| return label; |
| } |
| return ""; //$NON-NLS-1$ |
| } |
| |
| private String getOwnerText(IRepositoryElement element) { |
| if (element instanceof ITask && !(element instanceof LocalTask)) { |
| String owner = ((ITask) element).getOwner(); |
| if (!Strings.isNullOrEmpty(owner)) { |
| return NLS.bind(Messages.TaskListToolTip_Assigned_to_X, owner); |
| } |
| return NLS.bind(Messages.TaskListToolTip_Assigned_to_X, Messages.TaskListToolTip_Unassigned); |
| } |
| return null; |
| } |
| |
| private Image getOwnerImage(IRepositoryElement element) { |
| if (element instanceof ITask && !(element instanceof LocalTask)) { |
| ITask task = (ITask) element; |
| AbstractRepositoryConnector connector = TasksUi.getRepositoryConnector(task.getConnectorKind()); |
| TaskRepository repository = TasksUi.getRepositoryManager().getRepository(task.getConnectorKind(), |
| task.getRepositoryUrl()); |
| if (connector.isOwnedByUser(repository, task)) { |
| return CommonImages.getImage(CommonImages.PERSON_ME); |
| } else { |
| return CommonImages.getImage(CommonImages.PERSON); |
| } |
| } |
| return null; |
| } |
| |
| private String getExtendedToolTipText(IRepositoryElement element) { |
| if (element instanceof ITask) { |
| ITask task = (ITask) element; |
| String extendedToolTipInfo = task.getAttribute(ITasksCoreConstants.ATTRIBUTE_TASK_EXTENDED_TOOLTIP); |
| if (extendedToolTipInfo != null && extendedToolTipInfo.length() > 0) { |
| return extendedToolTipInfo; |
| } |
| } |
| return null; |
| } |
| |
| private String getActivityText(IRepositoryElement element) { |
| if (element instanceof AbstractTask) { |
| AbstractTask task = (AbstractTask) element; |
| |
| StringBuilder sb = new StringBuilder(); |
| |
| Date dueDate = task.getDueDate(); |
| if (dueDate != null) { |
| sb.append(NLS.bind(Messages.TaskListToolTip_Due, |
| new Object[] { new SimpleDateFormat("E").format(dueDate), //$NON-NLS-1$ |
| DateFormat.getDateInstance(DateFormat.LONG).format(dueDate), |
| DateFormat.getTimeInstance(DateFormat.SHORT).format(dueDate) })); |
| sb.append("\n"); //$NON-NLS-1$ |
| } |
| |
| DateRange scheduledDate = task.getScheduledForDate(); |
| if (scheduledDate != null) { |
| sb.append(NLS.bind(Messages.TaskListToolTip_Scheduled, scheduledDate.toString())); |
| sb.append("\n"); //$NON-NLS-1$ |
| } |
| long elapsed = TasksUiPlugin.getTaskActivityManager().getElapsedTime(task); |
| appendEstimateAndActive(sb, task.getEstimatedTimeHours(), elapsed); |
| return sb.toString(); |
| } |
| return null; |
| } |
| |
| private String getIncomingText(IRepositoryElement element) { |
| String text = null; |
| if (element instanceof ITask) { |
| ITask task = (ITask) element; |
| if (task.getSynchronizationState().isIncoming()) { |
| text = task.getAttribute(TaskListNotifier.KEY_INCOMING_NOTIFICATION_TEXT); |
| if (Strings.isNullOrEmpty(text)) { |
| TaskListNotifier notifier = new TaskListNotifier(TasksUiPlugin.getTaskDataManager(), |
| TasksUiPlugin.getDefault().getSynchronizationManger()); |
| text = notifier.computeNotificationText(task); |
| } |
| } |
| } |
| return text; |
| } |
| |
| private ImageDescriptor getIncomingImage() { |
| ImageDescriptor incomingImage = CommonImages.OVERLAY_SYNC_INCOMMING; |
| if (currentTipElement instanceof ITask) { |
| ITask task = (ITask) currentTipElement; |
| if (task.getSynchronizationState() == SynchronizationState.INCOMING_NEW) { |
| incomingImage = CommonImages.OVERLAY_SYNC_INCOMMING_NEW; |
| } |
| } |
| return incomingImage; |
| } |
| |
| private String getSynchronizationStateText(IRepositoryElement element) { |
| if (element instanceof ITaskContainer) { |
| Collection<ITask> tasks = ((ITaskContainer) element).getChildren(); |
| if (tasks.size() > 0) { |
| int incoming = 0; |
| int outgoing = 0; |
| for (ITask task : tasks) { |
| if (task.getSynchronizationState().isIncoming()) { |
| incoming++; |
| } |
| if (task.getSynchronizationState().isOutgoing()) { |
| outgoing++; |
| } |
| } |
| return NLS.bind(Messages.TaskListToolTip_Incoming_Outgoing, new Object[] { incoming, outgoing }); |
| } |
| } |
| return null; |
| } |
| |
| private Image getStatusIcon(IRepositoryElement element) { |
| if (element instanceof RepositoryQuery) { |
| return CommonImages.getImage(TasksUiInternal.getIconFromStatusOfQuery((RepositoryQuery) element)); |
| } |
| return CommonImages.getImage(CommonImages.WARNING); |
| } |
| |
| private String getStatusText(IRepositoryElement element) { |
| IStatus status = null; |
| if (element instanceof AbstractTask) { |
| AbstractTask task = (AbstractTask) element; |
| status = task.getStatus(); |
| } else if (element instanceof IRepositoryQuery) { |
| RepositoryQuery query = (RepositoryQuery) element; |
| status = query.getStatus(); |
| } |
| |
| if (status != null) { |
| StringBuilder sb = new StringBuilder(); |
| sb.append(status.getMessage()); |
| if (status instanceof RepositoryStatus && ((RepositoryStatus) status).isHtmlMessage()) { |
| sb.append(Messages.TaskListToolTip_Please_synchronize_manually_for_full_error_message); |
| } |
| return sb.toString(); |
| } |
| |
| return null; |
| } |
| |
| @Override |
| public Point getLocation(Point tipSize, Event event) { |
| Widget widget = getTipWidget(event); |
| if (widget != null) { |
| Rectangle bounds = getBounds(widget); |
| if (bounds != null) { |
| return control.toDisplay(bounds.x + X_SHIFT, bounds.y + bounds.height + Y_SHIFT); |
| } |
| } |
| return super.getLocation(tipSize, event); |
| } |
| |
| private ProgressData getProgressData(IRepositoryElement element) { |
| if (element instanceof ITaskContainer) { |
| Object[] children = new Object[0]; |
| |
| children = ((ITaskContainer) element).getChildren().toArray(); |
| |
| int total = children.length; |
| if (total > 0) { |
| int completed = 0; |
| for (ITask task : ((ITaskContainer) element).getChildren()) { |
| if (task.isCompleted()) { |
| completed++; |
| } |
| } |
| String text = NLS.bind(Messages.TaskListToolTip_Total_Complete_Incomplete, new Object[] { // |
| total, completed, (total - completed) }); |
| return new ProgressData(completed, total, text); |
| } |
| } |
| return null; |
| } |
| |
| private Image getImage(IRepositoryElement element) { |
| if (element instanceof IRepositoryQuery) { |
| IRepositoryQuery query = (IRepositoryQuery) element; |
| TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(query.getRepositoryUrl()); |
| if (repository != null) { |
| return TasksUiPlugin.getDefault().getBrandManager().getBrandingIcon(repository); |
| } |
| return TasksUiPlugin.getDefault().getBrandManager().getDefaultBrandingIcon(query.getConnectorKind()); |
| } else if (element instanceof ITask) { |
| ITask task = (ITask) element; |
| TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(task.getRepositoryUrl()); |
| if (repository != null) { |
| return TasksUiPlugin.getDefault().getBrandManager().getBrandingIcon(repository); |
| } |
| return TasksUiPlugin.getDefault().getBrandManager().getDefaultBrandingIcon(task.getConnectorKind()); |
| } else if (element instanceof ScheduledTaskContainer) { |
| return CommonImages.getImage(CommonImages.CALENDAR); |
| } |
| return null; |
| } |
| |
| protected Widget getTipWidget(Event event) { |
| Point widgetPosition = new Point(event.x, event.y); |
| Widget widget = event.widget; |
| if (widget instanceof ToolBar) { |
| ToolBar w = (ToolBar) widget; |
| return w.getItem(widgetPosition); |
| } |
| if (widget instanceof Table) { |
| Table w = (Table) widget; |
| return w.getItem(widgetPosition); |
| } |
| if (widget instanceof Tree) { |
| Tree w = (Tree) widget; |
| return w.getItem(widgetPosition); |
| } |
| |
| return widget; |
| } |
| |
| private Rectangle getBounds(Widget widget) { |
| if (widget instanceof ToolItem) { |
| ToolItem w = (ToolItem) widget; |
| return w.getBounds(); |
| } |
| if (widget instanceof TableItem) { |
| TableItem w = (TableItem) widget; |
| return w.getBounds(); |
| } |
| if (widget instanceof TreeItem) { |
| TreeItem w = (TreeItem) widget; |
| return w.getBounds(); |
| } |
| return null; |
| } |
| |
| @Override |
| protected boolean shouldCreateToolTip(Event event) { |
| currentTipElement = null; |
| |
| if (isTriggeredByMouse() && !enabled) { |
| return false; |
| } |
| |
| if (super.shouldCreateToolTip(event)) { |
| Widget tipWidget = getTipWidget(event); |
| if (tipWidget != null) { |
| Rectangle bounds = getBounds(tipWidget); |
| if (tipWidget instanceof ScalingHyperlink) { |
| currentTipElement = getTaskListElement(tipWidget); |
| } else if (bounds != null && contains(bounds.x, bounds.y)) { |
| currentTipElement = getTaskListElement(tipWidget); |
| } |
| } |
| } |
| |
| if (currentTipElement == null) { |
| hide(); |
| return false; |
| } else { |
| return true; |
| } |
| } |
| |
| private boolean contains(int x, int y) { |
| if (control instanceof Scrollable) { |
| return ((Scrollable) control).getClientArea().contains(x, y); |
| } else { |
| return control.getBounds().contains(x, y); |
| } |
| } |
| |
| @Override |
| protected Composite createToolTipArea(Event event, Composite parent) { |
| assert currentTipElement != null; |
| |
| Composite composite = createToolTipContentAreaComposite(parent); |
| |
| addIconAndLabel(composite, getImage(currentTipElement), getTitleText(currentTipElement), true); |
| |
| String detailsText = getDetailsText(currentTipElement); |
| if (detailsText != null) { |
| addIconAndLabel(composite, null, detailsText); |
| } |
| |
| String ownerText = getOwnerText(currentTipElement); |
| if (ownerText != null) { |
| addIconAndLabel(composite, getOwnerImage(currentTipElement), ownerText); |
| } |
| |
| String extendedText = getExtendedToolTipText(currentTipElement); |
| if (extendedText != null) { |
| addIconAndLabel(composite, null, extendedText); |
| } |
| |
| String synchText = getSynchText(currentTipElement); |
| if (synchText != null) { |
| addIconAndLabel(composite, CommonImages.getImage(TasksUiImages.REPOSITORY_SYNCHRONIZE), synchText); |
| } |
| |
| String activityText = getActivityText(currentTipElement); |
| if (activityText != null) { |
| addIconAndLabel(composite, CommonImages.getImage(CommonImages.CALENDAR), activityText); |
| } |
| |
| String incomingText = getIncomingText(currentTipElement); |
| if (!StringUtils.isEmpty(incomingText)) { |
| ImageDescriptor incomingImage = getIncomingImage(); |
| addIconAndLabel(composite, CommonImages.getImage(incomingImage), incomingText); |
| } |
| |
| String synchronizationStateText = getSynchronizationStateText(currentTipElement); |
| if (synchronizationStateText != null) { |
| addIconAndLabel(composite, null, synchronizationStateText); |
| } |
| |
| ProgressData progress = getProgressData(currentTipElement); |
| if (progress != null) { |
| addIconAndLabel(composite, null, progress.text); |
| |
| // label height need to be set to 0 to remove gap below the progress bar |
| Label label = new Label(composite, SWT.NONE); |
| GridData labelGridData = new GridData(SWT.FILL, SWT.TOP, true, false); |
| labelGridData.heightHint = 0; |
| label.setLayoutData(labelGridData); |
| |
| Composite progressComposite = new Composite(composite, SWT.NONE); |
| GridLayout progressLayout = new GridLayout(1, false); |
| progressLayout.marginWidth = 0; |
| progressLayout.marginHeight = 0; |
| progressComposite.setLayout(progressLayout); |
| progressComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); |
| |
| WorkweekProgressBar taskProgressBar = new WorkweekProgressBar(progressComposite); |
| taskProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); |
| taskProgressBar.reset(progress.completed, progress.total); |
| |
| // do we really need custom canvas? code below renders the same |
| // IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager(); |
| // Color color = themeManager.getCurrentTheme().getColorRegistry().get( |
| // TaskListColorsAndFonts.THEME_COLOR_TASK_TODAY_COMPLETED); |
| // ProgressBar bar = new ProgressBar(tipShell, SWT.SMOOTH); |
| // bar.setForeground(color); |
| // bar.setSelection((int) (100d * progress.completed / progress.total)); |
| // GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false); |
| // gridData.heightHint = 5; |
| // bar.setLayoutData(gridData); |
| } |
| |
| String statusText = getStatusText(currentTipElement); |
| if (statusText != null) { |
| addIconAndLabel(composite, getStatusIcon(currentTipElement), statusText); |
| } |
| |
| String helpText = getHelpText(currentTipElement); |
| if (helpText != null) { |
| addIconAndLabel(composite, CommonImages.getImage(CommonImages.QUESTION), helpText); |
| } |
| |
| visible = true; |
| |
| return composite; |
| } |
| |
| private String getHelpText(IRepositoryElement element) { |
| if (element instanceof TaskCategory || element instanceof IRepositoryQuery) { |
| if (AbstractTaskListFilter.hasDescendantIncoming((ITaskContainer) element)) { |
| TaskListView taskListView = TaskListView.getFromActivePerspective(); |
| if (taskListView != null) { |
| |
| if (!taskListView.isFocusedMode() && TasksUiPlugin.getDefault() |
| .getPreferenceStore() |
| .getBoolean(ITasksUiPreferenceConstants.FILTER_COMPLETE_MODE)) { |
| Object[] children = ((TaskListContentProvider) taskListView.getViewer().getContentProvider()) |
| .getChildren(element); |
| boolean hasIncoming = false; |
| for (Object child : children) { |
| if (child instanceof ITask) { |
| if (TasksUiInternal.shouldShowIncoming((ITask) child)) { |
| hasIncoming = true; |
| break; |
| } |
| } |
| } |
| if (!hasIncoming) { |
| return Messages.TaskListToolTip_Some_incoming_elements_may_be_filtered; |
| } |
| } |
| } |
| } |
| // if has incoming but no top level children have incoming, suggest incoming tasks may be filtered |
| } |
| if (element instanceof UncategorizedTaskContainer) { |
| return Messages.TaskListToolTip_Automatic_container_for_all_local_tasks; |
| } else if (element instanceof UnmatchedTaskContainer) { |
| return Messages.TaskListToolTip_Automatic_container_for_repository_tasks; |
| } |
| return null; |
| } |
| |
| protected Composite createToolTipContentAreaComposite(Composite parent) { |
| Composite composite = new Composite(parent, SWT.NONE); |
| GridLayout gridLayout = new GridLayout(); |
| gridLayout.numColumns = 2; |
| gridLayout.marginWidth = 5; |
| gridLayout.marginHeight = 2; |
| composite.setLayout(gridLayout); |
| composite.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); |
| return composite; |
| } |
| |
| private String getSynchText(IRepositoryElement element) { |
| if (element instanceof IRepositoryQuery) { |
| String syncStamp = ((RepositoryQuery) element).getLastSynchronizedTimeStamp(); |
| if (syncStamp != null) { |
| return NLS.bind(Messages.TaskListToolTip_Synchronized, syncStamp); |
| } |
| } |
| return null; |
| } |
| |
| private String removeTrailingNewline(String text) { |
| if (text.endsWith("\n")) { //$NON-NLS-1$ |
| return text.substring(0, text.length() - 1); |
| } |
| return text; |
| } |
| |
| protected void addIconAndLabel(Composite parent, Image image, String text) { |
| addIconAndLabel(parent, image, text, false); |
| } |
| |
| protected void addIconAndLabel(Composite parent, Image image, String text, boolean title) { |
| Label imageLabel = new Label(parent, SWT.NONE); |
| imageLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND)); |
| imageLabel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); |
| imageLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING)); |
| imageLabel.setImage(image); |
| |
| Label textLabel = new Label(parent, SWT.WRAP); |
| if (title) { |
| textLabel.setFont(CommonFonts.BOLD); |
| } |
| textLabel.setForeground(titleColor); |
| textLabel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND)); |
| textLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER)); |
| text = removeTrailingNewline(text); |
| textLabel.setText(LegacyActionTools.escapeMnemonics(text)); |
| int width = Math.min(textLabel.computeSize(SWT.DEFAULT, SWT.DEFAULT).x, MAX_WIDTH); |
| GridDataFactory.fillDefaults().align(SWT.FILL, SWT.BEGINNING).hint(width, SWT.DEFAULT).applyTo(textLabel); |
| } |
| |
| private static class ProgressData { |
| |
| int completed; |
| |
| int total; |
| |
| String text; |
| |
| public ProgressData(int completed, int total, String text) { |
| this.completed = completed; |
| this.total = total; |
| this.text = text; |
| } |
| |
| } |
| |
| public boolean isVisible() { |
| return visible; |
| } |
| |
| public boolean isTriggeredByMouse() { |
| return triggeredByMouse; |
| } |
| |
| @Override |
| public void show(Point location) { |
| triggeredByMouse = false; |
| super.show(location); |
| } |
| |
| public boolean isEnabled() { |
| return enabled; |
| } |
| |
| public void setEnabled(boolean enabled) { |
| this.enabled = enabled; |
| } |
| |
| } |