blob: 19e4bbb37bd77ea5387b6cad90ec44613680ecd5 [file] [log] [blame]
/*******************************************************************************
* 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;
}
}