lttng: Add possibility to select/deselect all in remote import dialog
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng2.ui / src / org / eclipse / linuxtools / internal / lttng2 / ui / views / control / dialogs / ImportDialog.java
CommitLineData
291cbdbf 1/**********************************************************************
ba3a9bd2 2 * Copyright (c) 2012, 2013 Ericsson
cfdb727a 3 *
291cbdbf
BH
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
cfdb727a
AM
8 *
9 * Contributors:
291cbdbf 10 * Bernd Hufmann - Initial API and implementation
ba3a9bd2 11 * Bernd Hufmann - Added handling of streamed traces
d600c18f 12 * Marc-Andre Laperle - Use common method to get opened tmf projects
291cbdbf
BH
13 **********************************************************************/
14package org.eclipse.linuxtools.internal.lttng2.ui.views.control.dialogs;
15
16import java.util.ArrayList;
17import java.util.List;
18
19import org.eclipse.core.resources.IFolder;
20import org.eclipse.core.resources.IProject;
291cbdbf
BH
21import org.eclipse.core.runtime.NullProgressMonitor;
22import org.eclipse.jface.dialogs.Dialog;
23import org.eclipse.jface.dialogs.IDialogConstants;
24import org.eclipse.jface.dialogs.MessageDialog;
25import org.eclipse.jface.viewers.CheckStateChangedEvent;
26import org.eclipse.jface.viewers.CheckboxTreeViewer;
27import org.eclipse.jface.viewers.ICheckStateListener;
28import org.eclipse.jface.window.Window;
29import org.eclipse.linuxtools.internal.lttng2.ui.Activator;
9315aeee 30import org.eclipse.linuxtools.internal.lttng2.ui.views.control.messages.Messages;
291cbdbf
BH
31import org.eclipse.linuxtools.internal.lttng2.ui.views.control.model.impl.TraceSessionComponent;
32import org.eclipse.linuxtools.internal.lttng2.ui.views.control.remote.IRemoteSystemProxy;
291cbdbf 33import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder;
d600c18f 34import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils;
cd9821de 35import org.eclipse.rse.core.subsystems.RemoteChildrenContentsType;
291cbdbf
BH
36import org.eclipse.rse.services.clientserver.messages.SystemMessageException;
37import org.eclipse.rse.subsystems.files.core.servicesubsystem.IFileServiceSubSystem;
38import org.eclipse.rse.subsystems.files.core.subsystems.IRemoteFile;
39import org.eclipse.swt.SWT;
40import org.eclipse.swt.custom.CCombo;
f75337be
BH
41import org.eclipse.swt.events.SelectionAdapter;
42import org.eclipse.swt.events.SelectionEvent;
291cbdbf
BH
43import org.eclipse.swt.graphics.Point;
44import org.eclipse.swt.layout.GridData;
45import org.eclipse.swt.layout.GridLayout;
46import org.eclipse.swt.widgets.Button;
47import org.eclipse.swt.widgets.Composite;
48import org.eclipse.swt.widgets.Control;
49import org.eclipse.swt.widgets.Group;
50import org.eclipse.swt.widgets.Shell;
51import org.eclipse.swt.widgets.Text;
52import org.eclipse.swt.widgets.Tree;
53import org.eclipse.ui.model.WorkbenchContentProvider;
54import org.eclipse.ui.model.WorkbenchLabelProvider;
55
56/**
291cbdbf
BH
57 * <p>
58 * Dialog box for collecting trace import information.
59 * </p>
cfdb727a 60 *
dbd4432d 61 * @author Bernd Hufmann
291cbdbf
BH
62 */
63public class ImportDialog extends Dialog implements IImportDialog {
64
65 // ------------------------------------------------------------------------
66 // Constants
67 // ------------------------------------------------------------------------
cfdb727a 68 /** The icon file for this dialog box. */
291cbdbf 69 public static final String IMPORT_ICON_FILE = "icons/elcl16/import_trace.gif"; //$NON-NLS-1$
cfdb727a
AM
70
71 /** Parent directory for UST traces */
291cbdbf
BH
72 public static final String UST_PARENT_DIRECTORY = "ust"; //$NON-NLS-1$
73
cd9821de
BH
74 /** Name of metadata file of trace */
75 public static final String METADATA_FILE_NAME = "metadata"; //$NON-NLS-1$
76
77 /** Default name of kernel traces */
78 public static final String DEFAULT_KERNEL_TRACE_NAME = "kernel"; //$NON-NLS-1$
79
291cbdbf
BH
80 // ------------------------------------------------------------------------
81 // Attributes
82 // ------------------------------------------------------------------------
83 /**
84 * The dialog composite.
85 */
86 private Composite fDialogComposite = null;
87 /**
88 * The checkbox tree viewer for selecting available traces
89 */
90 private CheckboxTreeViewer fFolderViewer;
91 /**
92 * The combo box for selecting a project.
93 */
94 private CCombo fCombo;
95 /**
cfdb727a 96 * The overwrite button
291cbdbf
BH
97 */
98 private Button fOverwriteButton;
99 /**
100 * List of available LTTng 2.0 projects
101 */
102 private List<IProject> fProjects;
103 /**
104 * The parent where the new node should be added.
105 */
106 private TraceSessionComponent fSession = null;
cd9821de
BH
107
108 /**
109 * The name of the default project name
110 */
111 private String fDefaultProjectName = null;
291cbdbf 112 /**
cfdb727a 113 * List of traces to import
291cbdbf 114 */
cfdb727a 115 private final List<ImportFileInfo> fTraces = new ArrayList<ImportFileInfo>();
291cbdbf 116 /**
cfdb727a 117 * Selection index in project combo box.
291cbdbf
BH
118 */
119 private int fProjectIndex;
120 /**
121 * Flag to indicate that something went wrong when creating the dialog box.
122 */
123 private boolean fIsError = false;
f75337be
BH
124 /**
125 * Children of the remote folder (can be null)
126 */
127 private Object[] fFolderChildren = null;
cfdb727a 128
291cbdbf
BH
129 // ------------------------------------------------------------------------
130 // Constructors
131 // ------------------------------------------------------------------------
132 /**
133 * Constructor
134 * @param shell - a shell for the display of the dialog
135 */
136 public ImportDialog(Shell shell) {
137 super(shell);
8a396998 138 setShellStyle(SWT.RESIZE | getShellStyle());
291cbdbf
BH
139 }
140
141 // ------------------------------------------------------------------------
142 // Accessors
143 // ------------------------------------------------------------------------
11252342 144
291cbdbf
BH
145 @Override
146 public List<ImportFileInfo> getTracePathes() {
147 List<ImportFileInfo> retList = new ArrayList<ImportFileInfo>();
148 retList.addAll(fTraces);
149 return retList;
150 }
151
291cbdbf
BH
152 @Override
153 public IProject getProject() {
154 return fProjects.get(fProjectIndex);
155 }
cfdb727a 156
291cbdbf
BH
157 @Override
158 public void setSession(TraceSessionComponent session) {
159 fSession = session;
160 }
161
cd9821de
BH
162 @Override
163 public void setDefaultProject(String defaultProject) {
164 fDefaultProjectName = defaultProject;
165 }
166
291cbdbf
BH
167 // ------------------------------------------------------------------------
168 // Operations
169 // ------------------------------------------------------------------------
11252342 170
291cbdbf
BH
171 @Override
172 protected void configureShell(Shell newShell) {
173 super.configureShell(newShell);
174 newShell.setText(Messages.TraceControl_ImportDialogTitle);
175 newShell.setImage(Activator.getDefault().loadIcon(IMPORT_ICON_FILE));
176 }
177
291cbdbf
BH
178 @Override
179 protected Control createDialogArea(Composite parent) {
cfdb727a 180
291cbdbf
BH
181 // Main dialog panel
182 fDialogComposite = new Composite(parent, SWT.NONE);
183 GridLayout layout = new GridLayout(1, true);
184 fDialogComposite.setLayout(layout);
185 fDialogComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
186
291cbdbf 187 try {
cd9821de 188 createRemoteComposite();
291cbdbf
BH
189 } catch (SystemMessageException e) {
190 createErrorComposite(parent, e.fillInStackTrace());
191 return fDialogComposite;
192 }
291cbdbf
BH
193 return fDialogComposite;
194 }
195
291cbdbf
BH
196 @Override
197 protected void createButtonsForButtonBar(Composite parent) {
f75337be
BH
198 Button selectAllButton = createButton(parent, IDialogConstants.SELECT_ALL_ID, Messages.TraceControl_ImportDialog_SelectAll, true);
199 selectAllButton.addSelectionListener(new SelectionAdapter() {
200 @Override
201 public void widgetSelected(SelectionEvent e) {
202 setFolderChildrenChecked(true);
203 }
204 });
205
206 Button deselectAllButton = createButton(parent, IDialogConstants.DESELECT_ALL_ID, Messages.TraceControl_ImportDialog_DeselectAll, true);
207 deselectAllButton.addSelectionListener(new SelectionAdapter() {
208 @Override
209 public void widgetSelected(SelectionEvent e) {
210 setFolderChildrenChecked(false);
211 }
212 });
213 createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, true);
214 createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
215 updateOKButtonEnablement();
291cbdbf
BH
216 }
217
291cbdbf
BH
218 @Override
219 protected void okPressed() {
220 if (!fIsError) {
f3b33d40 221
291cbdbf
BH
222 // Validate input data
223 fTraces.clear();
224
225 fProjectIndex = fCombo.getSelectionIndex();
226
227 if (fProjectIndex < 0) {
228 MessageDialog.openError(getShell(),
229 Messages.TraceControl_ImportDialogTitle,
230 Messages.TraceControl_ImportDialogNoProjectSelectedError);
231 return;
232 }
233
234 IProject project = fProjects.get(fProjectIndex);
235 IFolder traceFolder = project.getFolder(TmfTraceFolder.TRACE_FOLDER_NAME);
236
237 if (!traceFolder.exists()) {
238 // Invalid LTTng 2.0 project
239 MessageDialog.openError(getShell(),
240 Messages.TraceControl_ImportDialogTitle,
241 Messages.TraceControl_ImportDialogInvalidTracingProject + " (" + TmfTraceFolder.TRACE_FOLDER_NAME + ")"); //$NON-NLS-1$//$NON-NLS-2$
242 return;
243 }
244
245 boolean overwriteAll = fOverwriteButton.getSelection();
246
247 Object[] checked = fFolderViewer.getCheckedElements();
248 for (int i = 0; i < checked.length; i++) {
249 IRemoteFile file = (IRemoteFile) checked[i];
cd9821de
BH
250 if (!file.isDirectory() && file.getName().equals(METADATA_FILE_NAME)) {
251 IRemoteFile trace = file.getParentRemoteFile();
252 IRemoteFile parent = trace.getParentRemoteFile();
253 boolean isKernel = false;
254 if (trace.getName().equals(DEFAULT_KERNEL_TRACE_NAME)) {
255 isKernel = true;
256 }
257 StringBuffer traceName = new StringBuffer();
258 traceName.append(trace.getName());
259 traceName.insert(0, '-');
260
589d0d33
BH
261 String path = fSession.isSnapshotSession() ? fSession.getSnapshotInfo().getSnapshotPath() : fSession.getSessionPath();
262
263 while (!parent.getAbsolutePath().equals(path)) {
cd9821de
BH
264 traceName.insert(0, parent.getName());
265 traceName.insert(0, '-');
266 parent = parent.getParentRemoteFile();
267 }
268 traceName.insert(0, parent.getName());
cfdb727a 269
cd9821de
BH
270 ImportFileInfo info = new ImportFileInfo(trace, traceName.toString(), overwriteAll, isKernel);
271 IFolder folder = traceFolder.getFolder(traceName.toString());
291cbdbf 272
cfdb727a 273 // Verify if trace directory already exists (and not overwrite)
291cbdbf
BH
274 if (folder.exists() && !overwriteAll) {
275
276 // Ask user for overwrite or new name
277 IImportConfirmationDialog conf = TraceControlDialogFactory.getInstance().getImportConfirmationDialog();
cd9821de 278 conf.setTraceName(traceName.toString());
291cbdbf
BH
279
280 // Don't add trace to list if dialog was cancelled.
281 if (conf.open() == Window.OK) {
282 info.setOverwrite(conf.isOverwrite());
283 if (!conf.isOverwrite()) {
284 info.setLocalTraceName(conf.getNewTraceName());
285 }
286 fTraces.add(info);
287 }
cfdb727a 288 } else {
291cbdbf
BH
289 fTraces.add(info);
290 }
291 }
292 }
293
294 if (fTraces.isEmpty()) {
295 MessageDialog.openError(getShell(),
296 Messages.TraceControl_ImportDialogTitle,
297 Messages.TraceControl_ImportDialogNoTraceSelectedError);
298 return;
299 }
300 }
301
302 // validation successful -> call super.okPressed()
303 super.okPressed();
304 }
305
306 // ------------------------------------------------------------------------
307 // Helper methods and classes
308 // ------------------------------------------------------------------------
11252342 309
cfdb727a
AM
310 /**
311 * Helper class for the contents of a folder in a tracing project
312 *
313 * @author Bernd Hufmann
314 */
f455db37 315 public static class FolderContentProvider extends WorkbenchContentProvider {
291cbdbf
BH
316 @Override
317 public Object[] getChildren(Object o) {
318 if (o instanceof IRemoteFile) {
319 IRemoteFile element = (IRemoteFile) o;
320 // For our purpose, we need folders + files
321 if (!element.isDirectory()) {
322 return new Object[0];
323 }
324 }
325 return super.getChildren(o);
326 }
327 }
cfdb727a 328
291cbdbf
BH
329 /**
330 * Creates a dialog composite with an error message which can be used
331 * when an exception occurred during creation time of the dialog box.
332 * @param parent - a parent composite
cfdb727a 333 * @param e - a error causing exception
291cbdbf
BH
334 */
335 private void createErrorComposite(Composite parent, Throwable e) {
336 fIsError = true;
337 fDialogComposite.dispose();
cfdb727a 338
291cbdbf
BH
339 fDialogComposite = new Composite(parent, SWT.NONE);
340 GridLayout layout = new GridLayout(1, true);
341 fDialogComposite.setLayout(layout);
342 fDialogComposite.setLayoutData(new GridData(GridData.FILL_BOTH));
cfdb727a 343
291cbdbf
BH
344 Text errorText = new Text(fDialogComposite, SWT.MULTI);
345 StringBuffer error = new StringBuffer();
346 error.append(Messages.TraceControl_ImportDialogCreationError);
347 error.append(System.getProperty("line.separator")); //$NON-NLS-1$
348 error.append(System.getProperty("line.separator")); //$NON-NLS-1$
349 error.append(e.toString());
350 errorText.setText(error.toString());
351 errorText.setLayoutData(new GridData(GridData.FILL_BOTH));
352 }
353
d600c18f 354 private void createRemoteComposite() throws SystemMessageException{
f3b33d40
BH
355 Group contextGroup = new Group(fDialogComposite, SWT.SHADOW_NONE);
356 contextGroup.setText(Messages.TraceControl_ImportDialogTracesGroupName);
357 GridLayout layout = new GridLayout(1, true);
358 contextGroup.setLayout(layout);
359 contextGroup.setLayoutData(new GridData(GridData.FILL_BOTH));
360
361 IRemoteSystemProxy proxy = fSession.getTargetNode().getRemoteSystemProxy();
362
363 IFileServiceSubSystem fsss = proxy.getFileServiceSubSystem();
364
589d0d33
BH
365 final String path = fSession.isSnapshotSession() ? fSession.getSnapshotInfo().getSnapshotPath() : fSession.getSessionPath();
366 final IRemoteFile remoteFolder = fsss.getRemoteFileObject(path, new NullProgressMonitor());
367 // make sure that remote directory is read and not cached
368 remoteFolder.markStale(true, true);
f3b33d40 369
f75337be 370 fFolderViewer = new CheckboxTreeViewer(contextGroup, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
f3b33d40
BH
371 GridData data = new GridData(GridData.FILL_BOTH);
372 Tree tree = fFolderViewer.getTree();
373 tree.setLayoutData(data);
374 tree.setFont(fDialogComposite.getFont());
375 tree.setToolTipText(Messages.TraceControl_ImportDialogTracesTooltip);
376
377 fFolderViewer.setContentProvider(new FolderContentProvider());
378 fFolderViewer.setLabelProvider(new WorkbenchLabelProvider());
379
380 fFolderViewer.addCheckStateListener(new ICheckStateListener() {
381 @Override
382 public void checkStateChanged(CheckStateChangedEvent event) {
383 Object elem = event.getElement();
384 if (elem instanceof IRemoteFile) {
385 IRemoteFile element = (IRemoteFile) elem;
386 if (!element.isDirectory()) {
387 // A trick to keep selection of a file in sync with the directory
388 boolean p = fFolderViewer.getChecked((element.getParentRemoteFile()));
389 fFolderViewer.setChecked(element, p);
f75337be
BH
390 } else {
391 fFolderViewer.setSubtreeChecked(event.getElement(), event.getChecked());
392 if (!event.getChecked()) {
393 fFolderViewer.setChecked(element.getParentRemoteFile(), false);
394 }
f3b33d40 395 }
f75337be 396 updateOKButtonEnablement();
f3b33d40
BH
397 }
398 }
399 });
400 fFolderViewer.setInput(remoteFolder);
401
f75337be 402 fFolderChildren = remoteFolder.getContents(RemoteChildrenContentsType.getInstance());
589d0d33
BH
403 // children can be null if there the path doesn't exist. This happens when a trace
404 // session hadn't been started and no output was created.
f75337be 405 setFolderChildrenChecked(true);
cd9821de 406
f3b33d40
BH
407 Group projectGroup = new Group(fDialogComposite, SWT.SHADOW_NONE);
408 projectGroup.setText(Messages.TraceControl_ImportDialogProjectsGroupName);
409 layout = new GridLayout(1, true);
410 projectGroup.setLayout(layout);
411 projectGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
412
413 fProjects = new ArrayList<IProject>();
414 List<String> projectNames = new ArrayList<String>();
cd9821de 415
d600c18f
MAL
416 for (IProject project : TraceUtils.getOpenedTmfProjects()) {
417 fProjects.add(project);
418 projectNames.add(project.getName());
f3b33d40
BH
419 }
420
421 fCombo = new CCombo(projectGroup, SWT.READ_ONLY);
422 fCombo.setToolTipText(Messages.TraceControl_ImportDialogProjectsTooltip);
423 fCombo.setLayoutData(new GridData(GridData.FILL, GridData.CENTER, true, false, 1, 1));
424 fCombo.setItems(projectNames.toArray(new String[projectNames.size()]));
425
cd9821de
BH
426 if (fDefaultProjectName != null) {
427 int select = projectNames.indexOf(fDefaultProjectName);
428 fCombo.select(select);
429 }
430
f3b33d40
BH
431 Group overrideGroup = new Group(fDialogComposite, SWT.SHADOW_NONE);
432 layout = new GridLayout(1, true);
433 overrideGroup.setLayout(layout);
434 overrideGroup.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
435
436 fOverwriteButton = new Button(overrideGroup, SWT.CHECK);
437 fOverwriteButton.setText(Messages.TraceControl_ImportDialogOverwriteButtonText);
438 getShell().setMinimumSize(new Point(500, 400));
439 }
440
f75337be
BH
441 private void setFolderChildrenChecked(boolean isChecked) {
442 if (fFolderChildren != null) {
443 for (Object child : fFolderChildren) {
444 fFolderViewer.setSubtreeChecked(child, isChecked);
445 }
446 }
447 updateOKButtonEnablement();
448 }
449
450 private void updateOKButtonEnablement() {
451 Object[] checked = fFolderViewer.getCheckedElements();
452 Button okButton = getButton(IDialogConstants.OK_ID);
453 if (okButton != null) {
454 okButton.setEnabled(checked.length > 0);
455 }
456 }
291cbdbf 457 }
This page took 0.056166 seconds and 5 git commands to generate.