tmf: Add Export Time Selection action and related interface
[deliverable/tracecompass.git] / tmf / org.eclipse.tracecompass.tmf.ui / src / org / eclipse / tracecompass / internal / tmf / ui / project / handlers / TrimTraceHandler.java
1 /*******************************************************************************
2 * Copyright (c) 2016 EfficiOS Inc., Alexandre Montplaisir
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
10 package org.eclipse.tracecompass.internal.tmf.ui.project.handlers;
11
12 import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
13
14 import java.io.IOException;
15 import java.lang.reflect.InvocationTargetException;
16 import java.nio.file.Files;
17 import java.nio.file.Path;
18 import java.nio.file.Paths;
19
20 import org.eclipse.core.commands.AbstractHandler;
21 import org.eclipse.core.commands.ExecutionEvent;
22 import org.eclipse.core.commands.ExecutionException;
23 import org.eclipse.core.runtime.CoreException;
24 import org.eclipse.core.runtime.IProgressMonitor;
25 import org.eclipse.core.runtime.NullProgressMonitor;
26 import org.eclipse.jdt.annotation.NonNullByDefault;
27 import org.eclipse.jdt.annotation.Nullable;
28 import org.eclipse.jface.dialogs.MessageDialog;
29 import org.eclipse.jface.viewers.ISelection;
30 import org.eclipse.jface.viewers.IStructuredSelection;
31 import org.eclipse.swt.widgets.DirectoryDialog;
32 import org.eclipse.swt.widgets.Shell;
33 import org.eclipse.tracecompass.internal.tmf.ui.project.operations.TmfWorkspaceModifyOperation;
34 import org.eclipse.tracecompass.tmf.core.timestamp.TmfTimeRange;
35 import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
36 import org.eclipse.tracecompass.tmf.core.trace.TmfTraceManager;
37 import org.eclipse.tracecompass.tmf.core.trace.trim.ITmfTrimmableTrace;
38 import org.eclipse.tracecompass.tmf.ui.project.handlers.HandlerUtils;
39 import org.eclipse.tracecompass.tmf.ui.project.model.TmfOpenTraceHelper;
40 import org.eclipse.tracecompass.tmf.ui.project.model.TmfProjectElement;
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.TraceUtils;
44 import org.eclipse.ui.PlatformUI;
45 import org.eclipse.ui.handlers.HandlerUtil;
46
47 /**
48 * Handler for the Trace Trim operation.
49 *
50 * @author Alexandre Montplaisir
51 */
52 @NonNullByDefault
53 public class TrimTraceHandler extends AbstractHandler {
54
55 /** Suffix for new trimmed traces, added to the original trace name */
56 private static final String TRACE_NAME_SUFFIX = "-trimmed"; //$NON-NLS-1$
57
58 @Override
59 public boolean isEnabled() {
60 final Object element = HandlerUtils.getSelectedModelElement();
61 if (element == null) {
62 return false;
63 }
64
65 /*
66 * plugin.xml should have done type/count verification already
67 */
68 TmfTraceElement traceElem = (TmfTraceElement) element;
69 if (!(traceElem.getTrace() instanceof ITmfTrimmableTrace)) {
70 return false;
71 }
72
73 /* Only enable the action if a time range is currently selected */
74 TmfTraceManager tm = TmfTraceManager.getInstance();
75 TmfTimeRange selectionRange = tm.getCurrentTraceContext().getSelectionRange();
76 if (selectionRange.getStartTime().equals(selectionRange.getEndTime())) {
77 return false;
78 }
79
80 return true;
81 }
82
83 @Override
84 public @Nullable Object execute(@Nullable ExecutionEvent event) throws ExecutionException {
85 ISelection selection = HandlerUtil.getCurrentSelectionChecked(event);
86 Object element = ((IStructuredSelection) selection).getFirstElement();
87 final TmfTraceElement traceElem = (TmfTraceElement) element;
88
89 ITmfTrace trace = traceElem.getTrace();
90 if (trace == null) {
91 /* That trace is not currently opened */
92 return null;
93 }
94 ITmfTrimmableTrace trimmableTrace = (ITmfTrimmableTrace) trace;
95
96
97 /* Retrieve the current time range */
98 final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
99 TmfTraceManager tm = TmfTraceManager.getInstance();
100 TmfTimeRange timeRange = tm.getCurrentTraceContext().getSelectionRange();
101 if (timeRange.getStartTime().equals(timeRange.getEndTime())) {
102 MessageDialog.openError(shell, Messages.TrimTraces_InvalidTimeRange_DialogTitle, Messages.TrimTraces_InvalidTimeRange_DialogText);
103 return null;
104 }
105
106 /* Ensure the time range is in the right direction */
107 final TmfTimeRange tr = ((timeRange.getStartTime().compareTo(timeRange.getEndTime()) > 0) ?
108 new TmfTimeRange(timeRange.getEndTime(), timeRange.getStartTime()) :
109 timeRange);
110
111 /*
112 * Pop a dialog asking the user to select a parent directory for the new
113 * trace.
114 */
115 DirectoryDialog dialog = new DirectoryDialog(shell);
116 dialog.setText(Messages.TrimTraces_DirectoryChooser_DialogTitle);
117 String result = dialog.open();
118 if (result == null) {
119 /* Dialog was cancelled, take no further action. */
120 return null;
121 }
122
123 /* Verify that the selected path is valid and writeable */
124 final Path parentPath = checkNotNull(Paths.get(result));
125 if (!Files.isDirectory(parentPath)) {
126 MessageDialog.openError(shell, Messages.TrimTraces_InvalidDirectory_DialogTitle, Messages.TrimTraces_InvalidDirectory_DialogText);
127 return null;
128 }
129 if (!Files.isWritable(parentPath)) {
130 MessageDialog.openError(shell, Messages.TrimTraces_InvalidDirectory_DialogTitle, Messages.TrimTraces_NoWriteAccess_DialogText);
131 return null;
132 }
133
134 /*
135 * Create a directory for the new trace. We will pick the next available
136 * name, adding -2, -3, etc. as needed.
137 */
138 String newTraceName = trace.getName() + TRACE_NAME_SUFFIX;
139 Path potentialPath = parentPath.resolve(newTraceName);
140 for (int i = 2; Files.exists(potentialPath); i++) {
141 newTraceName = trace.getName() + TRACE_NAME_SUFFIX + '-' + String.valueOf(i);
142 potentialPath = parentPath.resolve(newTraceName);
143 }
144
145 final Path tracePath = checkNotNull(potentialPath);
146 try {
147 Files.createDirectory(tracePath);
148 } catch (IOException e) {
149 /* Should not happen since we have checked permissions, etc. */
150 throw new IllegalStateException(e);
151 }
152
153 TmfWorkspaceModifyOperation trimOperation = new TmfWorkspaceModifyOperation() {
154 @Override
155 public void execute(@Nullable IProgressMonitor monitor) throws CoreException {
156 IProgressMonitor mon = (monitor == null ? new NullProgressMonitor() : monitor);
157
158 /* Perform the trace-specific trim operation. */
159 trimmableTrace.trim(tr, tracePath, mon);
160
161 /* Import the new trace into the current project, at the top-level. */
162 TmfProjectElement currentProjectElement = traceElem.getProject();
163 TmfTraceFolder traceFolder =currentProjectElement.getTracesFolder();
164 TmfOpenTraceHelper.openTraceFromPath(traceFolder, tracePath.toString(), shell);
165 }
166 };
167
168 try {
169 PlatformUI.getWorkbench().getProgressService().run(true, true, trimOperation);
170 } catch (InterruptedException e) {
171 return null;
172 } catch (InvocationTargetException e) {
173 TraceUtils.displayErrorMsg(e.toString(), e.getTargetException().toString());
174 return null;
175 }
176
177 return null;
178 }
179
180 }
This page took 0.04475 seconds and 5 git commands to generate.