Commit | Line | Data |
---|---|---|
abfad0aa FC |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009, 2010 Ericsson | |
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 | * Francois Chouinard - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.tmf.ui.views.project; | |
14 | ||
15 | import java.io.File; | |
16 | import java.net.URI; | |
17 | import java.util.ArrayList; | |
18 | import java.util.List; | |
19 | ||
20 | import org.eclipse.core.commands.ExecutionException; | |
21 | import org.eclipse.core.commands.NotEnabledException; | |
22 | import org.eclipse.core.commands.NotHandledException; | |
23 | import org.eclipse.core.commands.common.NotDefinedException; | |
24 | import org.eclipse.core.resources.IFile; | |
25 | import org.eclipse.core.resources.IFolder; | |
26 | import org.eclipse.core.resources.IProject; | |
27 | import org.eclipse.core.resources.IResource; | |
28 | import org.eclipse.core.resources.IResourceChangeEvent; | |
29 | import org.eclipse.core.resources.IResourceChangeListener; | |
30 | import org.eclipse.core.resources.IWorkspace; | |
31 | import org.eclipse.core.resources.IWorkspaceRoot; | |
32 | import org.eclipse.core.resources.ResourcesPlugin; | |
33 | import org.eclipse.core.runtime.CoreException; | |
34 | import org.eclipse.core.runtime.Path; | |
35 | import org.eclipse.core.runtime.Status; | |
36 | import org.eclipse.core.runtime.preferences.IEclipsePreferences; | |
37 | import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener; | |
38 | import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent; | |
39 | import org.eclipse.core.runtime.preferences.InstanceScope; | |
40 | import org.eclipse.jface.action.MenuManager; | |
41 | import org.eclipse.jface.viewers.StructuredSelection; | |
abfad0aa FC |
42 | import org.eclipse.jface.viewers.TreeViewer; |
43 | import org.eclipse.jface.viewers.ViewerDropAdapter; | |
44 | import org.eclipse.jface.viewers.ViewerSorter; | |
45 | import org.eclipse.linuxtools.tmf.event.TmfEvent; | |
46 | import org.eclipse.linuxtools.tmf.experiment.TmfExperiment; | |
47 | import org.eclipse.linuxtools.tmf.signal.TmfExperimentSelectedSignal; | |
48 | import org.eclipse.linuxtools.tmf.trace.ITmfTrace; | |
49 | import org.eclipse.linuxtools.tmf.ui.TmfUiPlugin; | |
50 | import org.eclipse.linuxtools.tmf.ui.TmfUiPreferenceInitializer; | |
51 | import org.eclipse.linuxtools.tmf.ui.editors.TmfEditorInput; | |
52 | import org.eclipse.linuxtools.tmf.ui.parsers.ParserProviderManager; | |
53 | import org.eclipse.linuxtools.tmf.ui.views.TmfView; | |
54 | import org.eclipse.linuxtools.tmf.ui.views.project.model.ITmfProjectTreeNode; | |
55 | import org.eclipse.linuxtools.tmf.ui.views.project.model.TmfExperimentNode; | |
56 | import org.eclipse.linuxtools.tmf.ui.views.project.model.TmfProjectContentProvider; | |
57 | import org.eclipse.linuxtools.tmf.ui.views.project.model.TmfProjectLabelProvider; | |
58 | import org.eclipse.linuxtools.tmf.ui.views.project.model.TmfProjectNode; | |
59 | import org.eclipse.linuxtools.tmf.ui.views.project.model.TmfProjectRoot; | |
60 | import org.eclipse.linuxtools.tmf.ui.views.project.model.TmfProjectTreeNode; | |
61 | import org.eclipse.linuxtools.tmf.ui.views.project.model.TmfTraceNode; | |
62 | import org.eclipse.swt.SWT; | |
63 | import org.eclipse.swt.dnd.DND; | |
64 | import org.eclipse.swt.dnd.FileTransfer; | |
65 | import org.eclipse.swt.dnd.Transfer; | |
66 | import org.eclipse.swt.dnd.TransferData; | |
67 | import org.eclipse.swt.events.MouseAdapter; | |
68 | import org.eclipse.swt.events.MouseEvent; | |
529ee6a9 | 69 | import org.eclipse.swt.graphics.Point; |
abfad0aa FC |
70 | import org.eclipse.swt.widgets.Composite; |
71 | import org.eclipse.swt.widgets.Menu; | |
72 | import org.eclipse.swt.widgets.Tree; | |
529ee6a9 | 73 | import org.eclipse.swt.widgets.TreeItem; |
abfad0aa FC |
74 | import org.eclipse.ui.IEditorInput; |
75 | import org.eclipse.ui.IEditorPart; | |
76 | import org.eclipse.ui.IReusableEditor; | |
77 | import org.eclipse.ui.IViewSite; | |
78 | import org.eclipse.ui.IWorkbench; | |
79 | import org.eclipse.ui.IWorkbenchPage; | |
80 | import org.eclipse.ui.IWorkbenchWindow; | |
81 | import org.eclipse.ui.PartInitException; | |
82 | import org.eclipse.ui.PlatformUI; | |
83 | import org.eclipse.ui.handlers.IHandlerService; | |
84 | import org.eclipse.ui.part.ResourceTransfer; | |
85 | import org.osgi.service.prefs.BackingStoreException; | |
86 | ||
87 | /** | |
88 | * <b><u>ProjectView</u></b> | |
89 | * <p> | |
90 | * The ProjectView keeps track of the Tmf projects in the workspace. | |
91 | */ | |
92 | public class ProjectView extends TmfView { | |
93 | ||
3b38ea61 | 94 | public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.project"; //$NON-NLS-1$ |
abfad0aa FC |
95 | |
96 | // ------------------------------------------------------------------------ | |
97 | // Main data structures | |
98 | // ------------------------------------------------------------------------ | |
99 | ||
100 | private TreeViewer fViewer; | |
101 | private TmfProjectRoot fProjectRoot; | |
102 | ||
103 | private IWorkspace fWorkspace; | |
104 | private IResourceChangeListener fResourceChangeListener; | |
105 | private IPreferenceChangeListener fPreferenceChangeListener; | |
106 | ||
107 | // ------------------------------------------------------------------------ | |
108 | // Static methods | |
109 | // ------------------------------------------------------------------------ | |
110 | ||
111 | static public IFolder getActiveProjectTracesFolder() { | |
112 | IEclipsePreferences node = new InstanceScope() | |
113 | .getNode(TmfUiPlugin.PLUGIN_ID); | |
114 | String activeProjectName = node.get( | |
115 | TmfUiPreferenceInitializer.ACTIVE_PROJECT_PREFERENCE, | |
116 | TmfUiPreferenceInitializer.ACTIVE_PROJECT_DEFAULT); | |
117 | IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); | |
118 | IProject[] projects = root.getProjects(); | |
119 | for (IProject project : projects) { | |
120 | if (project.isAccessible() | |
121 | && project.getName().equals(activeProjectName)) { | |
122 | return project.getFolder(TmfProjectNode.TRACE_FOLDER_NAME); | |
123 | } | |
124 | } | |
125 | return null; | |
126 | } | |
127 | ||
128 | static public IFile createLink(URI uri) throws CoreException { | |
129 | IFolder folder = getActiveProjectTracesFolder(); | |
130 | if (folder == null || !folder.exists()) { | |
9c4eb5f7 | 131 | throw new CoreException(new Status(Status.ERROR, TmfUiPlugin.PLUGIN_ID, "No active project set")); //$NON-NLS-1$ |
abfad0aa FC |
132 | } |
133 | String path = uri.getPath(); | |
134 | // TODO: support duplicate file names | |
135 | IFile file = folder.getFile(path.substring(path | |
136 | .lastIndexOf(Path.SEPARATOR))); | |
137 | if (!file.exists()) { | |
138 | file.createLink(uri, IResource.NONE, null); | |
139 | } | |
140 | return file; | |
141 | } | |
142 | ||
143 | // ------------------------------------------------------------------------ | |
144 | // View refresher | |
145 | // ------------------------------------------------------------------------ | |
146 | ||
147 | // Perform updates on the UI thread | |
148 | private Runnable fViewRefresher = new Runnable() { | |
d4011df2 FC |
149 | @Override |
150 | public void run() { | |
db1ea19b | 151 | if ((fViewer != null) && (!fViewer.getTree().isDisposed())) { |
abfad0aa FC |
152 | Object[] elements = fViewer.getExpandedElements(); |
153 | fViewer.refresh(); | |
154 | fViewer.setExpandedElements(elements); | |
155 | } | |
156 | } | |
157 | }; | |
158 | ||
159 | public TmfProjectRoot getRoot() { | |
160 | return fProjectRoot; | |
161 | } | |
162 | ||
163 | // ------------------------------------------------------------------------ | |
164 | // Constructor | |
165 | // ------------------------------------------------------------------------ | |
166 | ||
167 | public ProjectView() { | |
3b38ea61 | 168 | super("Projects"); //$NON-NLS-1$ |
abfad0aa FC |
169 | |
170 | fWorkspace = ResourcesPlugin.getWorkspace(); | |
171 | try { | |
172 | fWorkspace.getRoot().refreshLocal(IResource.DEPTH_INFINITE, null); | |
173 | } catch (CoreException e) { | |
174 | e.printStackTrace(); | |
175 | } | |
176 | ||
177 | fProjectRoot = new TmfProjectRoot(this); | |
178 | } | |
179 | ||
180 | public void refresh() { | |
181 | Tree tree = fViewer.getTree(); | |
182 | if (tree != null && !tree.isDisposed()) | |
183 | tree.getDisplay().asyncExec(fViewRefresher); | |
184 | } | |
185 | ||
186 | public void setSelection(ITmfProjectTreeNode node) { | |
187 | fViewer.setSelection(new StructuredSelection(node), true); | |
188 | } | |
189 | ||
190 | @Override | |
191 | public void init(IViewSite site) throws PartInitException { | |
192 | super.init(site); | |
193 | fResourceChangeListener = new IResourceChangeListener() { | |
d4011df2 FC |
194 | @Override |
195 | public void resourceChanged(IResourceChangeEvent event) { | |
abfad0aa FC |
196 | if (event.getType() == IResourceChangeEvent.POST_CHANGE) { |
197 | fProjectRoot.refreshChildren(); | |
198 | refresh(); | |
199 | } | |
200 | } | |
201 | }; | |
202 | fWorkspace.addResourceChangeListener(fResourceChangeListener); | |
203 | fPreferenceChangeListener = new IPreferenceChangeListener() { | |
d4011df2 FC |
204 | @Override |
205 | public void preferenceChange(PreferenceChangeEvent event) { | |
abfad0aa FC |
206 | refresh(); |
207 | } | |
208 | }; | |
209 | IEclipsePreferences node = new InstanceScope().getNode(TmfUiPlugin.PLUGIN_ID); | |
210 | node.addPreferenceChangeListener(fPreferenceChangeListener); | |
211 | } | |
212 | ||
213 | @Override | |
214 | public void dispose() { | |
215 | fWorkspace.removeResourceChangeListener(fResourceChangeListener); | |
216 | } | |
217 | ||
218 | @Override | |
219 | public void createPartControl(Composite parent) { | |
220 | ||
221 | fViewer = new TreeViewer(parent, SWT.SINGLE); | |
222 | fViewer.setContentProvider(new TmfProjectContentProvider()); | |
223 | fViewer.setSorter(new ViewerSorter()); | |
224 | fViewer.setLabelProvider(new TmfProjectLabelProvider()); | |
225 | fViewer.setInput(fProjectRoot); | |
226 | ||
227 | int ops = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; | |
228 | Transfer[] transfers = new Transfer[] { ResourceTransfer.getInstance(), FileTransfer.getInstance() }; | |
229 | fViewer.addDropSupport(ops, transfers, new ViewerDropAdapter(fViewer) { | |
230 | @Override | |
231 | public boolean validateDrop(Object target, int operation, TransferData transferType) { | |
232 | if (! (target instanceof ITmfProjectTreeNode)) { | |
233 | return false; | |
234 | } | |
235 | overrideOperation(DND.DROP_LINK); | |
236 | return true; | |
237 | } | |
238 | @Override | |
239 | public boolean performDrop(Object data) { | |
240 | Object target = getCurrentTarget(); | |
241 | ITmfProjectTreeNode node = (TmfProjectTreeNode) target; | |
242 | while (node != null && !(node instanceof TmfProjectNode)) { | |
243 | node = node.getParent(); | |
244 | } | |
245 | IFolder targetFolder = ((TmfProjectNode) node).getTracesFolder().getFolder(); | |
246 | if (data instanceof String[]) { | |
247 | // FileTransfer | |
b9763f53 FC |
248 | System.out.println("Drop:" + ((String[])data)[0]); //$NON-NLS-1$ |
249 | System.out.println("Folder:" + targetFolder); //$NON-NLS-1$ | |
abfad0aa FC |
250 | for (String path : (String[]) data) { |
251 | File sourceFile = new File(path); | |
252 | if (sourceFile.isFile()) { | |
253 | IFile file = targetFolder.getFile(path.substring(path.lastIndexOf(File.separator))); | |
254 | try { | |
255 | file.createLink(sourceFile.toURI(), IResource.NONE, null); | |
256 | ITmfTrace trace = ParserProviderManager.getTrace(file); | |
257 | if (trace != null) { | |
258 | trace.dispose(); | |
259 | } | |
260 | } catch (CoreException e) { | |
261 | e.printStackTrace(); | |
262 | } | |
263 | } | |
264 | } | |
265 | } else if (data instanceof IResource[]) { | |
266 | // ResourceTransfer | |
b9763f53 FC |
267 | System.out.println("Drop:" + ((IResource[])data)[0].getName()); //$NON-NLS-1$ |
268 | System.out.println("Folder:" + targetFolder); //$NON-NLS-1$ | |
abfad0aa FC |
269 | for (IResource resource : (IResource[]) data) { |
270 | if (resource instanceof IFile) { | |
271 | IFile file = targetFolder.getFile(resource.getName()); | |
272 | try { | |
273 | file.createLink(resource.getLocation(), IResource.NONE, null); | |
274 | String parser = resource.getPersistentProperty(ParserProviderManager.PARSER_PROPERTY); | |
275 | file.setPersistentProperty(ParserProviderManager.PARSER_PROPERTY, parser); | |
276 | } catch (CoreException e) { | |
277 | e.printStackTrace(); | |
278 | } | |
279 | } | |
280 | ||
281 | } | |
282 | } | |
283 | return true; | |
284 | } | |
285 | }); | |
286 | ||
287 | getSite().setSelectionProvider(fViewer); | |
288 | hookMouse(); | |
289 | ||
290 | createContextMenu(); | |
291 | } | |
292 | ||
293 | // ------------------------------------------------------------------------ | |
294 | // ViewPart | |
295 | // ------------------------------------------------------------------------ | |
296 | ||
297 | @Override | |
3b38ea61 | 298 | @SuppressWarnings("nls") |
abfad0aa FC |
299 | public String toString() { |
300 | return "[ProjectView]"; | |
301 | } | |
302 | ||
303 | // ------------------------------------------------------------------------ | |
304 | // hookMouse | |
305 | // ------------------------------------------------------------------------ | |
306 | ||
307 | private void hookMouse() { | |
308 | fViewer.getTree().addMouseListener(new MouseAdapter() { | |
309 | @Override | |
310 | public void mouseDoubleClick(MouseEvent event) { | |
529ee6a9 FC |
311 | TreeItem treeItem = fViewer.getTree().getItem(new Point(event.x, event.y)); |
312 | if (treeItem == null) return; | |
313 | Object element = treeItem.getData(); | |
abfad0aa FC |
314 | if (element instanceof TmfExperimentNode) { |
315 | TmfExperimentNode experiment = (TmfExperimentNode) element; | |
316 | selectExperiment(experiment); | |
317 | } else if (element instanceof TmfProjectNode) { | |
318 | TmfProjectNode project = (TmfProjectNode) element; | |
319 | if (project.isOpen() && project.isTmfProject()) { | |
320 | IEclipsePreferences node = new InstanceScope().getNode(TmfUiPlugin.PLUGIN_ID); | |
321 | node.put(TmfUiPreferenceInitializer.ACTIVE_PROJECT_PREFERENCE, ((TmfProjectNode) element).getName()); | |
322 | try { | |
323 | node.flush(); | |
324 | } catch (BackingStoreException e) { | |
325 | e.printStackTrace(); | |
326 | } | |
327 | } | |
328 | } else if (element instanceof TmfTraceNode) { | |
329 | IWorkbench wb = PlatformUI.getWorkbench(); | |
330 | IWorkbenchWindow win = wb.getActiveWorkbenchWindow(); | |
331 | IHandlerService handlerService = (IHandlerService) win.getService(IHandlerService.class); | |
332 | try { | |
3b38ea61 | 333 | handlerService.executeCommand("org.eclipse.linuxtools.tmf.ui.command.project.trace.open", null); //$NON-NLS-1$ |
abfad0aa FC |
334 | } catch (ExecutionException e) { |
335 | e.printStackTrace(); | |
336 | } catch (NotDefinedException e) { | |
337 | e.printStackTrace(); | |
338 | } catch (NotEnabledException e) { | |
339 | } catch (NotHandledException e) { | |
340 | e.printStackTrace(); | |
341 | } | |
342 | } | |
343 | } | |
344 | }); | |
345 | } | |
346 | ||
347 | public void selectExperiment(TmfExperimentNode experiment) { | |
348 | String expId = experiment.getName(); | |
349 | // if (fSelectedExperiment != null) | |
350 | // fSelectedExperiment.deregister(); | |
351 | try { | |
352 | TmfTraceNode[] traceEntries = experiment.getTraces(); | |
353 | int nbTraces = traceEntries.length; | |
354 | List<ITmfTrace> traces = new ArrayList<ITmfTrace>(); | |
355 | int cacheSize = Integer.MAX_VALUE; | |
356 | for (int i = 0; i < nbTraces; i++) { | |
357 | IResource resource = traceEntries[i].getResource(); | |
358 | resource = experiment.getProject().getTracesFolder().getTraceForLocation(resource.getLocation()).getResource(); | |
359 | ITmfTrace expTrace = ParserProviderManager.getTrace(resource); | |
360 | if (expTrace != null) { | |
361 | traces.add(expTrace); | |
362 | cacheSize = Math.min(cacheSize, expTrace.getCacheSize()); | |
363 | try { | |
364 | // create a new independent copy of the trace for the editor | |
365 | ITmfTrace trace = ParserProviderManager.getTrace(resource); | |
366 | IEditorInput editorInput = new TmfEditorInput(resource, trace); | |
367 | IWorkbench wb = PlatformUI.getWorkbench(); | |
368 | IWorkbenchPage activePage = wb.getActiveWorkbenchWindow().getActivePage(); | |
369 | ||
370 | String editorId = ParserProviderManager.getEditorId(resource); | |
371 | IEditorPart editor = activePage.findEditor(editorInput); | |
372 | if (editor != null && editor instanceof IReusableEditor) { | |
373 | activePage.reuseEditor((IReusableEditor)editor, editorInput); | |
374 | activePage.activate(editor); | |
375 | } else { | |
376 | editor = activePage.openEditor(editorInput, editorId); | |
377 | } | |
378 | ||
379 | } catch (PartInitException e) { | |
380 | e.printStackTrace(); | |
381 | } | |
382 | } | |
383 | } | |
384 | TmfExperiment<TmfEvent> selectedExperiment = new TmfExperiment<TmfEvent>(TmfEvent.class, expId, traces.toArray(new ITmfTrace[0]), cacheSize); | |
385 | broadcast(new TmfExperimentSelectedSignal<TmfEvent>(this, selectedExperiment)); | |
386 | } catch (Exception e) { | |
387 | e.printStackTrace(); | |
388 | } | |
389 | } | |
390 | ||
391 | // ------------------------------------------------------------------------ | |
392 | // createContextMenu | |
393 | // ------------------------------------------------------------------------ | |
394 | ||
395 | // Populated from the plug-in | |
396 | private void createContextMenu() { | |
3b38ea61 | 397 | MenuManager menuManager = new MenuManager("#PopupMenu"); //$NON-NLS-1$ |
abfad0aa FC |
398 | menuManager.setRemoveAllWhenShown(true); |
399 | Menu menu = menuManager.createContextMenu(fViewer.getControl()); | |
400 | fViewer.getControl().setMenu(menu); | |
401 | getSite().registerContextMenu(menuManager, fViewer); | |
402 | } | |
403 | ||
404 | } |