Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 194510
Collapse All | Expand All

(-)src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListView.java (-4 / +2 lines)
Lines 878-887 Link Here
878
		hookOpenAction();
878
		hookOpenAction();
879
		contributeToActionBars();
879
		contributeToActionBars();
880
880
881
		if (!SWT.getPlatform().equals("carbon")) {
881
		TaskListToolTipHandler taskListToolTipHandler = new TaskListToolTipHandler(getViewer().getControl().getShell());
882
			TaskListToolTipHandler taskListToolTipHandler = new TaskListToolTipHandler();
882
		taskListToolTipHandler.activateHoverHelp(getViewer().getControl());
883
			taskListToolTipHandler.activateHoverHelp(getViewer().getControl());
884
		}
885
883
886
		// Set to empty string to disable native tooltips (windows only?)
884
		// Set to empty string to disable native tooltips (windows only?)
887
		// bug#160897
885
		// bug#160897
(-)src/org/eclipse/mylyn/internal/tasks/ui/views/TaskListToolTipHandler.java (-289 / +320 lines)
Lines 11-23 Link Here
11
11
12
package org.eclipse.mylyn.internal.tasks.ui.views;
12
package org.eclipse.mylyn.internal.tasks.ui.views;
13
13
14
import java.net.URL;
14
import java.text.DateFormat;
15
import java.text.DateFormat;
15
import java.text.SimpleDateFormat;
16
import java.util.Calendar;
16
import java.util.Calendar;
17
import java.util.Date;
17
import java.util.Date;
18
18
19
import org.eclipse.core.runtime.IAdaptable;
19
import org.eclipse.core.runtime.IAdaptable;
20
import org.eclipse.core.runtime.IStatus;
21
import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer;
20
import org.eclipse.mylyn.internal.tasks.core.ScheduledTaskContainer;
22
import org.eclipse.mylyn.internal.tasks.ui.ITaskListNotification;
21
import org.eclipse.mylyn.internal.tasks.ui.ITaskListNotification;
23
import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
22
import org.eclipse.mylyn.internal.tasks.ui.TasksUiImages;
Lines 56-69 Link Here
56
 * @author Mik Kersten
55
 * @author Mik Kersten
57
 * @author Eric Booth
56
 * @author Eric Booth
58
 * @author Leo Dos Santos - multi-monitor support
57
 * @author Leo Dos Santos - multi-monitor support
59
 * @author Steffen Pingel
60
 */
58
 */
61
public class TaskListToolTipHandler {
59
public class TaskListToolTipHandler {
62
60
61
	private static final String SEPARATOR = "\n\n";
62
63
	private static final String UNITS_HOURS = " hours";
64
65
	private static final String NO_MINUTES = "0 minutes";
66
63
	private Shell tipShell;
67
	private Shell tipShell;
64
68
69
	private Label tipLabelImage;
70
71
	private Label tipLabelText;
72
73
	private Label scheduledTipLabelImage;
74
75
	private Label scheduledTipLabelText;
76
77
	private Label incommingTipLabelImage;
78
79
	private Label incommingTipLabelText;
80
81
	private WorkweekProgressBar taskProgressBar;
82
65
	private Widget tipWidget;
83
	private Widget tipWidget;
66
84
85
	protected Point tipPosition;
86
87
	protected Point widgetPosition;
88
89
	public TaskListToolTipHandler(Shell parentShell) {
90
		if (parentShell != null) {
91
			tipShell = createTipShell(parentShell, null, true, true);
92
		}
93
	}
94
95
	private Shell createTipShell(Shell parent, Widget widget, boolean showScheduled, boolean showIncomming) {
96
		Shell tipShell = new Shell(parent.getDisplay(), SWT.TOOL | SWT.NO_FOCUS | SWT.MODELESS | SWT.ON_TOP);
97
		GridLayout gridLayout = new GridLayout();
98
		gridLayout.numColumns = 2;
99
		gridLayout.marginWidth = 2;
100
		gridLayout.marginHeight = 2;
101
		tipShell.setLayout(gridLayout);
102
		tipShell.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
103
104
		tipLabelImage = new Label(tipShell, SWT.NONE);
105
		tipLabelImage.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
106
		tipLabelImage.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
107
108
		GridData imageGridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
109
		tipLabelImage.setLayoutData(imageGridData);
110
111
		tipLabelText = new Label(tipShell, SWT.NONE);
112
		tipLabelText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
113
		tipLabelText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
114
115
		GridData textGridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
116
		tipLabelText.setLayoutData(textGridData);
117
118
		if (showScheduled) {
119
120
			scheduledTipLabelImage = new Label(tipShell, SWT.NONE);
121
			scheduledTipLabelImage.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
122
			scheduledTipLabelImage.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
123
124
			imageGridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
125
			scheduledTipLabelImage.setLayoutData(imageGridData);
126
127
			scheduledTipLabelText = new Label(tipShell, SWT.NONE);
128
			scheduledTipLabelText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
129
			scheduledTipLabelText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
130
131
			textGridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
132
			scheduledTipLabelText.setLayoutData(textGridData);
133
		}
134
135
		if (showIncomming) {
136
			incommingTipLabelImage = new Label(tipShell, SWT.NONE);
137
			incommingTipLabelImage.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
138
			incommingTipLabelImage.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
139
140
			imageGridData = new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING);
141
			incommingTipLabelImage.setLayoutData(imageGridData);
142
143
			incommingTipLabelText = new Label(tipShell, SWT.NONE);
144
			incommingTipLabelText.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
145
			incommingTipLabelText.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
146
147
			textGridData = new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER);
148
			incommingTipLabelText.setLayoutData(textGridData);
149
		}
150
151
		AbstractTaskContainer element = getTaskListElement(widget);
152
		if (element != null) {
153
			Composite progressComposite = new Composite(tipShell, SWT.NONE);
154
			GridLayout progressLayout = new GridLayout(1, false);
155
			progressLayout.marginWidth = 2;
156
			progressLayout.marginHeight = 0;
157
			progressLayout.marginBottom = 2;
158
			progressLayout.horizontalSpacing = 0;
159
			progressLayout.verticalSpacing = 0;
160
			progressComposite.setLayout(progressLayout);
161
			progressComposite.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false, 4, 1));
162
163
			taskProgressBar = new WorkweekProgressBar(progressComposite);
164
			taskProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
165
		}
166
167
		return tipShell;
168
	}
169
170
	private String updateContainerProgressBar(WorkweekProgressBar taskProgressBar, Object object) {
171
		if (taskProgressBar != null && !taskProgressBar.isDisposed() && object instanceof AbstractTaskContainer) {
172
			String text = "";
173
			AbstractTaskContainer container = (AbstractTaskContainer) object;
174
175
			int total = container.getChildren().size();
176
			int completed = 0;
177
			for (AbstractTask task : container.getChildren()) {
178
				if (task.isCompleted()) {
179
					completed++;
180
				}
181
			}
182
			String suffix = "";
183
			if (container instanceof AbstractRepositoryQuery) {
184
				AbstractRepositoryQuery query = ((AbstractRepositoryQuery) container);
185
				total = 0;
186
				completed = 0;
187
				total += query.getChildren().size();
188
				for (AbstractTask hit : query.getChildren()) {
189
					if (hit.isCompleted()) {
190
						completed++;
191
					}
192
				}
193
				// suffix = " (query max: " + query.getMaxHits() + ")";
194
			}
195
			taskProgressBar.reset(completed, total);
196
			text += "Completed " + completed + " of " + total + suffix;
197
			return text;
198
		} else {
199
			return "";
200
		}
201
	}
202
67
	private AbstractTaskContainer getTaskListElement(Object hoverObject) {
203
	private AbstractTaskContainer getTaskListElement(Object hoverObject) {
68
		if (hoverObject instanceof Widget) {
204
		if (hoverObject instanceof Widget) {
69
			Object data = ((Widget) hoverObject).getData();
205
			Object data = ((Widget) hoverObject).getData();
Lines 78-197 Link Here
78
		return null;
214
		return null;
79
	}
215
	}
80
216
81
	private String getTitleText(AbstractTaskContainer element) {
217
	protected String getBasicToolTextTip(Object object) {
82
		if (element instanceof ScheduledTaskContainer) {
218
		AbstractTaskContainer element = getTaskListElement(object);
83
			StringBuilder sb = new StringBuilder();
219
		String tooltip = "";
84
			sb.append(element.getSummary());
220
		String priority = "";
85
			Calendar start = ((ScheduledTaskContainer) element).getStart();
86
			sb.append("  [");
87
			sb.append(DateFormat.getDateInstance(DateFormat.LONG).format(start.getTime()));
88
			sb.append("]");
89
			return sb.toString();
90
		} else if (element instanceof AbstractRepositoryQuery) {
91
			AbstractRepositoryQuery query = (AbstractRepositoryQuery) element;
92
			StringBuilder sb = new StringBuilder();
93
			sb.append(element.getSummary());
94
			sb.append("  [");
95
			sb.append(getRepositoryLabel(query.getRepositoryKind(), query.getRepositoryUrl()));
96
			sb.append("]");
97
			return sb.toString();
98
		} else {
99
			return element.getSummary();
100
		}
101
	}
102
221
103
	private String getDetailsText(AbstractTaskContainer element) {
104
		if (element instanceof ScheduledTaskContainer) {
222
		if (element instanceof ScheduledTaskContainer) {
105
			ScheduledTaskContainer container = (ScheduledTaskContainer) element;
223
			ScheduledTaskContainer container = (ScheduledTaskContainer) element;
106
			StringBuilder sb = new StringBuilder();
224
			tooltip += "Estimate: " + container.getTotalEstimated() + UNITS_HOURS;
107
			sb.append("Estimate: ");
225
			String elapsedTimeString = NO_MINUTES;
108
			sb.append(container.getTotalEstimated());
226
			try {
109
			sb.append(" hours");
227
				elapsedTimeString = DateUtil.getFormattedDurationShort(container.getTotalElapsed());
110
			sb.append("\n");
228
				if (elapsedTimeString.equals("")) {
111
			sb.append("Elapsed: ");
229
					elapsedTimeString = NO_MINUTES;
112
			sb.append(DateUtil.getFormattedDurationShort(container.getTotalElapsed()));
230
				}
113
			sb.append("\n");
231
			} catch (RuntimeException e) {
114
			return sb.toString();
232
				// ignore
115
		} else if (element instanceof AbstractTask) {
233
			}
116
			AbstractTask task = (AbstractTask) element;
234
			tooltip += "   Elapsed: " + elapsedTimeString + "\n";
117
			StringBuilder sb = new StringBuilder();			
235
			return tooltip;
118
			sb.append(TasksUiPlugin.getConnectorUi(task.getConnectorKind()).getTaskKindLabel(task));
119
			String key = task.getTaskKey();
120
			if (key != null) {
121
				sb.append(" ");
122
				sb.append(key);
123
			}
124
			sb.append(", ");
125
			sb.append(task.getPriority());
126
			sb.append("  [");
127
			sb.append(getRepositoryLabel(task.getConnectorKind(), task.getRepositoryUrl()));
128
			sb.append("]");
129
			sb.append("\n");
130
			return sb.toString();
131
		} else {
132
			return null;
133
		}
236
		}
134
	}
135
237
136
	private String getRepositoryLabel(String repositoryKind, String repositoryUrl) {
238
		if (element instanceof AbstractRepositoryQuery) {
137
		TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(repositoryKind, repositoryUrl);
239
			AbstractRepositoryQuery query = (AbstractRepositoryQuery) element;
138
		if (repository != null) {
240
139
			String label = repository.getRepositoryLabel();
241
			try {
140
			if (label.indexOf("//") != -1) {
242
				tooltip += new URL(query.getRepositoryUrl()).getHost();
141
				return label.substring((repository.getUrl().indexOf("//") + 2));
243
			} catch (Exception e) {
244
				// ignore
245
			}
246
247
			String syncStamp = query.getLastSynchronizedTimeStamp();
248
			if (syncStamp != null) {
249
				tooltip += " (synched: " + syncStamp + ")\n";
142
			}
250
			}
143
			return label + "";
251
			if (query.getSynchronizationStatus() != null) {
252
				tooltip += "\n" + "Last Error: " + query.getSynchronizationStatus().getMessage();
253
				if (query.getSynchronizationStatus() instanceof RepositoryStatus
254
						&& ((RepositoryStatus) query.getSynchronizationStatus()).isHtmlMessage()) {
255
					tooltip += " Please synchronize manually for full error message.";
256
				}
257
				tooltip += "\n";
258
			}
259
			return tooltip;
144
		}
260
		}
145
		return "";
261
262
		if (element instanceof AbstractTask) {
263
264
			AbstractTask repositoryTask = (AbstractTask) element;
265
266
			tooltip += (element).getSummary();
267
268
			String taskKindLabel = TasksUiPlugin.getConnectorUi(repositoryTask.getConnectorKind())
269
			.getTaskKindLabel(repositoryTask);
270
271
			tooltip += "\n" + taskKindLabel + ", " + repositoryTask.getPriority();
272
273
			TaskRepository repository = TasksUiPlugin.getRepositoryManager().getRepository(
274
					repositoryTask.getConnectorKind(), repositoryTask.getRepositoryUrl());
275
			if (repository != null) {
276
				tooltip += "  [" + repository.getRepositoryLabel() + "]";
277
			}
278
279
			if (repositoryTask.getSynchronizationStatus() != null) {
280
				tooltip += SEPARATOR + "Last Error: " + repositoryTask.getSynchronizationStatus().getMessage();
281
			}
282
			return tooltip;
283
		} else if (element != null) {
284
			tooltip += (element).getSummary();
285
			return tooltip + priority;
286
		} else if (object instanceof Control) {
287
			return (String) ((Control) object).getData("TIP_TEXT");
288
		}
289
		return null;
146
	}
290
	}
147
291
148
	private String getActivityText(AbstractTaskContainer element) {
292
	private String getActivityText(AbstractTaskContainer element) {
149
		if (element instanceof AbstractTask) {
150
			AbstractTask task = (AbstractTask) element;
151
293
152
			StringBuilder sb = new StringBuilder();
294
		if (element != null && element instanceof AbstractTask) {
153
			Date date = task.getScheduledForDate();
295
			try {
154
			if (date != null) {
296
				String result = "";
155
				sb.append("Scheduled for: ");
297
				Date date = ((AbstractTask) element).getScheduledForDate();
156
				sb.append(new SimpleDateFormat("E").format(date)).append(", ");
298
				if (date != null) {
157
				sb.append(DateFormat.getDateInstance(DateFormat.LONG).format(date));
299
					result += "Scheduled for: " + DateFormat.getDateInstance(DateFormat.LONG).format(date) + " ("
158
				sb.append(" (").append(DateFormat.getTimeInstance(DateFormat.SHORT).format(date)).append(")\n");
300
							+ DateFormat.getTimeInstance(DateFormat.SHORT).format(date) + ")\n";
159
			}
301
				}
160
161
			long elapsed = TasksUiPlugin.getTaskListManager().getElapsedTime(task);
162
			String elapsedTimeString = DateUtil.getFormattedDurationShort(elapsed);
163
			sb.append("Elapsed: ");
164
			sb.append(elapsedTimeString);
165
			sb.append("\n");
166
302
167
			return sb.toString();
303
				long elapsed = TasksUiPlugin.getTaskListManager().getElapsedTime((AbstractTask) element);
304
				String elapsedTimeString = DateUtil.getFormattedDurationShort(elapsed);
305
				if (!elapsedTimeString.equals("")) {
306
					result += "Elapsed: " + elapsedTimeString + "\n";
307
				}
308
				return result;
309
			} catch (Exception e) {
310
				// ignore
311
			}
168
		}
312
		}
169
		return null;
313
		return null;
170
	}
314
	}
171
315
172
	private String getIncommingText(AbstractTaskContainer element) {
316
	private String getIncommingText(AbstractTaskContainer element) {
173
		if (element instanceof AbstractTask) {
317
		if (element instanceof AbstractTask) {
174
			AbstractTask task = (AbstractTask) element;
318
175
			if (task.getSynchronizationState() == RepositoryTaskSyncState.INCOMING) {
319
			AbstractTask repositoryTask = (AbstractTask) element;
320
321
			if (repositoryTask.getSynchronizationState() == RepositoryTaskSyncState.INCOMING) {
176
				AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
322
				AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
177
						task);
323
						repositoryTask);
178
				if (connector != null) {
324
				if (connector != null) {
179
					ITaskListNotification notification = TasksUiPlugin.getDefault().getIncommingNotification(connector, task);
325
					ITaskListNotification notification = TasksUiPlugin.getDefault().getIncommingNotification(connector, repositoryTask);
180
					if (notification != null) {
326
					if (notification != null) {
181
						String res = null;
327
						String descriptionText = null;
182
						if (notification.getDescription() != null) {
328
						if (notification.getDescription() != null) {
183
							String descriptionText = notification.getDescription();
329
							descriptionText = notification.getDescription();
184
							if (descriptionText != null && descriptionText.length() > 0) {
185
								res = descriptionText;
186
							}
187
						}
330
						}
188
						if(notification.getDetails() !=null) {
331
189
							String details = notification.getDetails();
332
						if (descriptionText != null && !descriptionText.equals("")) {
190
							if (details != null && details.length() > 0) {
333
							return descriptionText;
191
								res = res==null ? details : res + "\n" + details;
192
							}
193
						}
334
						}
194
						return res;
195
					}
335
					}
196
				}
336
				}
197
			}
337
			}
Lines 199-246 Link Here
199
		return null;
339
		return null;
200
	}
340
	}
201
341
202
	private String getStatusText(AbstractTaskContainer element) {
342
	protected Image getImage(Object object) {
203
		IStatus status = null;
343
		AbstractTaskContainer element = getTaskListElement(object);
204
		if (element instanceof AbstractTask) {
344
		if (object instanceof Control) {
205
			AbstractTask task = (AbstractTask) element;
345
			return (Image) ((Control) object).getData("TIP_IMAGE");
206
			status = task.getSynchronizationStatus();
207
		} else if (element instanceof AbstractRepositoryQuery) {
346
		} else if (element instanceof AbstractRepositoryQuery) {
208
			AbstractRepositoryQuery query = (AbstractRepositoryQuery) element;
347
			AbstractRepositoryQuery query = (AbstractRepositoryQuery) element;
209
			status = query.getSynchronizationStatus();
210
		}
211
		
212
		if (status != null) {
213
			StringBuilder sb = new StringBuilder();
214
			sb.append(status.getMessage());
215
			if (status instanceof RepositoryStatus && ((RepositoryStatus) status).isHtmlMessage()) {
216
				sb.append(" Please synchronize manually for full error message.");
217
			}
218
			return sb.toString();
219
		} 
220
		
221
		return null;
222
	}
223
224
	private ProgressData getProgressData(AbstractTaskContainer element) {
225
		if (element instanceof AbstractTask) {
226
			return null;
227
		}
228
229
		int total = element.getChildren().size();
230
		int completed = 0;
231
		for (AbstractTask task : element.getChildren()) {
232
			if (task.isCompleted()) {
233
				completed++;
234
			}
235
		}
236
237
		String text = "Total: " + total + " (Complete: " + completed + ", Incomplete: " + (total - completed) + ")";
238
		return new ProgressData(completed, total, text);
239
	}
240
241
	private Image getImage(AbstractTaskContainer element) {
242
		if (element instanceof AbstractRepositoryQuery) {
243
			AbstractRepositoryQuery query = (AbstractRepositoryQuery) element;
244
			AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
348
			AbstractRepositoryConnector connector = TasksUiPlugin.getRepositoryManager().getRepositoryConnector(
245
					query.getRepositoryKind());
349
					query.getRepositoryKind());
246
			if (connector != null) {
350
			if (connector != null) {
Lines 253-260 Link Here
253
			if (connector != null) {
357
			if (connector != null) {
254
				return TasksUiPlugin.getDefault().getBrandingIcon(connector.getConnectorKind());
358
				return TasksUiPlugin.getDefault().getBrandingIcon(connector.getConnectorKind());
255
			}
359
			}
256
		} else if (element instanceof ScheduledTaskContainer) {
360
		}
257
			return TasksUiImages.getImage(TasksUiImages.CALENDAR);
361
		return null;
362
	}
363
364
	protected Object getToolTipHelp(Object object) {
365
		if (object instanceof Control) {
366
			return ((Control) object).getData("TIP_HELPTEXT");
258
		}
367
		}
259
		return null;
368
		return null;
260
	}
369
	}
Lines 265-309 Link Here
265
	 * @control the control on which to enable hoverhelp
374
	 * @control the control on which to enable hoverhelp
266
	 */
375
	 */
267
	public void activateHoverHelp(final Control control) {
376
	public void activateHoverHelp(final Control control) {
268
		// hide tooltip if any window is deactivated 
377
269
		PlatformUI.getWorkbench().addWindowListener(new IWindowListener() {
378
		PlatformUI.getWorkbench().addWindowListener(new IWindowListener() {
270
379
271
			public void windowActivated(IWorkbenchWindow window) {
380
			public void windowActivated(IWorkbenchWindow window) {
381
				// ignore
382
272
			}
383
			}
273
384
274
			public void windowClosed(IWorkbenchWindow window) {
385
			public void windowClosed(IWorkbenchWindow window) {
386
				// ignore
387
275
			}
388
			}
276
389
277
			public void windowDeactivated(IWorkbenchWindow window) {
390
			public void windowDeactivated(IWorkbenchWindow window) {
278
				hideTooltip();
391
				hideTooltip();
392
279
			}
393
			}
280
394
281
			public void windowOpened(IWorkbenchWindow window) {
395
			public void windowOpened(IWorkbenchWindow window) {
396
				// ignore
397
282
			}
398
			}
283
		});
399
		});
284
400
285
		// hide tooltip if control underneath is activated 
401
		/*
402
		 * Get out of the way if we attempt to activate the control underneath
403
		 * the tooltip
404
		 */
286
		control.addMouseListener(new MouseAdapter() {
405
		control.addMouseListener(new MouseAdapter() {
287
406
288
			@Override
407
			@Override
289
			public void mouseDown(MouseEvent e) {
408
			public void mouseDown(MouseEvent e) {
290
				hideTooltip();
409
				hideTooltip();
291
				tipWidget = null;
292
			}
410
			}
293
		});
411
		});
294
412
		/*
295
		// trap hover events to pop-up tooltip
413
		 * Trap hover events to pop-up tooltip
414
		 */
296
		control.addMouseTrackListener(new MouseTrackAdapter() {
415
		control.addMouseTrackListener(new MouseTrackAdapter() {
297
416
298
			@Override
417
			@Override
299
			public void mouseExit(MouseEvent e) {
418
			public void mouseExit(MouseEvent e) {
300
				hideTooltip();
419
				// TODO: can these conditions be simplified? see bug 131776
420
				if (tipShell != null && !tipShell.isDisposed() && tipShell.getDisplay() != null
421
						&& !tipShell.getDisplay().isDisposed() && tipShell.isVisible()) {
422
					tipShell.setVisible(false);
423
				}
301
				tipWidget = null;
424
				tipWidget = null;
302
			}
425
			}
303
426
304
			@Override
427
			@Override
305
			public void mouseHover(MouseEvent event) {
428
			public void mouseHover(MouseEvent event) {
306
				Point widgetPosition = new Point(event.x, event.y);
429
				if (tipShell.isDisposed()) {
430
					return;
431
				}
432
				widgetPosition = new Point(event.x, event.y);
307
				Widget widget = event.widget;
433
				Widget widget = event.widget;
308
				if (widget instanceof ToolBar) {
434
				if (widget instanceof ToolBar) {
309
					ToolBar w = (ToolBar) widget;
435
					ToolBar w = (ToolBar) widget;
Lines 317-338 Link Here
317
					Tree w = (Tree) widget;
443
					Tree w = (Tree) widget;
318
					widget = w.getItem(widgetPosition);
444
					widget = w.getItem(widgetPosition);
319
				}
445
				}
320
				
446
				if (widget == null && !tipShell.isDisposed()) {
321
				if (widget == null) {
447
					tipShell.setVisible(false);
322
					hideTooltip();
323
					tipWidget = null;
448
					tipWidget = null;
324
					return;
449
					return;
325
				}
450
				}
326
				
451
				if (widget == tipWidget)
327
				if (widget == tipWidget) {
452
					return;
328
					// already displaying tooltip
453
				tipWidget = widget;
454
				tipPosition = control.toDisplay(widgetPosition);
455
				String baseText = getBasicToolTextTip(widget);
456
				String scheduledText = getActivityText(getTaskListElement(widget));
457
				String incommingText = getIncommingText(getTaskListElement(widget));
458
459
				Image repositoryImage = getImage(widget);
460
				Image activityImage = TasksUiImages.getImage(TasksUiImages.CALENDAR); // TODO
461
				// Fixme
462
				Image incommingImage = TasksUiImages.getImage(TasksUiImages.OVERLAY_INCOMMING);
463
464
				if (baseText == null) { // HACK: don't check length
329
					return;
465
					return;
330
				}
466
				}
331
467
332
				tipWidget = widget;
468
				if (!tipShell.isDisposed() && tipShell.getShell() != null
333
				showTooltip(control.toDisplay(widgetPosition));
469
						&& PlatformUI.getWorkbench().getDisplay().getActiveShell() != null) {
334
			}
470
					tipShell.close();
471
					tipShell = createTipShell(PlatformUI.getWorkbench().getDisplay().getActiveShell(), widget,
472
							scheduledText != null, incommingText != null);
473
				}
335
474
475
				AbstractTaskContainer element = getTaskListElement(widget);
476
				String progressText = updateContainerProgressBar(taskProgressBar, element);
477
478
				String dateText = "";
479
				if (element instanceof ScheduledTaskContainer) {
480
					Calendar start = ((ScheduledTaskContainer) element).getStart();
481
					dateText += DateFormat.getDateInstance(DateFormat.LONG).format(start.getTime()) + "\n";
482
				}
483
484
				tipLabelText.setText(dateText + baseText + progressText);
485
				tipLabelImage.setImage(repositoryImage); // accepts null
486
487
				if (scheduledText != null) {
488
					scheduledTipLabelText.setText(scheduledText);
489
					scheduledTipLabelImage.setImage(activityImage); // accepts
490
					// null
491
				}
492
493
				if (incommingText != null) {
494
					incommingTipLabelText.setText(incommingText);
495
					incommingTipLabelImage.setImage(incommingImage); // accepts
496
					// null
497
				}
498
499
				tipShell.pack();
500
				setHoverLocation(tipShell, tipPosition);
501
				tipShell.setVisible(true);
502
			}
336
		});
503
		});
337
	}
504
	}
338
505
Lines 374-516 Link Here
374
	}
541
	}
375
542
376
	private void hideTooltip() {
543
	private void hideTooltip() {
377
		// TODO: can these conditions be simplified? see bug 131776
544
		if (tipShell != null && !tipShell.isDisposed() && tipShell.isVisible())
378
		if (tipShell != null && !tipShell.isDisposed() && tipShell.getDisplay() != null
545
			tipShell.setVisible(false);
379
				&& !tipShell.getDisplay().isDisposed() && tipShell.isVisible()) {
380
//			tipShell.setVisible(false);
381
			tipShell.close();
382
			tipShell = null;
383
		}
384
	}
385
386
	private void showTooltip(Point location) {
387
		hideTooltip();
388
389
		AbstractTaskContainer element = getTaskListElement(tipWidget);
390
391
		Shell parent = PlatformUI.getWorkbench().getDisplay().getActiveShell();
392
		if (parent == null) {
393
			return;
394
		}
395
396
		tipShell = new Shell(parent.getDisplay(), SWT.TOOL | SWT.NO_FOCUS | SWT.MODELESS | SWT.ON_TOP);
397
		GridLayout gridLayout = new GridLayout();
398
		gridLayout.numColumns = 2;
399
		gridLayout.marginWidth = 5;
400
		gridLayout.marginHeight = 2;
401
		tipShell.setLayout(gridLayout);
402
		tipShell.setBackground(tipShell.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
403
404
		addIconAndLabel(tipShell, getImage(element), getTitleText(element));
405
406
		String detailsText = getDetailsText(element);
407
		if (detailsText != null) {
408
			addIconAndLabel(tipShell, null, detailsText);
409
		}
410
411
		String synchText = getSynchText(element);
412
		if (synchText != null) {
413
			addIconAndLabel(tipShell, TasksUiImages.getImage(TasksUiImages.REPOSITORY_SYNCHRONIZE), synchText);
414
		}
415
416
		String activityText = getActivityText(element);
417
		if (activityText != null) {
418
			addIconAndLabel(tipShell, TasksUiImages.getImage(TasksUiImages.CALENDAR), activityText);
419
		}
420
421
		String incommingText = getIncommingText(element);
422
		if (incommingText != null) {
423
			addIconAndLabel(tipShell, TasksUiImages.getImage(TasksUiImages.OVERLAY_INCOMMING), incommingText);
424
		}
425
426
		ProgressData progress = getProgressData(element);
427
		if (progress != null) {
428
			addIconAndLabel(tipShell, null, progress.text);
429
430
			// label height need to be set to 0 to remove gap below the progress bar 
431
			Label label = new Label(tipShell, SWT.NONE);
432
			GridData labelGridData = new GridData(SWT.FILL, SWT.TOP, true, false);
433
			labelGridData.heightHint = 0;
434
			label.setLayoutData(labelGridData);
435
			
436
			Composite progressComposite = new Composite(tipShell, SWT.NONE);
437
			GridLayout progressLayout = new GridLayout(1, false);
438
			progressLayout.marginWidth = 0;
439
			progressLayout.marginHeight = 0;
440
			progressComposite.setLayout(progressLayout);
441
			progressComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
442
443
			WorkweekProgressBar taskProgressBar = new WorkweekProgressBar(progressComposite);
444
			taskProgressBar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
445
			taskProgressBar.reset(progress.completed, progress.total);
446
447
			// do we really need custom canvas? code below renders the same
448
//			IThemeManager themeManager = PlatformUI.getWorkbench().getThemeManager();
449
//			Color color = themeManager.getCurrentTheme().getColorRegistry().get(
450
//					TaskListColorsAndFonts.THEME_COLOR_TASK_TODAY_COMPLETED);
451
//			ProgressBar bar = new ProgressBar(tipShell, SWT.SMOOTH);
452
//			bar.setForeground(color);
453
//			bar.setSelection((int) (100d * progress.completed / progress.total));
454
//			GridData gridData = new GridData(SWT.FILL, SWT.TOP, true, false);
455
//			gridData.heightHint = 5;
456
//			bar.setLayoutData(gridData);
457
		}
458
459
		String statusText = getStatusText(element);
460
		if (statusText != null) {
461
			addIconAndLabel(tipShell, TasksUiImages.getImage(TasksUiImages.WARNING), statusText);
462
		}
463
		
464
		tipShell.pack();
465
		setHoverLocation(tipShell, location);
466
		tipShell.setVisible(true);
467
	}
468
469
	private String getSynchText(AbstractTaskContainer element) {
470
		if (element instanceof AbstractRepositoryQuery) {
471
			String syncStamp = ((AbstractRepositoryQuery) element).getLastSynchronizedTimeStamp();
472
			if (syncStamp != null) {
473
				return "Synchronized: " + syncStamp;
474
			}
475
		}
476
		return null;
477
	}
478
479
	private String removeTrailingNewline(String text) {
480
		if (text.endsWith("\n")) {
481
			return text.substring(0, text.length() - 1);
482
		}
483
		return text;
484
	}
546
	}
485
486
	private void addIconAndLabel(Composite parent, Image image, String text) {
487
		Label imageLabel = new Label(parent, SWT.NONE);
488
		imageLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
489
		imageLabel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
490
		imageLabel.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING | GridData.VERTICAL_ALIGN_BEGINNING));
491
		imageLabel.setImage(image);
492
493
		Label textLabel = new Label(parent, SWT.NONE);
494
		textLabel.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_FOREGROUND));
495
		textLabel.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
496
		textLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
497
		textLabel.setText(removeTrailingNewline(text));
498
	}
499
500
	private static class ProgressData {
501
502
		int completed;
503
504
		int total;
505
506
		String text;
507
508
		public ProgressData(int completed, int total, String text) {
509
			this.completed = completed;
510
			this.total = total;
511
			this.text = text;
512
		}
513
514
	}
515
516
}
547
}

Return to bug 194510