ef6ffaa32ad692da77938362f8d247b77c208bd0
[deliverable/tracecompass.git] / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / dialogs / offset / OffsetDialog.java
1 /*******************************************************************************
2 * Copyright (c) 2014 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * Matthew Khouzam - Initial API and implementation
11 * Patrick Tasse - Initial API and implementation
12 *******************************************************************************/
13
14 package org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.offset;
15
16 import java.text.ParseException;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.Comparator;
20 import java.util.HashMap;
21 import java.util.List;
22 import java.util.Map;
23
24 import org.eclipse.core.runtime.IPath;
25 import org.eclipse.core.runtime.Path;
26 import org.eclipse.jface.dialogs.Dialog;
27 import org.eclipse.jface.viewers.CellEditor;
28 import org.eclipse.jface.viewers.ColumnLabelProvider;
29 import org.eclipse.jface.viewers.ColumnViewer;
30 import org.eclipse.jface.viewers.ColumnViewerEditor;
31 import org.eclipse.jface.viewers.ColumnViewerEditorActivationStrategy;
32 import org.eclipse.jface.viewers.EditingSupport;
33 import org.eclipse.jface.viewers.FocusCellOwnerDrawHighlighter;
34 import org.eclipse.jface.viewers.TextCellEditor;
35 import org.eclipse.jface.viewers.TreeViewerColumn;
36 import org.eclipse.jface.viewers.TreeViewerEditor;
37 import org.eclipse.jface.viewers.TreeViewerFocusCellManager;
38 import org.eclipse.jface.viewers.Viewer;
39 import org.eclipse.swt.SWT;
40 import org.eclipse.swt.custom.TreeEditor;
41 import org.eclipse.swt.events.DisposeEvent;
42 import org.eclipse.swt.events.DisposeListener;
43 import org.eclipse.swt.events.SelectionAdapter;
44 import org.eclipse.swt.events.SelectionEvent;
45 import org.eclipse.swt.layout.GridData;
46 import org.eclipse.swt.layout.GridLayout;
47 import org.eclipse.swt.layout.RowLayout;
48 import org.eclipse.swt.widgets.Button;
49 import org.eclipse.swt.widgets.Composite;
50 import org.eclipse.swt.widgets.Control;
51 import org.eclipse.swt.widgets.Display;
52 import org.eclipse.swt.widgets.Group;
53 import org.eclipse.swt.widgets.Label;
54 import org.eclipse.swt.widgets.Shell;
55 import org.eclipse.swt.widgets.Tree;
56 import org.eclipse.swt.widgets.TreeColumn;
57 import org.eclipse.swt.widgets.TreeItem;
58 import org.eclipse.tracecompass.tmf.core.signal.TmfEventSelectedSignal;
59 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalHandler;
60 import org.eclipse.tracecompass.tmf.core.signal.TmfSignalManager;
61 import org.eclipse.tracecompass.tmf.core.signal.TmfTimeSynchSignal;
62 import org.eclipse.tracecompass.tmf.core.signal.TmfTraceOpenedSignal;
63 import org.eclipse.tracecompass.tmf.core.timestamp.ITmfTimestamp;
64 import org.eclipse.tracecompass.tmf.core.timestamp.TmfNanoTimestamp;
65 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimestampFormat;
66 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
67 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
68 import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper;
69 import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
70 import org.eclipse.tracecompass.tmf.ui.viewers.ArrayTreeContentProvider;
71 import org.eclipse.ui.dialogs.FilteredTree;
72 import org.eclipse.ui.dialogs.PatternFilter;
73
74 /**
75 * Offset wizard dialog
76 *
77 * @author Matthew Khouzam
78 *
79 */
80 public class OffsetDialog extends Dialog {
81
82 private static final int TREE_EDITOR_MIN_WIDTH = 50;
83 private static final String EDITOR_KEY = "$editor$"; //$NON-NLS-1$
84 private static final String WIDTH_KEY = "$width$"; //$NON-NLS-1$
85
86 private static final TmfTimestampFormat TIME_FORMAT = new TmfTimestampFormat("yyyy-MM-dd HH:mm:ss.SSS SSS SSS"); //$NON-NLS-1$
87 private static final TmfTimestampFormat OFFSET_FORMAT = new TmfTimestampFormat("T.SSS SSS SSS"); //$NON-NLS-1$
88
89 private final Map<TmfTraceElement, Long> fOffsetMap;
90 private final Map<TmfTraceElement, ITmfTimestamp> fRefTimeMap;
91 private final Map<TmfTraceElement, ITmfTimestamp> fTargetTimeMap;
92
93 private Label fBasicMessageLabel;
94 private Group fButtonGroup;
95 private Label fAdvancedMessageLabel;
96 private FilteredTree fViewer;
97
98 private boolean fAdvancedMode = true;
99 private TreeViewerColumn fButtonViewerColumn;
100 private TreeColumn fRefTimeColumn;
101 private TreeColumn fTargetTimeColumn;
102
103 private abstract class ColumnEditingSupport extends EditingSupport {
104 private final TextCellEditor textCellEditor;
105
106 private ColumnEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) {
107 super(viewer);
108 this.textCellEditor = textCellEditor;
109 }
110
111 @Override
112 protected CellEditor getCellEditor(Object element) {
113 return textCellEditor;
114 }
115
116 @Override
117 protected boolean canEdit(Object element) {
118 return true;
119 }
120 }
121
122 private class TimeEditingSupport extends ColumnEditingSupport {
123 private Map<TmfTraceElement, ITmfTimestamp> map;
124
125 private TimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor, Map<TmfTraceElement, ITmfTimestamp> map) {
126 super(viewer, textCellEditor);
127 this.map = map;
128 }
129
130 @Override
131 protected void setValue(Object element, Object value) {
132 if (value instanceof String) {
133 String string = (String) value;
134 if (string.trim().isEmpty()) {
135 map.remove(element);
136 } else {
137 try {
138 ITmfTimestamp refTime = map.get(element);
139 long ref = refTime == null ? 0 : refTime.normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue();
140 Long newVal = TIME_FORMAT.parseValue(string, ref);
141 map.put((TmfTraceElement) element, new TmfNanoTimestamp(newVal));
142 } catch (ParseException e) {
143 /* Ignore and reload previous value */
144 }
145 }
146 fViewer.getViewer().update(element, null);
147 }
148 }
149
150 @Override
151 protected Object getValue(Object element) {
152 if (map.get(element) == null) {
153 return ""; //$NON-NLS-1$
154 }
155 return TIME_FORMAT.format(map.get(element).normalize(0, ITmfTimestamp.NANOSECOND_SCALE).getValue());
156 }
157 }
158
159 private class RefTimeEditingSupport extends TimeEditingSupport {
160 private RefTimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) {
161 super(viewer, textCellEditor, fRefTimeMap);
162 }
163 }
164
165 private class TargetTimeEditingSupport extends TimeEditingSupport {
166 private TargetTimeEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) {
167 super(viewer, textCellEditor, fTargetTimeMap);
168 }
169 }
170
171 private class OffsetEditingSupport extends ColumnEditingSupport {
172 private OffsetEditingSupport(ColumnViewer viewer, TextCellEditor textCellEditor) {
173 super(viewer, textCellEditor);
174 }
175
176 @Override
177 protected void setValue(Object element, Object value) {
178 if (value instanceof String) {
179 String string = (String) value;
180 if (string.trim().isEmpty()) {
181 fOffsetMap.put((TmfTraceElement) element, 0L);
182 } else {
183 try {
184 Long newVal = OFFSET_FORMAT.parseValue(string);
185 fOffsetMap.put((TmfTraceElement) element, newVal);
186 } catch (ParseException e) {
187 /* Ignore and reload previous value */
188 }
189 }
190 fViewer.getViewer().update(element, null);
191 }
192 }
193
194 @Override
195 protected Object getValue(Object element) {
196 if (fOffsetMap.get(element) == 0) {
197 return ""; //$NON-NLS-1$
198 }
199 return OFFSET_FORMAT.format((long) fOffsetMap.get(element));
200 }
201 }
202
203 /**
204 * Constructor
205 *
206 * @param parent
207 * parent shell
208 * @param results
209 * results to put the data into
210 */
211 public OffsetDialog(Shell parent, Map<TmfTraceElement, Long> results) {
212 super(parent);
213 setShellStyle(getShellStyle() & ~SWT.APPLICATION_MODAL);
214 fOffsetMap = results;
215 fRefTimeMap = new HashMap<>();
216 fTargetTimeMap = new HashMap<>();
217 }
218
219 @Override
220 protected boolean isResizable() {
221 return true;
222 }
223
224 @Override
225 protected Control createDialogArea(Composite parent) {
226 getShell().setText(Messages.OffsetDialog_Title);
227 Composite area = (Composite) super.createDialogArea(parent);
228 Composite composite = new Composite(area, SWT.NONE);
229 composite.setLayoutData(new GridData(GridData.FILL_BOTH));
230 GridLayout gl = new GridLayout();
231 gl.marginHeight = 0;
232 gl.marginWidth = 0;
233 composite.setLayout(new GridLayout());
234 createBasicMessage(composite);
235 createButtonGroup(composite);
236 createAdvancedMessage(composite);
237 createViewer(composite);
238
239 /* set label width hint equal to tree width */
240 int widthHint = fViewer.getViewer().getTree().computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
241 GridData gd = (GridData) fBasicMessageLabel.getLayoutData();
242 gd.widthHint = widthHint;
243 gd = (GridData) fAdvancedMessageLabel.getLayoutData();
244 gd.widthHint = widthHint;
245 gd = (GridData) composite.getLayoutData();
246 gd.heightHint = composite.computeSize(widthHint, SWT.DEFAULT).y;
247 setBasicMode();
248
249 TmfSignalManager.register(this);
250 composite.addDisposeListener(new DisposeListener() {
251 @Override
252 public void widgetDisposed(DisposeEvent e) {
253 TmfSignalManager.deregister(this);
254 }
255 });
256 return area;
257 }
258
259 private void createBasicMessage(final Composite parent) {
260 fBasicMessageLabel = new Label(parent, SWT.WRAP);
261 fBasicMessageLabel.setText(Messages.OffsetDialog_BasicMessage);
262 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
263 gd.widthHint = 0;
264 gd.heightHint = SWT.DEFAULT;
265 fBasicMessageLabel.setLayoutData(gd);
266 }
267
268 private void createButtonGroup(final Composite parent) {
269 fButtonGroup = new Group(parent, SWT.SHADOW_NONE);
270 fButtonGroup.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false));
271 fButtonGroup.setLayout(new RowLayout(SWT.HORIZONTAL));
272
273 final Button basicButton = new Button(fButtonGroup, SWT.RADIO);
274 basicButton.setText(Messages.OffsetDialog_BasicButton);
275 basicButton.addSelectionListener(new SelectionAdapter() {
276 @Override
277 public void widgetSelected(SelectionEvent e) {
278 if (!basicButton.getSelection() || !fAdvancedMode) {
279 return;
280 }
281 setBasicMode();
282 parent.layout();
283 }
284 });
285 basicButton.setSelection(true);
286
287 final Button advancedButton = new Button(fButtonGroup, SWT.RADIO);
288 advancedButton.setText(Messages.OffsetDialog_AdvancedButton);
289 advancedButton.addSelectionListener(new SelectionAdapter() {
290 @Override
291 public void widgetSelected(SelectionEvent e) {
292 if (!advancedButton.getSelection() || fAdvancedMode) {
293 return;
294 }
295 setAdvancedMode();
296 parent.layout();
297 }
298 });
299 }
300
301 private void createAdvancedMessage(final Composite parent) {
302 fAdvancedMessageLabel = new Label(parent, SWT.WRAP);
303 fAdvancedMessageLabel.setText(Messages.OffsetDialog_AdvancedMessage);
304 GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
305 gd.widthHint = 0;
306 gd.heightHint = SWT.DEFAULT;
307 fAdvancedMessageLabel.setLayoutData(gd);
308 }
309
310 private void createViewer(Composite parent) {
311
312 // Define the TableViewer
313 fViewer = new FilteredTree(parent, SWT.MULTI | SWT.H_SCROLL
314 | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER, new PatternFilter() {
315 @Override
316 protected boolean isLeafMatch(Viewer viewer, Object element) {
317 return wordMatches(((TmfTraceElement) element).getElementPath());
318 }
319 }, true);
320
321 // Make lines and make header visible
322 final Tree tree = fViewer.getViewer().getTree();
323 tree.setHeaderVisible(true);
324 tree.setLinesVisible(true);
325
326 TreeViewerFocusCellManager focusCellManager = new TreeViewerFocusCellManager(fViewer.getViewer(), new FocusCellOwnerDrawHighlighter(fViewer.getViewer()));
327 ColumnViewerEditorActivationStrategy actSupport = new ColumnViewerEditorActivationStrategy(fViewer.getViewer());
328 TreeViewerEditor.create(fViewer.getViewer(), focusCellManager, actSupport, ColumnViewerEditor.TABBING_HORIZONTAL
329 | ColumnViewerEditor.TABBING_MOVE_TO_ROW_NEIGHBOR
330 | ColumnViewerEditor.TABBING_VERTICAL | ColumnViewerEditor.KEYBOARD_ACTIVATION);
331
332 final TextCellEditor textCellEditor = new TextCellEditor(fViewer.getViewer().getTree(), SWT.RIGHT);
333
334 fViewer.getViewer().setColumnProperties(new String[] { Messages.OffsetDialog_TraceName, Messages.OffsetDialog_ReferenceTime, Messages.OffsetDialog_OffsetTime });
335
336 TreeViewerColumn column = createTreeViewerColumn(Messages.OffsetDialog_TraceName, SWT.NONE);
337 column.setLabelProvider(new ColumnLabelProvider() {
338 @Override
339 public String getText(Object element) {
340 return ((TmfTraceElement) element).getElementPath();
341 }
342 });
343
344 column = createTreeViewerColumn(Messages.OffsetDialog_OffsetTime, SWT.RIGHT);
345 column.setLabelProvider(new ColumnLabelProvider() {
346 @Override
347 public String getText(Object element) {
348 if (fOffsetMap.get(element) != 0) {
349 return super.getText(OFFSET_FORMAT.format((long) fOffsetMap.get(element)));
350 }
351 return ""; //$NON-NLS-1$
352 }
353 });
354 column.setEditingSupport(new OffsetEditingSupport(fViewer.getViewer(), textCellEditor));
355
356 column = createTreeViewerColumn("", SWT.NONE); //$NON-NLS-1$
357 column.setLabelProvider(new ColumnLabelProvider() {
358 @Override
359 public String getText(Object element) {
360 return ""; //$NON-NLS-1$
361 }
362 });
363 column.getColumn().setWidth(TREE_EDITOR_MIN_WIDTH);
364 column.getColumn().setResizable(false);
365 fButtonViewerColumn = column;
366
367 column = createTreeViewerColumn(Messages.OffsetDialog_ReferenceTime, SWT.RIGHT);
368 column.setLabelProvider(new ColumnLabelProvider() {
369 @Override
370 public String getText(Object element) {
371 return super.getText(fRefTimeMap.get(element));
372 }
373 });
374 column.setEditingSupport(new RefTimeEditingSupport(fViewer.getViewer(), textCellEditor));
375 fRefTimeColumn = column.getColumn();
376
377 column = createTreeViewerColumn(Messages.OffsetDialog_TargetTime, SWT.RIGHT);
378 column.setLabelProvider(new ColumnLabelProvider() {
379 @Override
380 public String getText(Object element) {
381 return super.getText(fTargetTimeMap.get(element));
382 }
383 });
384 column.setEditingSupport(new TargetTimeEditingSupport(fViewer.getViewer(), textCellEditor));
385 fTargetTimeColumn = column.getColumn();
386
387 List<TmfTraceElement> traces = new ArrayList<>(fOffsetMap.keySet());
388 Collections.sort(traces, new Comparator<TmfTraceElement>() {
389 @Override
390 public int compare(TmfTraceElement o1, TmfTraceElement o2) {
391 IPath folder1 = new Path(o1.getElementPath()).removeLastSegments(1);
392 IPath folder2 = new Path(o2.getElementPath()).removeLastSegments(1);
393 if (folder1.equals(folder2)) {
394 return o1.getName().compareToIgnoreCase(o2.getName());
395 }
396 if (folder1.isPrefixOf(folder2)) {
397 return 1;
398 } else if (folder2.isPrefixOf(folder1)) {
399 return -1;
400 }
401 return folder1.toString().compareToIgnoreCase(folder2.toString());
402 }
403 });
404
405 fViewer.getViewer().setContentProvider(new ArrayTreeContentProvider());
406 fViewer.getViewer().setInput(traces);
407
408 /* add button as tree editors to fourth column of every item */
409 for (TreeItem treeItem : tree.getItems()) {
410 TreeEditor treeEditor = new TreeEditor(tree);
411 Button applyButton = new Button(tree, SWT.PUSH);
412 applyButton.setText("<<"); //$NON-NLS-1$
413 applyButton.setData(treeItem.getData());
414 applyButton.addSelectionListener(new SelectionAdapter() {
415 @Override
416 public void widgetSelected(SelectionEvent e) {
417 TmfTraceElement traceElement = (TmfTraceElement) e.widget.getData();
418 ITmfTimestamp targetTime = fTargetTimeMap.get(traceElement);
419 ITmfTimestamp refTime = fRefTimeMap.get(traceElement);
420 if (targetTime != null && refTime != null) {
421 long offset = new TmfNanoTimestamp(targetTime).getValue() -
422 new TmfNanoTimestamp(refTime).getValue();
423 fOffsetMap.put(traceElement, offset);
424 fViewer.getViewer().update(traceElement, null);
425 }
426 }
427 });
428 treeEditor.grabHorizontal = true;
429 treeEditor.minimumWidth = TREE_EDITOR_MIN_WIDTH;
430 treeEditor.setEditor(applyButton, treeItem, 2);
431 treeItem.setData(EDITOR_KEY, applyButton);
432 }
433
434 /* put temporary values in maps to pack according to time formats */
435 fRefTimeMap.put(traces.get(0), new TmfNanoTimestamp());
436 fTargetTimeMap.put(traces.get(0), new TmfNanoTimestamp());
437 fViewer.getViewer().update(traces.get(0), null);
438 for (final TreeColumn treeColumn : tree.getColumns()) {
439 if (treeColumn.getResizable()) {
440 treeColumn.pack();
441 }
442 }
443 fRefTimeMap.clear();
444 fTargetTimeMap.clear();
445 fViewer.getViewer().update(traces.get(0), null);
446
447 for (TmfTraceElement traceElement : fOffsetMap.keySet()) {
448 for (ITmfTrace parentTrace : TmfTraceManager.getInstance().getOpenedTraces()) {
449 for (ITmfTrace trace : TmfTraceManager.getTraceSet(parentTrace)) {
450 if (traceElement.getResource().equals(trace.getResource())) {
451 fRefTimeMap.put(traceElement, trace.getStartTime());
452 fViewer.getViewer().update(traceElement, null);
453 break;
454 }
455 }
456 if (fRefTimeMap.get(traceElement) != null) {
457 break;
458 }
459 }
460 }
461
462 /* open trace when double-clicking a tree item */
463 tree.addSelectionListener(new SelectionAdapter() {
464 @Override
465 public void widgetDefaultSelected(SelectionEvent e) {
466 TmfTraceElement traceElement = (TmfTraceElement) e.item.getData();
467 TmfOpenTraceHelper.openTraceFromElement(traceElement);
468 }
469 });
470
471 tree.setFocus();
472 }
473
474 private TreeViewerColumn createTreeViewerColumn(String title, int style) {
475 final TreeViewerColumn viewerColumn = new TreeViewerColumn(fViewer.getViewer(), style);
476 final TreeColumn column = viewerColumn.getColumn();
477 column.setText(title);
478 column.setResizable(true);
479 return viewerColumn;
480 }
481
482 private void setBasicMode() {
483 fAdvancedMode = false;
484 fRefTimeColumn.setData(WIDTH_KEY, fRefTimeColumn.getWidth());
485 fTargetTimeColumn.setData(WIDTH_KEY, fTargetTimeColumn.getWidth());
486 for (TreeItem treeItem : fViewer.getViewer().getTree().getItems()) {
487 Control editor = (Control) treeItem.getData(EDITOR_KEY);
488 editor.setVisible(false);
489 }
490 fTargetTimeColumn.setWidth(0);
491 fTargetTimeColumn.setResizable(false);
492 fRefTimeColumn.setWidth(0);
493 fRefTimeColumn.setResizable(false);
494 fButtonViewerColumn.getColumn().setWidth(0);
495 fAdvancedMessageLabel.setText(""); //$NON-NLS-1$
496 }
497
498 private void setAdvancedMode() {
499 fAdvancedMode = true;
500 fButtonViewerColumn.getColumn().setWidth(TREE_EDITOR_MIN_WIDTH);
501 fRefTimeColumn.setWidth((Integer) fRefTimeColumn.getData(WIDTH_KEY));
502 fRefTimeColumn.setResizable(true);
503 fTargetTimeColumn.setWidth((Integer) fTargetTimeColumn.getData(WIDTH_KEY));
504 fTargetTimeColumn.setResizable(true);
505 for (TreeItem treeItem : fViewer.getViewer().getTree().getItems()) {
506 Control editor = (Control) treeItem.getData(EDITOR_KEY);
507 editor.setVisible(true);
508 }
509 fAdvancedMessageLabel.setText(Messages.OffsetDialog_AdvancedMessage);
510 }
511
512 /**
513 * Handler for the event selected signal
514 *
515 * @param signal
516 * the event selected signal
517 */
518 @TmfSignalHandler
519 public void eventSelected(final TmfEventSelectedSignal signal) {
520 Display.getDefault().asyncExec(new Runnable() {
521 @Override
522 public void run() {
523 for (TmfTraceElement traceElement : fOffsetMap.keySet()) {
524 if (traceElement.getResource().equals(signal.getEvent().getTrace().getResource())) {
525 fRefTimeMap.put(traceElement, signal.getEvent().getTimestamp());
526 fViewer.getViewer().update(traceElement, null);
527 break;
528 }
529 }
530 }
531 });
532 }
533
534 /**
535 * Handler for the time selected signal
536 *
537 * @param signal
538 * the event selected signal
539 */
540 @TmfSignalHandler
541 public void timeSelected(final TmfTimeSynchSignal signal) {
542 Display.getDefault().asyncExec(new Runnable() {
543 @Override
544 public void run() {
545 for (TmfTraceElement traceElement : fOffsetMap.keySet()) {
546 fTargetTimeMap.put(traceElement, signal.getBeginTime());
547 fViewer.getViewer().update(traceElement, null);
548 }
549 }
550 });
551 }
552
553 /**
554 * Handler for the trace opened signal
555 *
556 * @param signal
557 * the trace opened signal
558 */
559 @TmfSignalHandler
560 public void traceOpened(final TmfTraceOpenedSignal signal) {
561 Display.getDefault().asyncExec(new Runnable() {
562 @Override
563 public void run() {
564 for (ITmfTrace trace : TmfTraceManager.getTraceSet(signal.getTrace())) {
565 for (TmfTraceElement traceElement : fOffsetMap.keySet()) {
566 if (traceElement.getResource().equals(trace.getResource())) {
567 if (fRefTimeMap.get(traceElement) == null) {
568 fRefTimeMap.put(traceElement, trace.getStartTime());
569 fViewer.getViewer().update(traceElement, null);
570 }
571 break;
572 }
573 }
574 }
575 }
576 });
577 }
578 }
This page took 0.043903 seconds and 4 git commands to generate.