tmf: Split time graph filter dialog from TimeGraphCombo
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / widgets / timegraph / TimeGraphViewer.java
1 /*****************************************************************************
2 * Copyright (c) 2007, 2015 Intel Corporation, Ericsson, others
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Intel Corporation - Initial API and implementation
10 * Ruslan A. Scherbakov, Intel - Initial API and implementation
11 * Alexander N. Alexeev, Intel - Add monitors statistics support
12 * Alvaro Sanchez-Leon - Adapted for TMF
13 * Patrick Tasse - Refactoring
14 * Geneviève Bastien - Add event links between entries
15 *****************************************************************************/
16
17 package org.eclipse.tracecompass.tmf.ui.widgets.timegraph;
18
19 import java.util.ArrayList;
20 import java.util.List;
21
22 import org.eclipse.jface.action.Action;
23 import org.eclipse.jface.action.IAction;
24 import org.eclipse.jface.dialogs.IDialogSettings;
25 import org.eclipse.jface.viewers.AbstractTreeViewer;
26 import org.eclipse.jface.viewers.ISelectionProvider;
27 import org.eclipse.jface.viewers.ITableLabelProvider;
28 import org.eclipse.jface.viewers.ITreeContentProvider;
29 import org.eclipse.jface.viewers.ViewerFilter;
30 import org.eclipse.swt.SWT;
31 import org.eclipse.swt.events.ControlAdapter;
32 import org.eclipse.swt.events.ControlEvent;
33 import org.eclipse.swt.events.KeyAdapter;
34 import org.eclipse.swt.events.KeyEvent;
35 import org.eclipse.swt.events.MenuDetectListener;
36 import org.eclipse.swt.events.MouseEvent;
37 import org.eclipse.swt.events.MouseWheelListener;
38 import org.eclipse.swt.events.SelectionAdapter;
39 import org.eclipse.swt.events.SelectionEvent;
40 import org.eclipse.swt.events.SelectionListener;
41 import org.eclipse.swt.graphics.Rectangle;
42 import org.eclipse.swt.layout.FillLayout;
43 import org.eclipse.swt.layout.GridData;
44 import org.eclipse.swt.layout.GridLayout;
45 import org.eclipse.swt.widgets.Composite;
46 import org.eclipse.swt.widgets.Control;
47 import org.eclipse.swt.widgets.Display;
48 import org.eclipse.swt.widgets.Event;
49 import org.eclipse.swt.widgets.Listener;
50 import org.eclipse.swt.widgets.Slider;
51 import org.eclipse.tracecompass.internal.tmf.ui.Activator;
52 import org.eclipse.tracecompass.internal.tmf.ui.ITmfImageConstants;
53 import org.eclipse.tracecompass.internal.tmf.ui.Messages;
54 import org.eclipse.tracecompass.tmf.ui.signal.TmfTimeViewAlignmentInfo;
55 import org.eclipse.tracecompass.tmf.ui.views.ITmfTimeAligned;
56 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.ShowFilterDialogAction;
57 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.dialogs.TimeGraphLegend;
58 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ILinkEvent;
59 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeEvent;
60 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.model.ITimeGraphEntry;
61 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.ITimeDataProvider;
62 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeDataProviderCyclesConverter;
63 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphColorScheme;
64 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl;
65 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphScale;
66 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphTooltipHandler;
67 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils;
68 import org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.Utils.TimeFormat;
69
70 /**
71 * Generic time graph viewer implementation
72 *
73 * @author Patrick Tasse, and others
74 */
75 public class TimeGraphViewer implements ITimeDataProvider, SelectionListener {
76
77 /** Constant indicating that all levels of the time graph should be expanded */
78 public static final int ALL_LEVELS = AbstractTreeViewer.ALL_LEVELS;
79
80 private static final int DEFAULT_NAME_WIDTH = 200;
81 private static final int MIN_NAME_WIDTH = 6;
82 private static final int MAX_NAME_WIDTH = 1000;
83 private static final int DEFAULT_HEIGHT = 22;
84 private static final String HIDE_ARROWS_KEY = "hide.arrows"; //$NON-NLS-1$
85 private static final long DEFAULT_FREQUENCY = 1000000000L;
86 private static final int H_SCROLLBAR_MAX = Integer.MAX_VALUE - 1;
87
88 private long fMinTimeInterval;
89 private ITimeGraphEntry fSelectedEntry;
90 private long fBeginTime = SWT.DEFAULT; // The user-specified bounds start time
91 private long fEndTime = SWT.DEFAULT; // The user-specified bounds end time
92 private long fTime0 = SWT.DEFAULT; // The current window start time
93 private long fTime1 = SWT.DEFAULT; // The current window end time
94 private long fSelectionBegin = SWT.DEFAULT;
95 private long fSelectionEnd = SWT.DEFAULT;
96 private long fTime0Bound = SWT.DEFAULT; // The bounds start time
97 private long fTime1Bound = SWT.DEFAULT; // The bounds end time
98 private long fTime0ExtSynch = SWT.DEFAULT;
99 private long fTime1ExtSynch = SWT.DEFAULT;
100 private boolean fTimeRangeFixed;
101 private int fNameWidthPref = DEFAULT_NAME_WIDTH;
102 private int fMinNameWidth = MIN_NAME_WIDTH;
103 private int fNameWidth;
104 private Composite fDataViewer;
105
106 private TimeGraphControl fTimeGraphCtrl;
107 private TimeGraphScale fTimeScaleCtrl;
108 private Slider fHorizontalScrollBar;
109 private Slider fVerticalScrollBar;
110 private TimeGraphColorScheme fColorScheme;
111 private Object fInputElement;
112 private ITimeGraphContentProvider fTimeGraphContentProvider;
113 private ITimeGraphPresentationProvider fTimeGraphProvider;
114 private ITimeDataProvider fTimeDataProvider = this;
115 private TimeGraphTooltipHandler fToolTipHandler;
116
117 private List<ITimeGraphSelectionListener> fSelectionListeners = new ArrayList<>();
118 private List<ITimeGraphTimeListener> fTimeListeners = new ArrayList<>();
119 private List<ITimeGraphRangeListener> fRangeListeners = new ArrayList<>();
120
121 // Time format, using Epoch reference, Relative time format(default),
122 // Number, or Cycles
123 private TimeFormat fTimeFormat = TimeFormat.RELATIVE;
124 // Clock frequency to use for Cycles time format
125 private long fClockFrequency = DEFAULT_FREQUENCY;
126 private int fBorderWidth = 0;
127 private int fTimeScaleHeight = DEFAULT_HEIGHT;
128
129 private Action fResetScaleAction;
130 private Action fShowLegendAction;
131 private Action fNextEventAction;
132 private Action fPrevEventAction;
133 private Action fNextItemAction;
134 private Action fPreviousItemAction;
135 private Action fZoomInAction;
136 private Action fZoomOutAction;
137 private Action fHideArrowsAction;
138 private Action fFollowArrowFwdAction;
139 private Action fFollowArrowBwdAction;
140 private ShowFilterDialogAction fShowFilterDialogAction;
141
142 private ListenerNotifier fListenerNotifier;
143
144 private Composite fTimeAlignedComposite;
145
146 private class ListenerNotifier extends Thread {
147 private static final long DELAY = 400L;
148 private static final long POLLING_INTERVAL = 10L;
149 private long fLastUpdateTime = Long.MAX_VALUE;
150 private boolean fSelectionChanged = false;
151 private boolean fTimeRangeUpdated = false;
152 private boolean fTimeSelected = false;
153
154 @Override
155 public void run() {
156 while ((System.currentTimeMillis() - fLastUpdateTime) < DELAY) {
157 try {
158 Thread.sleep(POLLING_INTERVAL);
159 } catch (Exception e) {
160 return;
161 }
162 }
163 Display.getDefault().asyncExec(new Runnable() {
164 @Override
165 public void run() {
166 if (fListenerNotifier != ListenerNotifier.this) {
167 return;
168 }
169 fListenerNotifier = null;
170 if (ListenerNotifier.this.isInterrupted() || fDataViewer.isDisposed()) {
171 return;
172 }
173 if (fSelectionChanged) {
174 fireSelectionChanged(fSelectedEntry);
175 }
176 if (fTimeRangeUpdated) {
177 fireTimeRangeUpdated(fTime0, fTime1);
178 }
179 if (fTimeSelected) {
180 fireTimeSelected(fSelectionBegin, fSelectionEnd);
181 }
182 }
183 });
184 }
185
186 public void selectionChanged() {
187 fSelectionChanged = true;
188 fLastUpdateTime = System.currentTimeMillis();
189 }
190
191 public void timeRangeUpdated() {
192 fTimeRangeUpdated = true;
193 fLastUpdateTime = System.currentTimeMillis();
194 }
195
196 public void timeSelected() {
197 fTimeSelected = true;
198 fLastUpdateTime = System.currentTimeMillis();
199 }
200
201 public boolean hasSelectionChanged() {
202 return fSelectionChanged;
203 }
204
205 public boolean hasTimeRangeUpdated() {
206 return fTimeRangeUpdated;
207 }
208
209 public boolean hasTimeSelected() {
210 return fTimeSelected;
211 }
212 }
213
214 /**
215 * Standard constructor.
216 * <p>
217 * The default timegraph content provider accepts an ITimeGraphEntry[] as input element.
218 *
219 * @param parent
220 * The parent UI composite object
221 * @param style
222 * The style to use
223 */
224 public TimeGraphViewer(Composite parent, int style) {
225 createDataViewer(parent, style);
226 fTimeGraphContentProvider = new TimeGraphContentProvider();
227 }
228
229 /**
230 * Sets the timegraph content provider used by this timegraph viewer.
231 *
232 * @param timeGraphContentProvider
233 * the timegraph content provider
234 */
235 public void setTimeGraphContentProvider(ITimeGraphContentProvider timeGraphContentProvider) {
236 fTimeGraphContentProvider = timeGraphContentProvider;
237 }
238
239 /**
240 * Gets the timegraph content provider used by this timegraph viewer.
241 *
242 * @return the timegraph content provider
243 */
244 public ITimeGraphContentProvider getTimeGraphContentProvider() {
245 return fTimeGraphContentProvider;
246 }
247
248 /**
249 * Sets the timegraph presentation provider used by this timegraph viewer.
250 *
251 * @param timeGraphProvider
252 * the timegraph provider
253 */
254 public void setTimeGraphProvider(ITimeGraphPresentationProvider timeGraphProvider) {
255 fTimeGraphProvider = timeGraphProvider;
256 fTimeGraphCtrl.setTimeGraphProvider(timeGraphProvider);
257 fToolTipHandler = new TimeGraphTooltipHandler(fTimeGraphProvider, fTimeDataProvider);
258 fToolTipHandler.activateHoverHelp(fTimeGraphCtrl);
259 }
260
261 /**
262 * Sets the tree columns for this time graph combo's filter dialog.
263 *
264 * @param columnNames the tree column names
265 * @since 2.0
266 */
267 public void setFilterColumns(String[] columnNames) {
268 getShowFilterDialogAction().getFilterDialog().setColumnNames(columnNames);
269 }
270
271 /**
272 * Sets the tree content provider used by the filter dialog
273 *
274 * @param contentProvider the tree content provider
275 * @since 2.0
276 */
277 public void setFilterContentProvider(ITreeContentProvider contentProvider) {
278 getShowFilterDialogAction().getFilterDialog().setContentProvider(contentProvider);
279 }
280
281 /**
282 * Sets the tree label provider used by the filter dialog
283 *
284 * @param labelProvider the tree label provider
285 * @since 2.0
286 */
287 public void setFilterLabelProvider(ITableLabelProvider labelProvider) {
288 getShowFilterDialogAction().getFilterDialog().setLabelProvider(labelProvider);
289 }
290
291 /**
292 * Sets or clears the input for this time graph viewer.
293 *
294 * @param inputElement
295 * The input of this time graph viewer, or <code>null</code> if
296 * none
297 */
298 public void setInput(Object inputElement) {
299 fInputElement = inputElement;
300 ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(inputElement);
301 fListenerNotifier = null;
302 if (fTimeGraphCtrl != null) {
303 setTimeRange(input);
304 setTopIndex(0);
305 fSelectionBegin = SWT.DEFAULT;
306 fSelectionEnd = SWT.DEFAULT;
307 fSelectedEntry = null;
308 refreshAllData(input);
309 }
310 }
311
312 /**
313 * Gets the input for this time graph viewer.
314 *
315 * @return The input of this time graph viewer, or <code>null</code> if none
316 */
317 public Object getInput() {
318 return fInputElement;
319 }
320
321 /**
322 * Sets (or clears if null) the list of links to display on this combo
323 *
324 * @param links
325 * the links to display in this time graph combo
326 */
327 public void setLinks(List<ILinkEvent> links) {
328 if (fTimeGraphCtrl != null) {
329 fTimeGraphCtrl.refreshArrows(links);
330 }
331 }
332
333 /**
334 * Refresh the view
335 */
336 public void refresh() {
337 ITimeGraphEntry[] input = fTimeGraphContentProvider.getElements(fInputElement);
338 setTimeRange(input);
339 refreshAllData(input);
340 }
341
342 /**
343 * Callback for when the control is moved
344 *
345 * @param e
346 * The caller event
347 */
348 public void controlMoved(ControlEvent e) {
349 }
350
351 /**
352 * Callback for when the control is resized
353 *
354 * @param e
355 * The caller event
356 */
357 public void controlResized(ControlEvent e) {
358 resizeControls();
359 }
360
361 /**
362 * @return The string representing the view type
363 */
364 protected String getViewTypeStr() {
365 return "viewoption.threads"; //$NON-NLS-1$
366 }
367
368 int getMarginWidth() {
369 return 0;
370 }
371
372 int getMarginHeight() {
373 return 0;
374 }
375
376 void loadOptions() {
377 fMinTimeInterval = 1;
378 fSelectionBegin = SWT.DEFAULT;
379 fSelectionEnd = SWT.DEFAULT;
380 fNameWidth = Utils.loadIntOption(getPreferenceString("namewidth"), //$NON-NLS-1$
381 fNameWidthPref, fMinNameWidth, MAX_NAME_WIDTH);
382 }
383
384 void saveOptions() {
385 Utils.saveIntOption(getPreferenceString("namewidth"), fNameWidth); //$NON-NLS-1$
386 }
387
388 /**
389 * Create a data viewer.
390 *
391 * @param parent
392 * Parent composite
393 * @param style
394 * Style to use
395 * @return The new data viewer
396 */
397 protected Control createDataViewer(Composite parent, int style) {
398 loadOptions();
399 fColorScheme = new TimeGraphColorScheme();
400 fDataViewer = new Composite(parent, style) {
401 @Override
402 public void redraw() {
403 fTimeScaleCtrl.redraw();
404 fTimeGraphCtrl.redraw();
405 super.redraw();
406 }
407 };
408 GridLayout gl = new GridLayout(2, false);
409 gl.marginHeight = fBorderWidth;
410 gl.marginWidth = 0;
411 gl.verticalSpacing = 0;
412 gl.horizontalSpacing = 0;
413 fDataViewer.setLayout(gl);
414
415 fTimeAlignedComposite = new Composite(fDataViewer, style) {
416 @Override
417 public void redraw() {
418 fDataViewer.redraw();
419 super.redraw();
420 }
421 };
422 GridLayout gl2 = new GridLayout(1, false);
423 gl2.marginHeight = fBorderWidth;
424 gl2.marginWidth = 0;
425 gl2.verticalSpacing = 0;
426 gl2.horizontalSpacing = 0;
427 fTimeAlignedComposite.setLayout(gl2);
428 fTimeAlignedComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
429
430 fTimeScaleCtrl = new TimeGraphScale(fTimeAlignedComposite, fColorScheme);
431 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
432 fTimeScaleCtrl.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
433 fTimeScaleCtrl.setHeight(fTimeScaleHeight);
434 fTimeScaleCtrl.addMouseWheelListener(new MouseWheelListener() {
435 @Override
436 public void mouseScrolled(MouseEvent e) {
437 fTimeGraphCtrl.zoom(e.count > 0);
438 }
439 });
440
441 fTimeGraphCtrl = createTimeGraphControl(fTimeAlignedComposite, fColorScheme);
442
443 fTimeGraphCtrl.setTimeProvider(this);
444 fTimeGraphCtrl.setTimeGraphScale(fTimeScaleCtrl);
445 fTimeGraphCtrl.addSelectionListener(this);
446 fTimeGraphCtrl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
447 fTimeGraphCtrl.addMouseWheelListener(new MouseWheelListener() {
448 @Override
449 public void mouseScrolled(MouseEvent e) {
450 adjustVerticalScrollBar();
451 }
452 });
453 fTimeGraphCtrl.addKeyListener(new KeyAdapter() {
454 @Override
455 public void keyPressed(KeyEvent e) {
456 if (e.character == '+') {
457 zoomIn();
458 } else if (e.character == '-') {
459 zoomOut();
460 }
461 adjustVerticalScrollBar();
462 }
463 });
464
465 fVerticalScrollBar = new Slider(fDataViewer, SWT.VERTICAL | SWT.NO_FOCUS);
466 fVerticalScrollBar.setLayoutData(new GridData(SWT.DEFAULT, SWT.FILL, false, true, 1, 1));
467 fVerticalScrollBar.addSelectionListener(new SelectionAdapter() {
468 @Override
469 public void widgetSelected(SelectionEvent e) {
470 setTopIndex(fVerticalScrollBar.getSelection());
471 }
472 });
473
474 fHorizontalScrollBar = new Slider(fDataViewer, SWT.HORIZONTAL | SWT.NO_FOCUS);
475 fHorizontalScrollBar.setLayoutData(new GridData(SWT.FILL, SWT.DEFAULT, true, false));
476 fHorizontalScrollBar.addListener(SWT.MouseWheel, new Listener() {
477 @Override
478 public void handleEvent(Event event) {
479 if ((event.stateMask & SWT.MODIFIER_MASK) == SWT.CTRL) {
480 getTimeGraphControl().zoom(event.count > 0);
481 } else {
482 getTimeGraphControl().horizontalScroll(event.count > 0);
483 }
484 // don't handle the immediately following SWT.Selection event
485 event.doit = false;
486 }
487 });
488 fHorizontalScrollBar.addListener(SWT.Selection, new Listener() {
489 @Override
490 public void handleEvent(Event event) {
491 int start = fHorizontalScrollBar.getSelection();
492 long time0 = getTime0();
493 long time1 = getTime1();
494 long timeMin = getMinTime();
495 long timeMax = getMaxTime();
496 long delta = timeMax - timeMin;
497
498 long range = time1 - time0;
499 time0 = timeMin + Math.round(delta * ((double) start / H_SCROLLBAR_MAX));
500 time1 = time0 + range;
501
502 setStartFinishTimeNotify(time0, time1);
503 }
504 });
505
506 Composite filler = new Composite(fDataViewer, SWT.NONE);
507 GridData gd = new GridData(SWT.DEFAULT, SWT.DEFAULT, false, false);
508 gd.heightHint = fHorizontalScrollBar.getSize().y;
509 filler.setLayoutData(gd);
510 filler.setLayout(new FillLayout());
511
512 fTimeGraphCtrl.addControlListener(new ControlAdapter() {
513 @Override
514 public void controlResized(ControlEvent event) {
515 resizeControls();
516 }
517 });
518 resizeControls();
519 fDataViewer.update();
520 adjustHorizontalScrollBar();
521 adjustVerticalScrollBar();
522 return fDataViewer;
523 }
524
525 /**
526 * Dispose the view.
527 */
528 public void dispose() {
529 saveOptions();
530 fTimeGraphCtrl.dispose();
531 fDataViewer.dispose();
532 fColorScheme.dispose();
533 }
534
535 /**
536 * Create a new time graph control.
537 *
538 * @param parent
539 * The parent composite
540 * @param colors
541 * The color scheme
542 * @return The new TimeGraphControl
543 */
544 protected TimeGraphControl createTimeGraphControl(Composite parent,
545 TimeGraphColorScheme colors) {
546 return new TimeGraphControl(parent, colors);
547 }
548
549 /**
550 * Resize the controls
551 */
552 public void resizeControls() {
553 Rectangle r = fDataViewer.getClientArea();
554 if (r.isEmpty()) {
555 return;
556 }
557
558 int width = r.width;
559 if (fNameWidth > width - fMinNameWidth) {
560 fNameWidth = width - fMinNameWidth;
561 }
562 if (fNameWidth < fMinNameWidth) {
563 fNameWidth = fMinNameWidth;
564 }
565 adjustHorizontalScrollBar();
566 adjustVerticalScrollBar();
567 }
568
569 /**
570 * Recalculate the time bounds based on the time graph entries,
571 * if the user-specified bound is set to SWT.DEFAULT.
572 *
573 * @param entries
574 * The root time graph entries in the model
575 */
576 public void setTimeRange(ITimeGraphEntry entries[]) {
577 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
578 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
579 if (fBeginTime != SWT.DEFAULT && fEndTime != SWT.DEFAULT) {
580 return;
581 }
582 if (entries == null || entries.length == 0) {
583 return;
584 }
585 if (fTime0Bound == SWT.DEFAULT) {
586 fTime0Bound = Long.MAX_VALUE;
587 }
588 if (fTime1Bound == SWT.DEFAULT) {
589 fTime1Bound = Long.MIN_VALUE;
590 }
591 for (ITimeGraphEntry entry : entries) {
592 setTimeRange(entry);
593 }
594 }
595
596 private void setTimeRange(ITimeGraphEntry entry) {
597 if (fBeginTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getStartTime() != SWT.DEFAULT) {
598 fTime0Bound = Math.min(entry.getStartTime(), fTime0Bound);
599 }
600 if (fEndTime == SWT.DEFAULT && entry.hasTimeEvents() && entry.getEndTime() != SWT.DEFAULT) {
601 fTime1Bound = Math.max(entry.getEndTime(), fTime1Bound);
602 }
603 if (entry.hasChildren()) {
604 for (ITimeGraphEntry child : entry.getChildren()) {
605 setTimeRange(child);
606 }
607 }
608 }
609
610 /**
611 * Set the time bounds to the provided values.
612 *
613 * @param beginTime
614 * The bounds begin time, or SWT.DEFAULT to use the input bounds
615 * @param endTime
616 * The bounds end time, or SWT.DEFAULT to use the input bounds
617 */
618 public void setTimeBounds(long beginTime, long endTime) {
619 fBeginTime = beginTime;
620 fEndTime = endTime;
621 fTime0Bound = (fBeginTime != SWT.DEFAULT ? fBeginTime : fEndTime);
622 fTime1Bound = (fEndTime != SWT.DEFAULT ? fEndTime : fBeginTime);
623 if (fTime0Bound > fTime1Bound) {
624 // only possible if both are not default
625 fBeginTime = endTime;
626 fEndTime = beginTime;
627 fTime0Bound = fBeginTime;
628 fTime1Bound = fEndTime;
629 }
630 adjustHorizontalScrollBar();
631 }
632
633 /**
634 * Recalculate the current time window when bounds have changed.
635 */
636 public void setTimeBounds() {
637 if (!fTimeRangeFixed) {
638 fTime0 = fTime0Bound;
639 fTime1 = fTime1Bound;
640 }
641 fTime0 = Math.max(fTime0Bound, Math.min(fTime0, fTime1Bound));
642 fTime1 = Math.max(fTime0Bound, Math.min(fTime1, fTime1Bound));
643 if (fTime1 - fTime0 < fMinTimeInterval) {
644 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
645 }
646 }
647
648 /**
649 * @param traces
650 */
651 private void refreshAllData(ITimeGraphEntry[] traces) {
652 setTimeBounds();
653 if (fSelectionBegin < fBeginTime) {
654 fSelectionBegin = fBeginTime;
655 } else if (fSelectionBegin > fEndTime) {
656 fSelectionBegin = fEndTime;
657 }
658 if (fSelectionEnd < fBeginTime) {
659 fSelectionEnd = fBeginTime;
660 } else if (fSelectionEnd > fEndTime) {
661 fSelectionEnd = fEndTime;
662 }
663 fTimeGraphCtrl.refreshData(traces);
664 fTimeScaleCtrl.redraw();
665 adjustVerticalScrollBar();
666 }
667
668 /**
669 * Callback for when this view is focused
670 */
671 public void setFocus() {
672 if (null != fTimeGraphCtrl) {
673 fTimeGraphCtrl.setFocus();
674 }
675 }
676
677 /**
678 * Get the current focus status of this view.
679 *
680 * @return If the view is currently focused, or not
681 */
682 public boolean isInFocus() {
683 return fTimeGraphCtrl.isInFocus();
684 }
685
686 /**
687 * Get the view's current selection
688 *
689 * @return The entry that is selected
690 */
691 public ITimeGraphEntry getSelection() {
692 return fTimeGraphCtrl.getSelectedTrace();
693 }
694
695 /**
696 * Get the index of the current selection
697 *
698 * @return The index
699 */
700 public int getSelectionIndex() {
701 return fTimeGraphCtrl.getSelectedIndex();
702 }
703
704 @Override
705 public long getTime0() {
706 return fTime0;
707 }
708
709 @Override
710 public long getTime1() {
711 return fTime1;
712 }
713
714 @Override
715 public long getMinTimeInterval() {
716 return fMinTimeInterval;
717 }
718
719 @Override
720 public int getNameSpace() {
721 return fNameWidth;
722 }
723
724 @Override
725 public void setNameSpace(int width) {
726 fNameWidth = width;
727 int w = fTimeGraphCtrl.getClientArea().width;
728 if (fNameWidth > w - MIN_NAME_WIDTH) {
729 fNameWidth = w - MIN_NAME_WIDTH;
730 }
731 if (fNameWidth < MIN_NAME_WIDTH) {
732 fNameWidth = MIN_NAME_WIDTH;
733 }
734 fTimeGraphCtrl.redraw();
735 fTimeScaleCtrl.redraw();
736 }
737
738 @Override
739 public int getTimeSpace() {
740 int w = fTimeGraphCtrl.getClientArea().width;
741 return w - fNameWidth;
742 }
743
744 @Override
745 public long getBeginTime() {
746 return fBeginTime;
747 }
748
749 @Override
750 public long getEndTime() {
751 return fEndTime;
752 }
753
754 @Override
755 public long getMaxTime() {
756 return fTime1Bound;
757 }
758
759 @Override
760 public long getMinTime() {
761 return fTime0Bound;
762 }
763
764 @Override
765 public long getSelectionBegin() {
766 return fSelectionBegin;
767 }
768
769 @Override
770 public long getSelectionEnd() {
771 return fSelectionEnd;
772 }
773
774 @Override
775 public void setStartFinishTimeNotify(long time0, long time1) {
776 setStartFinishTimeInt(time0, time1);
777 notifyRangeListeners();
778 }
779
780 @Override
781 public void notifyStartFinishTime() {
782 notifyRangeListeners();
783 }
784
785 @Override
786 public void setStartFinishTime(long time0, long time1) {
787 /* if there is a pending time range, ignore this one */
788 if (fListenerNotifier != null && fListenerNotifier.hasTimeRangeUpdated()) {
789 return;
790 }
791 setStartFinishTimeInt(time0, time1);
792 updateExtSynchValues();
793 }
794
795 private void setStartFinishTimeInt(long time0, long time1) {
796 fTime0 = time0;
797 if (fTime0 < fTime0Bound) {
798 fTime0 = fTime0Bound;
799 }
800 if (fTime0 > fTime1Bound) {
801 fTime0 = fTime1Bound;
802 }
803 fTime1 = time1;
804 if (fTime1 < fTime0Bound) {
805 fTime1 = fTime0Bound;
806 }
807 if (fTime1 > fTime1Bound) {
808 fTime1 = fTime1Bound;
809 }
810 if (fTime1 - fTime0 < fMinTimeInterval) {
811 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
812 }
813 fTimeRangeFixed = true;
814 adjustHorizontalScrollBar();
815 fTimeGraphCtrl.redraw();
816 fTimeScaleCtrl.redraw();
817 }
818
819 @Override
820 public void resetStartFinishTime() {
821 setStartFinishTimeNotify(fTime0Bound, fTime1Bound);
822 fTimeRangeFixed = false;
823 }
824
825 @Override
826 public void setSelectedTimeNotify(long time, boolean ensureVisible) {
827 setSelectedTimeInt(time, ensureVisible, true);
828 }
829
830 @Override
831 public void setSelectedTime(long time, boolean ensureVisible) {
832 /* if there is a pending time selection, ignore this one */
833 if (fListenerNotifier != null && fListenerNotifier.hasTimeSelected()) {
834 return;
835 }
836 setSelectedTimeInt(time, ensureVisible, false);
837 }
838
839 @Override
840 public void setSelectionRangeNotify(long beginTime, long endTime) {
841 long time0 = fTime0;
842 long time1 = fTime1;
843 long selectionBegin = fSelectionBegin;
844 long selectionEnd = fSelectionEnd;
845 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
846 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
847 boolean changed = (selectionBegin != fSelectionBegin || selectionEnd != fSelectionEnd);
848 ensureVisible(fSelectionEnd);
849 fTimeGraphCtrl.redraw();
850 fTimeScaleCtrl.redraw();
851 if ((time0 != fTime0) || (time1 != fTime1)) {
852 notifyRangeListeners();
853 }
854 if (changed) {
855 notifyTimeListeners();
856 }
857 }
858
859 @Override
860 public void setSelectionRange(long beginTime, long endTime) {
861 /* if there is a pending time selection, ignore this one */
862 if (fListenerNotifier != null && fListenerNotifier.hasTimeSelected()) {
863 return;
864 }
865 fSelectionBegin = Math.max(fTime0Bound, Math.min(fTime1Bound, beginTime));
866 fSelectionEnd = Math.max(fTime0Bound, Math.min(fTime1Bound, endTime));
867 fTimeGraphCtrl.redraw();
868 fTimeScaleCtrl.redraw();
869 }
870
871 private void setSelectedTimeInt(long time, boolean ensureVisible, boolean doNotify) {
872 long selection = Math.max(fTime0Bound, Math.min(fTime1Bound, time));
873 long time0 = fTime0;
874 long time1 = fTime1;
875 if (ensureVisible) {
876 ensureVisible(selection);
877 }
878 fTimeGraphCtrl.redraw();
879 fTimeScaleCtrl.redraw();
880
881 boolean notifySelectedTime = (selection != fSelectionBegin || selection != fSelectionEnd);
882 fSelectionBegin = selection;
883 fSelectionEnd = selection;
884
885 if ((time0 != fTime0) || (time1 != fTime1)) {
886 notifyRangeListeners();
887 }
888
889 if (doNotify && notifySelectedTime) {
890 notifyTimeListeners();
891 }
892 }
893
894 private void ensureVisible(long time) {
895 long timeMid = (fTime1 - fTime0) / 2;
896 if (time < fTime0) {
897 long dt = fTime0 - time + timeMid;
898 fTime0 -= dt;
899 fTime1 -= dt;
900 } else if (time > fTime1) {
901 long dt = time - fTime1 + timeMid;
902 fTime0 += dt;
903 fTime1 += dt;
904 }
905 if (fTime0 < fTime0Bound) {
906 fTime1 = Math.min(fTime1Bound, fTime1 + (fTime0Bound - fTime0));
907 fTime0 = fTime0Bound;
908 } else if (fTime1 > fTime1Bound) {
909 fTime0 = Math.max(fTime0Bound, fTime0 - (fTime1 - fTime1Bound));
910 fTime1 = fTime1Bound;
911 }
912 if (fTime1 - fTime0 < fMinTimeInterval) {
913 fTime1 = Math.min(fTime1Bound, fTime0 + fMinTimeInterval);
914 }
915 adjustHorizontalScrollBar();
916 }
917
918 @Override
919 public void widgetDefaultSelected(SelectionEvent e) {
920 if (fSelectedEntry != getSelection()) {
921 fSelectedEntry = getSelection();
922 notifySelectionListeners();
923 }
924 }
925
926 @Override
927 public void widgetSelected(SelectionEvent e) {
928 if (fSelectedEntry != getSelection()) {
929 fSelectedEntry = getSelection();
930 notifySelectionListeners();
931 }
932 }
933
934 /**
935 * Callback for when the next event is selected
936 *
937 * @param extend
938 * true to extend selection range, false for single selection
939 * @since 1.0
940 */
941 public void selectNextEvent(boolean extend) {
942 fTimeGraphCtrl.selectNextEvent(extend);
943 adjustVerticalScrollBar();
944 }
945
946 /**
947 * Callback for when the previous event is selected
948 *
949 * @param extend
950 * true to extend selection range, false for single selection
951 * @since 1.0
952 */
953 public void selectPrevEvent(boolean extend) {
954 fTimeGraphCtrl.selectPrevEvent(extend);
955 adjustVerticalScrollBar();
956 }
957
958 /**
959 * Callback for when the next item is selected
960 */
961 public void selectNextItem() {
962 fTimeGraphCtrl.selectNextTrace();
963 adjustVerticalScrollBar();
964 }
965
966 /**
967 * Callback for when the previous item is selected
968 */
969 public void selectPrevItem() {
970 fTimeGraphCtrl.selectPrevTrace();
971 adjustVerticalScrollBar();
972 }
973
974 /**
975 * Callback for the show legend action
976 */
977 public void showLegend() {
978 if (fDataViewer == null || fDataViewer.isDisposed()) {
979 return;
980 }
981
982 TimeGraphLegend.open(fDataViewer.getShell(), fTimeGraphProvider);
983 }
984
985 /**
986 * Callback for the Zoom In action
987 */
988 public void zoomIn() {
989 fTimeGraphCtrl.zoomIn();
990 }
991
992 /**
993 * Callback for the Zoom Out action
994 */
995 public void zoomOut() {
996 fTimeGraphCtrl.zoomOut();
997 }
998
999 private String getPreferenceString(String string) {
1000 return getViewTypeStr() + "." + string; //$NON-NLS-1$
1001 }
1002
1003 /**
1004 * Add a selection listener
1005 *
1006 * @param listener
1007 * The listener to add
1008 */
1009 public void addSelectionListener(ITimeGraphSelectionListener listener) {
1010 fSelectionListeners.add(listener);
1011 }
1012
1013 /**
1014 * Remove a selection listener
1015 *
1016 * @param listener
1017 * The listener to remove
1018 */
1019 public void removeSelectionListener(ITimeGraphSelectionListener listener) {
1020 fSelectionListeners.remove(listener);
1021 }
1022
1023 private void notifySelectionListeners() {
1024 if (fListenerNotifier == null) {
1025 fListenerNotifier = new ListenerNotifier();
1026 fListenerNotifier.start();
1027 }
1028 fListenerNotifier.selectionChanged();
1029 }
1030
1031 private void fireSelectionChanged(ITimeGraphEntry selection) {
1032 TimeGraphSelectionEvent event = new TimeGraphSelectionEvent(this, selection);
1033
1034 for (ITimeGraphSelectionListener listener : fSelectionListeners) {
1035 listener.selectionChanged(event);
1036 }
1037 }
1038
1039 /**
1040 * Add a time listener
1041 *
1042 * @param listener
1043 * The listener to add
1044 */
1045 public void addTimeListener(ITimeGraphTimeListener listener) {
1046 fTimeListeners.add(listener);
1047 }
1048
1049 /**
1050 * Remove a time listener
1051 *
1052 * @param listener
1053 * The listener to remove
1054 */
1055 public void removeTimeListener(ITimeGraphTimeListener listener) {
1056 fTimeListeners.remove(listener);
1057 }
1058
1059 private void notifyTimeListeners() {
1060 if (fListenerNotifier == null) {
1061 fListenerNotifier = new ListenerNotifier();
1062 fListenerNotifier.start();
1063 }
1064 fListenerNotifier.timeSelected();
1065 }
1066
1067 private void fireTimeSelected(long startTime, long endTime) {
1068 TimeGraphTimeEvent event = new TimeGraphTimeEvent(this, startTime, endTime);
1069
1070 for (ITimeGraphTimeListener listener : fTimeListeners) {
1071 listener.timeSelected(event);
1072 }
1073 }
1074
1075 /**
1076 * Add a range listener
1077 *
1078 * @param listener
1079 * The listener to add
1080 */
1081 public void addRangeListener(ITimeGraphRangeListener listener) {
1082 fRangeListeners.add(listener);
1083 }
1084
1085 /**
1086 * Remove a range listener
1087 *
1088 * @param listener
1089 * The listener to remove
1090 */
1091 public void removeRangeListener(ITimeGraphRangeListener listener) {
1092 fRangeListeners.remove(listener);
1093 }
1094
1095 private void notifyRangeListeners() {
1096 if (fListenerNotifier == null) {
1097 fListenerNotifier = new ListenerNotifier();
1098 fListenerNotifier.start();
1099 }
1100 fListenerNotifier.timeRangeUpdated();
1101 }
1102
1103 private void fireTimeRangeUpdated(long startTime, long endTime) {
1104 // Check if the time has actually changed from last notification
1105 if (startTime != fTime0ExtSynch || endTime != fTime1ExtSynch) {
1106 // Notify Time Scale Selection Listeners
1107 TimeGraphRangeUpdateEvent event = new TimeGraphRangeUpdateEvent(this, startTime, endTime);
1108
1109 for (ITimeGraphRangeListener listener : fRangeListeners) {
1110 listener.timeRangeUpdated(event);
1111 }
1112
1113 // update external synch values
1114 updateExtSynchValues();
1115 }
1116 }
1117
1118 /**
1119 * Callback to set a selected event in the view
1120 *
1121 * @param event
1122 * The event that was selected
1123 * @param source
1124 * The source of this selection event
1125 */
1126 public void setSelectedEvent(ITimeEvent event, Object source) {
1127 if (event == null || source == this) {
1128 return;
1129 }
1130 fSelectedEntry = event.getEntry();
1131 fTimeGraphCtrl.selectItem(fSelectedEntry, false);
1132
1133 setSelectedTimeInt(event.getTime(), true, true);
1134 adjustVerticalScrollBar();
1135 }
1136
1137 /**
1138 * Set the seeked time of a trace
1139 *
1140 * @param trace
1141 * The trace that was seeked
1142 * @param time
1143 * The target time
1144 * @param source
1145 * The source of this seek event
1146 */
1147 public void setSelectedTraceTime(ITimeGraphEntry trace, long time, Object source) {
1148 if (trace == null || source == this) {
1149 return;
1150 }
1151 fSelectedEntry = trace;
1152 fTimeGraphCtrl.selectItem(trace, false);
1153
1154 setSelectedTimeInt(time, true, true);
1155 }
1156
1157 /**
1158 * Callback for a trace selection
1159 *
1160 * @param trace
1161 * The trace that was selected
1162 */
1163 public void setSelection(ITimeGraphEntry trace) {
1164 /* if there is a pending selection, ignore this one */
1165 if (fListenerNotifier != null && fListenerNotifier.hasSelectionChanged()) {
1166 return;
1167 }
1168 fSelectedEntry = trace;
1169 fTimeGraphCtrl.selectItem(trace, false);
1170 adjustVerticalScrollBar();
1171 }
1172
1173 /**
1174 * Callback for a time window selection
1175 *
1176 * @param time0
1177 * Start time of the range
1178 * @param time1
1179 * End time of the range
1180 * @param source
1181 * Source of the event
1182 */
1183 public void setSelectVisTimeWindow(long time0, long time1, Object source) {
1184 if (source == this) {
1185 return;
1186 }
1187
1188 setStartFinishTimeInt(time0, time1);
1189
1190 // update notification time values since we are now in synch with the
1191 // external application
1192 updateExtSynchValues();
1193 }
1194
1195 /**
1196 * update the cache values used to identify the need to send a time window
1197 * update to external registered listeners
1198 */
1199 private void updateExtSynchValues() {
1200 // last time notification cache
1201 fTime0ExtSynch = fTime0;
1202 fTime1ExtSynch = fTime1;
1203 }
1204
1205 @Override
1206 public TimeFormat getTimeFormat() {
1207 return fTimeFormat;
1208 }
1209
1210 /**
1211 * @param tf
1212 * the {@link TimeFormat} used to display timestamps
1213 */
1214 public void setTimeFormat(TimeFormat tf) {
1215 this.fTimeFormat = tf;
1216 if (tf == TimeFormat.CYCLES) {
1217 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1218 } else {
1219 fTimeDataProvider = this;
1220 }
1221 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1222 if (fToolTipHandler != null) {
1223 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1224 }
1225 }
1226
1227 /**
1228 * Sets the clock frequency. Used when the time format is set to CYCLES.
1229 *
1230 * @param clockFrequency
1231 * the clock frequency in Hz
1232 */
1233 public void setClockFrequency(long clockFrequency) {
1234 fClockFrequency = clockFrequency;
1235 if (fTimeFormat == TimeFormat.CYCLES) {
1236 fTimeDataProvider = new TimeDataProviderCyclesConverter(this, fClockFrequency);
1237 fTimeScaleCtrl.setTimeProvider(fTimeDataProvider);
1238 if (fToolTipHandler != null) {
1239 fToolTipHandler.setTimeProvider(fTimeDataProvider);
1240 }
1241 }
1242 }
1243
1244 /**
1245 * Retrieve the border width
1246 *
1247 * @return The width
1248 */
1249 public int getBorderWidth() {
1250 return fBorderWidth;
1251 }
1252
1253 /**
1254 * Set the border width
1255 *
1256 * @param borderWidth
1257 * The width
1258 */
1259 public void setBorderWidth(int borderWidth) {
1260 if (borderWidth > -1) {
1261 this.fBorderWidth = borderWidth;
1262 GridLayout gl = (GridLayout) fDataViewer.getLayout();
1263 gl.marginHeight = borderWidth;
1264 }
1265 }
1266
1267 /**
1268 * Retrieve the height of the header
1269 *
1270 * @return The height
1271 */
1272 public int getHeaderHeight() {
1273 return fTimeScaleHeight;
1274 }
1275
1276 /**
1277 * Set the height of the header
1278 *
1279 * @param headerHeight
1280 * The height to set
1281 */
1282 public void setHeaderHeight(int headerHeight) {
1283 if (headerHeight > -1) {
1284 this.fTimeScaleHeight = headerHeight;
1285 fTimeScaleCtrl.setHeight(headerHeight);
1286 }
1287 }
1288
1289 /**
1290 * Retrieve the height of an item row
1291 *
1292 * @return The height
1293 */
1294 public int getItemHeight() {
1295 if (fTimeGraphCtrl != null) {
1296 return fTimeGraphCtrl.getItemHeight();
1297 }
1298 return 0;
1299 }
1300
1301 /**
1302 * Set the height of an item row
1303 *
1304 * @param rowHeight
1305 * The height to set
1306 */
1307 public void setItemHeight(int rowHeight) {
1308 if (fTimeGraphCtrl != null) {
1309 fTimeGraphCtrl.setItemHeight(rowHeight);
1310 }
1311 }
1312
1313 /**
1314 * Set the minimum item width
1315 *
1316 * @param width
1317 * The min width
1318 */
1319 public void setMinimumItemWidth(int width) {
1320 if (fTimeGraphCtrl != null) {
1321 fTimeGraphCtrl.setMinimumItemWidth(width);
1322 }
1323 }
1324
1325 /**
1326 * Set the width for the name column
1327 *
1328 * @param width
1329 * The width
1330 */
1331 public void setNameWidthPref(int width) {
1332 fNameWidthPref = width;
1333 if (width == 0) {
1334 fMinNameWidth = 0;
1335 fNameWidth = 0;
1336 }
1337 }
1338
1339 /**
1340 * Retrieve the configure width for the name column
1341 *
1342 * @param width
1343 * Unused?
1344 * @return The width
1345 */
1346 public int getNameWidthPref(int width) {
1347 return fNameWidthPref;
1348 }
1349
1350 /**
1351 * Returns the primary control associated with this viewer.
1352 *
1353 * @return the SWT control which displays this viewer's content
1354 */
1355 public Control getControl() {
1356 return fDataViewer;
1357 }
1358
1359 /**
1360 * Returns the time graph control associated with this viewer.
1361 *
1362 * @return the time graph control
1363 */
1364 public TimeGraphControl getTimeGraphControl() {
1365 return fTimeGraphCtrl;
1366 }
1367
1368 /**
1369 * Returns the time graph scale associated with this viewer.
1370 *
1371 * @return the time graph scale
1372 */
1373 public TimeGraphScale getTimeGraphScale() {
1374 return fTimeScaleCtrl;
1375 }
1376
1377 /**
1378 * Returns the composite containing all the controls that are time aligned,
1379 * i.e. TimeGraphScale, TimeGraphControl.
1380 *
1381 * @return the time based composite
1382 * @since 1.0
1383 */
1384 public Composite getTimeAlignedComposite() {
1385 return fTimeAlignedComposite;
1386 }
1387
1388 /**
1389 * Return the x coordinate corresponding to a time
1390 *
1391 * @param time
1392 * the time
1393 * @return the x coordinate corresponding to the time
1394 */
1395 public int getXForTime(long time) {
1396 return fTimeGraphCtrl.getXForTime(time);
1397 }
1398
1399 /**
1400 * Return the time corresponding to an x coordinate
1401 *
1402 * @param x
1403 * the x coordinate
1404 * @return the time corresponding to the x coordinate
1405 */
1406 public long getTimeAtX(int x) {
1407 return fTimeGraphCtrl.getTimeAtX(x);
1408 }
1409
1410 /**
1411 * Get the selection provider
1412 *
1413 * @return the selection provider
1414 */
1415 public ISelectionProvider getSelectionProvider() {
1416 return fTimeGraphCtrl;
1417 }
1418
1419 /**
1420 * Wait for the cursor
1421 *
1422 * @param waitInd
1423 * Wait indefinitely?
1424 */
1425 public void waitCursor(boolean waitInd) {
1426 fTimeGraphCtrl.waitCursor(waitInd);
1427 }
1428
1429 /**
1430 * Get the horizontal scroll bar object
1431 *
1432 * @return The scroll bar
1433 */
1434 public Slider getHorizontalBar() {
1435 return fHorizontalScrollBar;
1436 }
1437
1438 /**
1439 * Get the vertical scroll bar object
1440 *
1441 * @return The scroll bar
1442 */
1443 public Slider getVerticalBar() {
1444 return fVerticalScrollBar;
1445 }
1446
1447 /**
1448 * Set the given index as the top one
1449 *
1450 * @param index
1451 * The index that will go to the top
1452 */
1453 public void setTopIndex(int index) {
1454 fTimeGraphCtrl.setTopIndex(index);
1455 adjustVerticalScrollBar();
1456 }
1457
1458 /**
1459 * Retrieve the current top index
1460 *
1461 * @return The top index
1462 */
1463 public int getTopIndex() {
1464 return fTimeGraphCtrl.getTopIndex();
1465 }
1466
1467 /**
1468 * Sets the auto-expand level to be used for new entries discovered when
1469 * calling {@link #setInput(Object)} or {@link #refresh()}. The value 0
1470 * means that there is no auto-expand; 1 means that top-level entries are
1471 * expanded, but not their children; 2 means that top-level entries are
1472 * expanded, and their children, but not grand-children; and so on.
1473 * <p>
1474 * The value {@link #ALL_LEVELS} means that all subtrees should be expanded.
1475 * </p>
1476 *
1477 * @param level
1478 * non-negative level, or <code>ALL_LEVELS</code> to expand all
1479 * levels of the tree
1480 */
1481 public void setAutoExpandLevel(int level) {
1482 fTimeGraphCtrl.setAutoExpandLevel(level);
1483 }
1484
1485 /**
1486 * Returns the auto-expand level.
1487 *
1488 * @return non-negative level, or <code>ALL_LEVELS</code> if all levels of
1489 * the tree are expanded automatically
1490 * @see #setAutoExpandLevel
1491 */
1492 public int getAutoExpandLevel() {
1493 return fTimeGraphCtrl.getAutoExpandLevel();
1494 }
1495
1496 /**
1497 * Get the expanded state of an entry.
1498 *
1499 * @param entry
1500 * The entry
1501 * @return true if the entry is expanded, false if collapsed
1502 * @since 2.0
1503 */
1504 public boolean getExpandedState(ITimeGraphEntry entry) {
1505 return fTimeGraphCtrl.getExpandedState(entry);
1506 }
1507
1508 /**
1509 * Set the expanded state of an entry
1510 *
1511 * @param entry
1512 * The entry to expand/collapse
1513 * @param expanded
1514 * True for expanded, false for collapsed
1515 */
1516 public void setExpandedState(ITimeGraphEntry entry, boolean expanded) {
1517 fTimeGraphCtrl.setExpandedState(entry, expanded);
1518 adjustVerticalScrollBar();
1519 }
1520
1521 /**
1522 * Collapses all nodes of the viewer's tree, starting with the root.
1523 */
1524 public void collapseAll() {
1525 fTimeGraphCtrl.collapseAll();
1526 adjustVerticalScrollBar();
1527 }
1528
1529 /**
1530 * Expands all entries of the viewer's tree, starting with the root.
1531 */
1532 public void expandAll() {
1533 fTimeGraphCtrl.expandAll();
1534 adjustVerticalScrollBar();
1535 }
1536
1537 /**
1538 * Get the number of expanded (visible) time graph entries. This includes
1539 * leafs and does not include filtered-out entries.
1540 *
1541 * @return The number of expanded (visible) time graph entries
1542 */
1543 public int getExpandedElementCount() {
1544 return fTimeGraphCtrl.getExpandedElementCount();
1545 }
1546
1547 /**
1548 * Get the expanded (visible) time graph entries. This includes leafs and
1549 * does not include filtered-out entries.
1550 *
1551 * @return The array of expanded (visible) time graph entries
1552 */
1553 public ITimeGraphEntry[] getExpandedElements() {
1554 return fTimeGraphCtrl.getExpandedElements();
1555 }
1556
1557 /**
1558 * Add a tree listener
1559 *
1560 * @param listener
1561 * The listener to add
1562 */
1563 public void addTreeListener(ITimeGraphTreeListener listener) {
1564 fTimeGraphCtrl.addTreeListener(listener);
1565 }
1566
1567 /**
1568 * Remove a tree listener
1569 *
1570 * @param listener
1571 * The listener to remove
1572 */
1573 public void removeTreeListener(ITimeGraphTreeListener listener) {
1574 fTimeGraphCtrl.removeTreeListener(listener);
1575 }
1576
1577 /**
1578 * Get the reset scale action.
1579 *
1580 * @return The Action object
1581 */
1582 public Action getResetScaleAction() {
1583 if (fResetScaleAction == null) {
1584 // resetScale
1585 fResetScaleAction = new Action() {
1586 @Override
1587 public void run() {
1588 resetStartFinishTime();
1589 }
1590 };
1591 fResetScaleAction.setText(Messages.TmfTimeGraphViewer_ResetScaleActionNameText);
1592 fResetScaleAction.setToolTipText(Messages.TmfTimeGraphViewer_ResetScaleActionToolTipText);
1593 fResetScaleAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HOME_MENU));
1594 }
1595 return fResetScaleAction;
1596 }
1597
1598 /**
1599 * Get the show legend action.
1600 *
1601 * @return The Action object
1602 */
1603 public Action getShowLegendAction() {
1604 if (fShowLegendAction == null) {
1605 // showLegend
1606 fShowLegendAction = new Action() {
1607 @Override
1608 public void run() {
1609 showLegend();
1610 }
1611 };
1612 fShowLegendAction.setText(Messages.TmfTimeGraphViewer_LegendActionNameText);
1613 fShowLegendAction.setToolTipText(Messages.TmfTimeGraphViewer_LegendActionToolTipText);
1614 fShowLegendAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_SHOW_LEGEND));
1615 }
1616
1617 return fShowLegendAction;
1618 }
1619
1620 /**
1621 * Get the the next event action.
1622 *
1623 * @return The action object
1624 */
1625 public Action getNextEventAction() {
1626 if (fNextEventAction == null) {
1627 fNextEventAction = new Action() {
1628 @Override
1629 public void runWithEvent(Event event) {
1630 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1631 selectNextEvent(extend);
1632 }
1633 };
1634
1635 fNextEventAction.setText(Messages.TmfTimeGraphViewer_NextEventActionNameText);
1636 fNextEventAction.setToolTipText(Messages.TmfTimeGraphViewer_NextEventActionToolTipText);
1637 fNextEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_EVENT));
1638 }
1639
1640 return fNextEventAction;
1641 }
1642
1643 /**
1644 * Get the previous event action.
1645 *
1646 * @return The Action object
1647 */
1648 public Action getPreviousEventAction() {
1649 if (fPrevEventAction == null) {
1650 fPrevEventAction = new Action() {
1651 @Override
1652 public void runWithEvent(Event event) {
1653 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1654 selectPrevEvent(extend);
1655 }
1656 };
1657
1658 fPrevEventAction.setText(Messages.TmfTimeGraphViewer_PreviousEventActionNameText);
1659 fPrevEventAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousEventActionToolTipText);
1660 fPrevEventAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_EVENT));
1661 }
1662
1663 return fPrevEventAction;
1664 }
1665
1666 /**
1667 * Get the next item action.
1668 *
1669 * @return The Action object
1670 */
1671 public Action getNextItemAction() {
1672 if (fNextItemAction == null) {
1673
1674 fNextItemAction = new Action() {
1675 @Override
1676 public void run() {
1677 selectNextItem();
1678 }
1679 };
1680 fNextItemAction.setText(Messages.TmfTimeGraphViewer_NextItemActionNameText);
1681 fNextItemAction.setToolTipText(Messages.TmfTimeGraphViewer_NextItemActionToolTipText);
1682 fNextItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_NEXT_ITEM));
1683 }
1684 return fNextItemAction;
1685 }
1686
1687 /**
1688 * Get the previous item action.
1689 *
1690 * @return The Action object
1691 */
1692 public Action getPreviousItemAction() {
1693 if (fPreviousItemAction == null) {
1694
1695 fPreviousItemAction = new Action() {
1696 @Override
1697 public void run() {
1698 selectPrevItem();
1699 }
1700 };
1701 fPreviousItemAction.setText(Messages.TmfTimeGraphViewer_PreviousItemActionNameText);
1702 fPreviousItemAction.setToolTipText(Messages.TmfTimeGraphViewer_PreviousItemActionToolTipText);
1703 fPreviousItemAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_PREV_ITEM));
1704 }
1705 return fPreviousItemAction;
1706 }
1707
1708 /**
1709 * Get the zoom in action
1710 *
1711 * @return The Action object
1712 */
1713 public Action getZoomInAction() {
1714 if (fZoomInAction == null) {
1715 fZoomInAction = new Action() {
1716 @Override
1717 public void run() {
1718 zoomIn();
1719 }
1720 };
1721 fZoomInAction.setText(Messages.TmfTimeGraphViewer_ZoomInActionNameText);
1722 fZoomInAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomInActionToolTipText);
1723 fZoomInAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_IN_MENU));
1724 }
1725 return fZoomInAction;
1726 }
1727
1728 /**
1729 * Get the zoom out action
1730 *
1731 * @return The Action object
1732 */
1733 public Action getZoomOutAction() {
1734 if (fZoomOutAction == null) {
1735 fZoomOutAction = new Action() {
1736 @Override
1737 public void run() {
1738 zoomOut();
1739 }
1740 };
1741 fZoomOutAction.setText(Messages.TmfTimeGraphViewer_ZoomOutActionNameText);
1742 fZoomOutAction.setToolTipText(Messages.TmfTimeGraphViewer_ZoomOutActionToolTipText);
1743 fZoomOutAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_ZOOM_OUT_MENU));
1744 }
1745 return fZoomOutAction;
1746 }
1747
1748 /**
1749 * Get the hide arrows action
1750 *
1751 * @param dialogSettings
1752 * The dialog settings section where the state should be stored,
1753 * or null
1754 *
1755 * @return The Action object
1756 */
1757 public Action getHideArrowsAction(final IDialogSettings dialogSettings) {
1758 if (fHideArrowsAction == null) {
1759 fHideArrowsAction = new Action(Messages.TmfTimeGraphViewer_HideArrowsActionNameText, IAction.AS_CHECK_BOX) {
1760 @Override
1761 public void run() {
1762 boolean hideArrows = fHideArrowsAction.isChecked();
1763 fTimeGraphCtrl.hideArrows(hideArrows);
1764 refresh();
1765 if (dialogSettings != null) {
1766 dialogSettings.put(HIDE_ARROWS_KEY, hideArrows);
1767 }
1768 if (fFollowArrowFwdAction != null) {
1769 fFollowArrowFwdAction.setEnabled(!hideArrows);
1770 }
1771 if (fFollowArrowBwdAction != null) {
1772 fFollowArrowBwdAction.setEnabled(!hideArrows);
1773 }
1774 }
1775 };
1776 fHideArrowsAction.setToolTipText(Messages.TmfTimeGraphViewer_HideArrowsActionToolTipText);
1777 fHideArrowsAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_HIDE_ARROWS));
1778 if (dialogSettings != null) {
1779 boolean hideArrows = dialogSettings.getBoolean(HIDE_ARROWS_KEY);
1780 fTimeGraphCtrl.hideArrows(hideArrows);
1781 fHideArrowsAction.setChecked(hideArrows);
1782 if (fFollowArrowFwdAction != null) {
1783 fFollowArrowFwdAction.setEnabled(!hideArrows);
1784 }
1785 if (fFollowArrowBwdAction != null) {
1786 fFollowArrowBwdAction.setEnabled(!hideArrows);
1787 }
1788 }
1789 }
1790 return fHideArrowsAction;
1791 }
1792
1793 /**
1794 * Get the follow arrow forward action.
1795 *
1796 * @return The Action object
1797 */
1798 public Action getFollowArrowFwdAction() {
1799 if (fFollowArrowFwdAction == null) {
1800 fFollowArrowFwdAction = new Action() {
1801 @Override
1802 public void runWithEvent(Event event) {
1803 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1804 fTimeGraphCtrl.followArrowFwd(extend);
1805 adjustVerticalScrollBar();
1806 }
1807 };
1808 fFollowArrowFwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionNameText);
1809 fFollowArrowFwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowForwardActionToolTipText);
1810 fFollowArrowFwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_FORWARD));
1811 if (fHideArrowsAction != null) {
1812 fFollowArrowFwdAction.setEnabled(!fHideArrowsAction.isChecked());
1813 }
1814 }
1815 return fFollowArrowFwdAction;
1816 }
1817
1818 /**
1819 * Get the follow arrow backward action.
1820 *
1821 * @return The Action object
1822 */
1823 public Action getFollowArrowBwdAction() {
1824 if (fFollowArrowBwdAction == null) {
1825 fFollowArrowBwdAction = new Action() {
1826 @Override
1827 public void runWithEvent(Event event) {
1828 boolean extend = (event.stateMask & SWT.SHIFT) != 0;
1829 fTimeGraphCtrl.followArrowBwd(extend);
1830 adjustVerticalScrollBar();
1831 }
1832 };
1833 fFollowArrowBwdAction.setText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionNameText);
1834 fFollowArrowBwdAction.setToolTipText(Messages.TmfTimeGraphViewer_FollowArrowBackwardActionToolTipText);
1835 fFollowArrowBwdAction.setImageDescriptor(Activator.getDefault().getImageDescripterFromPath(ITmfImageConstants.IMG_UI_FOLLOW_ARROW_BACKWARD));
1836 if (fHideArrowsAction != null) {
1837 fFollowArrowBwdAction.setEnabled(!fHideArrowsAction.isChecked());
1838 }
1839 }
1840 return fFollowArrowBwdAction;
1841 }
1842
1843 /**
1844 * Get the show filter dialog action.
1845 *
1846 * @return The Action object
1847 * @since 2.0
1848 */
1849 public ShowFilterDialogAction getShowFilterDialogAction() {
1850 if (fShowFilterDialogAction == null) {
1851 fShowFilterDialogAction = new ShowFilterDialogAction(this);
1852 }
1853 return fShowFilterDialogAction;
1854 }
1855
1856 private void adjustHorizontalScrollBar() {
1857 long time0 = getTime0();
1858 long time1 = getTime1();
1859 long timeMin = getMinTime();
1860 long timeMax = getMaxTime();
1861 long delta = timeMax - timeMin;
1862 int timePos = 0;
1863 int thumb = H_SCROLLBAR_MAX;
1864 if (delta != 0) {
1865 // Thumb size (page size)
1866 thumb = Math.max(1, (int) (H_SCROLLBAR_MAX * ((double) (time1 - time0) / delta)));
1867 // At the beginning of visible window
1868 timePos = (int) (H_SCROLLBAR_MAX * ((double) (time0 - timeMin) / delta));
1869 }
1870 fHorizontalScrollBar.setValues(timePos, 0, H_SCROLLBAR_MAX, thumb, Math.max(1, thumb / 2), Math.max(2, thumb));
1871 }
1872
1873 private void adjustVerticalScrollBar() {
1874 int topIndex = fTimeGraphCtrl.getTopIndex();
1875 int countPerPage = fTimeGraphCtrl.countPerPage();
1876 int expandedElementCount = fTimeGraphCtrl.getExpandedElementCount();
1877 if (topIndex + countPerPage > expandedElementCount) {
1878 fTimeGraphCtrl.setTopIndex(Math.max(0, expandedElementCount - countPerPage));
1879 }
1880
1881 int selection = fTimeGraphCtrl.getTopIndex();
1882 int min = 0;
1883 int max = Math.max(1, expandedElementCount - 1);
1884 int thumb = Math.min(max, Math.max(1, countPerPage - 1));
1885 int increment = 1;
1886 int pageIncrement = Math.max(1, countPerPage);
1887 fVerticalScrollBar.setValues(selection, min, max, thumb, increment, pageIncrement);
1888 }
1889
1890 /**
1891 * @param listener
1892 * a {@link MenuDetectListener}
1893 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
1894 */
1895 public void addTimeGraphEntryMenuListener(MenuDetectListener listener) {
1896 fTimeGraphCtrl.addTimeGraphEntryMenuListener(listener);
1897 }
1898
1899 /**
1900 * @param listener
1901 * a {@link MenuDetectListener}
1902 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeGraphEntryMenuListener(org.eclipse.swt.events.MenuDetectListener)
1903 */
1904 public void removeTimeGraphEntryMenuListener(MenuDetectListener listener) {
1905 fTimeGraphCtrl.removeTimeGraphEntryMenuListener(listener);
1906 }
1907
1908 /**
1909 * @param listener
1910 * a {@link MenuDetectListener}
1911 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#addTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
1912 */
1913 public void addTimeEventMenuListener(MenuDetectListener listener) {
1914 fTimeGraphCtrl.addTimeEventMenuListener(listener);
1915 }
1916
1917 /**
1918 * @param listener
1919 * a {@link MenuDetectListener}
1920 * @see org.eclipse.tracecompass.tmf.ui.widgets.timegraph.widgets.TimeGraphControl#removeTimeEventMenuListener(org.eclipse.swt.events.MenuDetectListener)
1921 */
1922 public void removeTimeEventMenuListener(MenuDetectListener listener) {
1923 fTimeGraphCtrl.removeTimeEventMenuListener(listener);
1924 }
1925
1926 /**
1927 * @param filter
1928 * The filter object to be attached to the view
1929 */
1930 public void addFilter(ViewerFilter filter) {
1931 fTimeGraphCtrl.addFilter(filter);
1932 refresh();
1933 }
1934
1935 /**
1936 * @param filter
1937 * The filter object to be attached to the view
1938 */
1939 public void removeFilter(ViewerFilter filter) {
1940 fTimeGraphCtrl.removeFilter(filter);
1941 refresh();
1942 }
1943
1944 /**
1945 * Returns this viewer's filters.
1946 *
1947 * @return an array of viewer filters
1948 * @since 2.0
1949 */
1950 public ViewerFilter[] getFilters() {
1951 return fTimeGraphCtrl.getFilters();
1952 }
1953
1954 /**
1955 * Sets the filters, replacing any previous filters, and triggers
1956 * refiltering of the elements.
1957 *
1958 * @param filters
1959 * an array of viewer filters, or null
1960 * @since 2.0
1961 */
1962 public void setFilters(ViewerFilter[] filters) {
1963 fTimeGraphCtrl.setFilters(filters);
1964 refresh();
1965 }
1966
1967 /**
1968 * Return the time alignment information
1969 *
1970 * @return the time alignment information
1971 *
1972 * @see ITmfTimeAligned
1973 *
1974 * @since 1.0
1975 */
1976 public TmfTimeViewAlignmentInfo getTimeViewAlignmentInfo() {
1977 return fTimeGraphCtrl.getTimeViewAlignmentInfo();
1978 }
1979
1980 /**
1981 * Return the available width for the time-axis.
1982 *
1983 * @see ITmfTimeAligned
1984 *
1985 * @param requestedOffset
1986 * the requested offset
1987 * @return the available width for the time-axis
1988 *
1989 * @since 1.0
1990 */
1991 public int getAvailableWidth(int requestedOffset) {
1992 int totalWidth = fTimeAlignedComposite.getSize().x;
1993 return Math.min(totalWidth, Math.max(0, totalWidth - requestedOffset));
1994 }
1995
1996 /**
1997 * Perform the alignment operation.
1998 *
1999 * @param offset
2000 * the alignment offset
2001 * @param width
2002 * the alignment width
2003 *
2004 * @see ITmfTimeAligned
2005 *
2006 * @since 1.0
2007 */
2008 public void performAlign(int offset, int width) {
2009 fTimeGraphCtrl.performAlign(offset);
2010 int alignmentWidth = width;
2011 int size = fTimeAlignedComposite.getSize().x;
2012 GridLayout layout = (GridLayout) fTimeAlignedComposite.getLayout();
2013 int marginSize = size - alignmentWidth - offset;
2014 layout.marginRight = Math.max(0, marginSize);
2015 fTimeAlignedComposite.layout();
2016 }
2017
2018 }
This page took 0.077687 seconds and 6 git commands to generate.