001: /*
002: * uDig - User Friendly Desktop Internet GIS client http://udig.refractions.net (C) 2004, Refractions Research Inc. This
003: * library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
004: * License as published by the Free Software Foundation; version 2.1 of the License. This library is distributed in the
005: * hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
006: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
007: */
008: package net.refractions.udig.project.ui.internal;
009:
010: import java.util.ArrayList;
011: import java.util.Collection;
012: import java.util.Collections;
013: import java.util.HashMap;
014: import java.util.Iterator;
015: import java.util.List;
016: import java.util.concurrent.atomic.AtomicReference;
017:
018: import net.refractions.udig.catalog.CatalogPlugin;
019: import net.refractions.udig.internal.ui.IDropTargetProvider;
020: import net.refractions.udig.project.ILayer;
021: import net.refractions.udig.project.IProject;
022: import net.refractions.udig.project.IProjectElement;
023: import net.refractions.udig.project.internal.Layer;
024: import net.refractions.udig.project.internal.Map;
025: import net.refractions.udig.project.internal.Project;
026: import net.refractions.udig.project.internal.ProjectPlugin;
027: import net.refractions.udig.project.internal.ProjectRegistry;
028: import net.refractions.udig.project.internal.provider.LoadingPlaceHolder;
029: import net.refractions.udig.project.ui.AdapterFactoryLabelProviderDecorator;
030: import net.refractions.udig.project.ui.ApplicationGIS;
031: import net.refractions.udig.project.ui.internal.UDIGAdapterFactoryContentProvider.InputChangedListener;
032: import net.refractions.udig.project.ui.internal.actions.OpenProject;
033: import net.refractions.udig.project.ui.tool.IToolManager;
034: import net.refractions.udig.ui.UDIGDragDropUtilities;
035: import net.refractions.udig.ui.ZoomingDialog;
036:
037: import org.eclipse.emf.common.notify.AdapterFactory;
038: import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
039: import org.eclipse.jface.action.Action;
040: import org.eclipse.jface.action.GroupMarker;
041: import org.eclipse.jface.action.IAction;
042: import org.eclipse.jface.action.IMenuListener;
043: import org.eclipse.jface.action.IMenuManager;
044: import org.eclipse.jface.action.IStatusLineManager;
045: import org.eclipse.jface.action.IToolBarManager;
046: import org.eclipse.jface.action.MenuManager;
047: import org.eclipse.jface.action.Separator;
048: import org.eclipse.jface.preference.IPreferenceStore;
049: import org.eclipse.jface.viewers.DoubleClickEvent;
050: import org.eclipse.jface.viewers.IDoubleClickListener;
051: import org.eclipse.jface.viewers.ISelection;
052: import org.eclipse.jface.viewers.ISelectionChangedListener;
053: import org.eclipse.jface.viewers.IStructuredSelection;
054: import org.eclipse.jface.viewers.SelectionChangedEvent;
055: import org.eclipse.jface.viewers.StructuredSelection;
056: import org.eclipse.jface.viewers.StructuredViewer;
057: import org.eclipse.jface.viewers.TreeViewer;
058: import org.eclipse.jface.viewers.Viewer;
059: import org.eclipse.jface.viewers.ViewerSorter;
060: import org.eclipse.jface.window.SameShellProvider;
061: import org.eclipse.swt.SWT;
062: import org.eclipse.swt.dnd.DropTargetEvent;
063: import org.eclipse.swt.widgets.Composite;
064: import org.eclipse.swt.widgets.Display;
065: import org.eclipse.swt.widgets.Event;
066: import org.eclipse.swt.widgets.Menu;
067: import org.eclipse.swt.widgets.Shell;
068: import org.eclipse.swt.widgets.Tree;
069: import org.eclipse.swt.widgets.TreeItem;
070: import org.eclipse.ui.IActionBars;
071: import org.eclipse.ui.IEditorPart;
072: import org.eclipse.ui.IPartListener2;
073: import org.eclipse.ui.IViewSite;
074: import org.eclipse.ui.IWorkbenchActionConstants;
075: import org.eclipse.ui.IWorkbenchPage;
076: import org.eclipse.ui.IWorkbenchPartReference;
077: import org.eclipse.ui.PartInitException;
078: import org.eclipse.ui.PlatformUI;
079: import org.eclipse.ui.actions.ActionFactory;
080: import org.eclipse.ui.dialogs.PropertyDialogAction;
081: import org.eclipse.ui.part.ISetSelectionTarget;
082: import org.eclipse.ui.part.ViewPart;
083: import org.eclipse.ui.views.properties.IPropertySheetPage;
084: import org.eclipse.ui.views.properties.PropertySheetPage;
085:
086: /**
087: * Displays the Projects and their contents
088: *
089: * @author jeichar
090: * @since 0.3
091: */
092: public class ProjectExplorer extends ViewPart implements IMenuListener,
093: ISetSelectionTarget, IDropTargetProvider {
094:
095: /** The Extension ID of ProjectExplorer */
096: public static final String ID = "net.refractions.udig.project.ui.projectExplorer"; //$NON-NLS-1$
097:
098: public static final String PROJECT_EXPLORER_LINKED = "PROJECT_EXPLORER_LINKED"; //$NON-NLS-1$
099:
100: ProjectRegistry projectRegistry;
101:
102: private Composite container;
103:
104: TreeViewer treeViewer;
105:
106: private PropertySheetPage propertySheetPage;
107:
108: private static ProjectExplorer explorer = new ProjectExplorer();
109:
110: private IAction propertiesAction;
111:
112: private Action openAction;
113:
114: private Action openProjectAction;
115:
116: private UDIGAdapterFactoryContentProvider contentProvider;
117:
118: private IAction deleteAction;
119:
120: private Action linkAction;
121:
122: /**
123: * Construct <code>ProjectExplorer</code>.
124: */
125: public ProjectExplorer() {
126: super ();
127: CatalogPlugin.getDefault();
128: explorer = this ;
129:
130: projectRegistry = ProjectPlugin.getPlugin()
131: .getProjectRegistry();
132:
133: }
134:
135: /**
136: * returns the list of all the selected objects of the given class.
137: *
138: * @param clazz The object types to add to the list.
139: * @return the list of all the selected objects of the given class
140: */
141: @SuppressWarnings("unchecked")
142: public <T> List<T> getSelected(Class<T> clazz) {
143: StructuredSelection selection = (StructuredSelection) treeViewer
144: .getSelection();
145: List<T> selected = new ArrayList<T>();
146: for (Iterator<T> iter = selection.iterator(); iter.hasNext();) {
147: T obj = iter.next();
148: if (clazz != null && clazz.isAssignableFrom(obj.getClass()))
149: selected.add(obj);
150: }
151: return selected;
152: }
153:
154: /**
155: * TODO summary sentence for init ...
156: *
157: * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
158: * @param site
159: * @throws org.eclipse.ui.PartInitException
160: */
161: public void init(IViewSite site) throws PartInitException {
162: super .init(site);
163:
164: }
165:
166: /**
167: * This creates a context menu for the viewer and adds a listener as well registering the menu
168: * for extension. <!--
169: *
170: * @param viewer The viewer to create a contect menu for.
171: */
172: protected void createContextMenuFor(StructuredViewer viewer) {
173: MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$
174: contextMenu.setRemoveAllWhenShown(true);
175: contextMenu.addMenuListener(this );
176: Menu menu = contextMenu.createContextMenu(viewer.getControl());
177:
178: viewer.getControl().setMenu(menu);
179:
180: getSite().registerContextMenu(contextMenu, viewer);
181: }
182:
183: /**
184: * Returns the composite object that is the UI of the ProjectExplorer.
185: *
186: * @return the composite object that is the UI of the ProjectExplorer.
187: */
188: public Composite getContainer() {
189: return container;
190: }
191:
192: /**
193: * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
194: * @param parent
195: */
196: public void createPartControl(Composite parent) {
197:
198: container = parent;
199:
200: Tree tree = new Tree(getContainer(), SWT.VIRTUAL | SWT.MULTI
201: | SWT.H_SCROLL | SWT.V_SCROLL);
202:
203: treeViewer = new TreeViewer(tree);
204:
205: UDIGDragDropUtilities.addDragDropSupport(treeViewer, this ,
206: true, true);
207:
208: treeViewer.setAutoExpandLevel(1);
209: contentProvider = new UDIGAdapterFactoryContentProvider(
210: getAdapterFactory());
211: treeViewer.setContentProvider(contentProvider);
212:
213: treeViewer
214: .setLabelProvider(new AdapterFactoryLabelProviderDecorator(
215: getAdapterFactory(), treeViewer));
216: treeViewer.setInput(projectRegistry);
217: setTreeSorter();
218: createContextMenuFor(treeViewer);
219: addMenuActions();
220: addToobarActions();
221: addSelectionListener();
222: addDoubleCickListener();
223: setGlobalActions();
224: }
225:
226: private void setTreeSorter() {
227: treeViewer.setSorter(new ViewerSorter() {
228: ViewerLayerSorter layerSorter = new ViewerLayerSorter();
229:
230: /**
231: * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer,
232: * java.lang.Object, java.lang.Object)
233: */
234: public int compare(Viewer viewer, Object e1, Object e2) {
235: if (e1 instanceof Layer && e2 instanceof Layer) {
236: return layerSorter.compare(viewer, e1, e2);
237: }
238: if (e1 instanceof LoadingPlaceHolder)
239: return 1;
240: if (e2 instanceof LoadingPlaceHolder)
241: return -1;
242: return super .compare(viewer, e1, e2);
243: }
244: });
245: }
246:
247: private void addDoubleCickListener() {
248: treeViewer.addDoubleClickListener(new IDoubleClickListener() {
249:
250: public void doubleClick(DoubleClickEvent event) {
251: if (PlatformUI.getWorkbench().isClosing())
252: return;
253:
254: final Object obj = ((IStructuredSelection) treeViewer
255: .getSelection()).getFirstElement();
256: if (!(obj instanceof IProjectElement)) {
257: Display.getDefault().asyncExec(new Runnable() {
258:
259: public void run() {
260: if (obj != null)
261: treeViewer.setExpandedState(obj,
262: !treeViewer
263: .getExpandedState(obj));
264: }
265: });
266: return;
267: }
268:
269: open((IProjectElement) obj, false);
270: }
271:
272: });
273: }
274:
275: private void addSelectionListener() {
276: final IPreferenceStore preferenceStore = ProjectUIPlugin
277: .getDefault().getPreferenceStore();
278: treeViewer
279: .addSelectionChangedListener(new ISelectionChangedListener() {
280:
281: public void selectionChanged(
282: SelectionChangedEvent event) {
283: if (event.getSelection().isEmpty())
284: return;
285: final Object obj = ((IStructuredSelection) treeViewer
286: .getSelection()).getFirstElement();
287: if (obj instanceof IProject)
288: projectRegistry
289: .setCurrentProject((Project) obj);
290: if (obj instanceof ILayer)
291: getViewSite()
292: .getActionBars()
293: .getStatusLineManager()
294: .setMessage(
295: ((ILayer) obj)
296: .getStatusMessage());
297: if (preferenceStore
298: .getBoolean(PROJECT_EXPLORER_LINKED)) {
299: if (obj instanceof IProjectElement) {
300: IWorkbenchPage page = getSite()
301: .getPage();
302: IEditorPart part = page
303: .findEditor(ApplicationGIS
304: .getInput((IProjectElement) obj));
305: page.bringToTop(part);
306: }
307: }
308: }
309:
310: });
311: }
312:
313: private void setGlobalActions() {
314: IToolManager toolManager = ApplicationGIS.getToolManager();
315: IActionBars actionBars = getViewSite().getActionBars();
316: toolManager.contributeGlobalActions(this , actionBars);
317: toolManager.registerActionsWithPart(this );
318: actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(),
319: getDeleteAction(actionBars));
320:
321: }
322:
323: private IAction getDeleteAction(IActionBars actionBars) {
324: if (deleteAction == null) {
325: deleteAction = ApplicationGIS.getToolManager()
326: .getDELETEAction();
327: }
328: return deleteAction;
329: }
330:
331: /**
332: * @return a ComposeableAdapterFactory for all the Udig's EMF objects.
333: */
334: public AdapterFactory getAdapterFactory() {
335: return ProjectUIPlugin.getDefault().getAdapterFactory();
336: }
337:
338: private void addToobarActions() {
339:
340: getActionBars().getToolBarManager().add(createLinkAction());
341: getActionBars()
342: .getToolBarManager()
343: .add(
344: new GroupMarker(
345: IWorkbenchActionConstants.MB_ADDITIONS));
346: }
347:
348: private IAction createLinkAction() {
349: final IPreferenceStore preferenceStore = ProjectUIPlugin
350: .getDefault().getPreferenceStore();
351: linkAction = new Action(Messages.ProjectExplorer_link_name,
352: SWT.CHECK) {
353:
354: @Override
355: public void runWithEvent(Event event) {
356: boolean linked = isChecked();
357: preferenceStore.setValue(PROJECT_EXPLORER_LINKED,
358: linked);
359: if (linked) {
360: addEditorListener();
361: } else {
362: removeEditorListener();
363: }
364: }
365: };
366: boolean linked = preferenceStore
367: .getBoolean(PROJECT_EXPLORER_LINKED);
368: linkAction.setChecked(linked);
369: linkAction.setImageDescriptor(Images
370: .getDescriptor(ImageConstants.LINKED_ENABLED_CO));
371: linkAction.setDisabledImageDescriptor(Images
372: .getDescriptor(ImageConstants.LINKED_DISABLED_CO));
373: linkAction
374: .setToolTipText(Messages.ProjectExplorer_link_tooltip);
375: if (linked)
376: addEditorListener();
377: return linkAction;
378: }
379:
380: IPartListener2 editorListener = new IPartListener2() {
381:
382: public void partActivated(IWorkbenchPartReference partRef) {
383: if (isLinkedWithEditor()
384: && partRef.getPart(false) instanceof MapEditor) {
385: MapEditor editor = (MapEditor) partRef.getPart(false);
386: setSelection(Collections.singleton(editor.getMap()),
387: true);
388: }
389: }
390:
391: public void partBroughtToTop(IWorkbenchPartReference partRef) {
392: }
393:
394: public void partClosed(IWorkbenchPartReference partRef) {
395: }
396:
397: public void partDeactivated(IWorkbenchPartReference partRef) {
398: }
399:
400: public void partHidden(IWorkbenchPartReference partRef) {
401: }
402:
403: public void partInputChanged(IWorkbenchPartReference partRef) {
404: }
405:
406: public void partOpened(IWorkbenchPartReference partRef) {
407: }
408:
409: public void partVisible(IWorkbenchPartReference partRef) {
410: }
411:
412: };
413:
414: protected void removeEditorListener() {
415: getSite().getPage().removePartListener(editorListener);
416: }
417:
418: protected void addEditorListener() {
419: getSite().getPage().addPartListener(editorListener);
420: }
421:
422: public boolean isLinkedWithEditor() {
423: return linkAction.isChecked();
424: }
425:
426: private void addMenuActions() {
427: getActionBars().getMenuManager().add(getOpenProjectAction());
428: getActionBars()
429: .getMenuManager()
430: .add(
431: new GroupMarker(
432: IWorkbenchActionConstants.MB_ADDITIONS));
433:
434: }
435:
436: /**
437: * @see org.eclipse.ui.IWorkbenchPart#setFocus()
438: */
439: public void setFocus() {
440: getSite().setSelectionProvider(treeViewer);
441: }
442:
443: /**
444: * This is how the framework determines which interfaces we implement. <!-- begin-user-doc -->
445: * <!-- end-user-doc -->
446: *
447: * @param key The desired class
448: * @return An object of type key or null;
449: */
450: public Object getAdapter(Class key) {
451: if (key.equals(IPropertySheetPage.class))
452: return getPropertySheetPage();
453: return super .getAdapter(key);
454: }
455:
456: /**
457: * This accesses a cached version of the property sheet. <!-- begin-user-doc --> <!--
458: * end-user-doc -->
459: *
460: * @return An IProperty page for the selected object
461: */
462: public IPropertySheetPage getPropertySheetPage() {
463: if (propertySheetPage == null) {
464: propertySheetPage = new PropertySheetPage() {
465: public void makeContributions(IMenuManager menuManager,
466: IToolBarManager toolBarManager,
467: IStatusLineManager statusLineManager) {
468: super .makeContributions(menuManager,
469: toolBarManager, statusLineManager);
470: }
471:
472: public void setActionBars(IActionBars actionBars) {
473: super .setActionBars(actionBars);
474: }
475: };
476: propertySheetPage
477: .setPropertySourceProvider(new AdapterFactoryContentProvider(
478: getAdapterFactory()));
479: }
480:
481: return propertySheetPage;
482: }
483:
484: /**
485: * Gets the site's action bars
486: *
487: * @return the site's action bars
488: */
489: public IActionBars getActionBars() {
490: return getViewSite().getActionBars();
491: }
492:
493: /**
494: * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
495: */
496: public void menuAboutToShow(IMenuManager manager) {
497: boolean addOpenAction = false;
498: for (Iterator iter = ((IStructuredSelection) treeViewer
499: .getSelection()).iterator(); iter.hasNext();) {
500: Object obj = iter.next();
501: if (obj instanceof IProjectElement) {
502: addOpenAction = true;
503: break;
504: }
505: }
506:
507: if (addOpenAction) {
508: manager.add(getOpenAction());
509: }
510: manager.add(getOpenProjectAction());
511: manager.add(getDeleteAction(getViewSite().getActionBars()));
512:
513: manager.add(new GroupMarker(
514: IWorkbenchActionConstants.MB_ADDITIONS));
515: // LayerApplicabilityMenuCreator creator = getApplicabilityMenu();
516: // if (creator != null)
517: // manager.add(creator.getMenuManager());
518:
519: manager
520: .add(ApplicationGIS.getToolManager()
521: .createOperationsContextMenu(
522: treeViewer.getSelection()));
523: manager.add(new Separator());
524: manager.add(ActionFactory.EXPORT.create(getSite()
525: .getWorkbenchWindow()));
526: if (!treeViewer.getSelection().isEmpty()
527: && ((IStructuredSelection) treeViewer.getSelection())
528: .getFirstElement() instanceof Map) {
529: manager.add(new Separator());
530: manager.add(getPropertiesAction());
531: }
532:
533: }
534:
535: private LayerApplicabilityMenuCreator applicabilityCreator;
536:
537: private LayerApplicabilityMenuCreator getApplicabilityMenu() {
538: if (applicabilityCreator == null) {
539: applicabilityCreator = new LayerApplicabilityMenuCreator();
540: }
541:
542: StructuredSelection selection = (StructuredSelection) treeViewer
543: .getSelection();
544: for (Iterator iter = selection.iterator(); iter.hasNext();) {
545: Object element = iter.next();
546: if (!(element instanceof Layer))
547: return null;
548: }
549:
550: return applicabilityCreator;
551: }
552:
553: /**
554: * TODO summary sentence for getOpenProjectAction ...
555: *
556: * @param manager
557: * @return
558: */
559: private IAction getOpenProjectAction() {
560: if (openProjectAction == null) {
561: openProjectAction = new Action() {
562: OpenProject delegate = new OpenProject();
563:
564: /**
565: * @see org.eclipse.jface.action.Action#run()
566: */
567: public void run() {
568: if (PlatformUI.getWorkbench().isClosing())
569: return;
570:
571: delegate.run(this );
572: }
573: };
574: openProjectAction
575: .setText(Messages.ProjectExplorer_openProject_text);
576: openProjectAction
577: .setToolTipText(Messages.ProjectExplorer_openProject_tooltip);
578: }
579: return openProjectAction;
580: }
581:
582: private IAction getPropertiesAction() {
583: if (propertiesAction == null) {
584: final Shell shell = PlatformUI.getWorkbench()
585: .getActiveWorkbenchWindow().getShell();
586: // propertiesAction=ActionFactory.PROPERTIES.create(getSite().getWorkbenchWindow());
587: // propertiesAction.setEnabled(true);
588:
589: final PropertyDialogAction tmp = new PropertyDialogAction(
590: new SameShellProvider(shell), treeViewer);
591:
592: propertiesAction = new Action() {
593: @Override
594: public void runWithEvent(Event event) {
595: ZoomingDialog dialog = new ZoomingDialog(shell, tmp
596: .createDialog(), ZoomingDialog
597: .calculateBounds(treeViewer.getTree()
598: .getSelection()[0], -1));
599: dialog.open();
600: }
601: };
602:
603: propertiesAction.setText(tmp.getText());
604: propertiesAction.setActionDefinitionId(tmp
605: .getActionDefinitionId());
606: propertiesAction.setDescription(tmp.getDescription());
607: propertiesAction.setHoverImageDescriptor(tmp
608: .getHoverImageDescriptor());
609: propertiesAction.setImageDescriptor(tmp
610: .getImageDescriptor());
611: propertiesAction.setToolTipText(tmp.getToolTipText());
612:
613: }
614: getActionBars().setGlobalActionHandler(
615: ActionFactory.PROPERTIES.getId(), propertiesAction);
616: return propertiesAction;
617: }
618:
619: private Action getOpenAction() {
620: if (openAction == null)
621: openAction = new Action() {
622: /**
623: * @see org.eclipse.jface.action.Action#run()
624: */
625: public void run() {
626: for (Iterator iter = ((IStructuredSelection) treeViewer
627: .getSelection()).iterator(); iter.hasNext();) {
628: open((IProjectElement) iter.next(), false);
629: }
630: }
631: };
632: openAction.setText(Messages.ProjectExplorer_open_text);
633: return openAction;
634: }
635:
636: class OpenWithActions extends Action {
637: UDIGEditorInputDescriptor input;
638:
639: /**
640: * Construct <code>ProjectExplorer.OpenWithActions</code>.
641: *
642: * @param input the editor input that
643: */
644: public OpenWithActions(UDIGEditorInputDescriptor input) {
645: this .input = input;
646: }
647:
648: /**
649: * @see org.eclipse.jface.action.Action#run()
650: */
651: @SuppressWarnings("unchecked")
652: public void run() {
653: for (Iterator iter = ((IStructuredSelection) treeViewer
654: .getSelection()).iterator(); iter.hasNext();) {
655: defaultEditorMap.put(input.getType(), this );
656: open((IProjectElement) iter.next(), false);
657: }
658: }
659: }
660:
661: @SuppressWarnings("unchecked")
662: List getOpenWithActions(Class type) {
663: List actions = (List) editorInputsMap.get(type);
664: if (actions == null) {
665: actions = new ArrayList();
666: List<UDIGEditorInputDescriptor> inputs = ApplicationGIS
667: .getEditorInputs(type);
668: for (Iterator iter = inputs.iterator(); iter.hasNext();) {
669: UDIGEditorInputDescriptor desc = (UDIGEditorInputDescriptor) iter
670: .next();
671: Action openWithAction = new OpenWithActions(desc);
672: openWithAction.setText(desc.getName());
673: actions.add(openWithAction);
674: }
675: if (actions != null)
676: editorInputsMap.put(type, actions);
677: }
678: return actions;
679: }
680:
681: /**
682: * Maps between a class and a list of associated UDIGEditorInput Objects
683: */
684: java.util.Map editorInputsMap = new HashMap();
685:
686: /**
687: * Maps between a class and the id of the editor input to use (from the list in editorInputsMap)
688: */
689: java.util.Map defaultEditorMap = new HashMap();
690:
691: /**
692: * Opens a map or page in the editor.
693: *
694: * @param obj the object to open
695: */
696: public void open(final IProjectElement obj) {
697: open(obj, false);
698: }
699:
700: /**
701: * Opens a map or page in the editor.
702: *
703: * @param obj the object to open
704: * @param wait indicates whether to block until the maps opens.
705: */
706: public void open(final IProjectElement obj, boolean wait) {
707: ApplicationGIS.openProjectElement(obj, wait);
708: }
709:
710: /**
711: * Returns an UDIGEditorInputDescriptor for the provided object.
712: *
713: * @return an UDIGEditorInputDescriptor for the provided object.
714: */
715: public UDIGEditorInputDescriptor getEditorInput(
716: final IProjectElement obj) {
717: List inputs = getOpenWithActions(obj.getClass());
718: String defaultEditor = (String) defaultEditorMap.get(obj
719: .getClass());
720:
721: OpenWithActions action = null;
722: if (defaultEditor == null) {
723: action = (OpenWithActions) inputs.get(0);
724: } else {
725: for (Iterator iter = inputs.iterator(); iter.hasNext();) {
726: OpenWithActions current = (OpenWithActions) iter.next();
727: if (current.input.getEditorID().equals(defaultEditor)) {
728: action = current;
729: break;
730: }
731: }
732: }
733:
734: OpenWithActions finalAction = action;
735: if (finalAction != null) {
736: final UDIGEditorInputDescriptor input = finalAction.input;
737: return input;
738: }
739: throw new Error(
740: "Unable to create a input descriptor for this object. A plugin may not be installed correctly"); //$NON-NLS-1$
741: }
742:
743: /*
744: * @see org.eclipse.ui.part.ISetSelectionTarget#selectReveal(org.eclipse.jface.viewers.ISelection)
745: */
746: public void selectReveal(ISelection selection) {
747: treeViewer.setSelection(selection);
748: }
749:
750: /**
751: * Returns the ProjectExplorer view if it has been created, otherwise an object is created and
752: * returned.
753: *
754: * @return the ProjectExplorer view if it has been created, otherwise an object is created and
755: * returned.
756: */
757: public static ProjectExplorer getProjectExplorer() {
758: return explorer;
759: }
760:
761: /**
762: * @see org.eclipse.ui.IWorkbenchPart#dispose()
763: */
764: @Override
765: public void dispose() {
766: if (PlatformUI.getWorkbench().isClosing()) {
767: ProjectPlugin.getPlugin().turnOffEvents();
768: }
769: treeViewer.getLabelProvider().dispose();
770: contentProvider.dispose();
771: super .dispose();
772: }
773:
774: public Object getTarget(DropTargetEvent event) {
775: return this ;
776: }
777:
778: public void collapseToLevel(IProject project, int i) {
779: treeViewer.collapseToLevel(project, i);
780: }
781:
782: /**
783: * Selects the project in the Project Explorer
784: *
785: * @param p sets the selection in the project explorer
786: * @param reveal TODO
787: */
788: public void setSelection(final IProject p, final boolean reveal) {
789: Display d = Display.getCurrent();
790: if (d == null) {
791: Display.getDefault().asyncExec(new Runnable() {
792: public void run() {
793: treeViewer.setSelection(new StructuredSelection(
794: new Object[] { p }), reveal);
795: }
796: });
797: } else
798: treeViewer.setSelection(new StructuredSelection(
799: new Object[] { p }), reveal);
800:
801: }
802:
803: /**
804: * Selects the element in the tree. This is a non-blocking method and selection may take a while to take effect.
805: *
806: * @param element elements to select select
807: */
808: public void setSelection(
809: final Collection<? extends IProjectElement> element,
810: final boolean reveal) {
811: if (treeViewer == null)
812: return;
813: Display d = Display.getCurrent();
814: if (d == null) {
815: Display.getDefault().asyncExec(new Runnable() {
816: public void run() {
817: inDisplaySelect(element, reveal);
818: }
819: });
820: } else
821: inDisplaySelect(element, reveal);
822:
823: }
824:
825: AtomicReference<SetSelectionListener> inputChangedListener = new AtomicReference<SetSelectionListener>();
826:
827: private void inDisplaySelect(
828: Collection<? extends IProjectElement> element,
829: boolean reveal) {
830: if (treeViewer == null)
831: return;
832: List<Object> visibleElements = getLoadedElements();
833: if (visibleElements.containsAll(element)) {
834: treeViewer.setSelection(new StructuredSelection(element
835: .toArray()), reveal);
836: return;
837: } else {
838: synchronized (contentProvider) {
839: SetSelectionListener old = inputChangedListener
840: .getAndSet(new SetSelectionListener(element,
841: reveal));
842: contentProvider.removeListener(old);
843: contentProvider.addListener(inputChangedListener.get());
844: }
845: for (IProjectElement element2 : element) {
846: treeViewer
847: .setExpandedState(element2.getProject(), true);
848: }
849: }
850: }
851:
852: private List<Object> getLoadedElements() {
853: if (treeViewer == null)
854: return Collections.emptyList();
855: Tree tree = (Tree) treeViewer.getControl();
856: TreeItem[] items = tree.getItems();
857: List<Object> data = new ArrayList<Object>();
858: collectData(items, data);
859: return data;
860: }
861:
862: private void collectData(TreeItem[] items, List<Object> data) {
863: if (items.length == 0)
864: return;
865: for (TreeItem item : items) {
866: Object data2 = item.getData();
867: if (data == null)
868: continue;
869: data.add(data2);
870: collectData(item.getItems(), data);
871: }
872: }
873:
874: /**
875: * Selects the elementChild <em>NOT</em> the element.
876: *
877: * @param element An ancestor of elementChild.
878: * @param elementChild the element to select.
879: */
880: public void setSelection(IProjectElement element,
881: Object elementChild) {
882:
883: }
884:
885: private class SetSelectionListener implements InputChangedListener {
886:
887: private Collection<? extends IProjectElement> elements;
888: private boolean reveal;
889:
890: public SetSelectionListener(
891: Collection<? extends IProjectElement> element,
892: boolean reveal) {
893: this .reveal = reveal;
894: this .elements = element;
895: }
896:
897: private boolean isValid() {
898: synchronized (contentProvider) {
899: if (inputChangedListener.get() != this ) {
900: contentProvider.removeListener(this );
901: return false;
902: }
903: return true;
904: }
905: }
906:
907: private void trySetSelection() {
908: List<Object> expandedElements = getLoadedElements();
909: if (expandedElements.containsAll(elements)) {
910: treeViewer.setSelection(new StructuredSelection(
911: elements.toArray()), reveal);
912: synchronized (contentProvider) {
913: contentProvider.removeListener(this );
914: inputChangedListener.set(null);
915: }
916: }
917: }
918:
919: public void changed() {
920: if (isValid()) {
921: if (Display.getCurrent() == null) {
922: Display.getDefault().asyncExec(new Runnable() {
923: public void run() {
924: trySetSelection();
925: }
926: });
927: } else
928: trySetSelection();
929: }
930: }
931:
932: }
933: }
|