Package org.locationtech.udig.project.ui.internal

Source Code of org.locationtech.udig.project.ui.internal.ProjectExplorer

/* uDig - User Friendly Desktop Internet GIS client
* http://udig.refractions.net
* (C) 2004-2012, Refractions Research Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* (http://www.eclipse.org/legal/epl-v10.html), and the Refractions BSD
* License v1.0 (http://udig.refractions.net/files/bsd3-v10.html).
*/
package org.locationtech.udig.project.ui.internal;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;

import org.locationtech.udig.catalog.CatalogPlugin;
import org.locationtech.udig.internal.ui.IDropTargetProvider;
import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.IProject;
import org.locationtech.udig.project.IProjectElement;
import org.locationtech.udig.project.element.ProjectElementAdapter;
import org.locationtech.udig.project.internal.Layer;
import org.locationtech.udig.project.internal.Map;
import org.locationtech.udig.project.internal.Project;
import org.locationtech.udig.project.internal.ProjectElement;
import org.locationtech.udig.project.internal.ProjectPlugin;
import org.locationtech.udig.project.internal.ProjectRegistry;
import org.locationtech.udig.project.internal.provider.LoadingPlaceHolder;
import org.locationtech.udig.project.ui.AdapterFactoryLabelProviderDecorator;
import org.locationtech.udig.project.ui.ApplicationGIS;
import org.locationtech.udig.project.ui.internal.UDIGAdapterFactoryContentProvider.InputChangedListener;
import org.locationtech.udig.project.ui.internal.actions.Delete;
import org.locationtech.udig.project.ui.internal.actions.OpenProject;
import org.locationtech.udig.project.ui.tool.IToolManager;
import org.locationtech.udig.ui.UDIGDragDropUtilities;
import org.locationtech.udig.ui.ZoomingDialog;

import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.jface.window.SameShellProvider;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.IViewSite;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.dialogs.PropertyDialogAction;
import org.eclipse.ui.part.ISetSelectionTarget;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.ui.views.properties.PropertySheetPage;

/**
* Displays the Projects and their contents
*
* @author jeichar
* @since 0.3
*/
public class ProjectExplorer extends ViewPart
        implements
            IMenuListener,
            ISetSelectionTarget,
            IDropTargetProvider {

    /** The Extension ID of ProjectExplorer */
    public static final String ID = "org.locationtech.udig.project.ui.projectExplorer"; //$NON-NLS-1$

    public static final String PROJECT_EXPLORER_LINKED = "PROJECT_EXPLORER_LINKED"; //$NON-NLS-1$

    ProjectRegistry projectRegistry;

    private Composite container;

    TreeViewer treeViewer;

    private PropertySheetPage propertySheetPage;

    private static ProjectExplorer explorer = new ProjectExplorer();

    private IAction propertiesAction;

    private Action openAction;

    private Action openProjectAction;

    private UDIGAdapterFactoryContentProvider contentProvider;

    private Action linkAction;

    /**
     * Construct <code>ProjectExplorer</code>.
     */
    public ProjectExplorer() {
        super();
        CatalogPlugin.getDefault();
        explorer = this;

        projectRegistry = ProjectPlugin.getPlugin().getProjectRegistry();
    }

    /**
     * returns the list of all the selected objects of the given class.
     *
     * @param clazz The object types to add to the list.
     * @return the list of all the selected objects of the given class
     */
    @SuppressWarnings("unchecked")
    public <T> List<T> getSelected( Class<T> clazz ) {
        StructuredSelection selection = (StructuredSelection) treeViewer.getSelection();
        List<T> selected = new ArrayList<T>();
        for( Iterator<T> iter = selection.iterator(); iter.hasNext(); ) {
            T obj = iter.next();
            if (clazz != null && clazz.isAssignableFrom(obj.getClass()))
                selected.add(obj);
        }
        return selected;
    }

    /**
     * TODO summary sentence for init ...
     *
     * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
     * @param site
     * @throws org.eclipse.ui.PartInitException
     */
    public void init( IViewSite site ) throws PartInitException {
        super.init(site);

    }

    /**
     * This creates a context menu for the viewer and adds a listener as well registering the menu
     * for extension. <!--
     *
     * @param viewer The viewer to create a contect menu for.
     */
    protected void createContextMenuFor( StructuredViewer viewer ) {
        MenuManager contextMenu = new MenuManager("#PopUp"); //$NON-NLS-1$
        contextMenu.setRemoveAllWhenShown(true);
        contextMenu.addMenuListener(this);
        Menu menu = contextMenu.createContextMenu(viewer.getControl());

        viewer.getControl().setMenu(menu);

        getSite().registerContextMenu(contextMenu, viewer);
    }

    /**
     * Returns the composite object that is the UI of the ProjectExplorer.
     *
     * @return the composite object that is the UI of the ProjectExplorer.
     */
    public Composite getContainer() {
        return container;
    }

    /**
     * @see org.eclipse.ui.IWorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     * @param parent
     */
    public void createPartControl( Composite parent ) {

        container = parent;

        Tree tree = new Tree(getContainer(), SWT.VIRTUAL | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL);

        treeViewer = new TreeViewer(tree);

        UDIGDragDropUtilities.addDragDropSupport(treeViewer, this, true, true);

        treeViewer.setAutoExpandLevel(1);
        contentProvider = new UDIGAdapterFactoryContentProvider(getAdapterFactory());
        treeViewer.setContentProvider(contentProvider);

        treeViewer.setLabelProvider(new AdapterFactoryLabelProviderDecorator(getAdapterFactory(),
                treeViewer));
        treeViewer.setInput(projectRegistry);

        // Limit the projects view to only show Maps and Pages (and not go any deeper)
        ViewerFilter[] filters = new ViewerFilter[1];
        filters[0] = new ViewerFilter(){
            public boolean select( Viewer viewer, Object parentElement, Object element ) {
                if (element instanceof ProjectElement && parentElement instanceof Project) {
                    ProjectElement mapElement = (ProjectElement) element;
                    Project projectElement = (Project) parentElement;

                    List<ProjectElement> elements = projectElement
                            .getElements(ProjectElement.class);
                    for( ProjectElement pElem : elements ) {
                        List<ProjectElement> projectElements = pElem
                                .getElements(ProjectElement.class);
                        for( ProjectElement projElem : projectElements ) {
                            if (projElem.equals(mapElement)) {
                                return false;
                            }
                        }
                    }
                }

                return true;
            }
        };
        treeViewer.setFilters(filters);

        // ensure our site knows our selection provider
        // so that global actions can hook into the selection
        //
        getSite().setSelectionProvider(treeViewer);

        setTreeSorter();
        createContextMenuFor(treeViewer);
        addMenuActions();
        addToobarActions();
        addSelectionListener();
        addDoubleCickListener();
        setGlobalActions();
    }

    private void setTreeSorter() {
        treeViewer.setSorter(new ViewerSorter(){
            ViewerLayerSorter layerSorter = new ViewerLayerSorter();
            /**
             * @see org.eclipse.jface.viewers.ViewerSorter#compare(org.eclipse.jface.viewers.Viewer,
             *      java.lang.Object, java.lang.Object)
             */
            public int compare( Viewer viewer, Object e1, Object e2 ) {
                if (e1 instanceof Layer && e2 instanceof Layer) {
                    return layerSorter.compare(viewer, e1, e2);
                }
                if (e1 instanceof LoadingPlaceHolder)
                    return 1;
                if (e2 instanceof LoadingPlaceHolder)
                    return -1;
                return super.compare(viewer, e1, e2);
            }
        });
    }

    private void addDoubleCickListener() {
        treeViewer.addDoubleClickListener(new IDoubleClickListener(){

            public void doubleClick( DoubleClickEvent event ) {
                if (PlatformUI.getWorkbench().isClosing())
                    return;

                final Object obj = ((IStructuredSelection) treeViewer.getSelection())
                        .getFirstElement();
                if (!(obj instanceof IProjectElement)) {
                    Display.getDefault().asyncExec(new Runnable(){

                        public void run() {
                            if (obj != null)
                                treeViewer.setExpandedState(obj, !treeViewer.getExpandedState(obj));
                        }
                    });
                    return;
                }

                open((IProjectElement) obj, false);
            }

        });
    }

    private void addSelectionListener() {
        final IPreferenceStore preferenceStore = ProjectUIPlugin.getDefault().getPreferenceStore();
        treeViewer.addSelectionChangedListener(new ISelectionChangedListener(){

            public void selectionChanged( SelectionChangedEvent event ) {
                if (event.getSelection().isEmpty())
                    return;
                final Object obj = ((IStructuredSelection) treeViewer.getSelection())
                        .getFirstElement();
                if (obj instanceof IProject)
                    projectRegistry.setCurrentProject((Project) obj);
                if (obj instanceof ILayer)
                    getViewSite().getActionBars().getStatusLineManager().setMessage(
                            ((ILayer) obj).getStatusMessage());
                if (preferenceStore.getBoolean(PROJECT_EXPLORER_LINKED)) {
                    if (obj instanceof IProjectElement) {
                        IWorkbenchPage page = getSite().getPage();
                        IEditorPart part = page.findEditor(ApplicationGIS
                                .getInput((IProjectElement) obj));
                        page.bringToTop(part);
                    }
                }
            }

        });
    }
    /**
     * We use this method to contribute some global actions from the ToolManager and
     * hook up a custom delete action that is willing to delete a project.
     */
    private void setGlobalActions() {
        IActionBars actionBars = getViewSite().getActionBars();
       
        // register with the tool manager so the projects view will pass keybindings
        // over to the editor
        IToolManager toolManager = ApplicationGIS.getToolManager();
        toolManager.contributeGlobalActions(this, actionBars);
        toolManager.registerActionsWithPart(this);
       
        // except for the delete key we want that one for us
        IKeyBindingService keyBindings = getSite().getKeyBindingService();

        actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), delAction );
        keyBindings.registerAction(delAction);
    }

    /**
     * @return a ComposeableAdapterFactory for all the Udig's EMF objects.
     */
    public AdapterFactory getAdapterFactory() {
        return ProjectUIPlugin.getDefault().getAdapterFactory();
    }

    private void addToobarActions() {

        getActionBars().getToolBarManager().add(createLinkAction());
        getActionBars().getToolBarManager().add(
                new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
    }

    private IAction createLinkAction() {
        final IPreferenceStore preferenceStore = ProjectUIPlugin.getDefault().getPreferenceStore();
        linkAction = new Action(Messages.ProjectExplorer_link_name, SWT.CHECK){

            @Override
            public void runWithEvent( Event event ) {
                boolean linked = isChecked();
                preferenceStore.setValue(PROJECT_EXPLORER_LINKED, linked);
                if (linked) {
                    addEditorListener();
                } else {
                    removeEditorListener();
                }
            }
        };
        boolean linked = preferenceStore.getBoolean(PROJECT_EXPLORER_LINKED);
        linkAction.setChecked(linked);
        linkAction.setImageDescriptor(ProjectUIPlugin.getDefault().getImageDescriptor(ISharedImages.LINKED_ENABLED_CO));
        linkAction.setDisabledImageDescriptor(ProjectUIPlugin.getDefault()
                .getImageDescriptor(ISharedImages.LINKED_DISABLED_CO));
        linkAction.setToolTipText(Messages.ProjectExplorer_link_tooltip);
        if (linked)
            addEditorListener();
        return linkAction;
    }

    IPartListener2 editorListener = new IPartListener2(){

        public void partActivated( IWorkbenchPartReference partRef ) {
            if (isLinkedWithEditor() && partRef.getPart(false) instanceof MapPart) {
                MapPart editor = (MapPart) partRef.getPart(false);
                setSelection(Collections.singleton(editor.getMap()), true);
            }
        }

        public void partBroughtToTop( IWorkbenchPartReference partRef ) {
        }

        public void partClosed( IWorkbenchPartReference partRef ) {
        }

        public void partDeactivated( IWorkbenchPartReference partRef ) {
        }

        public void partHidden( IWorkbenchPartReference partRef ) {
        }

        public void partInputChanged( IWorkbenchPartReference partRef ) {
        }

        public void partOpened( IWorkbenchPartReference partRef ) {
        }

        public void partVisible( IWorkbenchPartReference partRef ) {
        }

    };

    private IAction delAction = new Action(){
        Delete delete = new Delete(true);
        {
            setActionDefinitionId("org.eclipse.ui.edit.delete"); //$NON-NLS-1$
           
            IWorkbenchAction actionTemplate = ActionFactory.DELETE.create(PlatformUI.getWorkbench().getActiveWorkbenchWindow());
            setText(actionTemplate.getText());
            setToolTipText(actionTemplate.getToolTipText());
            setImageDescriptor(actionTemplate.getImageDescriptor());
            setDescription(actionTemplate.getDescription());
            setDisabledImageDescriptor(actionTemplate.getDisabledImageDescriptor());
        }
        @Override
        public void run() {
            delete.selectionChanged(this, treeViewer.getSelection() );
            delete.run(this);
        }
    };
   

    protected void removeEditorListener() {
        getSite().getPage().removePartListener(editorListener);
    }

    protected void addEditorListener() {
        getSite().getPage().addPartListener(editorListener);
    }

    public boolean isLinkedWithEditor() {
        return linkAction.isChecked();
    }

    private void addMenuActions() {
        getActionBars().getMenuManager().add(getOpenProjectAction());
        getActionBars().getMenuManager().add(
                new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));

    }

    /**
     * @see org.eclipse.ui.IWorkbenchPart#setFocus()
     */
    public void setFocus() {
        getSite().setSelectionProvider(treeViewer);
    }

    /**
     * This is how the framework determines which interfaces we implement. <!-- begin-user-doc -->
     * <!-- end-user-doc -->
     *
     * @param key The desired class
     * @return An object of type key or null;
     */
    public Object getAdapter( Class key ) {
        if (key.equals(IPropertySheetPage.class))
            return getPropertySheetPage();
        return super.getAdapter(key);
    }

    /**
     * This accesses a cached version of the property sheet. <!-- begin-user-doc --> <!--
     * end-user-doc -->
     *
     * @return An IProperty page for the selected object
     */
    public IPropertySheetPage getPropertySheetPage() {
        if (propertySheetPage == null) {
            propertySheetPage = new PropertySheetPage(){
                public void makeContributions( IMenuManager menuManager,
                        IToolBarManager toolBarManager, IStatusLineManager statusLineManager ) {
                    super.makeContributions(menuManager, toolBarManager, statusLineManager);
                }

                public void setActionBars( IActionBars actionBars ) {
                    super.setActionBars(actionBars);
                }
            };
            propertySheetPage.setPropertySourceProvider(new AdapterFactoryContentProvider(
                    getAdapterFactory()));
        }

        return propertySheetPage;
    }

    /**
     * Gets the site's action bars
     *
     * @return the site's action bars
     */
    public IActionBars getActionBars() {
        return getViewSite().getActionBars();
    }

    /**
     * @see org.eclipse.jface.action.IMenuListener#menuAboutToShow(org.eclipse.jface.action.IMenuManager)
     */
    public void menuAboutToShow( IMenuManager manager ) {
        boolean addOpenAction = false;
        for( Iterator iter = ((IStructuredSelection) treeViewer.getSelection()).iterator(); iter
                .hasNext(); ) {
            Object obj = iter.next();
            if (obj instanceof IProjectElement) {
                addOpenAction = true;
                break;
            }
        }

        if (addOpenAction) {
            manager.add(getOpenAction());
        }
        manager.add( getOpenProjectAction() );
        manager.add( delAction );

        manager.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS));
        // LayerApplicabilityMenuCreator creator = getApplicabilityMenu();
        // if (creator != null)
        // manager.add(creator.getMenuManager());

        manager.add(ApplicationGIS.getToolManager().createOperationsContextMenu(
                treeViewer.getSelection()));
        manager.add(new Separator());
        manager.add(ActionFactory.EXPORT.create(getSite().getWorkbenchWindow()));
        if (!treeViewer.getSelection().isEmpty()
                && ((IStructuredSelection) treeViewer.getSelection()).getFirstElement() instanceof Map) {
            manager.add(new Separator());
            manager.add(getPropertiesAction());
        }

    }

    private LayerApplicabilityMenuCreator applicabilityCreator;
    private LayerApplicabilityMenuCreator getApplicabilityMenu() {
        if (applicabilityCreator == null) {
            applicabilityCreator = new LayerApplicabilityMenuCreator();
        }

        StructuredSelection selection = (StructuredSelection) treeViewer.getSelection();
        for( Iterator iter = selection.iterator(); iter.hasNext(); ) {
            Object element = iter.next();
            if (!(element instanceof Layer))
                return null;
        }

        return applicabilityCreator;
    }
    /**
     * TODO summary sentence for getOpenProjectAction ...
     *
     * @param manager
     * @return
     */
    private IAction getOpenProjectAction() {
        if (openProjectAction == null) {
            openProjectAction = new Action(){
                OpenProject delegate = new OpenProject();

                /**
                 * @see org.eclipse.jface.action.Action#run()
                 */
                public void run() {
                    if (PlatformUI.getWorkbench().isClosing())
                        return;

                    delegate.run(this);
                }
            };
            openProjectAction.setText(Messages.ProjectExplorer_openProject_text);
            openProjectAction.setToolTipText(Messages.ProjectExplorer_openProject_tooltip);
        }
        return openProjectAction;
    }

    private IAction getPropertiesAction() {
        if (propertiesAction == null) {
            final Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
            // propertiesAction=ActionFactory.PROPERTIES.create(getSite().getWorkbenchWindow());
            // propertiesAction.setEnabled(true);

            final PropertyDialogAction tmp = new PropertyDialogAction(new SameShellProvider(shell),
                    treeViewer);

            propertiesAction = new Action(){
                @Override
                public void runWithEvent( Event event ) {
                    ZoomingDialog dialog = new ZoomingDialog(shell, tmp.createDialog(),
                            ZoomingDialog.calculateBounds(treeViewer.getTree().getSelection()[0],
                                    -1));
                    dialog.open();
                }
            };

            propertiesAction.setText(tmp.getText());
            propertiesAction.setActionDefinitionId(tmp.getActionDefinitionId());
            propertiesAction.setDescription(tmp.getDescription());
            propertiesAction.setHoverImageDescriptor(tmp.getHoverImageDescriptor());
            propertiesAction.setImageDescriptor(tmp.getImageDescriptor());
            propertiesAction.setToolTipText(tmp.getToolTipText());

        }
        getActionBars().setGlobalActionHandler(ActionFactory.PROPERTIES.getId(), propertiesAction);
        return propertiesAction;
    }

    private Action getOpenAction() {
        if (openAction == null)
            openAction = new Action(){
                /**
                 * @see org.eclipse.jface.action.Action#run()
                 */
                public void run() {
                    for( Iterator iter = ((IStructuredSelection) treeViewer.getSelection())
                            .iterator(); iter.hasNext(); ) {
                        open((IProjectElement) iter.next(), false);
                    }
                }
            };
        openAction.setText(Messages.ProjectExplorer_open_text);
        return openAction;
    }

    class OpenWithActions extends Action {
        UDIGEditorInputDescriptor input;

        /**
         * Construct <code>ProjectExplorer.OpenWithActions</code>.
         *
         * @param input the editor input that
         */
        public OpenWithActions( UDIGEditorInputDescriptor input ) {
            this.input = input;
        }

        /**
         * @see org.eclipse.jface.action.Action#run()
         */
        @SuppressWarnings("unchecked")
        public void run() {
            for( Iterator iter = ((IStructuredSelection) treeViewer.getSelection()).iterator(); iter
                    .hasNext(); ) {
                defaultEditorMap.put(input.getType(), this);
                open((IProjectElement) iter.next(), false);
            }
        }
    }

    @SuppressWarnings("unchecked")
    List getOpenWithActions( IProjectElement element ) {
        Class< ? > type;
        if (element instanceof ProjectElementAdapter) {
            type = ((ProjectElementAdapter) element).getBackingObject().getClass();
        } else {
            type = element.getClass();
        }
        List actions = (List) editorInputsMap.get(type);
        if (actions == null) {
            actions = new ArrayList();
            List<UDIGEditorInputDescriptor> inputs = ApplicationGIS.getEditorInputs(element);
            for( Iterator iter = inputs.iterator(); iter.hasNext(); ) {
                UDIGEditorInputDescriptor desc = (UDIGEditorInputDescriptor) iter.next();
                Action openWithAction = new OpenWithActions(desc);
                openWithAction.setText(desc.getName());
                actions.add(openWithAction);
            }
            if (actions != null)
                editorInputsMap.put(type, actions);
        }
        return actions;
    }

    /**
     * Maps between a class and a list of associated UDIGEditorInput Objects
     */
    java.util.Map editorInputsMap = new HashMap();

    /**
     * Maps between a class and the id of the editor input to use (from the list in editorInputsMap)
     */
    java.util.Map defaultEditorMap = new HashMap();

    /**
     * Opens a map or page in the editor.
     * 
     * @param obj the object to open
     */
    public void open( final IProjectElement obj ) {
        open(obj, false);
    }
    /**
     * Opens a map or page in the editor.
     *
     * @param obj the object to open
     * @param wait indicates whether to block until the maps opens.
     */
    public void open( final IProjectElement obj, boolean wait ) {
        ApplicationGIS.openProjectElement(obj, wait);
    }

    /**
     * Returns an UDIGEditorInputDescriptor for the provided object.
     *
     * @return an UDIGEditorInputDescriptor for the provided object.
     */
    public UDIGEditorInputDescriptor getEditorInput( final IProjectElement obj ) {
        List inputs = getOpenWithActions(obj);
        Class< ? > type;
        if (obj instanceof ProjectElementAdapter) {
            type = ((ProjectElementAdapter) obj).getBackingObject().getClass();
        } else {
            type = obj.getClass();
        }
        String defaultEditor = (String) defaultEditorMap.get(type);

        OpenWithActions action = null;
        if (defaultEditor == null) {
            action = (OpenWithActions) inputs.get(0);
        } else {
            for( Iterator iter = inputs.iterator(); iter.hasNext(); ) {
                OpenWithActions current = (OpenWithActions) iter.next();
                if (current.input.getEditorID().equals(defaultEditor)) {
                    action = current;
                    break;
                }
            }
        }

        OpenWithActions finalAction = action;
        if (finalAction != null) {
            final UDIGEditorInputDescriptor input = finalAction.input;
            return input;
        }
        throw new Error(
                "Unable to create a input descriptor for this object.  A plugin may not be installed correctly"); //$NON-NLS-1$
    }

    /*
     * @see org.eclipse.ui.part.ISetSelectionTarget#selectReveal(org.eclipse.jface.viewers.ISelection)
     */
    public void selectReveal( ISelection selection ) {
        treeViewer.setSelection(selection);
    }

    /**
     * Returns the ProjectExplorer view if it has been created, otherwise an object is created and
     * returned.
     *
     * @return the ProjectExplorer view if it has been created, otherwise an object is created and
     *         returned.
     */
    public static ProjectExplorer getProjectExplorer() {
        return explorer;
    }

    /**
     * @see org.eclipse.ui.IWorkbenchPart#dispose()
     */
    @Override
    public void dispose() {
        if (PlatformUI.getWorkbench().isClosing()) {
            ProjectPlugin.getPlugin().turnOffEvents();
        }
        treeViewer.getLabelProvider().dispose();
        contentProvider.dispose();
        super.dispose();
    }

    public Object getTarget( DropTargetEvent event ) {
        return this;
    }

    public void collapseToLevel( IProject project, int i ) {
        treeViewer.collapseToLevel(project, i);
    }

    /**
     * Selects the project in the Project Explorer
     *
     * @param p sets the selection in the project explorer
     * @param reveal TODO
     */
    public void setSelection( final IProject p, final boolean reveal ) {
        Display d = Display.getCurrent();
        if (d == null) {
            Display.getDefault().asyncExec(new Runnable(){
                public void run() {
                    treeViewer.setSelection(new StructuredSelection(new Object[]{p}), reveal);
                }
            });
        } else
            treeViewer.setSelection(new StructuredSelection(new Object[]{p}), reveal);

    }

    /**
     * Selects the element in the tree. This is a non-blocking method and selection may take a while to take effect.
     *
     * @param element elements to select select
     */
    public void setSelection( final Collection< ? extends IProjectElement> element,
            final boolean reveal ) {
        if (treeViewer == null)
            return;
        Display d = Display.getCurrent();
        Runnable runnable = new Runnable(){
            public void run() {
                inDisplaySelect(element, reveal);
            }
        };
        if (d == null) {
            Display.getDefault().asyncExec(runnable);
        } else {
            d.asyncExec(runnable);
        }

    }
    AtomicReference<SetSelectionListener> inputChangedListener = new AtomicReference<SetSelectionListener>();

    private void inDisplaySelect( Collection< ? extends IProjectElement> element, boolean reveal ) {
        if (treeViewer == null)
            return;
        List<Object> visibleElements = getLoadedElements();
        if (visibleElements.containsAll(element)) {
            treeViewer.setSelection(new StructuredSelection(element.toArray()), reveal);
            return;
        } else {
            synchronized (contentProvider) {
                SetSelectionListener old = inputChangedListener.getAndSet(new SetSelectionListener(
                        element, reveal));
                contentProvider.removeListener(old);
                contentProvider.addListener(inputChangedListener.get());
            }
            for( IProjectElement element2 : element ) {
                IProject project = element2.getProject();
                treeViewer.setExpandedState(project, true);
            }
        }
    }

    private List<Object> getLoadedElements() {
        if (treeViewer == null)
            return Collections.emptyList();
        Tree tree = (Tree) treeViewer.getControl();
        TreeItem[] items = tree.getItems();
        List<Object> data = new ArrayList<Object>();
        collectData(items, data);
        return data;
    }

    private void collectData( TreeItem[] items, List<Object> data ) {
        if (items.length == 0)
            return;
        for( TreeItem item : items ) {
            Object data2 = item.getData();
            if (data == null)
                continue;
            data.add(data2);
            collectData(item.getItems(), data);
        }
    }

    /**
     * Selects the elementChild <em>NOT</em> the element.
     *
     * @param element An ancestor of elementChild.
     * @param elementChild the element to select.
     */
    public void setSelection( IProjectElement element, Object elementChild ) {
        throw new UnsupportedOperationException("This method has not been implemented yet");
    }

    private class SetSelectionListener implements InputChangedListener {

        private Collection< ? extends IProjectElement> elements;
        private boolean reveal;

        public SetSelectionListener( Collection< ? extends IProjectElement> element, boolean reveal ) {
            this.reveal = reveal;
            this.elements = element;
        }

        private boolean isValid() {
            synchronized (contentProvider) {
                if (inputChangedListener.get() != this) {
                    contentProvider.removeListener(this);
                    return false;
                }
                return true;
            }
        }

        private void trySetSelection() {
            List<Object> expandedElements = getLoadedElements();
            if (expandedElements.containsAll(elements)) {
                treeViewer.setSelection(new StructuredSelection(elements.toArray()), reveal);
                synchronized (contentProvider) {
                    contentProvider.removeListener(this);
                    inputChangedListener.set(null);
                }
            }
        }

        public void changed() {
            if (isValid()) {
                if (Display.getCurrent() == null) {
                    Display.getDefault().asyncExec(new Runnable(){
                        public void run() {
                            trySetSelection();
                        }
                    });
                } else
                    trySetSelection();
            }
        }

    }
}
TOP

Related Classes of org.locationtech.udig.project.ui.internal.ProjectExplorer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.