1 /*******************************************************************************
2 * Copyright (c) 2009, 2010 Ericsson
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 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.tmf
.ui
.views
.project
;
17 import java
.util
.ArrayList
;
18 import java
.util
.List
;
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
;
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
;
69 import org
.eclipse
.swt
.graphics
.Point
;
70 import org
.eclipse
.swt
.widgets
.Composite
;
71 import org
.eclipse
.swt
.widgets
.Menu
;
72 import org
.eclipse
.swt
.widgets
.Tree
;
73 import org
.eclipse
.swt
.widgets
.TreeItem
;
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
.ide
.IDE
;
85 import org
.eclipse
.ui
.part
.ResourceTransfer
;
86 import org
.osgi
.service
.prefs
.BackingStoreException
;
89 * <b><u>ProjectView</u></b>
91 * The ProjectView keeps track of the Tmf projects in the workspace.
93 public class ProjectView
extends TmfView
{
95 public static final String ID
= "org.eclipse.linuxtools.tmf.ui.views.project"; //$NON-NLS-1$
97 // ------------------------------------------------------------------------
98 // Main data structures
99 // ------------------------------------------------------------------------
101 private TreeViewer fViewer
;
102 private TmfProjectRoot fProjectRoot
;
104 private IWorkspace fWorkspace
;
105 private IResourceChangeListener fResourceChangeListener
;
106 private IPreferenceChangeListener fPreferenceChangeListener
;
108 // ------------------------------------------------------------------------
110 // ------------------------------------------------------------------------
112 static public IFolder
getActiveProjectTracesFolder() {
113 IEclipsePreferences node
= new InstanceScope()
114 .getNode(TmfUiPlugin
.PLUGIN_ID
);
115 String activeProjectName
= node
.get(
116 TmfUiPreferenceInitializer
.ACTIVE_PROJECT_PREFERENCE
,
117 TmfUiPreferenceInitializer
.ACTIVE_PROJECT_DEFAULT
);
118 IWorkspaceRoot root
= ResourcesPlugin
.getWorkspace().getRoot();
119 IProject
[] projects
= root
.getProjects();
120 for (IProject project
: projects
) {
121 if (project
.isAccessible()
122 && project
.getName().equals(activeProjectName
)) {
123 return project
.getFolder(TmfProjectNode
.TRACE_FOLDER_NAME
);
129 static public IFile
createLink(URI uri
) throws CoreException
{
130 IFolder folder
= getActiveProjectTracesFolder();
131 if (folder
== null || !folder
.exists()) {
132 throw new CoreException(new Status(Status
.ERROR
, TmfUiPlugin
.PLUGIN_ID
, "No active project set")); //$NON-NLS-1$
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);
144 // ------------------------------------------------------------------------
146 // ------------------------------------------------------------------------
148 // Perform updates on the UI thread
149 private Runnable fViewRefresher
= new Runnable() {
152 if ((fViewer
!= null) && (!fViewer
.getTree().isDisposed())) {
153 Object
[] elements
= fViewer
.getExpandedElements();
155 fViewer
.setExpandedElements(elements
);
160 public TmfProjectRoot
getRoot() {
164 // ------------------------------------------------------------------------
166 // ------------------------------------------------------------------------
168 public ProjectView() {
169 super("Projects"); //$NON-NLS-1$
171 fWorkspace
= ResourcesPlugin
.getWorkspace();
173 fWorkspace
.getRoot().refreshLocal(IResource
.DEPTH_INFINITE
, null);
174 } catch (CoreException e
) {
178 fProjectRoot
= new TmfProjectRoot(this);
181 public void refresh() {
182 Tree tree
= fViewer
.getTree();
183 if (tree
!= null && !tree
.isDisposed())
184 tree
.getDisplay().asyncExec(fViewRefresher
);
187 public void setSelection(ITmfProjectTreeNode node
) {
188 fViewer
.setSelection(new StructuredSelection(node
), true);
192 public void init(IViewSite site
) throws PartInitException
{
194 fResourceChangeListener
= new IResourceChangeListener() {
196 public void resourceChanged(IResourceChangeEvent event
) {
197 if (event
.getType() == IResourceChangeEvent
.POST_CHANGE
) {
198 fProjectRoot
.refreshChildren();
203 fWorkspace
.addResourceChangeListener(fResourceChangeListener
);
204 fPreferenceChangeListener
= new IPreferenceChangeListener() {
206 public void preferenceChange(PreferenceChangeEvent event
) {
210 IEclipsePreferences node
= new InstanceScope().getNode(TmfUiPlugin
.PLUGIN_ID
);
211 node
.addPreferenceChangeListener(fPreferenceChangeListener
);
215 public void dispose() {
216 fWorkspace
.removeResourceChangeListener(fResourceChangeListener
);
220 public void createPartControl(Composite parent
) {
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
);
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
) {
232 public boolean validateDrop(Object target
, int operation
, TransferData transferType
) {
233 if (! (target
instanceof ITmfProjectTreeNode
)) {
236 overrideOperation(DND
.DROP_LINK
);
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();
246 IFolder targetFolder
= ((TmfProjectNode
) node
).getTracesFolder().getFolder();
247 if (data
instanceof String
[]) {
249 for (String path
: (String
[]) data
) {
250 File sourceFile
= new File(path
);
251 if (sourceFile
.isFile()) {
252 IFile file
= targetFolder
.getFile(path
.substring(path
.lastIndexOf(File
.separator
)));
254 file
.createLink(sourceFile
.toURI(), IResource
.NONE
, null);
255 ITmfTrace trace
= ParserProviderManager
.getTrace(file
);
259 } catch (CoreException e
) {
264 } else if (data
instanceof IResource
[]) {
266 for (IResource resource
: (IResource
[]) data
) {
267 if (resource
instanceof IFile
) {
268 IFile file
= targetFolder
.getFile(resource
.getName());
270 file
.createLink(resource
.getLocation(), IResource
.NONE
, null);
271 String parser
= resource
.getPersistentProperty(ParserProviderManager
.PARSER_PROPERTY
);
272 file
.setPersistentProperty(ParserProviderManager
.PARSER_PROPERTY
, parser
);
273 } catch (CoreException e
) {
284 getSite().setSelectionProvider(fViewer
);
290 // ------------------------------------------------------------------------
292 // ------------------------------------------------------------------------
295 @SuppressWarnings("nls")
296 public String
toString() {
297 return "[ProjectView]";
300 // ------------------------------------------------------------------------
302 // ------------------------------------------------------------------------
304 private void hookMouse() {
305 fViewer
.getTree().addMouseListener(new MouseAdapter() {
307 public void mouseDoubleClick(MouseEvent event
) {
308 TreeItem treeItem
= fViewer
.getTree().getItem(new Point(event
.x
, event
.y
));
309 if (treeItem
== null) return;
310 Object element
= treeItem
.getData();
311 if (element
instanceof TmfExperimentNode
) {
312 TmfExperimentNode experiment
= (TmfExperimentNode
) element
;
313 selectExperiment(experiment
);
314 } else if (element
instanceof TmfProjectNode
) {
315 TmfProjectNode project
= (TmfProjectNode
) element
;
316 if (project
.isOpen() && project
.isTmfProject()) {
317 IEclipsePreferences node
= new InstanceScope().getNode(TmfUiPlugin
.PLUGIN_ID
);
318 node
.put(TmfUiPreferenceInitializer
.ACTIVE_PROJECT_PREFERENCE
, ((TmfProjectNode
) element
).getName());
321 } catch (BackingStoreException e
) {
325 } else if (element
instanceof TmfTraceNode
) {
326 IWorkbench wb
= PlatformUI
.getWorkbench();
327 IWorkbenchWindow win
= wb
.getActiveWorkbenchWindow();
328 IHandlerService handlerService
= (IHandlerService
) win
.getService(IHandlerService
.class);
330 handlerService
.executeCommand("org.eclipse.linuxtools.tmf.ui.command.project.trace.open", null); //$NON-NLS-1$
331 } catch (ExecutionException e
) {
333 } catch (NotDefinedException e
) {
335 } catch (NotEnabledException e
) {
336 } catch (NotHandledException e
) {
344 public void selectExperiment(TmfExperimentNode experiment
) {
345 String expId
= experiment
.getName();
346 // if (fSelectedExperiment != null)
347 // fSelectedExperiment.deregister();
349 TmfTraceNode
[] traceEntries
= experiment
.getTraces();
350 int nbTraces
= traceEntries
.length
;
351 List
<ITmfTrace
> traces
= new ArrayList
<ITmfTrace
>();
352 int cacheSize
= Integer
.MAX_VALUE
;
353 for (int i
= 0; i
< nbTraces
; i
++) {
354 IResource resource
= traceEntries
[i
].getResource();
355 resource
= experiment
.getProject().getTracesFolder().getTraceForLocation(resource
.getLocation()).getResource();
356 ITmfTrace expTrace
= ParserProviderManager
.getTrace(resource
);
357 if (expTrace
!= null) {
358 traces
.add(expTrace
);
359 cacheSize
= Math
.min(cacheSize
, expTrace
.getCacheSize());
361 // create a new independent copy of the trace for the editor
362 ITmfTrace trace
= ParserProviderManager
.getTrace(resource
);
363 IEditorInput editorInput
= new TmfEditorInput(resource
, trace
);
364 IWorkbench wb
= PlatformUI
.getWorkbench();
365 IWorkbenchPage activePage
= wb
.getActiveWorkbenchWindow().getActivePage();
367 String editorId
= ParserProviderManager
.getEditorId(resource
);
368 if (resource
instanceof IFile
) {
369 IDE
.setDefaultEditor((IFile
) resource
, editorId
);
371 IEditorPart editor
= activePage
.findEditor(editorInput
);
372 if (editor
!= null && editor
instanceof IReusableEditor
) {
373 activePage
.reuseEditor((IReusableEditor
)editor
, editorInput
);
374 activePage
.activate(editor
);
376 editor
= activePage
.openEditor(editorInput
, editorId
);
379 } catch (PartInitException e
) {
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
) {
391 // ------------------------------------------------------------------------
393 // ------------------------------------------------------------------------
395 // Populated from the plug-in
396 private void createContextMenu() {
397 MenuManager menuManager
= new MenuManager("#PopupMenu"); //$NON-NLS-1$
398 menuManager
.setRemoveAllWhenShown(true);
399 Menu menu
= menuManager
.createContextMenu(fViewer
.getControl());
400 fViewer
.getControl().setMenu(menu
);
401 getSite().registerContextMenu(menuManager
, fViewer
);