1 /*******************************************************************************
2 * Copyright (c) 2010, 2011 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * Philippe Sawicki (INF4990.A2010@gmail.com) - Initial API and implementation
11 * Mathieu Denis (mathieu.denis55@gmail.com) - Refactored code
12 * Bernd Hufmann - Adapted to new messages file, fixed warnings
13 *******************************************************************************/
14 package org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.dialogs
;
16 import java
.util
.Vector
;
18 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.latency
.analyzer
.EventMatcher
;
19 import org
.eclipse
.linuxtools
.internal
.lttng
.core
.util
.EventsPair
;
20 import org
.eclipse
.linuxtools
.lttng
.ui
.views
.latency
.Messages
;
21 import org
.eclipse
.swt
.SWT
;
22 import org
.eclipse
.swt
.layout
.GridData
;
23 import org
.eclipse
.swt
.layout
.GridLayout
;
24 import org
.eclipse
.swt
.widgets
.Button
;
25 import org
.eclipse
.swt
.widgets
.Composite
;
26 import org
.eclipse
.swt
.widgets
.Control
;
27 import org
.eclipse
.swt
.widgets
.Event
;
28 import org
.eclipse
.swt
.widgets
.Listener
;
29 import org
.eclipse
.swt
.widgets
.Shell
;
30 import org
.eclipse
.swt
.widgets
.Table
;
31 import org
.eclipse
.swt
.widgets
.TableColumn
;
32 import org
.eclipse
.swt
.widgets
.TableItem
;
35 * <b><u>AddDialog</u></b>
37 * Add dialog, lets the user add custom start/end event pairs.
39 * @author Philippe Sawicki
41 public class AddDialog
extends AbstractDialog
{
43 // ------------------------------------------------------------------------
45 // ------------------------------------------------------------------------
48 * The dialog's start table.
50 protected Table fStartTable
;
53 * The dialog's end table.
55 protected Table fEndTable
;
58 * The dialog's list table.
60 protected Table fListTable
;
63 * Start table columns.
65 protected TableColumn
[] fStartColumns
;
70 protected TableColumn
[] fEndColumns
;
75 protected TableColumn
[] fListColumns
;
78 * Start table column names (header titles).
80 static final String
[] START_COLUMN_NAMES
= { "", Messages
.LatencyView_Dialogs_AddEvents_Columns_Start
}; //$NON-NLS-1$
83 * End table column names (header titles).
85 static final String
[] END_COLUMN_NAMES
= { "", Messages
.LatencyView_Dialogs_AddEvents_Columns_End
}; //$NON-NLS-1$
88 * List table column names (header titles).
90 static final String
[] LIST_COLUMN_NAMES
= {
92 Messages
.LatencyView_Dialogs_AddEvents_Columns_List_Trigger
,
93 Messages
.LatencyView_Dialogs_AddEvents_Columns_List_End
};
98 static final int[] COLUMN_WIDTHS
= { 25, 250, 250 };
101 * Possible event types.
103 protected Vector
<String
> fEventTypes
= new Vector
<String
>();
108 protected Vector
<String
> fEventStartTypes
;
113 protected Vector
<String
> fEventEndTypes
;
116 * Selected start type.
118 protected String fStartType
;
123 protected String fEndType
;
125 // ------------------------------------------------------------------------
127 // ------------------------------------------------------------------------
134 * The dialog's window title.
136 * The dialog's window message.
138 public AddDialog(Shell parentShell
, String title
, String message
) {
139 super(parentShell
, title
, message
);
141 // Get the possible events from the list
142 fEventTypes
= EventMatcher
.getInstance().getTypeList();
144 // Get the list of start and end types from the EventMatcher
145 EventsPair pair
= getMatchPairs();
146 fEventStartTypes
= pair
.getFirst();
147 fEventEndTypes
= pair
.getSecond();
150 // ------------------------------------------------------------------------
152 // ------------------------------------------------------------------------
155 * Creates the start table's columns (i.e. the table header).
157 protected void createStartColumns() {
158 fStartColumns
= new TableColumn
[START_COLUMN_NAMES
.length
];
159 for (int i
= 0; i
< START_COLUMN_NAMES
.length
; i
++) {
160 fStartColumns
[i
] = new TableColumn(fStartTable
, SWT
.LEFT
);
161 fStartColumns
[i
].setText(START_COLUMN_NAMES
[i
]);
162 fStartColumns
[i
].setWidth(COLUMN_WIDTHS
[i
]);
167 * Creates the end table's columns (i.e. the table header).
169 protected void createEndColumns() {
170 fEndColumns
= new TableColumn
[END_COLUMN_NAMES
.length
];
171 for (int i
= 0; i
< END_COLUMN_NAMES
.length
; i
++) {
172 fEndColumns
[i
] = new TableColumn(fEndTable
, SWT
.LEFT
);
173 fEndColumns
[i
].setText(END_COLUMN_NAMES
[i
]);
174 fEndColumns
[i
].setWidth(COLUMN_WIDTHS
[i
]);
179 * Creates the list table's columns (i.e. the table header).
181 protected void createListColumns() {
182 fListColumns
= new TableColumn
[LIST_COLUMN_NAMES
.length
];
183 for (int i
= 0; i
< LIST_COLUMN_NAMES
.length
; i
++) {
184 fListColumns
[i
] = new TableColumn(fListTable
, SWT
.LEFT
);
185 fListColumns
[i
].setText(LIST_COLUMN_NAMES
[i
]);
186 fListColumns
[i
].setWidth(COLUMN_WIDTHS
[i
]);
191 * Creates the start column list.
193 * The parent composite.
195 protected void createStartColumn(Composite parent
) {
196 final int style
= SWT
.SINGLE
| SWT
.CHECK
| SWT
.FULL_SELECTION
| SWT
.BORDER
| SWT
.V_SCROLL
;
197 GridData layoutData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
198 fStartTable
= new Table(parent
, style
);
199 fStartTable
.setLayoutData(layoutData
);
201 // Some cosmetic enhancements
202 fStartTable
.setHeaderVisible(true);
203 fStartTable
.setLinesVisible(true);
205 createStartColumns();
207 for (int i
= 0; i
< fEventTypes
.size(); i
++) {
208 TableItem item
= new TableItem(fStartTable
, SWT
.RIGHT
);
210 String
[] columns
= { fEventTypes
.get(i
), fEventTypes
.get(i
) };
212 item
.setText(columns
);
215 fStartTable
.setItemCount(fEventTypes
.size());
217 fStartTable
.addListener(SWT
.Selection
, new Listener() {
219 public void handleEvent(Event event
) {
220 if (event
.detail
== SWT
.CHECK
) {
221 TableItem
[] items
= fStartTable
.getItems();
222 for (TableItem item
: items
) {
223 if (item
!= event
.item
) {
224 item
.setChecked(false);
233 * Creates the end column list.
235 * The parent composite.
237 protected void createEndColumn(Composite parent
) {
238 final int style
= SWT
.SINGLE
| SWT
.CHECK
| SWT
.FULL_SELECTION
| SWT
.BORDER
| SWT
.V_SCROLL
;
239 GridData layoutData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
240 fEndTable
= new Table(parent
, style
);
241 fEndTable
.setLayoutData(layoutData
);
243 // Some cosmetic enhancements
244 fEndTable
.setHeaderVisible(true);
245 fEndTable
.setLinesVisible(true);
249 for (int i
= 0; i
< fEventTypes
.size(); i
++) {
250 TableItem item
= new TableItem(fEndTable
, SWT
.RIGHT
);
252 String
[] columns
= { fEventTypes
.get(i
), fEventTypes
.get(i
) };
254 item
.setText(columns
);
257 fEndTable
.setItemCount(fEventTypes
.size());
259 fEndTable
.addListener(SWT
.Selection
, new Listener() {
261 public void handleEvent(Event event
) {
262 if (event
.detail
== SWT
.CHECK
) {
263 TableItem
[] items
= fEndTable
.getItems();
264 for (TableItem item
: items
) {
265 if (item
!= event
.item
) {
266 item
.setChecked(false);
275 * Creates the list column for already existing event pairs.
277 * The parent composite.
279 protected void createListColumn(Composite parent
) {
280 final int style
= SWT
.SINGLE
| SWT
.FULL_SELECTION
| SWT
.BORDER
| SWT
.V_SCROLL
;
281 GridData layoutData
= new GridData(SWT
.FILL
, SWT
.FILL
, true, true);
282 layoutData
.horizontalSpan
= 2;
283 fListTable
= new Table(parent
, style
);
284 fListTable
.setLayoutData(layoutData
);
286 // Some cosmetic enhancements
287 fListTable
.setHeaderVisible(true);
288 fListTable
.setLinesVisible(true);
292 for (int i
= 0; i
< fEventStartTypes
.size(); i
++) {
293 TableItem item
= new TableItem(fListTable
, SWT
.RIGHT
);
295 String max
= String
.valueOf(fEventStartTypes
.size());
296 String number
= formatListNumber(i
+ 1, max
.length());
298 String
[] columns
= { number
, fEventStartTypes
.get(i
), fEventEndTypes
.get(i
) };
300 item
.setText(columns
);
303 fListTable
.setItemCount(103);
304 fListTable
.remove(fEventTypes
.size(), 103 - 1);
309 * @see org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.AbstractDialog#createDialogArea(org.eclipse.swt.widgets.Composite)
312 protected Control
createDialogArea(Composite parent
) {
313 GridLayout layout
= new GridLayout(2, true);
314 parent
.setLayout(layout
);
316 createStartColumn(parent
);
317 createEndColumn(parent
);
318 createListColumn(parent
);
325 * @see org.eclipse.linuxtools.lttng.ui.views.latency.dialogs.AbstractDialog#createButtonsForButtonBar(org.eclipse.swt.widgets.Composite)
328 protected void createButtonsForButtonBar(Composite parent
) {
329 GridData gridData
= new GridData();
330 gridData
.verticalAlignment
= GridData
.FILL
;
331 gridData
.horizontalSpan
= 1;
332 gridData
.grabExcessHorizontalSpace
= true;
333 gridData
.grabExcessVerticalSpace
= true;
334 gridData
.horizontalAlignment
= SWT
.RIGHT
;
336 parent
.setLayoutData(gridData
);
338 // Create the "Add" button
339 Button addButton
= createButton(parent
, ADD
, Messages
.LatencyView_Dialogs_AddEvents_Buttons_Add
, false);
340 addButton
.addListener(SWT
.Selection
, new Listener() {
342 public void handleEvent(Event event
) {
343 if (isValidInput()) {
344 // Add the event pair to the EventMatcher and save the pairs
345 EventMatcher
.getInstance().addMatch(fStartType
, fEndType
);
346 fEventStartTypes
.add(fStartType
);
347 fEventEndTypes
.add(fEndType
);
348 saveMatchPairs(fEventStartTypes
, fEventEndTypes
);
350 EventsPair pairs
= EventMatcher
.getInstance().getEvents();
351 fEventStartTypes
= pairs
.getFirst();
352 fEventEndTypes
= pairs
.getSecond();
354 fListTable
.removeAll();
356 for (int i
= 0; i
< fEventStartTypes
.size(); i
++) {
357 TableItem item
= new TableItem(fListTable
, SWT
.RIGHT
);
359 String max
= String
.valueOf(fEventStartTypes
.size());
360 String number
= formatListNumber(i
+ 1, max
.length());
362 String
[] columns
= { number
, fEventStartTypes
.get(i
), fEventEndTypes
.get(i
) };
364 item
.setText(columns
);
367 saveMatchPairs(fEventStartTypes
, fEventEndTypes
);
370 fRedrawGraphs
= true;
374 // Create the "Close" button
375 Button closeButton
= createButton(parent
, CANCEL
, Messages
.LatencyView_Dialogs_AddEvents_Buttons_Close
, false);
376 closeButton
.addListener(SWT
.Selection
, new Listener() {
378 public void handleEvent(Event event
) {
379 setReturnCode(CANCEL
);
381 if (fRedrawGraphs
== true)
390 * Validate the list before adding event pairs.
391 * @return "true" if the input is valid, "false" otherwise.
393 protected boolean isValidInput() {
394 // Remove the previous error message
395 setErrorMessage(null);
397 boolean valid
= true;
399 // Check if an item from the start list is selected
400 TableItem
[] items
= fStartTable
.getItems();
402 boolean startHasSelectedItem
= false;
403 for (int i
= 0; i
< items
.length
&& !startHasSelectedItem
; i
++) {
404 if (items
[i
].getChecked() == true) {
405 fStartType
= items
[i
].getText();
406 startHasSelectedItem
= true;
410 // Check if an item from the end list is selected
411 items
= fEndTable
.getItems();
413 boolean endHasSelectedItem
= false;
414 for (int i
= 0; i
< items
.length
&& !endHasSelectedItem
; i
++) {
415 if (items
[i
].getChecked() == true) {
416 fEndType
= items
[i
].getText();
417 endHasSelectedItem
= true;
421 // Print error message if needed.
422 if (!startHasSelectedItem
&& !endHasSelectedItem
) {
423 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_NoSelection
);
425 } else if (!startHasSelectedItem
) {
426 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_StartNotSelected
);
428 } else if (!endHasSelectedItem
) {
429 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_EndNotSelected
);
433 // Check if the same item is selected in both lists
434 if (startHasSelectedItem
&& endHasSelectedItem
) {
435 if (fStartType
.equalsIgnoreCase(fEndType
)) {
436 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_SameSelected
);
441 // Check if the selected item is already in the list
442 if (startHasSelectedItem
&& endHasSelectedItem
) {
443 EventsPair pairs
= getMatchPairs();
444 Vector
<String
> startEvents
= pairs
.getFirst();
445 Vector
<String
> endEvents
= pairs
.getSecond();
447 boolean startAlreadyUsed
= false;
448 boolean endAlreadyUsed
= false;
449 boolean startAsEndAlreadyUsed
= false;
450 boolean endAsStartAlreadyUsed
= false;
452 if (startEvents
.contains(fStartType
)) {
453 startAlreadyUsed
= true;
455 if (endEvents
.contains(fEndType
)) {
456 endAlreadyUsed
= true;
458 if (startEvents
.contains(fEndType
)) {
459 endAsStartAlreadyUsed
= true;
461 if (endEvents
.contains(fStartType
)) {
462 startAsEndAlreadyUsed
= true;
465 if (startAlreadyUsed
&& endAlreadyUsed
) {
466 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_AlreadyMatched
);
468 } else if (startAlreadyUsed
) {
469 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_StartAlreadyMatched
);
471 } else if (endAlreadyUsed
) {
472 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_EndAlreadyMatched
);
476 if (startAsEndAlreadyUsed
) {
477 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_StartAsEnd
);
480 if (endAsStartAlreadyUsed
) {
481 setErrorMessage(Messages
.LatencyView_Dialogs_AddEvents_Errors_EndAsStart
);