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
.part
.ResourceTransfer
;
85 import org
.osgi
.service
.prefs
.BackingStoreException
;
88 * <b><u>ProjectView</u></b>
90 * The ProjectView keeps track of the Tmf projects in the workspace.
92 public class ProjectView
extends TmfView
{
94 public static final String ID
= "org.eclipse.linuxtools.tmf.ui.views.project"; //$NON-NLS-1$
96 // ------------------------------------------------------------------------
97 // Main data structures
98 // ------------------------------------------------------------------------
100 private TreeViewer fViewer
;
101 private TmfProjectRoot fProjectRoot
;
103 private IWorkspace fWorkspace
;
104 private IResourceChangeListener fResourceChangeListener
;
105 private IPreferenceChangeListener fPreferenceChangeListener
;
107 // ------------------------------------------------------------------------
109 // ------------------------------------------------------------------------
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
);
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
, "No active project set"));
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);
143 // ------------------------------------------------------------------------
145 // ------------------------------------------------------------------------
147 // Perform updates on the UI thread
148 private Runnable fViewRefresher
= new Runnable() {
151 if ((fViewer
!= null) && (!fViewer
.getTree().isDisposed())) {
152 Object
[] elements
= fViewer
.getExpandedElements();
154 fViewer
.setExpandedElements(elements
);
159 public TmfProjectRoot
getRoot() {
163 // ------------------------------------------------------------------------
165 // ------------------------------------------------------------------------
167 public ProjectView() {
168 super("Projects"); //$NON-NLS-1$
170 fWorkspace
= ResourcesPlugin
.getWorkspace();
172 fWorkspace
.getRoot().refreshLocal(IResource
.DEPTH_INFINITE
, null);
173 } catch (CoreException e
) {
177 fProjectRoot
= new TmfProjectRoot(this);
180 public void refresh() {
181 Tree tree
= fViewer
.getTree();
182 if (tree
!= null && !tree
.isDisposed())
183 tree
.getDisplay().asyncExec(fViewRefresher
);
186 public void setSelection(ITmfProjectTreeNode node
) {
187 fViewer
.setSelection(new StructuredSelection(node
), true);
191 public void init(IViewSite site
) throws PartInitException
{
193 fResourceChangeListener
= new IResourceChangeListener() {
195 public void resourceChanged(IResourceChangeEvent event
) {
196 if (event
.getType() == IResourceChangeEvent
.POST_CHANGE
) {
197 fProjectRoot
.refreshChildren();
202 fWorkspace
.addResourceChangeListener(fResourceChangeListener
);
203 fPreferenceChangeListener
= new IPreferenceChangeListener() {
205 public void preferenceChange(PreferenceChangeEvent event
) {
209 IEclipsePreferences node
= new InstanceScope().getNode(TmfUiPlugin
.PLUGIN_ID
);
210 node
.addPreferenceChangeListener(fPreferenceChangeListener
);
214 public void dispose() {
215 fWorkspace
.removeResourceChangeListener(fResourceChangeListener
);
219 public void createPartControl(Composite parent
) {
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
);
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
) {
231 public boolean validateDrop(Object target
, int operation
, TransferData transferType
) {
232 if (! (target
instanceof ITmfProjectTreeNode
)) {
235 overrideOperation(DND
.DROP_LINK
);
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();
245 IFolder targetFolder
= ((TmfProjectNode
) node
).getTracesFolder().getFolder();
246 if (data
instanceof String
[]) {
248 System
.out
.println("Drop:" + ((String
[])data
)[0]);
249 System
.out
.println("Folder:" + targetFolder
);
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
)));
255 file
.createLink(sourceFile
.toURI(), IResource
.NONE
, null);
256 ITmfTrace trace
= ParserProviderManager
.getTrace(file
);
260 } catch (CoreException e
) {
265 } else if (data
instanceof IResource
[]) {
267 System
.out
.println("Drop:" + ((IResource
[])data
)[0].getName());
268 System
.out
.println("Folder:" + targetFolder
);
269 for (IResource resource
: (IResource
[]) data
) {
270 if (resource
instanceof IFile
) {
271 IFile file
= targetFolder
.getFile(resource
.getName());
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
) {
287 getSite().setSelectionProvider(fViewer
);
293 // ------------------------------------------------------------------------
295 // ------------------------------------------------------------------------
298 @SuppressWarnings("nls")
299 public String
toString() {
300 return "[ProjectView]";
303 // ------------------------------------------------------------------------
305 // ------------------------------------------------------------------------
307 private void hookMouse() {
308 fViewer
.getTree().addMouseListener(new MouseAdapter() {
310 public void mouseDoubleClick(MouseEvent event
) {
311 TreeItem treeItem
= fViewer
.getTree().getItem(new Point(event
.x
, event
.y
));
312 if (treeItem
== null) return;
313 Object element
= treeItem
.getData();
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());
324 } catch (BackingStoreException e
) {
328 } else if (element
instanceof TmfTraceNode
) {
329 IWorkbench wb
= PlatformUI
.getWorkbench();
330 IWorkbenchWindow win
= wb
.getActiveWorkbenchWindow();
331 IHandlerService handlerService
= (IHandlerService
) win
.getService(IHandlerService
.class);
333 handlerService
.executeCommand("org.eclipse.linuxtools.tmf.ui.command.project.trace.open", null); //$NON-NLS-1$
334 } catch (ExecutionException e
) {
336 } catch (NotDefinedException e
) {
338 } catch (NotEnabledException e
) {
339 } catch (NotHandledException e
) {
347 public void selectExperiment(TmfExperimentNode experiment
) {
348 String expId
= experiment
.getName();
349 // if (fSelectedExperiment != null)
350 // fSelectedExperiment.deregister();
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());
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();
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
);
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
);