Commit | Line | Data |
---|---|---|
6e651d8b | 1 | /******************************************************************************* |
8d03681c | 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 | ||
13 | package org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.importexport; | |
14 | ||
15 | import java.io.File; | |
16 | import java.lang.reflect.InvocationTargetException; | |
195355a9 MAL |
17 | import java.text.MessageFormat; |
18 | import java.util.ArrayList; | |
6e651d8b MAL |
19 | import java.util.List; |
20 | ||
21 | import org.eclipse.core.resources.IProject; | |
a6ee485c | 22 | import org.eclipse.core.resources.IResource; |
6e651d8b MAL |
23 | import org.eclipse.core.resources.ResourcesPlugin; |
24 | import org.eclipse.core.runtime.IProgressMonitor; | |
25 | import org.eclipse.core.runtime.IStatus; | |
195355a9 | 26 | import org.eclipse.jface.dialogs.IDialogConstants; |
6e651d8b MAL |
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.IStructuredSelection; | |
32 | import org.eclipse.linuxtools.internal.tmf.ui.Activator; | |
195355a9 | 33 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageOperation; |
6e651d8b MAL |
34 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.AbstractTracePackageWizardPage; |
35 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageElement; | |
36 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageFilesElement; | |
37 | import org.eclipse.linuxtools.internal.tmf.ui.project.wizards.tracepkg.TracePackageTraceElement; | |
38 | import org.eclipse.linuxtools.tmf.core.TmfCommonConstants; | |
6e651d8b | 39 | import org.eclipse.linuxtools.tmf.ui.project.model.TmfProjectRegistry; |
6e651d8b MAL |
40 | import org.eclipse.linuxtools.tmf.ui.project.model.TmfTraceFolder; |
41 | import org.eclipse.linuxtools.tmf.ui.project.model.TraceUtils; | |
42 | import org.eclipse.swt.SWT; | |
43 | import org.eclipse.swt.events.SelectionAdapter; | |
44 | import org.eclipse.swt.events.SelectionEvent; | |
45 | import org.eclipse.swt.events.TraverseEvent; | |
46 | import org.eclipse.swt.events.TraverseListener; | |
47 | import org.eclipse.swt.layout.GridData; | |
48 | import org.eclipse.swt.layout.GridLayout; | |
49 | import org.eclipse.swt.widgets.Button; | |
50 | import org.eclipse.swt.widgets.Combo; | |
51 | import org.eclipse.swt.widgets.Composite; | |
52 | import org.eclipse.swt.widgets.Event; | |
53 | import org.eclipse.swt.widgets.Label; | |
54 | import org.eclipse.swt.widgets.Listener; | |
55 | import org.eclipse.swt.widgets.Text; | |
56 | import org.eclipse.ui.dialogs.ElementListSelectionDialog; | |
57 | import org.eclipse.ui.model.WorkbenchLabelProvider; | |
58 | ||
59 | /** | |
60 | * Wizard page for the import trace package wizard | |
61 | * | |
62 | * @author Marc-Andre Laperle | |
63 | */ | |
64 | public class ImportTracePackageWizardPage extends AbstractTracePackageWizardPage { | |
65 | ||
66 | private static final String ICON_PATH = "icons/wizban/trace_import_wiz.png"; //$NON-NLS-1$ | |
67 | private static final String PAGE_NAME = "ImportTracePackagePage"; //$NON-NLS-1$ | |
68 | private static final String STORE_PROJECT_NAME_ID = PAGE_NAME + ".STORE_PROJECT_NAME_ID"; //$NON-NLS-1$ | |
69 | ||
70 | private String fValidatedFilePath; | |
71 | private TmfTraceFolder fTmfTraceFolder; | |
72 | private Text fProjectText; | |
73 | private List<IProject> fOpenedTmfProjects; | |
74 | ||
75 | /** | |
76 | * Constructor for the import trace package wizard page | |
77 | * | |
78 | * @param selection | |
79 | * the current object selection | |
80 | */ | |
81 | public ImportTracePackageWizardPage(IStructuredSelection selection) { | |
82 | super(PAGE_NAME, Messages.ImportTracePackageWizardPage_Title, Activator.getDefault().getImageDescripterFromPath(ICON_PATH), selection); | |
83 | ||
84 | if (getSelection().getFirstElement() instanceof TmfTraceFolder) { | |
85 | fTmfTraceFolder = (TmfTraceFolder) getSelection().getFirstElement(); | |
86 | } | |
87 | } | |
88 | ||
89 | @Override | |
90 | public void createControl(Composite parent) { | |
91 | initializeDialogUnits(parent); | |
92 | ||
93 | Composite composite = new Composite(parent, SWT.NULL); | |
94 | composite.setLayout(new GridLayout()); | |
95 | composite.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_FILL | |
96 | | GridData.HORIZONTAL_ALIGN_FILL)); | |
97 | composite.setFont(parent.getFont()); | |
98 | ||
99 | createFilePathGroup(composite, Messages.ImportTracePackageWizardPage_FromArchive, SWT.OPEN); | |
100 | createElementViewer(composite); | |
101 | createButtonsGroup(composite); | |
102 | if (fTmfTraceFolder == null) { | |
103 | createProjectSelectionGroup(composite); | |
104 | } | |
105 | ||
106 | restoreWidgetValues(); | |
107 | setMessage(Messages.ImportTracePackageWizardPage_Message); | |
108 | updatePageCompletion(); | |
109 | ||
110 | setControl(composite); | |
111 | } | |
112 | ||
113 | private void createProjectSelectionGroup(Composite parent) { | |
114 | ||
115 | Composite projectSelectionGroup = new Composite(parent, SWT.NONE); | |
116 | GridLayout layout = new GridLayout(); | |
117 | layout.numColumns = 3; | |
118 | projectSelectionGroup.setLayout(layout); | |
119 | projectSelectionGroup.setLayoutData(new GridData( | |
120 | GridData.HORIZONTAL_ALIGN_FILL | GridData.VERTICAL_ALIGN_FILL)); | |
121 | ||
122 | Label projectLabel = new Label(projectSelectionGroup, SWT.NONE); | |
123 | projectLabel.setText(Messages.ImportTracePackageWizardPage_Project); | |
124 | ||
125 | fProjectText = new Text(projectSelectionGroup, SWT.BORDER | SWT.SINGLE | SWT.READ_ONLY); | |
126 | GridData data = new GridData(GridData.HORIZONTAL_ALIGN_FILL | |
127 | | GridData.GRAB_HORIZONTAL); | |
128 | data.grabExcessHorizontalSpace = true; | |
129 | fProjectText.setLayoutData(data); | |
130 | ||
131 | fOpenedTmfProjects = TraceUtils.getOpenedTmfProjects(); | |
132 | ||
133 | // No project to import to, create a default project if it doesn't exist | |
134 | if (fOpenedTmfProjects.isEmpty()) { | |
135 | IProject defaultProject = ResourcesPlugin.getWorkspace().getRoot().getProject(TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME); | |
136 | if (!defaultProject.exists()) { | |
137 | IProject project = TmfProjectRegistry.createProject(TmfCommonConstants.DEFAULT_TRACE_PROJECT_NAME, null, null); | |
6e651d8b MAL |
138 | fOpenedTmfProjects.add(project); |
139 | } | |
140 | } | |
141 | ||
142 | if (!fOpenedTmfProjects.isEmpty()) { | |
143 | selectProject(fOpenedTmfProjects.get(0)); | |
144 | } | |
145 | ||
146 | Button button = new Button(projectSelectionGroup, | |
147 | SWT.PUSH); | |
148 | button.setText(Messages.ImportTracePackageWizardPage_SelectProjectButton); | |
149 | button.addListener(SWT.Selection, new Listener() { | |
150 | @Override | |
151 | public void handleEvent(Event event) { | |
152 | ElementListSelectionDialog d = new ElementListSelectionDialog(getContainer().getShell(), new WorkbenchLabelProvider()); | |
153 | ||
154 | d.setBlockOnOpen(true); | |
155 | d.setTitle(Messages.ImportTracePackageWizardPage_SelectProjectDialogTitle); | |
156 | ||
157 | d.setElements(fOpenedTmfProjects.toArray(new IProject[] {})); | |
158 | ||
159 | d.open(); | |
160 | if (d.getFirstResult() != null) { | |
161 | IProject project = (IProject) d.getFirstResult(); | |
162 | selectProject(project); | |
163 | } | |
164 | } | |
165 | }); | |
166 | setButtonLayoutData(button); | |
167 | } | |
168 | ||
169 | @Override | |
170 | protected void restoreWidgetValues() { | |
171 | super.restoreWidgetValues(); | |
172 | IDialogSettings settings = getDialogSettings(); | |
173 | if (settings != null && fProjectText != null) { | |
174 | ||
175 | // Restore last selected project | |
176 | String projectName = settings.get(STORE_PROJECT_NAME_ID); | |
177 | if (projectName != null && !projectName.isEmpty()) { | |
178 | for (IProject project : fOpenedTmfProjects) { | |
179 | if (project.getName().equals(projectName)) { | |
180 | selectProject(project); | |
181 | break; | |
182 | } | |
183 | } | |
184 | } | |
185 | } | |
186 | } | |
187 | ||
188 | @Override | |
189 | protected void saveWidgetValues() { | |
190 | super.saveWidgetValues(); | |
191 | ||
192 | IDialogSettings settings = getDialogSettings(); | |
193 | if (settings != null) { | |
194 | settings.put(STORE_PROJECT_NAME_ID, fTmfTraceFolder.getProject().getResource().getName()); | |
195 | } | |
196 | } | |
197 | ||
198 | private void selectProject(IProject project) { | |
199 | fProjectText.setText(project.getName()); | |
f537c959 | 200 | fTmfTraceFolder = TmfProjectRegistry.getProject(project, true).getTracesFolder(); |
6e651d8b MAL |
201 | updatePageCompletion(); |
202 | } | |
203 | ||
204 | @Override | |
205 | protected boolean determinePageCompletion() { | |
206 | return super.determinePageCompletion() && fTmfTraceFolder != null; | |
207 | } | |
208 | ||
8d03681c MAL |
209 | /** |
210 | * Create the operation that will be responsible of creating the manifest | |
211 | * based on the file name. | |
212 | * | |
213 | * @param fileName the file name to generate the manifest from | |
214 | * | |
215 | * @return the operation that will extract the manifest | |
216 | */ | |
217 | protected AbstractTracePackageOperation createExtractManifestOperation(String fileName) { | |
218 | return new TracePackageExtractManifestOperation(fileName); | |
219 | } | |
220 | ||
6e651d8b MAL |
221 | @Override |
222 | protected Object createElementViewerInput() { | |
223 | ||
8d03681c | 224 | final AbstractTracePackageOperation op = createExtractManifestOperation(getFilePathValue()); |
6e651d8b MAL |
225 | |
226 | try { | |
227 | getContainer().run(true, true, new IRunnableWithProgress() { | |
228 | ||
229 | @Override | |
230 | public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { | |
231 | monitor.beginTask(Messages.ImportTracePackageWizardPage_ReadingPackage, 10); | |
232 | op.run(monitor); | |
233 | monitor.done(); | |
234 | } | |
235 | ||
236 | }); | |
237 | ||
238 | IStatus status = op.getStatus(); | |
239 | if (status.getSeverity() == IStatus.ERROR) { | |
240 | handleErrorStatus(status); | |
241 | } | |
242 | } catch (InvocationTargetException e1) { | |
243 | handleError(Messages.TracePackageExtractManifestOperation_ErrorReadingManifest, e1); | |
244 | } catch (InterruptedException e1) { | |
245 | // Canceled | |
246 | } | |
247 | ||
8d03681c | 248 | TracePackageElement[] resultElements = op.getResultElements(); |
195355a9 | 249 | if (resultElements == null || resultElements.length == 0) { |
6e651d8b MAL |
250 | return null; |
251 | } | |
252 | ||
195355a9 | 253 | return resultElements; |
6e651d8b MAL |
254 | } |
255 | ||
256 | @Override | |
257 | protected void createFilePathGroup(Composite parent, String label, int fileDialogStyle) { | |
258 | super.createFilePathGroup(parent, label, fileDialogStyle); | |
259 | ||
260 | Combo filePathCombo = getFilePathCombo(); | |
261 | filePathCombo.addSelectionListener(new SelectionAdapter() { | |
262 | @Override | |
263 | public void widgetSelected(SelectionEvent e) { | |
264 | updateWithFilePathSelection(); | |
265 | } | |
266 | }); | |
267 | ||
268 | // User can type-in path and press return to validate | |
269 | filePathCombo.addTraverseListener(new TraverseListener() { | |
270 | @Override | |
271 | public void keyTraversed(TraverseEvent e) { | |
272 | if (e.detail == SWT.TRAVERSE_RETURN) { | |
273 | e.doit = false; | |
274 | updateWithFilePathSelection(); | |
275 | } | |
276 | } | |
277 | }); | |
278 | } | |
279 | ||
280 | @Override | |
281 | protected void updateWithFilePathSelection() { | |
282 | if (!isFilePathValid()) { | |
283 | setErrorMessage(Messages.ImportTracePackageWizardPage_ErrorFileNotFound); | |
284 | getElementViewer().setInput(null); | |
285 | return; | |
286 | } | |
287 | setErrorMessage(null); | |
288 | ||
289 | getContainer().getShell().getDisplay().asyncExec(new Runnable() { | |
290 | @Override | |
291 | public void run() { | |
292 | CheckboxTreeViewer elementViewer = getElementViewer(); | |
293 | Object elementViewerInput = createElementViewerInput(); | |
294 | elementViewer.setInput(elementViewerInput); | |
295 | if (elementViewerInput != null) { | |
296 | elementViewer.expandToLevel(2); | |
297 | setAllChecked(elementViewer, false, true); | |
298 | fValidatedFilePath = getFilePathValue(); | |
299 | } | |
300 | ||
301 | updatePageCompletion(); | |
302 | } | |
303 | }); | |
304 | } | |
305 | ||
306 | private boolean isFilePathValid() { | |
307 | return new File(getFilePathValue()).exists(); | |
308 | } | |
309 | ||
310 | /** | |
311 | * Finish the wizard page | |
312 | * | |
313 | * @return true on success | |
314 | */ | |
315 | public boolean finish() { | |
316 | if (!checkForOverwrite()) { | |
317 | return false; | |
318 | } | |
319 | ||
320 | saveWidgetValues(); | |
321 | ||
195355a9 MAL |
322 | Object input = getElementViewer().getInput(); |
323 | TracePackageElement[] traceElements = (TracePackageElement[]) input; | |
324 | final TracePackageImportOperation importOperation = new TracePackageImportOperation(fValidatedFilePath, traceElements, fTmfTraceFolder); | |
6e651d8b MAL |
325 | |
326 | try { | |
327 | getContainer().run(true, true, new IRunnableWithProgress() { | |
328 | @Override | |
329 | public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { | |
330 | importOperation.run(monitor); | |
331 | } | |
332 | }); | |
333 | ||
334 | IStatus status = importOperation.getStatus(); | |
335 | if (status.getSeverity() == IStatus.ERROR) { | |
336 | handleErrorStatus(status); | |
337 | } | |
338 | ||
339 | } catch (InvocationTargetException e) { | |
340 | handleError(Messages.ImportTracePackageWizardPage_ErrorOperation, e); | |
341 | } catch (InterruptedException e) { | |
342 | } | |
343 | ||
344 | return importOperation.getStatus().getSeverity() == IStatus.OK; | |
345 | } | |
346 | ||
347 | private boolean checkForOverwrite() { | |
195355a9 | 348 | TracePackageElement[] traceElements = (TracePackageElement[]) getElementViewer().getInput(); |
507b1336 | 349 | List<TracePackageTraceElement> noImportTraces = new ArrayList<>(); |
195355a9 MAL |
350 | boolean noToAll = false; |
351 | for (TracePackageElement packageElement : traceElements) { | |
352 | TracePackageTraceElement traceElement = (TracePackageTraceElement) packageElement; | |
353 | if (!AbstractTracePackageOperation.isFilesChecked(traceElement)) { | |
354 | continue; | |
355 | } | |
356 | ||
357 | if (noToAll) { | |
358 | noImportTraces.add(traceElement); | |
359 | continue; | |
360 | } | |
361 | ||
a6ee485c MAL |
362 | if (traceExists(traceElement)) { |
363 | int returnCode = promptForOverwrite(traceElement.getDestinationElementPath()); | |
8b83115b MAL |
364 | // The return code is an index to a button in the dialog but the |
365 | // 'X' button in the window corner is not considered a button | |
366 | // therefore it returns -1 and unfortunately, there is no | |
367 | // constant for that. | |
368 | if (returnCode < 0) { | |
369 | return false; | |
370 | } | |
371 | ||
195355a9 MAL |
372 | final String[] response = new String[] { IDialogConstants.NO_TO_ALL_LABEL, IDialogConstants.NO_LABEL, IDialogConstants.YES_TO_ALL_LABEL, IDialogConstants.YES_LABEL }; |
373 | if (response[returnCode].equals(IDialogConstants.YES_TO_ALL_LABEL)) { | |
374 | break; | |
375 | } else if (response[returnCode].equals(IDialogConstants.NO_TO_ALL_LABEL)) { | |
376 | noToAll = true; | |
377 | noImportTraces.add(traceElement); | |
378 | } else if (response[returnCode].equals(IDialogConstants.NO_LABEL)) { | |
379 | noImportTraces.add(traceElement); | |
380 | } | |
381 | } | |
382 | } | |
383 | ||
384 | // Unselect the traces that the user decided not to import | |
385 | for (TracePackageTraceElement t : noImportTraces) { | |
386 | for (TracePackageElement e : t.getChildren()) { | |
387 | if (e instanceof TracePackageFilesElement) { | |
388 | ((TracePackageFilesElement) e).setChecked(false); | |
389 | } | |
390 | } | |
391 | } | |
392 | ||
393 | return true; | |
394 | } | |
6e651d8b | 395 | |
a6ee485c MAL |
396 | private boolean traceExists(TracePackageTraceElement traceElement) { |
397 | IResource traceRes = fTmfTraceFolder.getResource().findMember(traceElement.getDestinationElementPath()); | |
398 | return traceRes != null; | |
195355a9 MAL |
399 | } |
400 | ||
401 | private int promptForOverwrite(String traceName) { | |
402 | final MessageDialog dialog = new MessageDialog(getContainer() | |
403 | .getShell(), null, null, MessageFormat.format(Messages.ImportTracePackageWizardPage_AlreadyExists, traceName), | |
404 | MessageDialog.QUESTION, new String[] { | |
405 | IDialogConstants.NO_TO_ALL_LABEL, | |
406 | IDialogConstants.NO_LABEL, | |
407 | IDialogConstants.YES_TO_ALL_LABEL, | |
408 | IDialogConstants.YES_LABEL, | |
409 | }, 3) { | |
410 | @Override | |
411 | protected int getShellStyle() { | |
412 | return super.getShellStyle() | SWT.SHEET; | |
413 | } | |
414 | }; | |
415 | return dialog.open(); | |
6e651d8b MAL |
416 | } |
417 | } |