1 /*******************************************************************************
2 * Copyright (c) 2009, 2014 Ericsson, École Polytechnique de Montréal
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 * Francois Chouinard - Initial API and implementation
11 * Patrick Tasse - Close editors to release resources
12 * Geneviève Bastien - Moved the delete code to element model's classes
13 * Marc-Andre Laperle - Merged DeleteTraceHandler and DeleteFolderHandler
14 *******************************************************************************/
16 package org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.handlers
;
18 import java
.lang
.reflect
.InvocationTargetException
;
19 import java
.util
.Iterator
;
21 import org
.eclipse
.core
.commands
.AbstractHandler
;
22 import org
.eclipse
.core
.commands
.ExecutionEvent
;
23 import org
.eclipse
.core
.commands
.ExecutionException
;
24 import org
.eclipse
.core
.resources
.IResource
;
25 import org
.eclipse
.core
.resources
.IResourceVisitor
;
26 import org
.eclipse
.core
.runtime
.CoreException
;
27 import org
.eclipse
.core
.runtime
.IProgressMonitor
;
28 import org
.eclipse
.core
.runtime
.OperationCanceledException
;
29 import org
.eclipse
.core
.runtime
.SubMonitor
;
30 import org
.eclipse
.jface
.viewers
.ISelection
;
31 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
32 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
33 import org
.eclipse
.jface
.viewers
.TreeSelection
;
34 import org
.eclipse
.swt
.SWT
;
35 import org
.eclipse
.swt
.widgets
.Display
;
36 import org
.eclipse
.swt
.widgets
.MessageBox
;
37 import org
.eclipse
.swt
.widgets
.Shell
;
38 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
39 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.operations
.TmfWorkspaceModifyOperation
;
40 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfExperimentElement
;
41 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceElement
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceFolder
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTracesFolder
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TraceUtils
;
45 import org
.eclipse
.ui
.IWorkbenchPage
;
46 import org
.eclipse
.ui
.IWorkbenchPart
;
47 import org
.eclipse
.ui
.IWorkbenchWindow
;
48 import org
.eclipse
.ui
.PlatformUI
;
49 import org
.eclipse
.ui
.handlers
.HandlerUtil
;
52 * An handler for deletion of both traces and trace folders. It allows mixing
53 * both types of elements.
55 public class DeleteTraceFolderElementHandler
extends AbstractHandler
{
57 private TreeSelection fSelection
= null;
59 private enum DeleteType
{
61 * Only trace folders are selected.
65 * Only traces are selected.
69 * A mix of different elements are selected.
73 * Only Traces (top trace folders) are selected.
77 * Only Traces under experiments are selected.
79 REMOVE_TRACES_FROM_EXPERIMENT
82 // ------------------------------------------------------------------------
84 // ------------------------------------------------------------------------
87 public boolean isEnabled() {
89 // Check if we are closing down
90 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
96 IWorkbenchPage page
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getActivePage();
97 IWorkbenchPart part
= page
.getActivePart();
101 ISelectionProvider selectionProvider
= part
.getSite().getSelectionProvider();
102 if (selectionProvider
== null) {
105 ISelection selection
= selectionProvider
.getSelection();
107 // Make sure selection contains only traces and trace folders
109 if (selection
instanceof TreeSelection
) {
110 fSelection
= (TreeSelection
) selection
;
111 Iterator
<Object
> iterator
= fSelection
.iterator();
112 while (iterator
.hasNext()) {
113 Object element
= iterator
.next();
114 if (!(element
instanceof TmfTraceElement
) && !(element
instanceof TmfTraceFolder
)) {
120 // If we get here, either nothing is selected or everything is a trace or folder
121 return !selection
.isEmpty();
124 // ------------------------------------------------------------------------
126 // ------------------------------------------------------------------------
128 private static DeleteType
getDeleteType(ISelection selection
) {
129 int numTracesFolder
= 0;
130 int numTraceFolder
= 0;
132 int numTracesUnderExperiment
= 0;
134 @SuppressWarnings("rawtypes")
135 Iterator iterator
= ((IStructuredSelection
) selection
).iterator();
136 while (iterator
.hasNext()) {
137 Object next
= iterator
.next();
138 if ((next
instanceof TmfTracesFolder
)) {
140 } else if (next
instanceof TmfTraceFolder
) {
142 } else if (next
instanceof TmfTraceElement
) {
143 TmfTraceElement traceElement
= (TmfTraceElement
) next
;
144 if (traceElement
.getParent() instanceof TmfExperimentElement
) {
145 numTracesUnderExperiment
++;
152 int total
= numTraceFolder
+ numTracesFolder
+ numTracesUnderExperiment
+ numTraces
;
154 if (numTracesFolder
== total
) {
155 return DeleteType
.CLEAR_TRACES_FOLDER
;
158 if (numTraceFolder
== total
) {
159 return DeleteType
.DELETE_TRACE_FOLDERS
;
162 if (numTraces
== total
) {
163 return DeleteType
.DELETE_TRACES
;
166 if (numTracesUnderExperiment
== total
) {
167 return DeleteType
.REMOVE_TRACES_FROM_EXPERIMENT
;
170 return DeleteType
.DELETE_GENERIC
;
173 private static String
getTitle(final DeleteType deleteType
) {
178 case DELETE_TRACE_FOLDERS
:
179 return Messages
.DeleteDialog_Title
;
180 case CLEAR_TRACES_FOLDER
:
181 return Messages
.ClearDialog_Title
;
182 case REMOVE_TRACES_FROM_EXPERIMENT
:
183 return Messages
.RemoveDialog_Title
;
185 throw new IllegalArgumentException();
189 private static String
getMessage(DeleteType deleteType
) {
193 return Messages
.DeleteTraceHandlerGeneric_Message
;
195 return Messages
.DeleteTraceHandler_Message
;
196 case CLEAR_TRACES_FOLDER
:
197 return Messages
.DeleteFolderHandlerClear_Message
;
198 case DELETE_TRACE_FOLDERS
:
199 return Messages
.DeleteFolderHandler_Message
;
200 case REMOVE_TRACES_FROM_EXPERIMENT
:
201 return Messages
.RemoveTraceFromExperimentHandler_Message
;
203 throw new IllegalArgumentException();
207 private static String
getTraceErrorMessage(DeleteType deleteType
) {
208 return deleteType
== DeleteType
.REMOVE_TRACES_FROM_EXPERIMENT ? Messages
.RemoveTraceFromExperimentHandler_Error
: Messages
.DeleteFolderHandler_Error
;
211 private static String
getFolderErrorMessage(DeleteType deleteType
) {
212 return deleteType
== DeleteType
.CLEAR_TRACES_FOLDER ? Messages
.DeleteFolderHandlerClear_Error
: Messages
.DeleteFolderHandler_Error
;
215 private static String
getTraceTaskName(DeleteType deleteType
) {
216 return deleteType
== DeleteType
.REMOVE_TRACES_FROM_EXPERIMENT ? Messages
.RemoveTraceFromExperimentHandler_TaskName
: Messages
.DeleteFolderHandler_TaskName
;
219 private static String
getTraceFolderTaskName(DeleteType deleteType
) {
220 return deleteType
== DeleteType
.CLEAR_TRACES_FOLDER ? Messages
.DeleteFolderHandlerClear_TaskName
: Messages
.DeleteFolderHandler_TaskName
;
224 public Object
execute(ExecutionEvent event
) throws ExecutionException
{
226 // Check if we are closing down
227 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
228 if (window
== null) {
233 ISelection selection
= HandlerUtil
.getCurrentSelection(event
);
234 if (!(selection
instanceof IStructuredSelection
)) {
237 final DeleteType deleteType
= getDeleteType(selection
);
239 // Confirm the operation
240 Shell shell
= window
.getShell();
241 MessageBox confirmOperation
= new MessageBox(shell
, SWT
.ICON_QUESTION
| SWT
.CANCEL
| SWT
.OK
);
242 confirmOperation
.setText(getTitle(deleteType
));
243 confirmOperation
.setMessage(getMessage(deleteType
));
244 if (confirmOperation
.open() != SWT
.OK
) {
248 final Iterator
<Object
> iterator
= fSelection
.iterator();
249 final int nbElements
= fSelection
.size();
251 TmfWorkspaceModifyOperation operation
= new TmfWorkspaceModifyOperation() {
253 public void execute(IProgressMonitor monitor
) throws CoreException
{
254 SubMonitor subMonitor
= SubMonitor
.convert(monitor
, nbElements
);
256 while (iterator
.hasNext()) {
257 if (monitor
.isCanceled()) {
258 throw new OperationCanceledException();
260 Object element
= iterator
.next();
261 IProgressMonitor elementSubMonitor
= subMonitor
.newChild(1);
262 if (element
instanceof TmfTraceElement
) {
263 final TmfTraceElement trace
= (TmfTraceElement
) element
;
264 if (!trace
.getResource().exists()) {
267 subMonitor
.setTaskName(getTraceTaskName(deleteType
) + " " + trace
.getElementPath()); //$NON-NLS-1$
269 SubMonitor deleteSubMonitor
= SubMonitor
.convert(elementSubMonitor
, 1);
270 trace
.delete(deleteSubMonitor
);
271 } catch (final CoreException e
) {
272 Display
.getDefault().asyncExec(new Runnable() {
275 final MessageBox mb
= new MessageBox(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell());
276 mb
.setText(getTraceErrorMessage(deleteType
) + ' ' + trace
.getName());
277 mb
.setMessage(e
.getMessage());
281 Activator
.getDefault().logError(getTraceErrorMessage(deleteType
) + trace
.getName(), e
);
283 } else if (element
instanceof TmfTraceFolder
) {
284 final TmfTraceFolder folder
= (TmfTraceFolder
) element
;
285 final IResource resource
= folder
.getResource();
286 if (!resource
.exists()) {
290 subMonitor
.setTaskName(getTraceFolderTaskName(deleteType
) + " " + folder
.getPath()); //$NON-NLS-1$
293 // delete all traces under this folder
294 SubMonitor childrenSubMonitor
= SubMonitor
.convert(elementSubMonitor
, folder
.getTraces().size() + 1);
295 for (TmfTraceElement traceElement
: folder
.getTraces()) {
296 traceElement
.delete(childrenSubMonitor
.newChild(1));
299 // Finally, delete the folder. For the Traces
300 // folder, we only delete the children since the
301 // folder should always be there.
302 final IProgressMonitor deleteSubMonitor
= subMonitor
.newChild(1);
303 if (folder
instanceof TmfTracesFolder
) {
304 resource
.accept(new IResourceVisitor() {
306 public boolean visit(IResource visitedResource
) throws CoreException
{
307 if (visitedResource
!= resource
) {
308 visitedResource
.delete(true, deleteSubMonitor
);
312 }, IResource
.DEPTH_ONE
, 0);
314 resource
.delete(true, deleteSubMonitor
);
316 childrenSubMonitor
.done();
317 } catch (final CoreException e
) {
318 Display
.getDefault().asyncExec(new Runnable() {
321 final MessageBox mb
= new MessageBox(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell());
322 mb
.setText(getFolderErrorMessage(deleteType
) + ' ' + folder
.getName());
323 mb
.setMessage(e
.getMessage());
327 Activator
.getDefault().logError(getFolderErrorMessage(deleteType
) + folder
.getName(), e
);
330 subMonitor
.setTaskName(""); //$NON-NLS-1$
331 elementSubMonitor
.done();
337 PlatformUI
.getWorkbench().getProgressService().run(true, true, operation
);
338 } catch (InterruptedException e
) {
340 } catch (InvocationTargetException e
) {
341 TraceUtils
.displayErrorMsg(e
.toString(), e
.getTargetException().toString());