Commit | Line | Data |
---|---|---|
6e651d8b | 1 | /******************************************************************************* |
ed902a2b | 2 | * Copyright (c) 2013, 2014 Ericsson |
6e651d8b MAL |
3 | * |
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 | |
8 | * | |
9 | * Contributors: | |
10 | * Marc-Andre Laperle - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
2bdf0193 | 13 | package org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.importexport; |
6e651d8b MAL |
14 | |
15 | import java.io.File; | |
16 | import java.lang.reflect.InvocationTargetException; | |
17 | import java.text.MessageFormat; | |
18 | import java.util.ArrayList; | |
19 | import java.util.List; | |
20 | ||
21 | import org.eclipse.core.resources.IFile; | |
22 | import org.eclipse.core.resources.IMarker; | |
23 | import org.eclipse.core.resources.IResource; | |
24 | import org.eclipse.core.runtime.CoreException; | |
25 | import org.eclipse.core.runtime.IProgressMonitor; | |
26 | import org.eclipse.core.runtime.IStatus; | |
27 | import org.eclipse.jface.dialogs.IDialogSettings; | |
28 | import org.eclipse.jface.dialogs.MessageDialog; | |
29 | import org.eclipse.jface.operation.IRunnableWithProgress; | |
30 | import org.eclipse.jface.viewers.CheckboxTreeViewer; | |
31 | import org.eclipse.jface.viewers.ColumnLabelProvider; | |
32 | import org.eclipse.jface.viewers.IStructuredSelection; | |
33 | import org.eclipse.jface.viewers.TreeViewerColumn; | |
6e651d8b MAL |
34 | import org.eclipse.swt.SWT; |
35 | import org.eclipse.swt.events.ModifyEvent; | |
36 | import org.eclipse.swt.events.ModifyListener; | |
37 | import org.eclipse.swt.events.SelectionAdapter; | |
38 | import org.eclipse.swt.events.SelectionEvent; | |
39 | import org.eclipse.swt.layout.GridData; | |
40 | import org.eclipse.swt.layout.GridLayout; | |
41 | import org.eclipse.swt.layout.RowLayout; | |
42 | import org.eclipse.swt.widgets.Button; | |
43 | import org.eclipse.swt.widgets.Composite; | |
44 | import org.eclipse.swt.widgets.Group; | |
45 | import org.eclipse.swt.widgets.Label; | |
2bdf0193 AM |
46 | import org.eclipse.tracecompass.internal.tmf.ui.Activator; |
47 | import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageWizardPage; | |
48 | import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageBookmarkElement; | |
49 | import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; | |
50 | import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; | |
51 | import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageLabelProvider; | |
52 | import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFileElement; | |
53 | import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageSupplFilesElement; | |
54 | import org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; | |
55 | import org.eclipse.tracecompass.tmf.ui.project.model.TmfTraceElement; | |
6e651d8b MAL |
56 | |
57 | /** | |
58 | * Wizard page for the export trace package wizard | |
59 | * | |
60 | * @author Marc-Andre Laperle | |
61 | */ | |
62 | public class ExportTracePackageWizardPage extends AbstractTracePackageWizardPage { | |
63 | ||
64 | private static final int CONTENT_COL_WIDTH = 300; | |
65 | private static final int SIZE_COL_WIDTH = 100; | |
66 | ||
67 | private static final String ZIP_EXTENSION = ".zip"; //$NON-NLS-1$ | |
68 | private static final String TAR_EXTENSION = ".tar"; //$NON-NLS-1$ | |
69 | private static final String TAR_GZ_EXTENSION = ".tar.gz"; //$NON-NLS-1$ | |
70 | private static final String TGZ_EXTENSION = ".tgz"; //$NON-NLS-1$ | |
71 | ||
72 | private static final String ICON_PATH = "icons/wizban/export_wiz.png"; //$NON-NLS-1$ | |
73 | ||
74 | /** | |
75 | * The page name, can be referenced from other pages | |
76 | */ | |
77 | public static final String PAGE_NAME = "ExportTracePackageWizardPage"; //$NON-NLS-1$ | |
78 | // dialog store id constants | |
79 | private static final String STORE_COMPRESS_CONTENTS_ID = PAGE_NAME + ".STORE_COMPRESS_CONTENTS_ID"; //$NON-NLS-1$ | |
80 | private static final String STORE_FORMAT_ID = PAGE_NAME + ".STORE_FORMAT_ID"; //$NON-NLS-1$ | |
81 | ||
82 | private Button fCompressContentsCheckbox; | |
83 | private Button fZipFormatButton; | |
84 | private Button fTargzFormatButton; | |
85 | private Label fApproximateSizeLabel; | |
86 | private List<TmfTraceElement> fSelectedTraces; | |
87 | ||
88 | /** | |
89 | * Constructor for the export trace package wizard page | |
90 | * | |
91 | * @param selection | |
92 | * the current object selection | |
195355a9 MAL |
93 | * @param selectedTraces |
94 | * the selected traces from the selection | |
6e651d8b | 95 | */ |
195355a9 | 96 | public ExportTracePackageWizardPage(IStructuredSelection selection, List<TmfTraceElement> selectedTraces) { |
6e651d8b | 97 | super(PAGE_NAME, Messages.ExportTracePackageWizardPage_Title, Activator.getDefault().getImageDescripterFromPath(ICON_PATH), selection); |
195355a9 | 98 | fSelectedTraces = selectedTraces; |
6e651d8b MAL |
99 | } |
100 | ||
101 | /** | |
102 | * Set the selected trace from the previous page to be displayed in the | |
103 | * element viewer | |
104 | * | |
105 | * @param selectedTraces | |
106 | * the selected trace | |
107 | */ | |
108 | public void setSelectedTraces(List<TmfTraceElement> selectedTraces) { | |
109 | if (!fSelectedTraces.containsAll(selectedTraces) || !selectedTraces.containsAll(fSelectedTraces)) { | |
110 | fSelectedTraces = selectedTraces; | |
111 | CheckboxTreeViewer elementViewer = getElementViewer(); | |
112 | elementViewer.setInput(createElementViewerInput()); | |
113 | elementViewer.expandToLevel(2); | |
114 | setAllChecked(elementViewer, false, true); | |
115 | updateApproximateSelectedSize(); | |
116 | } | |
117 | } | |
118 | ||
119 | @Override | |
120 | public void createControl(Composite parent) { | |
121 | ||
122 | initializeDialogUnits(parent); | |
123 | ||
124 | Composite composite = new Composite(parent, SWT.NULL); | |
125 | composite.setLayout(new GridLayout()); | |
126 | composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | GridData.HORIZONTAL_ALIGN_FILL)); | |
127 | ||
128 | createElementViewer(composite); | |
129 | createButtonsGroup(composite); | |
130 | createFilePathGroup(composite, Messages.ExportTracePackageWizardPage_ToArchive, SWT.SAVE); | |
131 | createOptionsGroup(composite); | |
132 | ||
133 | restoreWidgetValues(); | |
134 | setMessage(Messages.ExportTracePackageWizardPage_ChooseContent); | |
135 | ||
136 | updateApproximateSelectedSize(); | |
137 | updatePageCompletion(); | |
138 | ||
139 | setControl(composite); | |
140 | } | |
141 | ||
195355a9 MAL |
142 | @Override |
143 | public void setVisible(boolean visible) { | |
144 | super.setVisible(visible); | |
145 | if (visible) { | |
146 | updatePageCompletion(); | |
147 | } else { | |
148 | setPageComplete(false); | |
149 | } | |
150 | } | |
151 | ||
6e651d8b MAL |
152 | /** |
153 | * Restore widget values to the values that they held last time this wizard | |
154 | * was used to completion. | |
155 | */ | |
156 | @Override | |
157 | protected void restoreWidgetValues() { | |
158 | super.restoreWidgetValues(); | |
159 | ||
160 | IDialogSettings settings = getDialogSettings(); | |
161 | if (settings != null) { | |
162 | if (getFilePathCombo().getItemCount() > 0) { | |
163 | String item = getFilePathCombo().getItem(0); | |
164 | setFilePathValue(item); | |
165 | } | |
166 | fCompressContentsCheckbox.setSelection(settings.getBoolean(STORE_COMPRESS_CONTENTS_ID)); | |
167 | fZipFormatButton.setSelection(settings.getBoolean(STORE_FORMAT_ID)); | |
168 | fTargzFormatButton.setSelection(!settings.getBoolean(STORE_FORMAT_ID)); | |
169 | updateWithFilePathSelection(); | |
170 | } | |
171 | } | |
172 | ||
173 | @Override | |
174 | protected void createFilePathGroup(Composite parent, String label, int fileDialogStyle) { | |
175 | super.createFilePathGroup(parent, label, fileDialogStyle); | |
176 | ||
177 | getFilePathCombo().addModifyListener(new ModifyListener() { | |
178 | @Override | |
179 | public void modifyText(ModifyEvent e) { | |
180 | updatePageCompletion(); | |
181 | } | |
182 | }); | |
183 | } | |
184 | ||
185 | private void createOptionsGroup(Composite parent) { | |
186 | Group optionsGroup = new Group(parent, SWT.NONE); | |
187 | optionsGroup.setLayout(new RowLayout(SWT.VERTICAL)); | |
188 | optionsGroup.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL | |
189 | | GridData.GRAB_HORIZONTAL)); | |
190 | optionsGroup.setText(Messages.ExportTracePackageWizardPage_Options); | |
191 | ||
192 | SelectionAdapter listener = new SelectionAdapter() { | |
193 | @Override | |
194 | public void widgetSelected(SelectionEvent e) { | |
195 | updateWithFilePathSelection(); | |
196 | } | |
197 | }; | |
198 | ||
199 | fZipFormatButton = new Button(optionsGroup, SWT.RADIO | SWT.LEFT); | |
200 | fZipFormatButton.setText(Messages.ExportTracePackageWizardPage_SaveInZipFormat); | |
201 | fZipFormatButton.setSelection(true); | |
202 | fZipFormatButton.addSelectionListener(listener); | |
203 | ||
204 | fTargzFormatButton = new Button(optionsGroup, SWT.RADIO | SWT.LEFT); | |
205 | fTargzFormatButton.setText(Messages.ExportTracePackageWizardPage_SaveInTarFormat); | |
206 | fTargzFormatButton.setSelection(false); | |
207 | fTargzFormatButton.addSelectionListener(listener); | |
208 | ||
209 | fCompressContentsCheckbox = new Button(optionsGroup, SWT.CHECK | SWT.LEFT); | |
210 | fCompressContentsCheckbox.setText(Messages.ExportTracePackageWizardPage_CompressContents); | |
211 | fCompressContentsCheckbox.setSelection(true); | |
212 | fCompressContentsCheckbox.addSelectionListener(listener); | |
213 | } | |
214 | ||
215 | @Override | |
216 | protected void createElementViewer(Composite parent) { | |
217 | super.createElementViewer(parent); | |
218 | ||
219 | CheckboxTreeViewer elementViewer = getElementViewer(); | |
220 | elementViewer.getTree().setHeaderVisible(true); | |
221 | // Content column | |
222 | TreeViewerColumn column = new TreeViewerColumn(elementViewer, SWT.NONE); | |
223 | column.getColumn().setWidth(CONTENT_COL_WIDTH); | |
224 | column.getColumn().setText(Messages.ExportTracePackageWizardPage_ContentColumnName); | |
225 | column.setLabelProvider(new TracePackageLabelProvider()); | |
226 | ||
227 | // Size column | |
228 | column = new TreeViewerColumn(elementViewer, SWT.NONE); | |
229 | column.getColumn().setWidth(SIZE_COL_WIDTH); | |
230 | column.getColumn().setText(Messages.ExportTracePackageWizardPage_SizeColumnName); | |
231 | column.setLabelProvider(new ColumnLabelProvider() { | |
232 | @Override | |
233 | public String getText(Object element) { | |
234 | TracePackageElement tracePackageElement = (TracePackageElement) element; | |
235 | long size = tracePackageElement.getSize(false); | |
236 | if (size == 0) { | |
237 | return null; | |
238 | } | |
239 | int level = 0; | |
240 | TracePackageElement curElement = tracePackageElement.getParent(); | |
241 | while (curElement != null) { | |
242 | curElement = curElement.getParent(); | |
243 | ++level; | |
244 | } | |
245 | ||
246 | return indent(getHumanReadable(size), level); | |
247 | } | |
248 | ||
249 | private String indent(String humanReadable, int level) { | |
250 | StringBuilder s = new StringBuilder(humanReadable); | |
251 | for (int i = 0; i < level; ++i) { | |
252 | final String indentStr = " "; //$NON-NLS-1$ | |
253 | s.insert(0, indentStr); | |
254 | } | |
255 | return s.toString(); | |
256 | } | |
257 | }); | |
258 | ||
259 | elementViewer.setInput(createElementViewerInput()); | |
260 | elementViewer.expandToLevel(2); | |
261 | setAllChecked(elementViewer, false, true); | |
262 | } | |
263 | ||
264 | @Override | |
265 | protected void updateApproximateSelectedSize() { | |
266 | long checkedSize = 0; | |
267 | TracePackageElement[] tracePackageElements = (TracePackageElement[]) getElementViewer().getInput(); | |
268 | for (TracePackageElement element : tracePackageElements) { | |
269 | checkedSize += element.getSize(true); | |
270 | } | |
271 | checkedSize = Math.max(0, checkedSize); | |
272 | fApproximateSizeLabel.setText(MessageFormat.format(Messages.ExportTracePackageWizardPage_ApproximateSizeLbl, getHumanReadable(checkedSize))); | |
273 | } | |
274 | ||
275 | /** | |
276 | * Get the human readable string for a size in bytes. (KB, MB, etc). | |
277 | * | |
278 | * @param size | |
279 | * the size to print in human readable, | |
280 | * @return the human readable string | |
281 | */ | |
282 | private static String getHumanReadable(long size) { | |
283 | String humanSuffix[] = { Messages.ExportTracePackageWizardPage_SizeByte, Messages.ExportTracePackageWizardPage_SizeKilobyte, | |
284 | Messages.ExportTracePackageWizardPage_SizeMegabyte, Messages.ExportTracePackageWizardPage_SizeGigabyte, | |
285 | Messages.ExportTracePackageWizardPage_SizeTerabyte }; | |
286 | long curSize = size; | |
287 | ||
288 | int suffixIndex = 0; | |
289 | while (curSize >= 1024) { | |
290 | curSize /= 1024; | |
291 | ++suffixIndex; | |
292 | } | |
293 | ||
294 | return Long.toString(curSize) + " " + humanSuffix[suffixIndex]; //$NON-NLS-1$ | |
295 | } | |
296 | ||
297 | @Override | |
298 | protected Object createElementViewerInput() { | |
507b1336 | 299 | List<TracePackageTraceElement> traceElements = new ArrayList<>(); |
6e651d8b MAL |
300 | for (TmfTraceElement tmfTraceElement : fSelectedTraces) { |
301 | TracePackageTraceElement traceElement = new TracePackageTraceElement(null, tmfTraceElement); | |
302 | ||
303 | // Trace files | |
507b1336 | 304 | List<TracePackageElement> children = new ArrayList<>(); |
6e651d8b MAL |
305 | TracePackageFilesElement filesElement = new TracePackageFilesElement(traceElement, tmfTraceElement.getResource()); |
306 | filesElement.setChecked(true); | |
6e651d8b MAL |
307 | children.add(filesElement); |
308 | ||
309 | // Supplementary files | |
310 | IResource[] supplementaryResources = tmfTraceElement.getSupplementaryResources(); | |
507b1336 | 311 | List<TracePackageElement> suppFilesChildren = new ArrayList<>(); |
6e651d8b MAL |
312 | TracePackageSupplFilesElement suppFilesElement = new TracePackageSupplFilesElement(traceElement); |
313 | children.add(suppFilesElement); | |
314 | for (IResource res : supplementaryResources) { | |
315 | suppFilesChildren.add(new TracePackageSupplFileElement(res, suppFilesElement)); | |
316 | } | |
6e651d8b MAL |
317 | |
318 | // Bookmarks | |
319 | IFile bookmarksFile = tmfTraceElement.getBookmarksFile(); | |
320 | if (bookmarksFile != null && bookmarksFile.exists()) { | |
321 | IMarker[] findMarkers; | |
322 | try { | |
323 | findMarkers = bookmarksFile.findMarkers(IMarker.BOOKMARK, false, IResource.DEPTH_ZERO); | |
324 | if (findMarkers.length > 0) { | |
325 | children.add(new TracePackageBookmarkElement(traceElement, null)); | |
326 | } | |
327 | } catch (CoreException e) { | |
328 | // Should not happen since we just checked bookmarksFile.exists() but log it just in case | |
329 | Activator.getDefault().logError("Error finding bookmarks", e); //$NON-NLS-1$ | |
330 | } | |
331 | } | |
332 | ||
6e651d8b MAL |
333 | traceElements.add(traceElement); |
334 | ||
335 | } | |
336 | ||
337 | return traceElements.toArray(new TracePackageTraceElement[] {}); | |
338 | } | |
339 | ||
340 | @Override | |
341 | protected final Composite createButtonsGroup(Composite parent) { | |
342 | Composite buttonGroup = super.createButtonsGroup(parent); | |
343 | ||
344 | // Add the label on the same row of the select/deselect all buttons | |
345 | fApproximateSizeLabel = new Label(buttonGroup, SWT.RIGHT); | |
346 | GridData layoutData = new GridData(GridData.FILL_HORIZONTAL); | |
347 | layoutData.grabExcessHorizontalSpace = true; | |
348 | fApproximateSizeLabel.setLayoutData(layoutData); | |
349 | ||
350 | return buttonGroup; | |
351 | } | |
352 | ||
353 | /** | |
354 | * Save widget values to Dialog settings | |
355 | */ | |
356 | @Override | |
357 | protected void saveWidgetValues() { | |
358 | super.saveWidgetValues(); | |
359 | ||
360 | IDialogSettings settings = getDialogSettings(); | |
361 | if (settings != null) { | |
362 | settings.put(STORE_COMPRESS_CONTENTS_ID, fCompressContentsCheckbox.getSelection()); | |
363 | settings.put(STORE_FORMAT_ID, fZipFormatButton.getSelection()); | |
364 | } | |
365 | } | |
366 | ||
367 | private String getOutputExtension() { | |
368 | if (fZipFormatButton.getSelection()) { | |
369 | return ZIP_EXTENSION; | |
370 | } else if (fCompressContentsCheckbox.getSelection()) { | |
371 | return TAR_GZ_EXTENSION; | |
372 | } else { | |
373 | return TAR_EXTENSION; | |
374 | } | |
375 | } | |
376 | ||
377 | @Override | |
378 | protected void updateWithFilePathSelection() { | |
379 | String filePathValue = getFilePathValue(); | |
380 | if (filePathValue.isEmpty()) { | |
381 | return; | |
382 | } | |
383 | ||
384 | filePathValue = stripKnownExtension(filePathValue); | |
385 | filePathValue = filePathValue.concat(getOutputExtension()); | |
386 | ||
387 | setFilePathValue(filePathValue); | |
388 | } | |
389 | ||
390 | private static String stripKnownExtension(String str) { | |
391 | String ret = str; | |
392 | if (str.endsWith(TAR_GZ_EXTENSION)) { | |
7ae40916 | 393 | ret = ret.substring(0, ret.lastIndexOf('.')); |
6e651d8b MAL |
394 | } |
395 | ||
550885a4 | 396 | if (ret.endsWith(ZIP_EXTENSION) || ret.endsWith(TAR_EXTENSION) || ret.endsWith(TGZ_EXTENSION)) { |
7ae40916 | 397 | ret = ret.substring(0, ret.lastIndexOf('.')); |
6e651d8b MAL |
398 | } |
399 | ||
400 | return ret; | |
401 | } | |
402 | ||
403 | /** | |
404 | * Finish the wizard page | |
405 | * | |
406 | * @return true on success | |
407 | */ | |
408 | public boolean finish() { | |
409 | if (!checkForOverwrite()) { | |
410 | return false; | |
411 | } | |
412 | ||
413 | saveWidgetValues(); | |
414 | ||
415 | TracePackageTraceElement[] traceExportElements = (TracePackageTraceElement[]) getElementViewer().getInput(); | |
416 | boolean useCompression = fCompressContentsCheckbox.getSelection(); | |
417 | boolean useTar = fTargzFormatButton.getSelection(); | |
418 | String fileName = getFilePathValue(); | |
419 | final TracePackageExportOperation exporter = new TracePackageExportOperation(traceExportElements, useCompression, useTar, fileName); | |
420 | ||
421 | try { | |
422 | getContainer().run(true, true, new IRunnableWithProgress() { | |
423 | ||
424 | @Override | |
425 | public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { | |
426 | exporter.run(monitor); | |
427 | } | |
428 | }); | |
429 | ||
430 | IStatus status = exporter.getStatus(); | |
431 | if (status.getSeverity() == IStatus.ERROR) { | |
432 | handleErrorStatus(status); | |
433 | } | |
434 | ||
435 | } catch (InvocationTargetException e) { | |
2bdf0193 | 436 | handleError(org.eclipse.tracecompass.internal.tmf.ui.project.wizards.tracepkg.Messages.TracePackage_ErrorOperation, e); |
6e651d8b MAL |
437 | } catch (InterruptedException e) { |
438 | } | |
439 | ||
440 | return exporter.getStatus().getSeverity() == IStatus.OK; | |
441 | } | |
442 | ||
443 | private boolean checkForOverwrite() { | |
444 | File file = new File(getFilePathValue()); | |
445 | if (file.exists()) { | |
446 | return MessageDialog.openQuestion(getContainer().getShell(), null, Messages.ExportTracePackageWizardPage_AlreadyExitst); | |
447 | } | |
448 | return true; | |
449 | } | |
450 | } |