• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2008 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.ddmuilib.log.event;
18 
19 import com.android.ddmlib.log.EventContainer;
20 import com.android.ddmlib.log.EventLogParser;
21 import com.android.ddmlib.log.EventValueDescription;
22 import com.android.ddmuilib.DdmUiPreferences;
23 import com.android.ddmuilib.ImageLoader;
24 import com.android.ddmuilib.log.event.EventDisplay.OccurrenceDisplayDescriptor;
25 import com.android.ddmuilib.log.event.EventDisplay.ValueDisplayDescriptor;
26 import org.eclipse.jface.preference.IPreferenceStore;
27 import org.eclipse.swt.SWT;
28 import org.eclipse.swt.events.ModifyEvent;
29 import org.eclipse.swt.events.ModifyListener;
30 import org.eclipse.swt.events.SelectionAdapter;
31 import org.eclipse.swt.events.SelectionEvent;
32 import org.eclipse.swt.graphics.Rectangle;
33 import org.eclipse.swt.layout.GridData;
34 import org.eclipse.swt.layout.GridLayout;
35 import org.eclipse.swt.widgets.Button;
36 import org.eclipse.swt.widgets.Combo;
37 import org.eclipse.swt.widgets.Composite;
38 import org.eclipse.swt.widgets.Dialog;
39 import org.eclipse.swt.widgets.Display;
40 import org.eclipse.swt.widgets.Event;
41 import org.eclipse.swt.widgets.Group;
42 import org.eclipse.swt.widgets.Label;
43 import org.eclipse.swt.widgets.List;
44 import org.eclipse.swt.widgets.Listener;
45 import org.eclipse.swt.widgets.Shell;
46 import org.eclipse.swt.widgets.Text;
47 
48 import java.util.ArrayList;
49 import java.util.Iterator;
50 import java.util.Map;
51 
52 class EventDisplayOptions  extends Dialog {
53     private static final int DLG_WIDTH = 700;
54     private static final int DLG_HEIGHT = 700;
55 
56     private Shell mParent;
57     private Shell mShell;
58 
59     private boolean mEditStatus = false;
60     private final ArrayList<EventDisplay> mDisplayList = new ArrayList<EventDisplay>();
61 
62     /* LEFT LIST */
63     private List mEventDisplayList;
64     private Button mEventDisplayNewButton;
65     private Button mEventDisplayDeleteButton;
66     private Button mEventDisplayUpButton;
67     private Button mEventDisplayDownButton;
68     private Text mDisplayWidthText;
69     private Text mDisplayHeightText;
70 
71     /* WIDGETS ON THE RIGHT */
72     private Text mDisplayNameText;
73     private Combo mDisplayTypeCombo;
74     private Group mChartOptions;
75     private Group mHistOptions;
76     private Button mPidFilterCheckBox;
77     private Text mPidText;
78 
79     /** Map with (event-tag, event name) */
80     private Map<Integer, String> mEventTagMap;
81 
82     /** Map with (event-tag, array of value info for the event) */
83     private Map<Integer, EventValueDescription[]> mEventDescriptionMap;
84 
85     /** list of current pids */
86     private ArrayList<Integer> mPidList;
87 
88     private EventLogParser mLogParser;
89 
90     private Group mInfoGroup;
91 
92     private static class SelectionWidgets {
93         private List mList;
94         private Button mNewButton;
95         private Button mEditButton;
96         private Button mDeleteButton;
97 
setEnabled(boolean enable)98         private void setEnabled(boolean enable) {
99             mList.setEnabled(enable);
100             mNewButton.setEnabled(enable);
101             mEditButton.setEnabled(enable);
102             mDeleteButton.setEnabled(enable);
103         }
104     }
105 
106     private SelectionWidgets mValueSelection;
107     private SelectionWidgets mOccurrenceSelection;
108 
109     /** flag to temporarly disable processing of {@link Text} changes, so that
110      * {@link Text#setText(String)} can be called safely. */
111     private boolean mProcessTextChanges = true;
112     private Text mTimeLimitText;
113     private Text mHistWidthText;
114 
EventDisplayOptions(Shell parent)115     EventDisplayOptions(Shell parent) {
116         super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
117     }
118 
119     /**
120      * Opens the display option dialog, to edit the {@link EventDisplay} objects provided in the
121      * list.
122      * @param logParser
123      * @param displayList
124      * @param eventList
125      * @return true if the list of {@link EventDisplay} objects was updated.
126      */
open(EventLogParser logParser, ArrayList<EventDisplay> displayList, ArrayList<EventContainer> eventList)127     boolean open(EventLogParser logParser, ArrayList<EventDisplay> displayList,
128             ArrayList<EventContainer> eventList) {
129         mLogParser = logParser;
130 
131         if (logParser != null) {
132             // we need 2 things from the parser.
133             // the event tag / event name map
134             mEventTagMap = logParser.getTagMap();
135 
136             // the event info map
137             mEventDescriptionMap = logParser.getEventInfoMap();
138         }
139 
140         // make a copy of the EventDisplay list since we'll use working copies.
141         duplicateEventDisplay(displayList);
142 
143         // build a list of pid from the list of events.
144         buildPidList(eventList);
145 
146         createUI();
147 
148         if (mParent == null || mShell == null) {
149             return false;
150         }
151 
152         // Set the dialog size.
153         mShell.setMinimumSize(DLG_WIDTH, DLG_HEIGHT);
154         Rectangle r = mParent.getBounds();
155         // get the center new top left.
156         int cx = r.x + r.width/2;
157         int x = cx - DLG_WIDTH / 2;
158         int cy = r.y + r.height/2;
159         int y = cy - DLG_HEIGHT / 2;
160         mShell.setBounds(x, y, DLG_WIDTH, DLG_HEIGHT);
161 
162         mShell.layout();
163 
164         // actually open the dialog
165         mShell.open();
166 
167         // event loop until the dialog is closed.
168         Display display = mParent.getDisplay();
169         while (!mShell.isDisposed()) {
170             if (!display.readAndDispatch())
171                 display.sleep();
172         }
173 
174         return mEditStatus;
175     }
176 
getEventDisplays()177     ArrayList<EventDisplay> getEventDisplays() {
178         return mDisplayList;
179     }
180 
createUI()181     private void createUI() {
182         mParent = getParent();
183         mShell = new Shell(mParent, getStyle());
184         mShell.setText("Event Display Configuration");
185 
186         mShell.setLayout(new GridLayout(1, true));
187 
188         final Composite topPanel = new Composite(mShell, SWT.NONE);
189         topPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
190         topPanel.setLayout(new GridLayout(2, false));
191 
192         // create the tree on the left and the controls on the right.
193         Composite leftPanel = new Composite(topPanel, SWT.NONE);
194         Composite rightPanel = new Composite(topPanel, SWT.NONE);
195 
196         createLeftPanel(leftPanel);
197         createRightPanel(rightPanel);
198 
199         mShell.addListener(SWT.Close, new Listener() {
200             public void handleEvent(Event event) {
201                 event.doit = true;
202             }
203         });
204 
205         Label separator = new Label(mShell, SWT.SEPARATOR | SWT.HORIZONTAL);
206         separator.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
207 
208         Composite bottomButtons = new Composite(mShell, SWT.NONE);
209         bottomButtons.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
210         GridLayout gl;
211         bottomButtons.setLayout(gl = new GridLayout(2, true));
212         gl.marginHeight = gl.marginWidth = 0;
213 
214         Button okButton = new Button(bottomButtons, SWT.PUSH);
215         okButton.setText("OK");
216         okButton.addSelectionListener(new SelectionAdapter() {
217             /* (non-Javadoc)
218              * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
219              */
220             @Override
221             public void widgetSelected(SelectionEvent e) {
222                 mShell.close();
223             }
224         });
225 
226         Button cancelButton = new Button(bottomButtons, SWT.PUSH);
227         cancelButton.setText("Cancel");
228         cancelButton.addSelectionListener(new SelectionAdapter() {
229             /* (non-Javadoc)
230              * @see org.eclipse.swt.events.SelectionAdapter#widgetSelected(org.eclipse.swt.events.SelectionEvent)
231              */
232             @Override
233             public void widgetSelected(SelectionEvent e) {
234                 // cancel the modification flag.
235                 mEditStatus = false;
236 
237                 // and close
238                 mShell.close();
239             }
240         });
241 
242         enable(false);
243 
244         // fill the list with the current display
245         fillEventDisplayList();
246     }
247 
createLeftPanel(Composite leftPanel)248     private void createLeftPanel(Composite leftPanel) {
249         final IPreferenceStore store = DdmUiPreferences.getStore();
250 
251         GridLayout gl;
252 
253         leftPanel.setLayoutData(new GridData(GridData.FILL_VERTICAL));
254         leftPanel.setLayout(gl = new GridLayout(1, false));
255         gl.verticalSpacing = 1;
256 
257         mEventDisplayList = new List(leftPanel,
258                 SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL | SWT.FULL_SELECTION);
259         mEventDisplayList.setLayoutData(new GridData(GridData.FILL_BOTH));
260         mEventDisplayList.addSelectionListener(new SelectionAdapter() {
261             @Override
262             public void widgetSelected(SelectionEvent e) {
263                 handleEventDisplaySelection();
264             }
265         });
266 
267         Composite bottomControls = new Composite(leftPanel, SWT.NONE);
268         bottomControls.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
269         bottomControls.setLayout(gl = new GridLayout(5, false));
270         gl.marginHeight = gl.marginWidth = 0;
271         gl.verticalSpacing = 0;
272         gl.horizontalSpacing = 0;
273 
274         ImageLoader loader = ImageLoader.getDdmUiLibLoader();
275         mEventDisplayNewButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
276         mEventDisplayNewButton.setImage(loader.loadImage("add.png", //$NON-NLS-1$
277                 leftPanel.getDisplay()));
278         mEventDisplayNewButton.setToolTipText("Adds a new event display");
279         mEventDisplayNewButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
280         mEventDisplayNewButton.addSelectionListener(new SelectionAdapter() {
281             @Override
282             public void widgetSelected(SelectionEvent e) {
283                 createNewEventDisplay();
284             }
285         });
286 
287         mEventDisplayDeleteButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
288         mEventDisplayDeleteButton.setImage(loader.loadImage("delete.png", //$NON-NLS-1$
289                 leftPanel.getDisplay()));
290         mEventDisplayDeleteButton.setToolTipText("Deletes the selected event display");
291         mEventDisplayDeleteButton.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
292         mEventDisplayDeleteButton.addSelectionListener(new SelectionAdapter() {
293             @Override
294             public void widgetSelected(SelectionEvent e) {
295                 deleteEventDisplay();
296             }
297         });
298 
299         mEventDisplayUpButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
300         mEventDisplayUpButton.setImage(loader.loadImage("up.png", //$NON-NLS-1$
301                 leftPanel.getDisplay()));
302         mEventDisplayUpButton.setToolTipText("Moves the selected event display up");
303         mEventDisplayUpButton.addSelectionListener(new SelectionAdapter() {
304             @Override
305             public void widgetSelected(SelectionEvent e) {
306                 // get current selection.
307                 int selection = mEventDisplayList.getSelectionIndex();
308                 if (selection > 0) {
309                     // update the list of EventDisplay.
310                     EventDisplay display = mDisplayList.remove(selection);
311                     mDisplayList.add(selection - 1, display);
312 
313                     // update the list widget
314                     mEventDisplayList.remove(selection);
315                     mEventDisplayList.add(display.getName(), selection - 1);
316 
317                     // update the selection and reset the ui.
318                     mEventDisplayList.select(selection - 1);
319                     handleEventDisplaySelection();
320                     mEventDisplayList.showSelection();
321 
322                     setModified();
323                 }
324             }
325         });
326 
327         mEventDisplayDownButton = new Button(bottomControls, SWT.PUSH | SWT.FLAT);
328         mEventDisplayDownButton.setImage(loader.loadImage("down.png", //$NON-NLS-1$
329                 leftPanel.getDisplay()));
330         mEventDisplayDownButton.setToolTipText("Moves the selected event display down");
331         mEventDisplayDownButton.addSelectionListener(new SelectionAdapter() {
332             @Override
333             public void widgetSelected(SelectionEvent e) {
334                 // get current selection.
335                 int selection = mEventDisplayList.getSelectionIndex();
336                 if (selection != -1 && selection < mEventDisplayList.getItemCount() - 1) {
337                     // update the list of EventDisplay.
338                     EventDisplay display = mDisplayList.remove(selection);
339                     mDisplayList.add(selection + 1, display);
340 
341                     // update the list widget
342                     mEventDisplayList.remove(selection);
343                     mEventDisplayList.add(display.getName(), selection + 1);
344 
345                     // update the selection and reset the ui.
346                     mEventDisplayList.select(selection + 1);
347                     handleEventDisplaySelection();
348                     mEventDisplayList.showSelection();
349 
350                     setModified();
351                 }
352             }
353         });
354 
355         Group sizeGroup = new Group(leftPanel, SWT.NONE);
356         sizeGroup.setText("Display Size:");
357         sizeGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
358         sizeGroup.setLayout(new GridLayout(2, false));
359 
360         Label l = new Label(sizeGroup, SWT.NONE);
361         l.setText("Width:");
362 
363         mDisplayWidthText = new Text(sizeGroup, SWT.LEFT | SWT.SINGLE | SWT.BORDER);
364         mDisplayWidthText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
365         mDisplayWidthText.setText(Integer.toString(
366                 store.getInt(EventLogPanel.PREFS_DISPLAY_WIDTH)));
367         mDisplayWidthText.addModifyListener(new ModifyListener() {
368             public void modifyText(ModifyEvent e) {
369                 String text = mDisplayWidthText.getText().trim();
370                 try {
371                     store.setValue(EventLogPanel.PREFS_DISPLAY_WIDTH, Integer.parseInt(text));
372                     setModified();
373                 } catch (NumberFormatException nfe) {
374                     // do something?
375                 }
376             }
377         });
378 
379         l = new Label(sizeGroup, SWT.NONE);
380         l.setText("Height:");
381 
382         mDisplayHeightText = new Text(sizeGroup, SWT.LEFT | SWT.SINGLE | SWT.BORDER);
383         mDisplayHeightText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
384         mDisplayHeightText.setText(Integer.toString(
385                 store.getInt(EventLogPanel.PREFS_DISPLAY_HEIGHT)));
386         mDisplayHeightText.addModifyListener(new ModifyListener() {
387             public void modifyText(ModifyEvent e) {
388                 String text = mDisplayHeightText.getText().trim();
389                 try {
390                     store.setValue(EventLogPanel.PREFS_DISPLAY_HEIGHT, Integer.parseInt(text));
391                     setModified();
392                 } catch (NumberFormatException nfe) {
393                     // do something?
394                 }
395             }
396         });
397     }
398 
createRightPanel(Composite rightPanel)399     private void createRightPanel(Composite rightPanel) {
400         rightPanel.setLayout(new GridLayout(1, true));
401         rightPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
402 
403         mInfoGroup = new Group(rightPanel, SWT.NONE);
404         mInfoGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
405         mInfoGroup.setLayout(new GridLayout(2, false));
406 
407         Label nameLabel = new Label(mInfoGroup, SWT.LEFT);
408         nameLabel.setText("Name:");
409 
410         mDisplayNameText = new Text(mInfoGroup, SWT.BORDER | SWT.LEFT | SWT.SINGLE);
411         mDisplayNameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
412         mDisplayNameText.addModifyListener(new ModifyListener() {
413             public void modifyText(ModifyEvent e) {
414                 if (mProcessTextChanges) {
415                     EventDisplay eventDisplay = getCurrentEventDisplay();
416                     if (eventDisplay != null) {
417                         eventDisplay.setName(mDisplayNameText.getText());
418                         int index = mEventDisplayList.getSelectionIndex();
419                         mEventDisplayList.remove(index);
420                         mEventDisplayList.add(eventDisplay.getName(), index);
421                         mEventDisplayList.select(index);
422                         handleEventDisplaySelection();
423                         setModified();
424                     }
425                 }
426             }
427         });
428 
429         Label displayLabel = new Label(mInfoGroup, SWT.LEFT);
430         displayLabel.setText("Type:");
431 
432         mDisplayTypeCombo = new Combo(mInfoGroup, SWT.READ_ONLY | SWT.DROP_DOWN);
433         mDisplayTypeCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
434         // add the combo values. This must match the values EventDisplay.DISPLAY_TYPE_*
435         mDisplayTypeCombo.add("Log All");
436         mDisplayTypeCombo.add("Filtered Log");
437         mDisplayTypeCombo.add("Graph");
438         mDisplayTypeCombo.add("Sync");
439         mDisplayTypeCombo.add("Sync Histogram");
440         mDisplayTypeCombo.add("Sync Performance");
441         mDisplayTypeCombo.addSelectionListener(new SelectionAdapter() {
442             @Override
443             public void widgetSelected(SelectionEvent e) {
444                 EventDisplay eventDisplay = getCurrentEventDisplay();
445                 if (eventDisplay != null && eventDisplay.getDisplayType() != mDisplayTypeCombo.getSelectionIndex()) {
446                     /* Replace the EventDisplay object with a different subclass */
447                     setModified();
448                     String name = eventDisplay.getName();
449                     EventDisplay newEventDisplay = EventDisplay.eventDisplayFactory(mDisplayTypeCombo.getSelectionIndex(), name);
450                     setCurrentEventDisplay(newEventDisplay);
451                     fillUiWith(newEventDisplay);
452                 }
453             }
454         });
455 
456         mChartOptions = new Group(mInfoGroup, SWT.NONE);
457         mChartOptions.setText("Chart Options");
458         GridData gd;
459         mChartOptions.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
460         gd.horizontalSpan = 2;
461         mChartOptions.setLayout(new GridLayout(2, false));
462 
463         Label l = new Label(mChartOptions, SWT.NONE);
464         l.setText("Time Limit (seconds):");
465 
466         mTimeLimitText = new Text(mChartOptions, SWT.BORDER);
467         mTimeLimitText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
468         mTimeLimitText.addModifyListener(new ModifyListener() {
469             public void modifyText(ModifyEvent arg0) {
470                 String text = mTimeLimitText.getText().trim();
471                 EventDisplay eventDisplay = getCurrentEventDisplay();
472                 if (eventDisplay != null) {
473                     try {
474                         if (text.length() == 0) {
475                             eventDisplay.resetChartTimeLimit();
476                         } else {
477                             eventDisplay.setChartTimeLimit(Long.parseLong(text));
478                         }
479                     } catch (NumberFormatException nfe) {
480                         eventDisplay.resetChartTimeLimit();
481                     } finally {
482                         setModified();
483                     }
484                 }
485             }
486         });
487 
488         mHistOptions = new Group(mInfoGroup, SWT.NONE);
489         mHistOptions.setText("Histogram Options");
490         GridData gdh;
491         mHistOptions.setLayoutData(gdh = new GridData(GridData.FILL_HORIZONTAL));
492         gdh.horizontalSpan = 2;
493         mHistOptions.setLayout(new GridLayout(2, false));
494 
495         Label lh = new Label(mHistOptions, SWT.NONE);
496         lh.setText("Histogram width (hours):");
497 
498         mHistWidthText = new Text(mHistOptions, SWT.BORDER);
499         mHistWidthText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
500         mHistWidthText.addModifyListener(new ModifyListener() {
501             public void modifyText(ModifyEvent arg0) {
502                 String text = mHistWidthText.getText().trim();
503                 EventDisplay eventDisplay = getCurrentEventDisplay();
504                 if (eventDisplay != null) {
505                     try {
506                         if (text.length() == 0) {
507                             eventDisplay.resetHistWidth();
508                         } else {
509                             eventDisplay.setHistWidth(Long.parseLong(text));
510                         }
511                     } catch (NumberFormatException nfe) {
512                         eventDisplay.resetHistWidth();
513                     } finally {
514                         setModified();
515                     }
516                 }
517             }
518         });
519 
520         mPidFilterCheckBox = new Button(mInfoGroup, SWT.CHECK);
521         mPidFilterCheckBox.setText("Enable filtering by pid");
522         mPidFilterCheckBox.setLayoutData(gd = new GridData(GridData.FILL_HORIZONTAL));
523         gd.horizontalSpan = 2;
524         mPidFilterCheckBox.addSelectionListener(new SelectionAdapter() {
525             @Override
526             public void widgetSelected(SelectionEvent e) {
527                 EventDisplay eventDisplay = getCurrentEventDisplay();
528                 if (eventDisplay != null) {
529                     eventDisplay.setPidFiltering(mPidFilterCheckBox.getSelection());
530                     mPidText.setEnabled(mPidFilterCheckBox.getSelection());
531                     setModified();
532                 }
533             }
534         });
535 
536         Label pidLabel = new Label(mInfoGroup, SWT.NONE);
537         pidLabel.setText("Pid Filter:");
538         pidLabel.setToolTipText("Enter all pids, separated by commas");
539 
540         mPidText = new Text(mInfoGroup, SWT.BORDER);
541         mPidText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
542         mPidText.addModifyListener(new ModifyListener() {
543             public void modifyText(ModifyEvent e) {
544                 if (mProcessTextChanges) {
545                     EventDisplay eventDisplay = getCurrentEventDisplay();
546                     if (eventDisplay != null && eventDisplay.getPidFiltering()) {
547                         String pidText = mPidText.getText().trim();
548                         String[] pids = pidText.split("\\s*,\\s*"); //$NON-NLS-1$
549 
550                         ArrayList<Integer> list = new ArrayList<Integer>();
551                         for (String pid : pids) {
552                             try {
553                                 list.add(Integer.valueOf(pid));
554                             } catch (NumberFormatException nfe) {
555                                 // just ignore non valid pid
556                             }
557                         }
558 
559                         eventDisplay.setPidFilterList(list);
560                         setModified();
561                     }
562                 }
563             }
564         });
565 
566         /* ------------------
567          * EVENT VALUE/OCCURRENCE SELECTION
568          * ------------------ */
569         mValueSelection = createEventSelection(rightPanel, ValueDisplayDescriptor.class,
570                 "Event Value Display");
571         mOccurrenceSelection = createEventSelection(rightPanel, OccurrenceDisplayDescriptor.class,
572                 "Event Occurrence Display");
573     }
574 
createEventSelection(Composite rightPanel, final Class<? extends OccurrenceDisplayDescriptor> descriptorClass, String groupMessage)575     private SelectionWidgets createEventSelection(Composite rightPanel,
576             final Class<? extends OccurrenceDisplayDescriptor> descriptorClass,
577             String groupMessage) {
578 
579         Group eventSelectionPanel = new Group(rightPanel, SWT.NONE);
580         eventSelectionPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
581         GridLayout gl;
582         eventSelectionPanel.setLayout(gl = new GridLayout(2, false));
583         gl.marginHeight = gl.marginWidth = 0;
584         eventSelectionPanel.setText(groupMessage);
585 
586         final SelectionWidgets widgets = new SelectionWidgets();
587 
588         widgets.mList = new List(eventSelectionPanel, SWT.BORDER | SWT.SINGLE | SWT.V_SCROLL);
589         widgets.mList.setLayoutData(new GridData(GridData.FILL_BOTH));
590         widgets.mList.addSelectionListener(new SelectionAdapter() {
591             @Override
592             public void widgetSelected(SelectionEvent e) {
593                 int index = widgets.mList.getSelectionIndex();
594                 if (index != -1) {
595                     widgets.mDeleteButton.setEnabled(true);
596                     widgets.mEditButton.setEnabled(true);
597                 } else {
598                     widgets.mDeleteButton.setEnabled(false);
599                     widgets.mEditButton.setEnabled(false);
600                 }
601             }
602         });
603 
604         Composite rightControls = new Composite(eventSelectionPanel, SWT.NONE);
605         rightControls.setLayoutData(new GridData(GridData.FILL_VERTICAL));
606         rightControls.setLayout(gl = new GridLayout(1, false));
607         gl.marginHeight = gl.marginWidth = 0;
608         gl.verticalSpacing = 0;
609         gl.horizontalSpacing = 0;
610 
611         widgets.mNewButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
612         widgets.mNewButton.setText("New...");
613         widgets.mNewButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
614         widgets.mNewButton.setEnabled(false);
615         widgets.mNewButton.addSelectionListener(new SelectionAdapter() {
616             @Override
617             public void widgetSelected(SelectionEvent e) {
618                 // current event
619                 try {
620                     EventDisplay eventDisplay = getCurrentEventDisplay();
621                     if (eventDisplay != null) {
622                         EventValueSelector dialog = new EventValueSelector(mShell);
623                         if (dialog.open(descriptorClass, mLogParser)) {
624                             eventDisplay.addDescriptor(dialog.getDescriptor());
625                             fillUiWith(eventDisplay);
626                             setModified();
627                         }
628                     }
629                 } catch (Exception e1) {
630                     e1.printStackTrace();
631                 }
632             }
633         });
634 
635         widgets.mEditButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
636         widgets.mEditButton.setText("Edit...");
637         widgets.mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
638         widgets.mEditButton.setEnabled(false);
639         widgets.mEditButton.addSelectionListener(new SelectionAdapter() {
640             @Override
641             public void widgetSelected(SelectionEvent e) {
642                 // current event
643                 EventDisplay eventDisplay = getCurrentEventDisplay();
644                 if (eventDisplay != null) {
645                     // get the current descriptor index
646                     int index = widgets.mList.getSelectionIndex();
647                     if (index != -1) {
648                         // get the descriptor itself
649                         OccurrenceDisplayDescriptor descriptor = eventDisplay.getDescriptor(
650                                 descriptorClass, index);
651 
652                         // open the edit dialog.
653                         EventValueSelector dialog = new EventValueSelector(mShell);
654                         if (dialog.open(descriptor, mLogParser)) {
655                             descriptor.replaceWith(dialog.getDescriptor());
656                             eventDisplay.updateValueDescriptorCheck();
657                             fillUiWith(eventDisplay);
658 
659                             // reselect the item since fillUiWith remove the selection.
660                             widgets.mList.select(index);
661                             widgets.mList.notifyListeners(SWT.Selection, null);
662 
663                             setModified();
664                         }
665                     }
666                 }
667             }
668         });
669 
670         widgets.mDeleteButton = new Button(rightControls, SWT.PUSH | SWT.FLAT);
671         widgets.mDeleteButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
672         widgets.mDeleteButton.setText("Delete");
673         widgets.mDeleteButton.setEnabled(false);
674         widgets.mDeleteButton.addSelectionListener(new SelectionAdapter() {
675             @Override
676             public void widgetSelected(SelectionEvent e) {
677                 // current event
678                 EventDisplay eventDisplay = getCurrentEventDisplay();
679                 if (eventDisplay != null) {
680                     // get the current descriptor index
681                     int index = widgets.mList.getSelectionIndex();
682                     if (index != -1) {
683                         eventDisplay.removeDescriptor(descriptorClass, index);
684                         fillUiWith(eventDisplay);
685                         setModified();
686                     }
687                 }
688             }
689         });
690 
691         return widgets;
692     }
693 
694 
duplicateEventDisplay(ArrayList<EventDisplay> displayList)695     private void duplicateEventDisplay(ArrayList<EventDisplay> displayList) {
696         for (EventDisplay eventDisplay : displayList) {
697             mDisplayList.add(EventDisplay.clone(eventDisplay));
698         }
699     }
700 
buildPidList(ArrayList<EventContainer> eventList)701     private void buildPidList(ArrayList<EventContainer> eventList) {
702         mPidList = new ArrayList<Integer>();
703         for (EventContainer event : eventList) {
704             if (mPidList.indexOf(event.pid) == -1) {
705                 mPidList.add(event.pid);
706             }
707         }
708     }
709 
setModified()710     private void setModified() {
711         mEditStatus = true;
712     }
713 
714 
enable(boolean status)715     private void enable(boolean status) {
716         mEventDisplayDeleteButton.setEnabled(status);
717 
718         // enable up/down
719         int selection = mEventDisplayList.getSelectionIndex();
720         int count = mEventDisplayList.getItemCount();
721         mEventDisplayUpButton.setEnabled(status && selection > 0);
722         mEventDisplayDownButton.setEnabled(status && selection != -1 && selection < count - 1);
723 
724         mDisplayNameText.setEnabled(status);
725         mDisplayTypeCombo.setEnabled(status);
726         mPidFilterCheckBox.setEnabled(status);
727 
728         mValueSelection.setEnabled(status);
729         mOccurrenceSelection.setEnabled(status);
730         mValueSelection.mNewButton.setEnabled(status);
731         mOccurrenceSelection.mNewButton.setEnabled(status);
732         if (status == false) {
733             mPidText.setEnabled(false);
734         }
735     }
736 
fillEventDisplayList()737     private void fillEventDisplayList() {
738         for (EventDisplay eventDisplay : mDisplayList) {
739             mEventDisplayList.add(eventDisplay.getName());
740         }
741     }
742 
createNewEventDisplay()743     private void createNewEventDisplay() {
744         int count = mDisplayList.size();
745 
746         String name = String.format("display %1$d", count + 1);
747 
748         EventDisplay eventDisplay = EventDisplay.eventDisplayFactory(0 /* type*/, name);
749 
750         mDisplayList.add(eventDisplay);
751         mEventDisplayList.add(name);
752 
753         mEventDisplayList.select(count);
754         handleEventDisplaySelection();
755         mEventDisplayList.showSelection();
756 
757         setModified();
758     }
759 
deleteEventDisplay()760     private void deleteEventDisplay() {
761         int selection = mEventDisplayList.getSelectionIndex();
762         if (selection != -1) {
763             mDisplayList.remove(selection);
764             mEventDisplayList.remove(selection);
765             if (mDisplayList.size() < selection) {
766                 selection--;
767             }
768             mEventDisplayList.select(selection);
769             handleEventDisplaySelection();
770 
771             setModified();
772         }
773     }
774 
getCurrentEventDisplay()775     private EventDisplay getCurrentEventDisplay() {
776         int selection = mEventDisplayList.getSelectionIndex();
777         if (selection != -1) {
778             return mDisplayList.get(selection);
779         }
780 
781         return null;
782     }
783 
setCurrentEventDisplay(EventDisplay eventDisplay)784     private void setCurrentEventDisplay(EventDisplay eventDisplay) {
785         int selection = mEventDisplayList.getSelectionIndex();
786         if (selection != -1) {
787             mDisplayList.set(selection, eventDisplay);
788         }
789     }
790 
handleEventDisplaySelection()791     private void handleEventDisplaySelection() {
792         EventDisplay eventDisplay = getCurrentEventDisplay();
793         if (eventDisplay != null) {
794             // enable the UI
795             enable(true);
796 
797             // and fill it
798             fillUiWith(eventDisplay);
799         } else {
800             // disable the UI
801             enable(false);
802 
803             // and empty it.
804             emptyUi();
805         }
806     }
807 
emptyUi()808     private void emptyUi() {
809         mDisplayNameText.setText("");
810         mDisplayTypeCombo.clearSelection();
811         mValueSelection.mList.removeAll();
812         mOccurrenceSelection.mList.removeAll();
813     }
814 
fillUiWith(EventDisplay eventDisplay)815     private void fillUiWith(EventDisplay eventDisplay) {
816         mProcessTextChanges = false;
817 
818         mDisplayNameText.setText(eventDisplay.getName());
819         int displayMode = eventDisplay.getDisplayType();
820         mDisplayTypeCombo.select(displayMode);
821         if (displayMode == EventDisplay.DISPLAY_TYPE_GRAPH) {
822             GridData gd = (GridData) mChartOptions.getLayoutData();
823             gd.exclude = false;
824             mChartOptions.setVisible(!gd.exclude);
825             long limit = eventDisplay.getChartTimeLimit();
826             if (limit != -1) {
827                 mTimeLimitText.setText(Long.toString(limit));
828             } else {
829                 mTimeLimitText.setText(""); //$NON-NLS-1$
830             }
831         } else {
832             GridData gd = (GridData) mChartOptions.getLayoutData();
833             gd.exclude = true;
834             mChartOptions.setVisible(!gd.exclude);
835             mTimeLimitText.setText(""); //$NON-NLS-1$
836         }
837 
838         if (displayMode == EventDisplay.DISPLAY_TYPE_SYNC_HIST) {
839             GridData gd = (GridData) mHistOptions.getLayoutData();
840             gd.exclude = false;
841             mHistOptions.setVisible(!gd.exclude);
842             long limit = eventDisplay.getHistWidth();
843             if (limit != -1) {
844                 mHistWidthText.setText(Long.toString(limit));
845             } else {
846                 mHistWidthText.setText(""); //$NON-NLS-1$
847             }
848         } else {
849             GridData gd = (GridData) mHistOptions.getLayoutData();
850             gd.exclude = true;
851             mHistOptions.setVisible(!gd.exclude);
852             mHistWidthText.setText(""); //$NON-NLS-1$
853         }
854         mInfoGroup.layout(true);
855         mShell.layout(true);
856         mShell.pack();
857 
858         if (eventDisplay.getPidFiltering()) {
859             mPidFilterCheckBox.setSelection(true);
860             mPidText.setEnabled(true);
861 
862             // build the pid list.
863             ArrayList<Integer> list = eventDisplay.getPidFilterList();
864             if (list != null) {
865                 StringBuilder sb = new StringBuilder();
866                 int count = list.size();
867                 for (int i = 0 ; i < count ; i++) {
868                     sb.append(list.get(i));
869                     if (i < count - 1) {
870                         sb.append(", ");//$NON-NLS-1$
871                     }
872                 }
873                 mPidText.setText(sb.toString());
874             } else {
875                 mPidText.setText(""); //$NON-NLS-1$
876             }
877         } else {
878             mPidFilterCheckBox.setSelection(false);
879             mPidText.setEnabled(false);
880             mPidText.setText(""); //$NON-NLS-1$
881         }
882 
883         mProcessTextChanges = true;
884 
885         mValueSelection.mList.removeAll();
886         mOccurrenceSelection.mList.removeAll();
887 
888         if (eventDisplay.getDisplayType() == EventDisplay.DISPLAY_TYPE_FILTERED_LOG ||
889                 eventDisplay.getDisplayType() == EventDisplay.DISPLAY_TYPE_GRAPH) {
890             mOccurrenceSelection.setEnabled(true);
891             mValueSelection.setEnabled(true);
892 
893             Iterator<ValueDisplayDescriptor> valueIterator = eventDisplay.getValueDescriptors();
894 
895             while (valueIterator.hasNext()) {
896                 ValueDisplayDescriptor descriptor = valueIterator.next();
897                 mValueSelection.mList.add(String.format("%1$s: %2$s [%3$s]%4$s",
898                         mEventTagMap.get(descriptor.eventTag), descriptor.valueName,
899                         getSeriesLabelDescription(descriptor), getFilterDescription(descriptor)));
900             }
901 
902             Iterator<OccurrenceDisplayDescriptor> occurrenceIterator =
903                 eventDisplay.getOccurrenceDescriptors();
904 
905             while (occurrenceIterator.hasNext()) {
906                 OccurrenceDisplayDescriptor descriptor = occurrenceIterator.next();
907 
908                 mOccurrenceSelection.mList.add(String.format("%1$s [%2$s]%3$s",
909                         mEventTagMap.get(descriptor.eventTag),
910                         getSeriesLabelDescription(descriptor),
911                         getFilterDescription(descriptor)));
912             }
913 
914             mValueSelection.mList.notifyListeners(SWT.Selection, null);
915             mOccurrenceSelection.mList.notifyListeners(SWT.Selection, null);
916         } else {
917             mOccurrenceSelection.setEnabled(false);
918             mValueSelection.setEnabled(false);
919         }
920 
921     }
922 
923     /**
924      * Returns a String describing what is used as the series label
925      * @param descriptor the descriptor of the display.
926      */
getSeriesLabelDescription(OccurrenceDisplayDescriptor descriptor)927     private String getSeriesLabelDescription(OccurrenceDisplayDescriptor descriptor) {
928         if (descriptor.seriesValueIndex != -1) {
929             if (descriptor.includePid) {
930                 return String.format("%1$s + pid",
931                         mEventDescriptionMap.get(
932                                 descriptor.eventTag)[descriptor.seriesValueIndex].getName());
933             } else {
934                 return mEventDescriptionMap.get(descriptor.eventTag)[descriptor.seriesValueIndex]
935                                                                      .getName();
936             }
937         }
938         return "pid";
939     }
940 
getFilterDescription(OccurrenceDisplayDescriptor descriptor)941     private String getFilterDescription(OccurrenceDisplayDescriptor descriptor) {
942         if (descriptor.filterValueIndex != -1) {
943             return String.format(" [%1$s %2$s %3$s]",
944                     mEventDescriptionMap.get(
945                             descriptor.eventTag)[descriptor.filterValueIndex].getName(),
946                             descriptor.filterCompareMethod.testString(),
947                             descriptor.filterValue != null ?
948                                     descriptor.filterValue.toString() : "?"); //$NON-NLS-1$
949         }
950         return ""; //$NON-NLS-1$
951     }
952 
953 }
954