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 | ||
94 | public static final String ID = "org.eclipse.linuxtools.tmf.ui.views.project"; | |
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()) { | |
131 | throw new CoreException(new Status(Status.ERROR, TmfUiPlugin.PLUGIN_ID, | |
132 | "No active project set")); | |
133 | } | |
134 | String path = uri.getPath(); | |
135 | // TODO: support duplicate file names | |
136 | IFile file = folder.getFile(path.substring(path | |
137 | .lastIndexOf(Path.SEPARATOR))); | |
138 | if (!file.exists()) { | |
139 | file.createLink(uri, IResource.NONE, null); | |
140 | } | |
141 | return file; | |
142 | } | |
143 | ||
144 | // ------------------------------------------------------------------------ | |
145 | // View refresher | |
146 | // ------------------------------------------------------------------------ | |
147 | ||
148 | // Perform updates on the UI thread | |
149 | private Runnable fViewRefresher = new Runnable() { | |
d4011df2 FC |
150 | @Override |
151 | public void run() { | |
db1ea19b | 152 | if ((fViewer != null) && (!fViewer.getTree().isDisposed())) { |
abfad0aa FC |
153 | Object[] elements = fViewer.getExpandedElements(); |
154 | fViewer.refresh(); | |
155 | fViewer.setExpandedElements(elements); | |
156 | } | |
157 | } | |
158 | }; | |
159 | ||
160 | public TmfProjectRoot getRoot() { | |
161 | return fProjectRoot; | |
162 | } | |
163 | ||
164 | // ------------------------------------------------------------------------ | |
165 | // Constructor | |
166 | // ------------------------------------------------------------------------ | |
167 | ||
168 | public ProjectView() { | |
169 | super("Projects"); | |
170 | ||
171 | fWorkspace = ResourcesPlugin.getWorkspace(); | |
172 | try { | |
173 | fWorkspace.getRoot().refreshLocal(IResource.DEPTH_INFINITE, null); | |
174 | } catch (CoreException e) { | |
175 | e.printStackTrace(); | |
176 | } | |
177 | ||
178 | fProjectRoot = new TmfProjectRoot(this); | |
179 | } | |
180 | ||
181 | public void refresh() { | |
182 | Tree tree = fViewer.getTree(); | |
183 | if (tree != null && !tree.isDisposed()) | |
184 | tree.getDisplay().asyncExec(fViewRefresher); | |
185 | } | |
186 | ||
187 | public void setSelection(ITmfProjectTreeNode node) { | |
188 | fViewer.setSelection(new StructuredSelection(node), true); | |
189 | } | |
190 | ||
191 | @Override | |
192 | public void init(IViewSite site) throws PartInitException { | |
193 | super.init(site); | |
194 | fResourceChangeListener = new IResourceChangeListener() { | |
d4011df2 FC |
195 | @Override |
196 | public void resourceChanged(IResourceChangeEvent event) { | |
abfad0aa FC |
197 | if (event.getType() == IResourceChangeEvent.POST_CHANGE) { |
198 | fProjectRoot.refreshChildren(); | |
199 | refresh(); | |
200 | } | |
201 | } | |
202 | }; | |
203 | fWorkspace.addResourceChangeListener(fResourceChangeListener); | |
204 | fPreferenceChangeListener = new IPreferenceChangeListener() { | |
d4011df2 FC |
205 | @Override |
206 | public void preferenceChange(PreferenceChangeEvent event) { | |
abfad0aa FC |
207 | refresh(); |
208 | } | |
209 | }; | |
210 | IEclipsePreferences node = new InstanceScope().getNode(TmfUiPlugin.PLUGIN_ID); | |
211 | node.addPreferenceChangeListener(fPreferenceChangeListener); | |
212 | } | |
213 | ||
214 | @Override | |
215 | public void dispose() { | |
216 | fWorkspace.removeResourceChangeListener(fResourceChangeListener); | |
217 | } | |
218 | ||
219 | @Override | |
220 | public void createPartControl(Composite parent) { | |
221 | ||
222 | fViewer = new TreeViewer(parent, SWT.SINGLE); | |
223 | fViewer.setContentProvider(new TmfProjectContentProvider()); | |
224 | fViewer.setSorter(new ViewerSorter()); | |
225 | fViewer.setLabelProvider(new TmfProjectLabelProvider()); | |
226 | fViewer.setInput(fProjectRoot); | |
227 | ||
228 | int ops = DND.DROP_COPY | DND.DROP_MOVE | DND.DROP_LINK; | |
229 | Transfer[] transfers = new Transfer[] { ResourceTransfer.getInstance(), FileTransfer.getInstance() }; | |
230 | fViewer.addDropSupport(ops, transfers, new ViewerDropAdapter(fViewer) { | |
231 | @Override | |
232 | public boolean validateDrop(Object target, int operation, TransferData transferType) { | |
233 | if (! (target instanceof ITmfProjectTreeNode)) { | |
234 | return false; | |
235 | } | |
236 | overrideOperation(DND.DROP_LINK); | |
237 | return true; | |
238 | } | |
239 | @Override | |
240 | public boolean performDrop(Object data) { | |
241 | Object target = getCurrentTarget(); | |
242 | ITmfProjectTreeNode node = (TmfProjectTreeNode) target; | |
243 | while (node != null && !(node instanceof TmfProjectNode)) { | |
244 | node = node.getParent(); | |
245 | } | |
246 | IFolder targetFolder = ((TmfProjectNode) node).getTracesFolder().getFolder(); | |
247 | if (data instanceof String[]) { | |
248 | // FileTransfer | |
249 | System.out.println("Drop:" + ((String[])data)[0]); | |
250 | System.out.println("Folder:" + targetFolder); | |
251 | for (String path : (String[]) data) { | |
252 | File sourceFile = new File(path); | |
253 | if (sourceFile.isFile()) { | |
254 | IFile file = targetFolder.getFile(path.substring(path.lastIndexOf(File.separator))); | |
255 | try { | |
256 | file.createLink(sourceFile.toURI(), IResource.NONE, null); | |
257 | ITmfTrace trace = ParserProviderManager.getTrace(file); | |
258 | if (trace != null) { | |
259 | trace.dispose(); | |
260 | } | |
261 | } catch (CoreException e) { | |
262 | e.printStackTrace(); | |
263 | } | |
264 | } | |
265 | } | |
266 | } else if (data instanceof IResource[]) { | |
267 | // ResourceTransfer | |
268 | System.out.println("Drop:" + ((IResource[])data)[0].getName()); | |
269 | System.out.println("Folder:" + targetFolder); | |
270 | for (IResource resource : (IResource[]) data) { | |
271 | if (resource instanceof IFile) { | |
272 | IFile file = targetFolder.getFile(resource.getName()); | |
273 | try { | |
274 | file.createLink(resource.getLocation(), IResource.NONE, null); | |
275 | String parser = resource.getPersistentProperty(ParserProviderManager.PARSER_PROPERTY); | |
276 | file.setPersistentProperty(ParserProviderManager.PARSER_PROPERTY, parser); | |
277 | } catch (CoreException e) { | |
278 | e.printStackTrace(); | |
279 | } | |
280 | } | |
281 | ||
282 | } | |
283 | } | |
284 | return true; | |
285 | } | |
286 | }); | |
287 | ||
288 | getSite().setSelectionProvider(fViewer); | |
289 | hookMouse(); | |
290 | ||
291 | createContextMenu(); | |
292 | } | |
293 | ||
294 | // ------------------------------------------------------------------------ | |
295 | // ViewPart | |
296 | // ------------------------------------------------------------------------ | |
297 | ||
298 | @Override | |
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 { | |
333 | handlerService.executeCommand("org.eclipse.linuxtools.tmf.ui.command.project.trace.open", null); | |
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() { | |
397 | MenuManager menuManager = new MenuManager("#PopupMenu"); | |
398 | menuManager.setRemoveAllWhenShown(true); | |
399 | Menu menu = menuManager.createContextMenu(fViewer.getControl()); | |
400 | fViewer.getControl().setMenu(menu); | |
401 | getSite().registerContextMenu(menuManager, fViewer); | |
402 | } | |
403 | ||
404 | } |