Fix some null warnings
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / tmf / ui / project / wizards / SelectTracesWizardPage.java
CommitLineData
12c155f5 1/*******************************************************************************
1acb7949 2 * Copyright (c) 2009, 2015 Ericsson, École Polytechnique de Montréal
abbdd66a 3 *
12c155f5
FC
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
abbdd66a 8 *
12c155f5
FC
9 * Contributors:
10 * Francois Chouinard - Initial API and implementation
beb19106 11 * Geneviève Bastien - Moved the add and remove code to the experiment class
339d539c 12 * Patrick Tasse - Add support for folder elements
6039bcf3 13 * Marc-Andre Laperle - Convert to tree structure and add select/deselect all
12c155f5
FC
14 *******************************************************************************/
15
2bdf0193 16package org.eclipse.tracecompass.tmf.ui.project.wizards;
12c155f5 17
f0837186 18import java.lang.reflect.InvocationTargetException;
7340b814 19import java.util.ArrayList;
1acb7949 20import java.util.Arrays;
12c155f5 21import java.util.HashMap;
7340b814 22import java.util.List;
12c155f5
FC
23import java.util.Map;
24import java.util.Set;
12c155f5 25
12c155f5 26import org.eclipse.core.resources.IFolder;
f0837186
BH
27import org.eclipse.core.resources.IWorkspace;
28import org.eclipse.core.resources.IWorkspaceRunnable;
29import org.eclipse.core.resources.ResourcesPlugin;
12c155f5 30import org.eclipse.core.runtime.CoreException;
f0837186
BH
31import org.eclipse.core.runtime.IProgressMonitor;
32import org.eclipse.core.runtime.IStatus;
33import org.eclipse.core.runtime.Status;
34import org.eclipse.core.runtime.SubMonitor;
1acb7949 35import org.eclipse.jdt.annotation.NonNull;
f0837186
BH
36import org.eclipse.jface.dialogs.MessageDialog;
37import org.eclipse.jface.operation.IRunnableWithProgress;
38import org.eclipse.jface.operation.ModalContext;
6039bcf3
MAL
39import org.eclipse.jface.viewers.CheckStateChangedEvent;
40import org.eclipse.jface.viewers.CheckboxTreeViewer;
41import org.eclipse.jface.viewers.ColumnLabelProvider;
42import org.eclipse.jface.viewers.ICheckStateListener;
43import org.eclipse.jface.viewers.TreeViewer;
44import org.eclipse.jface.viewers.TreeViewerColumn;
339d539c 45import org.eclipse.jface.viewers.ViewerSorter;
12c155f5 46import org.eclipse.jface.wizard.WizardPage;
12c155f5 47import org.eclipse.swt.SWT;
6039bcf3
MAL
48import org.eclipse.swt.events.SelectionAdapter;
49import org.eclipse.swt.events.SelectionEvent;
50import org.eclipse.swt.graphics.Image;
51import org.eclipse.swt.layout.FillLayout;
52import org.eclipse.swt.layout.GridData;
53import org.eclipse.swt.layout.GridLayout;
54import org.eclipse.swt.widgets.Button;
12c155f5 55import org.eclipse.swt.widgets.Composite;
2f5c2df5 56import org.eclipse.swt.widgets.Display;
6039bcf3 57import org.eclipse.swt.widgets.Tree;
2bdf0193
AM
58import org.eclipse.tracecompass.internal.tmf.ui.Activator;
59import org.eclipse.tracecompass.tmf.core.project.model.TmfTraceType;
60import org.eclipse.tracecompass.tmf.ui.project.model.ITmfProjectModelElement;
61import org.eclipse.tracecompass.tmf.ui.project.model.TmfExperimentElement;
62import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorContentProvider;
63import org.eclipse.tracecompass.tmf.ui.project.model.TmfNavigatorLabelProvider;
64import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement;
65import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement;
66import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceFolder;
6039bcf3
MAL
67import org.eclipse.ui.dialogs.FilteredTree;
68import org.eclipse.ui.dialogs.PatternFilter;
12c155f5
FC
69
70/**
b544077e 71 * Implementation of a wizard page for selecting trace for an experiment.
12c155f5 72 * <p>
abbdd66a 73 *
b544077e
BH
74 * @version 1.0
75 * @author Francois Chouinard
12c155f5
FC
76 */
77public class SelectTracesWizardPage extends WizardPage {
78
79 // ------------------------------------------------------------------------
80 // Attributes
81 // ------------------------------------------------------------------------
82
83 private final TmfProjectElement fProject;
84 private final TmfExperimentElement fExperiment;
9fa32496 85 private Map<String, TmfTraceElement> fPreviousTraces;
6039bcf3
MAL
86 private CheckboxTreeViewer fCheckboxTreeViewer;
87 private TmfNavigatorContentProvider fContentProvider;
88 private TmfNavigatorLabelProvider fLabelProvider;
89
90 private static final int COLUMN_WIDTH = 200;
91 private static final int BUTTON_SPACING = 4;
12c155f5
FC
92
93 // ------------------------------------------------------------------------
94 // Constructor
95 // ------------------------------------------------------------------------
b544077e
BH
96 /**
97 * Constructor
ba560b10
MK
98 *
99 * @param project
100 * The project model element.
101 * @param experiment
102 * The experiment model experiment.
b544077e 103 */
12c155f5
FC
104 protected SelectTracesWizardPage(TmfProjectElement project, TmfExperimentElement experiment) {
105 super(""); //$NON-NLS-1$
106 setTitle(Messages.SelectTracesWizardPage_WindowTitle);
107 setDescription(Messages.SelectTracesWizardPage_Description);
108 fProject = project;
109 fExperiment = experiment;
110 }
111
112 // ------------------------------------------------------------------------
113 // Dialog
114 // ------------------------------------------------------------------------
11252342 115
12c155f5
FC
116 @Override
117 public void createControl(Composite parent) {
118 Composite container = new Composite(parent, SWT.NULL);
6039bcf3 119 container.setLayout(new GridLayout(2, false));
12c155f5
FC
120 setControl(container);
121
6039bcf3
MAL
122 new FilteredTree(container, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER, new PatternFilter(), true) {
123 @Override
124 protected TreeViewer doCreateTreeViewer(Composite aparent, int style) {
125 return SelectTracesWizardPage.this.doCreateTreeViewer(aparent);
126 }
127 };
128
129 Composite buttonComposite = new Composite(container, SWT.NONE);
130 FillLayout layout = new FillLayout(SWT.VERTICAL);
131 layout.spacing = BUTTON_SPACING;
132 buttonComposite.setLayout(layout);
133 GridData gd = new GridData();
134 gd.verticalAlignment = SWT.CENTER;
135 buttonComposite.setLayoutData(gd);
136
137 Button selectAllButton = new Button(buttonComposite, SWT.PUSH);
2bdf0193 138 selectAllButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.Messages.Dialog_SelectAll);
6039bcf3
MAL
139 selectAllButton.addSelectionListener(new SelectionAdapter() {
140 @Override
141 public void widgetSelected(SelectionEvent e) {
142 setAllChecked(true);
143 }
144 });
145
146 Button deselectAllButton = new Button(buttonComposite, SWT.PUSH);
2bdf0193 147 deselectAllButton.setText(org.eclipse.tracecompass.internal.tmf.ui.project.dialogs.Messages.Dialog_DeselectAll);
6039bcf3
MAL
148 deselectAllButton.addSelectionListener(new SelectionAdapter() {
149 @Override
150 public void widgetSelected(SelectionEvent e) {
151 setAllChecked(false);
152 }
153 });
154 }
155
156 private TreeViewer doCreateTreeViewer(Composite parent) {
157 fCheckboxTreeViewer = new CheckboxTreeViewer(parent, SWT.BORDER);
158 fContentProvider = new TmfNavigatorContentProvider() {
159
160 @Override
161 public Object[] getElements(Object inputElement) {
7340b814 162 return getChildren(inputElement);
6039bcf3
MAL
163 }
164
165 @Override
166 public synchronized Object[] getChildren(Object parentElement) {
167 // We only care about the content of trace folders
168 if (parentElement instanceof TmfTraceFolder) {
7340b814
MAL
169 Object[] children = super.getChildren(parentElement);
170 List<ITmfProjectModelElement> filteredChildren = new ArrayList<>();
171 for (Object child : children) {
172 if (child instanceof TmfTraceElement) {
173 TmfTraceElement traceElement = (TmfTraceElement) child;
45a3131c
MAL
174 String traceType = traceElement.getTraceType();
175 if (traceType != null && TmfTraceType.getTraceType(traceType) != null) {
7340b814
MAL
176 filteredChildren.add(traceElement);
177 }
178 } else if (child instanceof TmfTraceFolder) {
179 filteredChildren.add((TmfTraceFolder) child);
180 }
181 }
182 return filteredChildren.toArray();
6039bcf3
MAL
183 }
184 return null;
185 }
12c155f5 186
6039bcf3
MAL
187 @Override
188 public boolean hasChildren(Object element) {
7340b814
MAL
189 Object[] children = getChildren(element);
190 return children != null && children.length > 0;
6039bcf3
MAL
191 }
192 };
193 fCheckboxTreeViewer.setContentProvider(fContentProvider);
194 fLabelProvider = new TmfNavigatorLabelProvider();
195 fCheckboxTreeViewer.setLabelProvider(fLabelProvider);
196 fCheckboxTreeViewer.setSorter(new ViewerSorter());
12c155f5 197
6039bcf3
MAL
198 final Tree tree = fCheckboxTreeViewer.getTree();
199 GridData gd = new GridData(SWT.FILL, SWT.FILL, true, true);
200 tree.setLayoutData(gd);
201 tree.setHeaderVisible(true);
202
203 final TreeViewerColumn column = new TreeViewerColumn(fCheckboxTreeViewer, SWT.NONE);
204 column.getColumn().setWidth(COLUMN_WIDTH);
205 column.getColumn().setText(Messages.SelectTracesWizardPage_TraceColumnHeader);
206 column.setLabelProvider(new ColumnLabelProvider() {
207 @Override
208 public String getText(Object element) {
209 return fLabelProvider.getText(element);
210 }
ba560b10 211
6039bcf3
MAL
212 @Override
213 public Image getImage(Object element) {
214 return fLabelProvider.getImage(element);
215 }
216 });
12c155f5
FC
217
218 // Get the list of traces already part of the experiment
507b1336 219 fPreviousTraces = new HashMap<>();
12c155f5
FC
220 for (ITmfProjectModelElement child : fExperiment.getChildren()) {
221 if (child instanceof TmfTraceElement) {
222 TmfTraceElement trace = (TmfTraceElement) child;
339d539c 223 String name = trace.getElementPath();
12c155f5
FC
224 fPreviousTraces.put(name, trace);
225 }
226 }
227
228 // Populate the list of traces to choose from
229 Set<String> keys = fPreviousTraces.keySet();
230 TmfTraceFolder traceFolder = fProject.getTracesFolder();
6039bcf3 231 fCheckboxTreeViewer.setInput(traceFolder);
12c155f5
FC
232
233 // Set the checkbox for the traces already included
6039bcf3
MAL
234 setCheckedAlreadyIncludedTraces(keys, fContentProvider.getElements(fCheckboxTreeViewer.getInput()));
235
236 fCheckboxTreeViewer.addCheckStateListener(new ICheckStateListener() {
237 @Override
238 public void checkStateChanged(CheckStateChangedEvent event) {
239 Object element = event.getElement();
240 setSubtreeChecked(element, event.getChecked());
241 maintainCheckIntegrity(element);
242 }
243 });
244
245 return fCheckboxTreeViewer;
246 }
247
248 private void maintainCheckIntegrity(final Object element) {
249 Object parentElement = fContentProvider.getParent(element);
250 boolean allChecked = true;
251 boolean oneChecked = false;
252 boolean oneGrayed = false;
253 if (parentElement != null) {
254 if (fContentProvider.getChildren(parentElement) != null) {
255 for (Object child : fContentProvider.getChildren(parentElement)) {
256 boolean checked = fCheckboxTreeViewer.getChecked(child);
257 oneChecked |= checked;
258 allChecked &= checked;
259 oneGrayed |= fCheckboxTreeViewer.getGrayed(child);
260 }
261 }
262 if (oneGrayed || oneChecked && !allChecked) {
263 fCheckboxTreeViewer.setGrayChecked(parentElement, true);
264 } else {
265 fCheckboxTreeViewer.setGrayed(parentElement, false);
266 fCheckboxTreeViewer.setChecked(parentElement, allChecked);
267 }
268 maintainCheckIntegrity(parentElement);
269 }
270 }
271
272 private void setCheckedAlreadyIncludedTraces(Set<String> alreadyIncludedTraces, Object[] elements) {
273 for (Object element : elements) {
12c155f5
FC
274 if (element instanceof TmfTraceElement) {
275 TmfTraceElement trace = (TmfTraceElement) element;
6039bcf3
MAL
276 String elementPath = trace.getElementPath();
277 if (alreadyIncludedTraces.contains(elementPath)) {
278 fCheckboxTreeViewer.setChecked(element, true);
279 maintainCheckIntegrity(element);
12c155f5
FC
280 }
281 }
6039bcf3
MAL
282 Object[] children = fContentProvider.getChildren(element);
283 if (children != null) {
284 setCheckedAlreadyIncludedTraces(alreadyIncludedTraces, children);
285 }
286 }
287 }
288
289 /**
290 * Sets all items in the element viewer to be checked or unchecked
291 *
292 * @param checked
293 * whether or not items should be checked
294 */
295 private void setAllChecked(boolean checked) {
296 for (Object element : fContentProvider.getChildren(fCheckboxTreeViewer.getInput())) {
297 setSubtreeChecked(element, checked);
298 }
299 }
300
301 /**
302 * A version of setSubtreeChecked that also handles the grayed state
303 *
304 * @param element
305 * the element
306 * @param checked
307 * true if the item should be checked, and false if it should be
308 * unchecked
309 */
310 private void setSubtreeChecked(Object element, boolean checked) {
311 fCheckboxTreeViewer.setChecked(element, checked);
312 if (checked) {
313 fCheckboxTreeViewer.setGrayed(element, false);
314 }
315 Object[] children = fContentProvider.getChildren(element);
316 if (children != null) {
317 for (Object child : children) {
318 setSubtreeChecked(child, checked);
319 }
12c155f5
FC
320 }
321 }
322
b544077e
BH
323 /**
324 * Method to finalize the select operation.
ba560b10 325 *
b544077e
BH
326 * @return <code>true</code> if successful else <code>false</code>
327 */
12c155f5
FC
328 public boolean performFinish() {
329
330 IFolder experiment = fExperiment.getResource();
331
f0837186
BH
332 final SelectTracesOperation operation = new SelectTracesOperation(experiment, getSelection());
333
334 IStatus status = Status.OK_STATUS;
335 try {
336 getContainer().run(true, true, new IRunnableWithProgress() {
337 @Override
338 public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
ba560b10
MK
339 // Wrapper to have only one resource changed event at the
340 // end of the operation.
f0837186
BH
341 IWorkspaceRunnable workspaceRunnable = new IWorkspaceRunnable() {
342 @Override
343 public void run(IProgressMonitor pm) throws CoreException {
344 operation.run(pm);
345 }
346 };
347
348 IWorkspace workspace = ResourcesPlugin.getWorkspace();
349 try {
350 workspace.run(workspaceRunnable, workspace.getRoot(), IWorkspace.AVOID_UPDATE, monitor);
351 } catch (CoreException e) {
352 throw new InvocationTargetException(e);
353 } finally {
354 monitor.done();
355 }
356 }
357 });
358
359 status = operation.getStatus();
360 } catch (InvocationTargetException e) {
361 status = new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e);
362 } catch (InterruptedException e) {
363 status = Status.CANCEL_STATUS;
ba560b10
MK
364 }
365 if (!status.isOK()) {
366 if (status.getSeverity() == IStatus.CANCEL) {
367 setMessage(Messages.SelectTracesWizardPage_SelectionOperationCancelled);
368 setErrorMessage(null);
369 } else {
370 if (status.getException() != null) {
371 MessageDialog.open(MessageDialog.ERROR, getContainer().getShell(),
372 Messages.SelectTracesWizardPage_InternalErrorTitle, status.getMessage() + ": " + status.getException(), SWT.SHEET); //$NON-NLS-1$
f0837186 373 }
ba560b10
MK
374 setMessage(null);
375 setErrorMessage(Messages.SelectTracesWizardPage_SelectionError);
12c155f5 376 }
ba560b10 377 return false;
12c155f5 378 }
f0837186
BH
379 setErrorMessage(null);
380
381 return true;
382 }
383
384 private class SelectTracesOperation {
385
386 IFolder experiment = null;
387 TmfTraceElement[] traces;
388 private IStatus fStatus;
389
1acb7949 390 public SelectTracesOperation(IFolder experiment, @NonNull TmfTraceElement[] traces) {
f0837186 391 this.experiment = experiment;
1acb7949 392 this.traces = Arrays.copyOf(traces, traces.length);
f0837186 393 }
12c155f5 394
f0837186
BH
395 public void run(IProgressMonitor progressMonitor) {
396
397 // Check if operation was cancelled.
398 boolean changed = false;
399
400 // Add the selected traces to the experiment
401 Set<String> keys = fPreviousTraces.keySet();
402 SubMonitor subMonitor = SubMonitor.convert(progressMonitor, traces.length + keys.size());
12c155f5 403 try {
f0837186
BH
404 for (TmfTraceElement trace : traces) {
405 ModalContext.checkCanceled(progressMonitor);
406 String name = trace.getElementPath();
407 if (keys.contains(name)) {
408 subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$
409 fPreviousTraces.remove(name);
410 } else {
411 subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceSelectionTask + " " + trace.getElementPath()); //$NON-NLS-1$
412 fExperiment.addTrace(trace, false);
413 changed = true;
414 }
415 subMonitor.worked(1);
416 }
417
ba560b10
MK
418 // Remove traces that were unchecked (thus left in
419 // fPreviousTraces)
202956f1 420 for (Map.Entry<String, TmfTraceElement> entry : fPreviousTraces.entrySet()) {
f0837186 421 ModalContext.checkCanceled(progressMonitor);
202956f1 422 TmfTraceElement trace = entry.getValue();
f0837186
BH
423 subMonitor.setTaskName(Messages.SelectTracesWizardPage_TraceRemovalTask + " " + trace.getElementPath()); //$NON-NLS-1$
424
425 try {
426 fExperiment.removeTrace(trace);
427 } catch (CoreException e) {
428 Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError + " " + experiment.getName(), e); //$NON-NLS-1$
429 }
430 changed = true;
431 subMonitor.worked(1);
432 }
433 if (changed) {
2f5c2df5
PT
434 Display.getDefault().syncExec(new Runnable() {
435 @Override
436 public void run() {
437 fExperiment.closeEditors();
438 }
439 });
f0837186
BH
440 fExperiment.deleteSupplementaryResources();
441 }
442 setStatus(Status.OK_STATUS);
443 } catch (InterruptedException e) {
444 setStatus(Status.CANCEL_STATUS);
445 } catch (Exception e) {
446 Activator.getDefault().logError(Messages.SelectTracesWizardPage_SelectionError, e);
ba560b10 447 setStatus(new Status(IStatus.ERROR, Activator.PLUGIN_ID, Messages.SelectTracesWizardPage_SelectionError, e));
12c155f5
FC
448 }
449 }
f0837186
BH
450
451 /**
452 * Set the status for this operation
453 *
454 * @param status
455 * the status
456 */
457 protected void setStatus(IStatus status) {
458 fStatus = status;
459 }
460
461 public IStatus getStatus() {
462 return fStatus;
639181ba 463 }
12c155f5 464
12c155f5
FC
465 }
466
12c155f5
FC
467 /**
468 * Get the list of selected traces
469 */
1acb7949
MK
470 private @NonNull TmfTraceElement[] getSelection() {
471 List<TmfTraceElement> traces = new ArrayList<>();
6039bcf3 472 Object[] selection = fCheckboxTreeViewer.getCheckedElements();
12c155f5 473 for (Object sel : selection) {
abbdd66a 474 if (sel instanceof TmfTraceElement) {
12c155f5 475 traces.add((TmfTraceElement) sel);
abbdd66a 476 }
12c155f5 477 }
aa353506 478 return traces.toArray(new @NonNull TmfTraceElement[0]);
12c155f5
FC
479 }
480
481}
This page took 0.130608 seconds and 5 git commands to generate.