|
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 |
} |