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
.dialogs
.IDialogConstants
;
31 import org
.eclipse
.jface
.dialogs
.MessageDialog
;
32 import org
.eclipse
.jface
.viewers
.ISelection
;
33 import org
.eclipse
.jface
.viewers
.ISelectionProvider
;
34 import org
.eclipse
.jface
.viewers
.IStructuredSelection
;
35 import org
.eclipse
.jface
.viewers
.TreeSelection
;
36 import org
.eclipse
.swt
.SWT
;
37 import org
.eclipse
.swt
.widgets
.Display
;
38 import org
.eclipse
.swt
.widgets
.MessageBox
;
39 import org
.eclipse
.swt
.widgets
.Shell
;
40 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.Activator
;
41 import org
.eclipse
.tracecompass
.internal
.tmf
.ui
.project
.operations
.TmfWorkspaceModifyOperation
;
42 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfExperimentElement
;
43 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceElement
;
44 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTraceFolder
;
45 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TmfTracesFolder
;
46 import org
.eclipse
.tracecompass
.tmf
.ui
.project
.model
.TraceUtils
;
47 import org
.eclipse
.ui
.IWorkbenchPage
;
48 import org
.eclipse
.ui
.IWorkbenchPart
;
49 import org
.eclipse
.ui
.IWorkbenchWindow
;
50 import org
.eclipse
.ui
.PlatformUI
;
51 import org
.eclipse
.ui
.handlers
.HandlerUtil
;
54 * An handler for deletion of both traces and trace folders. It allows mixing
55 * both types of elements.
57 public class DeleteTraceFolderElementHandler
extends AbstractHandler
{
59 private TreeSelection fSelection
= null;
61 private enum DeleteType
{
63 * Only trace folders are selected.
67 * Only traces are selected.
71 * A mix of different elements are selected.
75 * Only Traces (top trace folders) are selected.
79 * Only Traces under experiments are selected.
81 REMOVE_TRACES_FROM_EXPERIMENT
84 // ------------------------------------------------------------------------
86 // ------------------------------------------------------------------------
89 public boolean isEnabled() {
91 // Check if we are closing down
92 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
98 IWorkbenchPage page
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getActivePage();
99 IWorkbenchPart part
= page
.getActivePart();
103 ISelectionProvider selectionProvider
= part
.getSite().getSelectionProvider();
104 if (selectionProvider
== null) {
107 ISelection selection
= selectionProvider
.getSelection();
109 // Make sure selection contains only traces and trace folders
111 if (selection
instanceof TreeSelection
) {
112 fSelection
= (TreeSelection
) selection
;
113 Iterator
<Object
> iterator
= fSelection
.iterator();
114 while (iterator
.hasNext()) {
115 Object element
= iterator
.next();
116 if (!(element
instanceof TmfTraceElement
) && !(element
instanceof TmfTraceFolder
)) {
122 // If we get here, either nothing is selected or everything is a trace or folder
123 return !selection
.isEmpty();
126 // ------------------------------------------------------------------------
128 // ------------------------------------------------------------------------
130 private static DeleteType
getDeleteType(ISelection selection
) {
131 int numTracesFolder
= 0;
132 int numTraceFolder
= 0;
134 int numTracesUnderExperiment
= 0;
136 @SuppressWarnings("rawtypes")
137 Iterator iterator
= ((IStructuredSelection
) selection
).iterator();
138 while (iterator
.hasNext()) {
139 Object next
= iterator
.next();
140 if ((next
instanceof TmfTracesFolder
)) {
142 } else if (next
instanceof TmfTraceFolder
) {
144 } else if (next
instanceof TmfTraceElement
) {
145 TmfTraceElement traceElement
= (TmfTraceElement
) next
;
146 if (traceElement
.getParent() instanceof TmfExperimentElement
) {
147 numTracesUnderExperiment
++;
154 int total
= numTraceFolder
+ numTracesFolder
+ numTracesUnderExperiment
+ numTraces
;
156 if (numTracesFolder
== total
) {
157 return DeleteType
.CLEAR_TRACES_FOLDER
;
160 if (numTraceFolder
== total
) {
161 return DeleteType
.DELETE_TRACE_FOLDERS
;
164 if (numTraces
== total
) {
165 return DeleteType
.DELETE_TRACES
;
168 if (numTracesUnderExperiment
== total
) {
169 return DeleteType
.REMOVE_TRACES_FROM_EXPERIMENT
;
172 return DeleteType
.DELETE_GENERIC
;
175 private static String
getTitle(final DeleteType deleteType
) {
180 case DELETE_TRACE_FOLDERS
:
181 return Messages
.DeleteDialog_Title
;
182 case CLEAR_TRACES_FOLDER
:
183 return Messages
.ClearDialog_Title
;
184 case REMOVE_TRACES_FROM_EXPERIMENT
:
185 return Messages
.RemoveDialog_Title
;
187 throw new IllegalArgumentException();
191 private static String
getMessage(DeleteType deleteType
) {
195 return Messages
.DeleteTraceHandlerGeneric_Message
;
197 return Messages
.DeleteTraceHandler_Message
;
198 case CLEAR_TRACES_FOLDER
:
199 return Messages
.DeleteFolderHandlerClear_Message
;
200 case DELETE_TRACE_FOLDERS
:
201 return Messages
.DeleteFolderHandler_Message
;
202 case REMOVE_TRACES_FROM_EXPERIMENT
:
203 return Messages
.RemoveTraceFromExperimentHandler_Message
;
205 throw new IllegalArgumentException();
209 private static String
getTraceErrorMessage(DeleteType deleteType
) {
210 return deleteType
== DeleteType
.REMOVE_TRACES_FROM_EXPERIMENT ? Messages
.RemoveTraceFromExperimentHandler_Error
: Messages
.DeleteFolderHandler_Error
;
213 private static String
getFolderErrorMessage(DeleteType deleteType
) {
214 return deleteType
== DeleteType
.CLEAR_TRACES_FOLDER ? Messages
.DeleteFolderHandlerClear_Error
: Messages
.DeleteFolderHandler_Error
;
217 private static String
getTraceTaskName(DeleteType deleteType
) {
218 return deleteType
== DeleteType
.REMOVE_TRACES_FROM_EXPERIMENT ? Messages
.RemoveTraceFromExperimentHandler_TaskName
: Messages
.DeleteFolderHandler_TaskName
;
221 private static String
getTraceFolderTaskName(DeleteType deleteType
) {
222 return deleteType
== DeleteType
.CLEAR_TRACES_FOLDER ? Messages
.DeleteFolderHandlerClear_TaskName
: Messages
.DeleteFolderHandler_TaskName
;
226 public Object
execute(ExecutionEvent event
) throws ExecutionException
{
228 // Check if we are closing down
229 IWorkbenchWindow window
= PlatformUI
.getWorkbench().getActiveWorkbenchWindow();
230 if (window
== null) {
235 ISelection selection
= HandlerUtil
.getCurrentSelection(event
);
236 if (!(selection
instanceof IStructuredSelection
)) {
239 final DeleteType deleteType
= getDeleteType(selection
);
241 // Confirm the operation
242 Shell shell
= window
.getShell();
243 MessageDialog dialog
= new MessageDialog(shell
, getTitle(deleteType
), null, getMessage(deleteType
), MessageDialog
.QUESTION
, 1, new String
[] { IDialogConstants
.YES_LABEL
,
244 IDialogConstants
.NO_LABEL
}) {
246 setShellStyle(SWT
.SHEET
);
249 if (dialog
.open() != 0) {
253 final Iterator
<Object
> iterator
= fSelection
.iterator();
254 final int nbElements
= fSelection
.size();
256 TmfWorkspaceModifyOperation operation
= new TmfWorkspaceModifyOperation() {
258 public void execute(IProgressMonitor monitor
) throws CoreException
{
259 SubMonitor subMonitor
= SubMonitor
.convert(monitor
, nbElements
);
261 while (iterator
.hasNext()) {
262 if (monitor
.isCanceled()) {
263 throw new OperationCanceledException();
265 Object element
= iterator
.next();
266 IProgressMonitor elementSubMonitor
= subMonitor
.newChild(1);
267 if (element
instanceof TmfTraceElement
) {
268 final TmfTraceElement trace
= (TmfTraceElement
) element
;
269 if (!trace
.getResource().exists()) {
272 subMonitor
.setTaskName(getTraceTaskName(deleteType
) + " " + trace
.getElementPath()); //$NON-NLS-1$
274 SubMonitor deleteSubMonitor
= SubMonitor
.convert(elementSubMonitor
, 1);
275 trace
.delete(deleteSubMonitor
);
276 } catch (final CoreException e
) {
277 Display
.getDefault().asyncExec(new Runnable() {
280 final MessageBox mb
= new MessageBox(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell());
281 mb
.setText(getTraceErrorMessage(deleteType
) + ' ' + trace
.getName());
282 mb
.setMessage(e
.getMessage());
286 Activator
.getDefault().logError(getTraceErrorMessage(deleteType
) + trace
.getName(), e
);
288 } else if (element
instanceof TmfTraceFolder
) {
289 final TmfTraceFolder folder
= (TmfTraceFolder
) element
;
290 final IResource resource
= folder
.getResource();
291 if (!resource
.exists()) {
295 subMonitor
.setTaskName(getTraceFolderTaskName(deleteType
) + " " + folder
.getPath()); //$NON-NLS-1$
298 // delete all traces under this folder
299 SubMonitor childrenSubMonitor
= SubMonitor
.convert(elementSubMonitor
, folder
.getTraces().size() + 1);
300 for (TmfTraceElement traceElement
: folder
.getTraces()) {
301 traceElement
.delete(childrenSubMonitor
.newChild(1));
304 // Finally, delete the folder. For the Traces
305 // folder, we only delete the children since the
306 // folder should always be there.
307 final IProgressMonitor deleteSubMonitor
= subMonitor
.newChild(1);
308 if (folder
instanceof TmfTracesFolder
) {
309 resource
.accept(new IResourceVisitor() {
311 public boolean visit(IResource visitedResource
) throws CoreException
{
312 if (visitedResource
!= resource
) {
313 visitedResource
.delete(true, deleteSubMonitor
);
317 }, IResource
.DEPTH_ONE
, 0);
319 resource
.delete(true, deleteSubMonitor
);
321 childrenSubMonitor
.done();
322 } catch (final CoreException e
) {
323 Display
.getDefault().asyncExec(new Runnable() {
326 final MessageBox mb
= new MessageBox(PlatformUI
.getWorkbench().getActiveWorkbenchWindow().getShell());
327 mb
.setText(getFolderErrorMessage(deleteType
) + ' ' + folder
.getName());
328 mb
.setMessage(e
.getMessage());
332 Activator
.getDefault().logError(getFolderErrorMessage(deleteType
) + folder
.getName(), e
);
335 subMonitor
.setTaskName(""); //$NON-NLS-1$
336 elementSubMonitor
.done();
342 PlatformUI
.getWorkbench().getProgressService().run(true, true, operation
);
343 } catch (InterruptedException e
) {
345 } catch (InvocationTargetException e
) {
346 TraceUtils
.displayErrorMsg(e
.toString(), e
.getTargetException().toString());