Workwaround to SWT not recporting to correct itemHeight in "not gnome desktop". Allow...
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.ui / src / org / eclipse / linuxtools / lttng / ui / views / controlflow / ControlFlowView.java
1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
3 *
4 * All rights reserved. This program and the accompanying materials are made
5 * 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: Alvaro Sanchez-Leon - Initial implementation
10 *******************************************************************************/
11 package org.eclipse.linuxtools.lttng.ui.views.controlflow;
12
13 import java.util.Arrays;
14 import java.util.Vector;
15
16 import org.eclipse.jface.action.Action;
17 import org.eclipse.jface.action.IMenuListener;
18 import org.eclipse.jface.action.IMenuManager;
19 import org.eclipse.jface.action.IToolBarManager;
20 import org.eclipse.jface.action.MenuManager;
21 import org.eclipse.jface.action.Separator;
22 import org.eclipse.jface.dialogs.MessageDialog;
23 import org.eclipse.jface.viewers.DoubleClickEvent;
24 import org.eclipse.jface.viewers.IDoubleClickListener;
25 import org.eclipse.jface.viewers.ISelection;
26 import org.eclipse.jface.viewers.ISelectionChangedListener;
27 import org.eclipse.jface.viewers.IStructuredContentProvider;
28 import org.eclipse.jface.viewers.IStructuredSelection;
29 import org.eclipse.jface.viewers.ITableLabelProvider;
30 import org.eclipse.jface.viewers.LabelProvider;
31 import org.eclipse.jface.viewers.SelectionChangedEvent;
32 import org.eclipse.jface.viewers.StructuredViewer;
33 import org.eclipse.jface.viewers.TableViewer;
34 import org.eclipse.jface.viewers.Viewer;
35 import org.eclipse.jface.viewers.ViewerFilter;
36 import org.eclipse.linuxtools.lttng.event.LttngTimestamp;
37 import org.eclipse.linuxtools.lttng.state.StateDataRequest;
38 import org.eclipse.linuxtools.lttng.state.StateManager;
39 import org.eclipse.linuxtools.lttng.state.evProcessor.EventProcessorProxy;
40 import org.eclipse.linuxtools.lttng.state.experiment.StateExperimentManager;
41 import org.eclipse.linuxtools.lttng.state.experiment.StateManagerFactory;
42 import org.eclipse.linuxtools.lttng.ui.TraceDebug;
43 import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeEventProcess;
44 import org.eclipse.linuxtools.lttng.ui.model.trange.TimeRangeViewerProvider;
45 import org.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView;
46 import org.eclipse.linuxtools.lttng.ui.views.common.ParamsUpdater;
47 import org.eclipse.linuxtools.lttng.ui.views.controlflow.evProcessor.FlowTRangeUpdateFactory;
48 import org.eclipse.linuxtools.lttng.ui.views.controlflow.model.FlowModelFactory;
49 import org.eclipse.linuxtools.tmf.event.TmfTimeRange;
50 import org.eclipse.linuxtools.tmf.signal.TmfSignalHandler;
51 import org.eclipse.linuxtools.tmf.signal.TmfSignalManager;
52 import org.eclipse.linuxtools.tmf.signal.TmfTimeSynchSignal;
53 import org.eclipse.linuxtools.tmf.ui.viewers.TmfViewerFactory;
54 import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITimeAnalysisViewer;
55 import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeFilterSelectionListener;
56 import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeScaleSelectionListener;
57 import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.ITmfTimeSelectionListener;
58 import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeFilterSelectionEvent;
59 import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeScaleSelectionEvent;
60 import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.TmfTimeSelectionEvent;
61 import org.eclipse.linuxtools.tmf.ui.viewers.timeAnalysis.model.ITmfTimeAnalysisEntry;
62 import org.eclipse.swt.SWT;
63 import org.eclipse.swt.custom.SashForm;
64 import org.eclipse.swt.custom.ScrolledComposite;
65 import org.eclipse.swt.events.ControlAdapter;
66 import org.eclipse.swt.events.ControlEvent;
67 import org.eclipse.swt.events.ControlListener;
68 import org.eclipse.swt.events.KeyEvent;
69 import org.eclipse.swt.events.KeyListener;
70 import org.eclipse.swt.graphics.Image;
71 import org.eclipse.swt.graphics.Point;
72 import org.eclipse.swt.graphics.Rectangle;
73 import org.eclipse.swt.layout.FillLayout;
74 import org.eclipse.swt.widgets.Composite;
75 import org.eclipse.swt.widgets.Display;
76 import org.eclipse.swt.widgets.Menu;
77 import org.eclipse.swt.widgets.ScrollBar;
78 import org.eclipse.swt.widgets.Table;
79 import org.eclipse.swt.widgets.TableColumn;
80 import org.eclipse.swt.widgets.TableItem;
81 import org.eclipse.ui.IActionBars;
82 import org.eclipse.ui.IWorkbenchActionConstants;
83 import org.eclipse.ui.PlatformUI;
84 import org.eclipse.ui.plugin.AbstractUIPlugin;
85
86 /**
87 * <b><u>ControlFlowView</u></b>
88 * <p>
89 * TODO: Implement me. Please.
90 */
91 /**
92 * @author alvaro
93 *
94 */
95 public class ControlFlowView extends AbsTimeUpdateView implements
96 ITmfTimeSelectionListener, ITmfTimeScaleSelectionListener,
97 ITmfTimeFilterSelectionListener {
98
99 public static final String ID = "org.eclipse.linuxtools.lttng.ui.views.controlflow";
100
101 // ========================================================================
102 // Table data
103 // ========================================================================
104 private final String PROCESS_COLUMN = "Process";
105 private final String BRAND_COLUMN = "Brand";
106 private final String PID_COLUMN = "PID";
107 private final String TGID_COLUMN = "TGID";
108 private final String PPID_COLUMN = "PPID";
109 private final String CPU_COLUMN = "CPU";
110 private final String BIRTH_SEC_COLUMN = "Birth sec";
111 private final String BIRTH_NSEC_COLUMN = "Birth nsec";
112 private final String TRACE = "TRACE";
113
114 private final String[] columnNames = new String[] { PROCESS_COLUMN, /* */
115 BRAND_COLUMN,/* */
116 PID_COLUMN,/* */
117 TGID_COLUMN,/* */
118 PPID_COLUMN,/* */
119 CPU_COLUMN, /* */
120 BIRTH_SEC_COLUMN,/* */
121 BIRTH_NSEC_COLUMN,/* */
122 TRACE /* */
123 };
124
125 // ========================================================================
126 // Data
127 // ========================================================================
128 private TableViewer tableViewer;
129 // private int totalNumItems = 0;
130 // Actions
131 private Action doubleClickAction;
132 private Action resetScale;
133 private Action nextEvent;
134 private Action prevEvent;
135 private Action nextTrace;
136 private Action prevTrace;
137 private Action showLegend;
138 private Action filterTraces;
139 private Action zoomIn;
140 private Action zoomOut;
141 private Action synch;
142
143 private ITimeAnalysisViewer tsfviewer;
144 private ViewProcessFilter tableFilter = null;
145 private ScrolledComposite scrollFrame = null;
146 private Composite wrapper = null;
147 private Composite top;
148
149 // private static SimpleDateFormat stimeformat = new SimpleDateFormat(
150 // "yy/MM/dd HH:mm:ss");
151
152 // private TraceModelImplFactory fact;
153
154 // ========================================================================
155 // Methods
156 // ========================================================================
157 /*
158 * The content provider class is responsible for providing objects to the
159 * view. It can wrap existing objects in adapters or simply return objects
160 * as-is. These objects may be sensitive to the current input of the view,
161 * or ignore it and always show the same content (like Task List, for
162 * example).
163 */
164
165 class ViewContentProvider implements
166 /* ILazyContentProvider, */IStructuredContentProvider {
167 private TableViewer cviewer = null;
168 private ITmfTimeAnalysisEntry[] elements = null;
169
170 public ViewContentProvider(TableViewer v) {
171 cviewer = v;
172 }
173
174 public void inputChanged(Viewer v, Object oldInput, Object newInput) {
175 this.elements = (ITmfTimeAnalysisEntry[]) newInput;
176 if (elements != null) {
177 TraceDebug
178 .debug("Total number of processes provided to Control Flow view: "
179 + elements.length);
180 } else {
181 TraceDebug.debug("New input = null");
182 }
183 }
184
185 public void dispose() {
186
187 }
188
189 // Needed with the use of virtual tables in order to initialize items
190 // which were not initially visible.
191 public void updateElement(int index) {
192 cviewer.replace(elements[index], index);
193 }
194
195 // @Override
196 public Object[] getElements(Object inputElement) {
197 // TODO Auto-generated method stub
198 return elements;
199 }
200 }
201
202 class ViewLabelProvider extends LabelProvider implements
203 ITableLabelProvider {
204 public String getColumnText(Object obj, int index) {
205 String strRes = ""; //$NON-NLS-1$
206 LttngTimestamp time;
207 if (obj instanceof TimeRangeEventProcess) {
208 TimeRangeEventProcess process = (TimeRangeEventProcess) obj;
209 switch (index) {
210 case 0:
211 strRes = process.getName();
212 break;
213 case 1:
214 strRes = process.getBrand();
215 break;
216 case 2:
217 strRes = process.getPid().toString();
218 break;
219 case 3:
220 strRes = process.getTgid().toString();
221 break;
222 case 4:
223 strRes = process.getPpid().toString();
224 break;
225 case 5:
226 strRes = process.getCpu().toString();
227 break;
228 case 6:
229 time = new LttngTimestamp(process.getCreationTime()
230 .longValue());
231 strRes = time.getSeconds();
232 break;
233 case 7:
234 time = new LttngTimestamp(process.getCreationTime()
235 .longValue());
236 strRes = time.getNanoSeconds();
237 break;
238 case 8:
239 strRes = process.getTraceID();
240 break;
241 default:
242 break;
243 }
244 } else {
245 return getText(obj);
246 }
247
248 return strRes;
249 }
250
251 public Image getColumnImage(Object obj, int index) {
252 return getImage(obj);
253 }
254
255 @Override
256 public Image getImage(Object obj) {
257 // No image needed for the time being
258 // return PlatformUI.getWorkbench().getSharedImages().getImage(
259 // ISharedImages.IMG_OBJ_ELEMENT);
260 return null;
261 }
262 }
263
264 class ViewProcessFilter extends ViewerFilter {
265
266 private Vector<ITmfTimeAnalysisEntry> filteredSet = new Vector<ITmfTimeAnalysisEntry>();
267 StructuredViewer viewer;
268
269 public ViewProcessFilter(StructuredViewer rviewer) {
270 this.viewer = rviewer;
271 }
272
273 public void setFilter(Vector<ITmfTimeAnalysisEntry> filtered) {
274 if (filtered != null) {
275 this.filteredSet = filtered;
276 viewer.refresh();
277 }
278 }
279
280 @Override
281 public boolean select(Viewer viewer, Object parentElement,
282 Object element) {
283 boolean filteredIn = true;
284 if (element instanceof ITmfTimeAnalysisEntry) {
285 ITmfTimeAnalysisEntry process = (ITmfTimeAnalysisEntry) element;
286 if (filteredSet.contains(process)) {
287 // The element is marked to be filtered out
288 return false;
289 }
290 } else {
291 TraceDebug.debug("Unexpected type of filter element received: "
292 + element.toString());
293 }
294 // Compare element versus a list of filtered out
295 return filteredIn;
296 }
297 }
298
299 /**
300 * The constructor.
301 */
302 public ControlFlowView() {
303 super(ID);
304 }
305
306 /**
307 * This is a callback that will allow us to create the viewer and initialize
308 * it.
309 */
310 @Override
311 public void createPartControl(Composite parent) {
312 top = new Composite(parent, SWT.BORDER);
313
314 top.setLayout(new FillLayout());
315
316 scrollFrame = new ScrolledComposite(top, SWT.V_SCROLL | SWT.H_SCROLL);
317 scrollFrame.setBounds(top.getClientArea());
318
319 wrapper = new Composite(scrollFrame, SWT.NONE);
320 scrollFrame.setEnabled(true);
321 scrollFrame.setRedraw(true);
322 scrollFrame.setExpandVertical(true);
323 scrollFrame.setExpandHorizontal(true);
324 scrollFrame.setContent(wrapper);
325 scrollFrame.setAlwaysShowScrollBars(true);
326 wrapper.setLayout(new FillLayout());
327
328 SashForm sash = new SashForm(wrapper, SWT.NONE);
329 final Composite tableComposite = new Composite(sash, SWT.NO_SCROLL);
330 FillLayout layout = new FillLayout();
331 tableComposite.setLayout(layout);
332 tableViewer = new TableViewer(tableComposite, SWT.FULL_SELECTION
333 | SWT.H_SCROLL);
334 tableViewer.setContentProvider(new ViewContentProvider(tableViewer));
335 tableViewer.setLabelProvider(new ViewLabelProvider());
336 Table table = tableViewer.getTable();
337 tableViewer
338 .addSelectionChangedListener(new ISelectionChangedListener() {
339 public void selectionChanged(SelectionChangedEvent event) {
340 ISelection sel = event.getSelection();
341 if (!sel.isEmpty()) {
342 Object firstSel = null;
343 if (sel instanceof IStructuredSelection) {
344 firstSel = ((IStructuredSelection) sel)
345 .getFirstElement();
346
347 // Make sure the selection is visible
348 updateScrollOrigin();
349
350 if (firstSel instanceof ITmfTimeAnalysisEntry) {
351 ITmfTimeAnalysisEntry trace = (ITmfTimeAnalysisEntry) firstSel;
352 tsfviewer.setSelectedTrace(trace);
353 }
354 }
355 }
356 }
357
358 /**
359 * Make sure the selected item is visible
360 */
361 private void updateScrollOrigin() {
362 Table table = tableViewer.getTable();
363 if (table != null && table.getItemCount() > 0) {
364 TableItem item = table.getSelection()[0];
365 if (item == null) {
366 // no selected reference to go up or down
367 return;
368 }
369
370 Rectangle itemRect = item.getBounds();
371 int step = itemRect.height;
372
373 // calculate height of horizontal bar
374 int hscrolly = 0;
375 ScrollBar hbar = scrollFrame.getHorizontalBar();
376 if (hbar != null) {
377 hscrolly = hbar.getSize().y;
378 }
379
380 int visibleHeight = scrollFrame.getSize().y
381 - hscrolly;
382
383 // the current scrollbar offset to adjust i.e. start
384 // of
385 // the visible window
386 Point origin = scrollFrame.getOrigin();
387 // end of visible window
388 int endy = origin.y + visibleHeight;
389
390 int itemStartPos = itemRect.y
391 + table.getHeaderHeight()
392 + table.getBorderWidth()
393 + table.getParent().getBorderWidth();
394
395 // Item End Position
396 int itemEndPos = itemStartPos + step;
397
398 // check if need to go up
399 if (origin.y >= step && itemStartPos < origin.y) {
400 // one step up
401 scrollFrame
402 .setOrigin(origin.x, origin.y - step);
403
404 }
405
406 // check if it needs to go down
407 if (itemEndPos > endy) {
408 // one step down
409 scrollFrame
410 .setOrigin(origin.x, origin.y + step);
411
412 }
413 }
414 }
415 });
416
417 // Listen to page up /down and Home / Enc keys
418 tableViewer.getTable().addKeyListener(new KeyListener() {
419 public void keyPressed(KeyEvent e) {
420 Table table = tableViewer.getTable();
421 Point origin = scrollFrame.getOrigin();
422 if (table == null || table.getItemCount() < 1) {
423 // nothing to page
424 return;
425 }
426
427 TableItem item;
428 int count;
429
430 switch (e.keyCode) {
431 case SWT.PAGE_DOWN:
432 updateScrollPageDown();
433 break;
434 case SWT.PAGE_UP:
435 updateScrollUp();
436 break;
437 case SWT.HOME:
438 // Home
439 count = table.getItemCount();
440 item = table.getItem(0);
441 // Go to the top
442 scrollFrame.setOrigin(origin.x, 0);
443 break;
444 case SWT.END:
445 // End Selected
446 count = table.getItemCount();
447 item = table.getItem(count - 1);
448 int itemStartPos = item.getBounds().y;
449 // Get to the bottom
450 scrollFrame.setOrigin(origin.x, itemStartPos);
451 break;
452 default:
453 break;
454 }
455 }
456
457 public void keyReleased(KeyEvent e) {
458 // Nothing to do
459
460 }
461
462 /**
463 * Scroll one page down
464 */
465 private void updateScrollPageDown() {
466 // null protection before calling private method
467 Table table = tableViewer.getTable();
468 int step = table.getItemHeight();
469
470 int hscrolly = 0;
471 ScrollBar hbar = scrollFrame.getHorizontalBar();
472 if (hbar != null) {
473 hscrolly = hbar.getSize().y;
474 }
475
476 Point origin = scrollFrame.getOrigin();
477 int visibleHeight = scrollFrame.getSize().y - hscrolly;
478 int endy = origin.y + visibleHeight;
479
480 scrollFrame.setOrigin(origin.x, endy - step);
481 }
482
483 /**
484 * Scroll one page up
485 */
486 private void updateScrollUp() {
487 // null protection before calling private method
488 Table table = tableViewer.getTable();
489 int step = table.getItemHeight();
490
491 int hscrolly = 0;
492 ScrollBar hbar = scrollFrame.getHorizontalBar();
493 if (hbar != null) {
494 hscrolly = hbar.getSize().y;
495 }
496
497 Point origin = scrollFrame.getOrigin();
498 int visibleHeight = scrollFrame.getSize().y - hscrolly;
499 int pageUpPos = origin.y - visibleHeight + step;
500 pageUpPos = pageUpPos > 0 ? pageUpPos : 0;
501 scrollFrame.setOrigin(origin.x, pageUpPos);
502 }
503
504 });
505 // Describe table
506 applyTableLayout(table);
507
508 int borderWidth = table.getBorderWidth();
509
510 int itemHeight = table.getItemHeight();
511 int headerHeight = table.getHeaderHeight();
512 table.getVerticalBar().setVisible(false);
513
514 tsfviewer = TmfViewerFactory.createViewer(sash,
515 new TimeRangeViewerProvider());
516
517 tsfviewer.addWidgetSelectionListner(this);
518 tsfviewer.addWidgetTimeScaleSelectionListner(this);
519
520 // Traces shall not be grouped to allow synchronisation
521 tsfviewer.groupTraces(false);
522
523 int swtBugAjustment = checkForSWTBugItemHeightAdjustement();
524 tsfviewer.setItemHeight(itemHeight + swtBugAjustment);
525
526 tsfviewer.setBorderWidth(borderWidth);
527 tsfviewer.setHeaderHeight(headerHeight);
528 tsfviewer.setVisibleVerticalScroll(false);
529 // Names provided by the table
530 tsfviewer.setNameWidthPref(0);
531 tsfviewer.setAcceptSelectionAPIcalls(true);
532
533 // Viewer to notify selection to this class
534 // This class will synchronise selections with table.
535 tsfviewer.addWidgetSelectionListner(this);
536 tsfviewer.addFilterSelectionListner(this);
537 tsfviewer.addWidgetTimeScaleSelectionListner(this);
538
539 sash.setWeights(new int[] { 1, 1 });
540 // Create the help context id for the viewer's control
541 // TODO: Associate with help system
542 PlatformUI.getWorkbench().getHelpSystem().setHelp(
543 tableViewer.getControl(),
544 "org.eclipse.linuxtools.lttnng.ui.views.flow.viewer"); //$NON-NLS-1$
545
546 makeActions();
547 hookContextMenu();
548 hookDoubleClickAction();
549 contributeToActionBars();
550
551 scrollFrame.addControlListener(new ControlAdapter() {
552 @Override
553 public void controlResized(ControlEvent e) {
554 tsfviewer.resizeControls();
555 updateScrolls(scrollFrame, wrapper);
556 }
557 });
558
559 tableComposite.addControlListener(new ControlListener() {
560 public void controlResized(ControlEvent e) {
561 scrollFrame.getParent().update();
562 }
563
564 public void controlMoved(ControlEvent e) {
565
566 }
567 });
568
569 // Register the updater in charge to refresh elements as we update the
570 // time ranges
571 // FlowParamsUpdater listener = FlowModelFactory.getParamsUpdater();
572 // tsfviewer.addWidgetTimeScaleSelectionListner(listener);
573
574 // Register this view to receive updates when the model is updated with
575 // fresh info
576 // ModelListenFactory.getRegister().addFlowModelUpdatesListener(this);
577
578 // Register the event processor factory in charge of event handling
579 EventProcessorProxy.getInstance().addEventProcessorFactory(
580 FlowTRangeUpdateFactory.getInstance());
581
582 // set the initial view parameter values
583 // Experiment start and end time
584 // as well as time space width in pixels, used by the time analysis
585 // widget
586 ParamsUpdater paramUpdater = FlowModelFactory.getParamsUpdater();
587 StateExperimentManager experimentManger = StateManagerFactory
588 .getExperimentManager();
589 // Read relevant values
590 int timeSpaceWidth = tsfviewer.getTimeSpace();
591 TmfTimeRange timeRange = experimentManger.getExperimentTimeRange();
592 if (timeRange != null) {
593 long time0 = timeRange.getStartTime().getValue();
594 long time1 = timeRange.getEndTime().getValue();
595 paramUpdater.update(time0, time1, timeSpaceWidth);
596 }
597
598 experimentManger.readExperiment("flowView", this);
599 }
600
601 private void hookContextMenu() {
602 MenuManager menuMgr = new MenuManager("#PopupMenu"); //$NON-NLS-1$
603 menuMgr.setRemoveAllWhenShown(true);
604 menuMgr.addMenuListener(new IMenuListener() {
605 public void menuAboutToShow(IMenuManager manager) {
606 ControlFlowView.this.fillContextMenu(manager);
607 }
608 });
609 Menu menu = menuMgr.createContextMenu(tableViewer.getControl());
610 tableViewer.getControl().setMenu(menu);
611 getSite().registerContextMenu(menuMgr, tableViewer);
612 }
613
614 private void contributeToActionBars() {
615 IActionBars bars = getViewSite().getActionBars();
616 fillLocalPullDown(bars.getMenuManager());
617 fillLocalToolBar(bars.getToolBarManager());
618 }
619
620 private void fillLocalPullDown(IMenuManager manager) {
621 manager.add(new Separator());
622 // manager.add(showLegend);
623 manager.add(new Separator());
624 manager.add(resetScale);
625 manager.add(nextEvent);
626 manager.add(prevEvent);
627 manager.add(nextTrace);
628 manager.add(prevTrace);
629 // manager.add(filterTraces);
630 manager.add(zoomIn);
631 manager.add(zoomOut);
632 manager.add(synch);
633 manager.add(new Separator());
634 }
635
636 private void fillContextMenu(IMenuManager manager) {
637 // manager.add(showLegend);
638 manager.add(new Separator());
639 manager.add(resetScale);
640 manager.add(nextEvent);
641 manager.add(prevEvent);
642 manager.add(nextTrace);
643 manager.add(prevTrace);
644 // manager.add(showLegend);
645 // manager.add(filterTraces);
646 manager.add(zoomIn);
647 manager.add(zoomOut);
648 manager.add(synch);
649 manager.add(new Separator());
650 manager.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));
651 }
652
653 private void fillLocalToolBar(IToolBarManager manager) {
654 // manager.add(showLegend);
655 manager.add(new Separator());
656 manager.add(resetScale);
657 manager.add(nextEvent);
658 manager.add(prevEvent);
659 manager.add(nextTrace);
660 manager.add(prevTrace);
661 // manager.add(filterTraces);
662 manager.add(zoomIn);
663 manager.add(zoomOut);
664 manager.add(synch);
665 manager.add(new Separator());
666 }
667
668 private void makeActions() {
669 // resetScale
670 resetScale = new Action() {
671 @Override
672 public void run() {
673 if (tsfviewer != null) {
674 tsfviewer.resetStartFinishTime();
675 }
676
677 }
678 };
679 resetScale.setText(Messages.getString("ControlFlowView.Action.Reset")); //$NON-NLS-1$
680 resetScale.setToolTipText(Messages
681 .getString("ControlFlowView.Action.Reset.ToolTip")); //$NON-NLS-1$
682 resetScale.setImageDescriptor(AbstractUIPlugin
683 .imageDescriptorFromPlugin(Messages
684 .getString("ControlFlowView.tmf.UI"),
685 "icons/home_nav.gif"));
686
687 // nextEvent
688 nextEvent = new Action() {
689 @Override
690 public void run() {
691 if (tsfviewer != null) {
692 tsfviewer.selectNextEvent();
693 }
694 }
695 };
696 nextEvent.setText(Messages
697 .getString("ControlFlowView.Action.NextEvent")); //$NON-NLS-1$
698 nextEvent.setToolTipText(Messages
699 .getString("ControlFlowView.Action.NextEvent.Tooltip")); //$NON-NLS-1$
700 nextEvent.setImageDescriptor(AbstractUIPlugin
701 .imageDescriptorFromPlugin(Messages
702 .getString("ControlFlowView.tmf.UI"),
703 "icons/next_event.gif"));
704
705 // prevEvent
706 prevEvent = new Action() {
707 @Override
708 public void run() {
709 if (tsfviewer != null) {
710 tsfviewer.selectPrevEvent();
711 }
712 }
713 };
714 prevEvent.setText(Messages
715 .getString("ControlFlowView.Action.PrevEvent")); //$NON-NLS-1$
716 prevEvent.setToolTipText(Messages
717 .getString("ControlFlowView.Action.PrevEvent.Tooltip")); //$NON-NLS-1$
718 prevEvent.setImageDescriptor(AbstractUIPlugin
719 .imageDescriptorFromPlugin(Messages
720 .getString("ControlFlowView.tmf.UI"),
721 "icons/prev_event.gif"));
722
723 // nextTrace
724 nextTrace = new Action() {
725 @Override
726 public void run() {
727 if (tsfviewer != null) {
728 tsfviewer.selectNextTrace();
729 }
730 }
731 };
732 nextTrace.setText(Messages
733 .getString("ControlFlowView.Action.NextProcess")); //$NON-NLS-1$
734 nextTrace.setToolTipText(Messages
735 .getString("ControlFlowView.Action.NextProcess.ToolTip")); //$NON-NLS-1$
736 nextTrace.setImageDescriptor(AbstractUIPlugin
737 .imageDescriptorFromPlugin(Messages
738 .getString("ControlFlowView.tmf.UI"),
739 "icons/next_item.gif"));
740
741 // prevTrace
742 prevTrace = new Action() {
743 @Override
744 public void run() {
745 if (tsfviewer != null) {
746 tsfviewer.selectPrevTrace();
747 }
748 }
749 };
750 prevTrace.setText(Messages
751 .getString("ControlFlowView.Action.PreviousProcess")); //$NON-NLS-1$
752 prevTrace.setToolTipText(Messages
753 .getString("ControlFlowView.Action.PreviousProcess.Tooltip")); //$NON-NLS-1$
754 prevTrace.setImageDescriptor(AbstractUIPlugin
755 .imageDescriptorFromPlugin(Messages
756 .getString("ControlFlowView.tmf.UI"),
757 "icons/prev_item.gif"));
758
759 // showLegend
760 showLegend = new Action() {
761 @Override
762 public void run() {
763 if (tsfviewer != null) {
764 tsfviewer.showLegend();
765 }
766 }
767 };
768 showLegend.setText(Messages.getString("ControlFlowView.Action.Legend")); //$NON-NLS-1$
769 showLegend.setToolTipText(Messages
770 .getString("ControlFlowView.Action.Legend.ToolTip")); //$NON-NLS-1$
771
772 // filterTraces
773 filterTraces = new Action() {
774 @Override
775 public void run() {
776 if (tsfviewer != null) {
777 tsfviewer.filterTraces();
778 }
779 }
780 };
781 filterTraces.setText(Messages
782 .getString("ControlFlowView.Action.Filter")); //$NON-NLS-1$
783 filterTraces.setToolTipText(Messages
784 .getString("ControlFlowView.Action.Filter.ToolTip")); //$NON-NLS-1$
785 filterTraces.setImageDescriptor(AbstractUIPlugin
786 .imageDescriptorFromPlugin(Messages
787 .getString("ControlFlowView.tmf.UI"),
788 "icons/filter_items.gif"));
789
790 // zoomIn
791 zoomIn = new Action() {
792 @Override
793 public void run() {
794 if (tsfviewer != null) {
795 tsfviewer.zoomIn();
796 }
797 }
798 };
799 zoomIn.setText(Messages.getString("ControlFlowView.Action.ZoomIn")); //$NON-NLS-1$
800 zoomIn.setToolTipText(Messages
801 .getString("ControlFlowView.Action.ZoomIn.Tooltip")); //$NON-NLS-1$
802 zoomIn.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
803 Messages.getString("ControlFlowView.tmf.UI"),
804 "icons/zoomin_nav.gif"));
805
806 // zoomOut
807 zoomOut = new Action() {
808 @Override
809 public void run() {
810 if (tsfviewer != null) {
811 tsfviewer.zoomOut();
812 }
813 }
814 };
815 zoomOut.setText(Messages.getString("ControlFlowView.Action.ZoomOut")); //$NON-NLS-1$
816 zoomOut.setToolTipText(Messages
817 .getString("ControlFlowView.Action.ZoomOut.tooltip")); //$NON-NLS-1$
818 zoomOut.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
819 Messages.getString("ControlFlowView.tmf.UI"),
820 "icons/zoomout_nav.gif"));
821
822 // synch
823 synch = new Action() {
824 @Override
825 public void run() {
826 // Note: No action since the synch flag is used by Control flow
827 // view
828 // the actual viewer is set to accept api selections in
829 // createpartcontrol.
830
831 // if (synch.isChecked()) {
832 // tsfviewer.setAcceptSelectionAPIcalls(true);
833 // } else {
834 // tsfviewer.setAcceptSelectionAPIcalls(false);
835 // }
836 }
837 };
838 synch.setText(Messages.getString("ControlFlowView.Action.Synchronize")); //$NON-NLS-1$
839 synch.setToolTipText(Messages
840 .getString("ControlFlowView.Action.Synchronize.ToolTip")); //$NON-NLS-1$
841 synch.setChecked(false);
842 synch.setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(
843 Messages.getString("ControlFlowView.tmf.UI"),
844 "icons/synced.gif"));
845 // PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_ELCL_SYNCED);
846
847 doubleClickAction = new Action() {
848 @Override
849 public void run() {
850 ISelection selection = tableViewer.getSelection();
851 Object obj = ((IStructuredSelection) selection)
852 .getFirstElement();
853 showMessage("Double-click detected on " + obj.toString()); //$NON-NLS-1$
854 }
855 };
856 }
857
858 private void hookDoubleClickAction() {
859 tableViewer.addDoubleClickListener(new IDoubleClickListener() {
860 public void doubleClick(DoubleClickEvent event) {
861 doubleClickAction.run();
862 }
863 });
864 }
865
866 private void showMessage(String message) {
867 MessageDialog.openInformation(tableViewer.getControl().getShell(),
868 Messages.getString("ControlFlowView.msgSlogan"), message); //$NON-NLS-1$
869 }
870
871 /**
872 * Passing the focus request to the viewer's control.
873 */
874 @Override
875 public void setFocus() {
876 tableViewer.getControl().setFocus();
877 }
878
879 public void tsfTmProcessSelEvent(TmfTimeSelectionEvent event) {
880 Object source = event.getSource();
881 if (source == null) {
882 return;
883 }
884
885 // Reselect the table viewer to widget selection
886 ISelection sel = tsfviewer.getSelectionTrace();
887 if (sel != null && !sel.isEmpty()) {
888 tableViewer.setSelection(sel);
889 }
890
891 ParamsUpdater paramUpdater = FlowModelFactory.getParamsUpdater();
892 Long savedSelTime = paramUpdater.getSelectedTime();
893
894 long selTimens = event.getSelectedTime();
895
896 // make sure the new selected time is different than saved before
897 // executing update
898 if (savedSelTime == null || savedSelTime != selTimens) {
899 // Notify listener views.
900 synchTimeNotification(selTimens);
901
902 // Update the parameter updater to save the selected time
903 paramUpdater.setSelectedTime(selTimens);
904
905 if (TraceDebug.isDEBUG()) {
906 // Object selection = event.getSelection();
907 TraceDebug.debug("Selected Time in control Flow View: "
908 + new LttngTimestamp(selTimens));
909 }
910 }
911 }
912
913 public synchronized void tsfTmProcessTimeScaleEvent(
914 TmfTimeScaleSelectionEvent event) {
915 // source needed to keep track of source values
916 Object source = event.getSource();
917
918 if (source != null) {
919 // Update the parameter updater before carrying out a read request
920 ParamsUpdater paramUpdater = FlowModelFactory.getParamsUpdater();
921 boolean newParams = paramUpdater.processTimeScaleEvent(event);
922
923 if (newParams) {
924 // Read the updated time window
925 TmfTimeRange trange = paramUpdater.getTrange();
926 if (trange != null) {
927 // Request new data for specified time range
928 dataRequest(trange);
929 }
930 }
931 }
932 }
933
934 /**
935 * Obtains the remainder fraction on unit Seconds of the entered value in
936 * nanoseconds. e.g. input: 1241207054171080214 ns The number of seconds can
937 * be obtain by removing the last 9 digits: 1241207054 the fractional
938 * portion of seconds, expressed in ns is: 171080214
939 *
940 * @param v
941 * @return
942 */
943 public String formatNs(long v) {
944 StringBuffer str = new StringBuffer();
945 boolean neg = v < 0;
946 if (neg) {
947 v = -v;
948 str.append('-');
949 }
950
951 String strVal = String.valueOf(v);
952 if (v < 1000000000) {
953 return strVal;
954 }
955
956 // Extract the last nine digits (e.g. fraction of a S expressed in ns
957 return strVal.substring(strVal.length() - 9);
958 }
959
960 private void applyTableLayout(Table table) {
961 for (int i = 0; i < columnNames.length; i++) {
962 TableColumn tableColumn = new TableColumn(table, SWT.LEFT);
963 tableColumn.setText(columnNames[i]);
964 tableColumn.pack();
965 }
966 table.setHeaderVisible(true);
967 table.setLinesVisible(true);
968 }
969
970 /**
971 * @param items
972 * @param startTime
973 * @param endTime
974 * @param updateTimeBounds - Update needed e.g. a new Experiment or trace selected
975 */
976 public void flowModelUpdates(final ITmfTimeAnalysisEntry[] items,
977 final long startTime, final long endTime,
978 final boolean updateTimeBounds) {
979 final Table table = tableViewer.getTable();
980 Display display = table.getDisplay();
981
982 // Perform the updates on the UI thread)
983 display.asyncExec(new Runnable() {
984 public void run() {
985
986 tableViewer.setInput(items); // This shall be the minimal
987 // initial
988 tableFilter = new ViewProcessFilter(tableViewer);
989 tableViewer.setFilters(new ViewerFilter[] { tableFilter });
990
991 resizeTableColumns(table);
992 table.update();
993 tableViewer.refresh();
994
995 tsfviewer.display(items, startTime, endTime, updateTimeBounds);
996 tsfviewer.resizeControls();
997
998 // Adjust the size of the vertical scroll bar to fit the
999 // contents
1000 if (scrollFrame != null && wrapper != null) {
1001 updateScrolls(scrollFrame, wrapper);
1002 // scrollFrame.update();
1003 }
1004 }
1005 });
1006 }
1007
1008 @Override
1009 public void dispose() {
1010 // dispose parent resources
1011 super.dispose();
1012 // Remove the event processor factory
1013 EventProcessorProxy.getInstance().removeEventProcessorFactory(
1014 FlowTRangeUpdateFactory.getInstance());
1015
1016 // Remove listener to model updates
1017 // ModelListenFactory.getRegister().removeFlowModelUpdatesListener(this);
1018 tsfviewer.removeFilterSelectionListner(this);
1019 tsfviewer.removeWidgetSelectionListner(this);
1020 tsfviewer.removeWidgetTimeScaleSelectionListner(this);
1021 tableViewer = null;
1022 tsfviewer = null;
1023 }
1024
1025 /**
1026 * @param tableComposite
1027 * @param table
1028 */
1029 private synchronized void resizeTableColumns(Table table) {
1030 if (table != null) {
1031 Composite parent = table.getParent();
1032 int tableWidthSum = parent.getBorderWidth();
1033
1034 TableColumn[] columns = table.getColumns();
1035 for (TableColumn column : columns) {
1036 column.pack();
1037 tableWidthSum += column.getWidth();
1038 }
1039 }
1040 }
1041
1042 // @Override
1043 public void tmfTaProcessFilterSelection(TmfTimeFilterSelectionEvent event) {
1044 if (tableFilter != null) {
1045 Vector<ITmfTimeAnalysisEntry> filteredout = event.getFilteredOut();
1046 if (filteredout != null) {
1047 tableFilter.setFilter(filteredout);
1048 } else {
1049 tableFilter.setFilter(new Vector<ITmfTimeAnalysisEntry>());
1050 }
1051 tableViewer.refresh();
1052 }
1053 }
1054
1055 /**
1056 * @param scrollFrame
1057 * @param wrapper
1058 */
1059 private void updateScrolls(final ScrolledComposite scrollFrame,
1060 final Composite wrapper) {
1061
1062 Point ptSize = wrapper.computeSize(SWT.DEFAULT, SWT.DEFAULT);
1063 wrapper.setSize(ptSize);
1064 scrollFrame.setMinSize(ptSize);
1065
1066 // calculate the increment area considering the table header height and
1067 // borders
1068 Rectangle area = top.getBounds();
1069 int marginsHeight = tableViewer.getTable().getHeaderHeight();
1070 marginsHeight -= top.getBorderWidth() + wrapper.getBorderWidth();
1071 area.height -= marginsHeight;
1072
1073 // set page vertical increment area
1074 ScrollBar verBar = scrollFrame.getVerticalBar();
1075 ScrollBar horBar = scrollFrame.getHorizontalBar();
1076 if (verBar != null) {
1077 verBar.setPageIncrement(area.height);
1078 }
1079 if (horBar != null) {
1080 horBar.setPageIncrement(area.width);
1081 }
1082
1083 }
1084
1085 /**
1086 * Trigger time synchronisation to other views this method shall be called
1087 * when a check has been performed to note that an actual change of time has
1088 * been performed vs a pure re-selection of the same time
1089 *
1090 * @param time
1091 */
1092 private void synchTimeNotification(long time) {
1093 // if synchronisation selected
1094 if (synch.isChecked()) {
1095 // Notify other views
1096 TmfSignalManager.dispatchSignal(new TmfTimeSynchSignal(this,
1097 new LttngTimestamp(time)));
1098 }
1099 }
1100
1101 /**
1102 * Registers as listener of time selection from other tmf views
1103 *
1104 * @param signal
1105 */
1106 @TmfSignalHandler
1107 public void synchToTime(TmfTimeSynchSignal signal) {
1108 if (synch.isChecked()) {
1109 Object source = signal.getSource();
1110 if (signal != null && source != null && source != this) {
1111 // Internal value is expected in nano seconds.
1112 long selectedTime = signal.getCurrentTime().getValue();
1113 if (tsfviewer != null) {
1114 tsfviewer.setSelectedTime(selectedTime, true, source);
1115 }
1116 }
1117 }
1118 }
1119
1120 /*
1121 * (non-Javadoc)
1122 *
1123 * @see
1124 * org.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#waitCursor
1125 * (boolean)
1126 */
1127 @Override
1128 protected synchronized void waitCursor(final boolean waitInd) {
1129 if (tsfviewer != null) {
1130 Display display = tsfviewer.getControl().getDisplay();
1131
1132 // Perform the updates on the UI thread
1133 display.asyncExec(new Runnable() {
1134 public void run() {
1135 tsfviewer.waitCursor(waitInd);
1136 }
1137 });
1138 }
1139 }
1140
1141 /*
1142 * (non-Javadoc)
1143 *
1144 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.AbsTimeUpdateView#
1145 * ModelUpdatePrep(java.lang.String, boolean)
1146 */
1147 @Override
1148 public void ModelUpdatePrep(String traceId, boolean clearAllData,
1149 TmfTimeRange trange) {
1150 if (clearAllData) {
1151 FlowModelFactory.getProcContainer().clearProcesses();
1152 // Obtain the current process array
1153 TimeRangeEventProcess[] processArr = FlowModelFactory
1154 .getProcContainer().readProcesses();
1155
1156
1157 // initialise to an empty model
1158 flowModelUpdates(processArr, -1, -1, false);
1159 } else {
1160 FlowModelFactory.getProcContainer().clearChildren(traceId);
1161 }
1162
1163 ParamsUpdater updater = FlowModelFactory.getParamsUpdater();
1164 // Start over
1165 updater.setEventsDiscarded(0);
1166
1167 // Update new visible time range if available
1168 if (trange != null) {
1169 updater.update(trange.getStartTime().getValue(), trange
1170 .getEndTime().getValue());
1171 }
1172 }
1173
1174 /*
1175 * (non-Javadoc)
1176 *
1177 * @seeorg.eclipse.linuxtools.lttng.ui.views.common.LttngTimeUpdateView#
1178 * ModelUpdateComplete(org.eclipse.linuxtools.lttng.state.StateDataRequest)
1179 */
1180 @Override
1181 public void ModelUpdateComplete(StateDataRequest request) {
1182 long experimentStartTime = -1;
1183 long experimentEndTime = -1;
1184 StateManager smanager = request.getStateManager();
1185 TmfTimeRange experimentTimeRange = smanager.getExperimentTimeWindow();
1186 if (experimentTimeRange != null) {
1187 experimentStartTime = experimentTimeRange.getStartTime().getValue();
1188 experimentEndTime = experimentTimeRange.getEndTime().getValue();
1189 }
1190 // Obtain the current process array
1191 TimeRangeEventProcess[] processArr = FlowModelFactory
1192 .getProcContainer().readProcesses();
1193 // Sort the array by pid
1194 Arrays.sort(processArr);
1195
1196 // Update the view part
1197 flowModelUpdates(processArr, experimentStartTime, experimentEndTime,
1198 request.isclearDataInd());
1199
1200 // get back to user selected time if still within range
1201 ParamsUpdater paramUpdater = FlowModelFactory.getParamsUpdater();
1202 final Long selTime = paramUpdater.getSelectedTime();
1203 if (selTime != null) {
1204 Display display = tsfviewer.getControl().getDisplay();
1205 display.asyncExec(new Runnable() {
1206 public void run() {
1207 tsfviewer.setSelectedTime(selTime, false, this);
1208 }
1209 });
1210 }
1211
1212 if (TraceDebug.isDEBUG()) {
1213 int eventCount = 0;
1214 Long count = smanager.getEventCount();
1215 for ( int pos = 0; pos<processArr.length; pos++ ) {
1216 eventCount += processArr[pos].getTraceEvents().size();
1217 }
1218
1219 int discarded = FlowModelFactory.getParamsUpdater()
1220 .getEventsDiscarded();
1221 int discardedOutofOrder = FlowModelFactory.getParamsUpdater()
1222 .getEventsDiscardedWrongOrder();
1223 TmfTimeRange range = request.getRange();
1224 StringBuilder sb = new StringBuilder(
1225 "Events handled: "
1226 + count
1227 + " Events loaded in Control Flow view: "
1228 + eventCount
1229 + " Number of events discarded: "
1230 + discarded
1231 + "\n\tNumber of events discarded with start time earlier than next good time: "
1232 + discardedOutofOrder);
1233
1234 sb.append("\n\t\tRequested Time Range: " + range.getStartTime()
1235 + "-" + range.getEndTime());
1236 sb.append("\n\t\tExperiment Time Range: " + experimentStartTime
1237 + "-" + experimentEndTime);
1238 TraceDebug.debug(sb.toString());
1239 }
1240 }
1241
1242 // *** HACK ***
1243 //
1244 //
1245 //
1246 public int checkForSWTBugItemHeightAdjustement() {
1247 int returnedAjustement = 0;
1248 String desktopSessionName = System.getenv("DESKTOP_SESSION");
1249
1250 // Gnome : most common case, no adjustement
1251 if ( desktopSessionName.equals("gnome") ) {
1252 returnedAjustement = 0;
1253 }
1254 // Kde : ajustement of 2 is needed
1255 else if ( desktopSessionName.equals("kde") ) {
1256 returnedAjustement = 2;
1257 }
1258
1259 return returnedAjustement;
1260 }
1261 }
1262
This page took 0.064709 seconds and 6 git commands to generate.