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

Source Code of org.locationtech.udig.project.ui.internal.actions.Delete

/*
*    uDig - User Friendly Desktop Internet GIS client
*    http://udig.refractions.net
*    (C) 2004, 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.actions;

import java.io.File;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import org.locationtech.udig.core.Pair;
import org.locationtech.udig.core.filter.AdaptingFilter;
import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.IMap;
import org.locationtech.udig.project.IProjectElement;
import org.locationtech.udig.project.command.MapCommand;
import org.locationtech.udig.project.command.UndoableMapCommand;
import org.locationtech.udig.project.command.factory.EditCommandFactory;
import org.locationtech.udig.project.internal.Layer;
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.commands.edit.DeleteManyFeaturesCommand;
import org.locationtech.udig.project.preferences.PreferenceConstants;
import org.locationtech.udig.project.ui.ApplicationGIS;
import org.locationtech.udig.project.ui.UDIGGenericAction;
import org.locationtech.udig.project.ui.commands.DrawCommandFactory;
import org.locationtech.udig.project.ui.commands.IDrawCommand;
import org.locationtech.udig.project.ui.internal.ApplicationGISInternal;
import org.locationtech.udig.project.ui.internal.Messages;
import org.locationtech.udig.project.ui.internal.ProjectUIPlugin;
import org.locationtech.udig.project.ui.internal.UDIGEditorInputDescriptor;
import org.locationtech.udig.project.ui.render.displayAdapter.ViewportPane;
import org.locationtech.udig.ui.PlatformGIS;

import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.dialogs.MessageDialogWithToggle;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PlatformUI;
import org.opengis.feature.simple.SimpleFeature;

/**
* Deletes the selected elements from a project.
*
* @author jeichar
* @since 0.3
*/
public class Delete extends UDIGGenericAction {
   
    /**
     * Indicates whether to run the commands synchronously or not.
     */
    private boolean runSync = false;
    private boolean canDeleteProjectElements;

    public Delete( boolean canDeleteProjectElements){
        this.canDeleteProjectElements = canDeleteProjectElements;
    }
    /**
     * Run has been overriden to ignore deleting maps.
     * <p>
     * This is due to UDIG-1836 where it is noted that the default selection
     * provided by a MapEditor is a MapImpl (and thus 90% of the time hitting delete
     * will result in the map being removed).
     * <p>
     * The ProjectExplorer view and LayerView make use of their own delete action and thus are
     * not effected here.
     *
     * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction)
     */
    public void run( IAction action ) {
        ISelection sel = getSelection();
        if (sel == null || sel.isEmpty() || !(sel instanceof IStructuredSelection)) {
            return; // nothing selected to delete
        }
        IStructuredSelection selection = (IStructuredSelection) sel;
       
        /*
         * Optimization for a set of objects in selection of the same nature. The goal: run an
         * operation once over all selected objects.
         */
        ArrayList<Layer> layers = new ArrayList<Layer>(selection.size());
       
        Object firstElem = selection.iterator().next();
       
        Pair<Boolean, Integer> stateData;
       
        if (canDeleteProjectElements && firstElem instanceof Project) {
            stateData = showErrorMessage(selection.size(), (Project) firstElem);
        } else if (canDeleteProjectElements && firstElem instanceof IProjectElement) {
            stateData = showErrorMessage(selection.size(), (ProjectElement) firstElem);
        } else if (firstElem instanceof Layer) {
            stateData = showErrorMessage(selection.size(), (Layer) firstElem);
        } else if (firstElem instanceof SimpleFeature) {
            stateData = showErrorMessage(selection.size(), (SimpleFeature) firstElem);
        } else if (firstElem instanceof AdaptingFilter) {
            AdaptingFilter<?> f = (AdaptingFilter<?>) firstElem;
            ILayer layer = (ILayer) f.getAdapter(ILayer.class);
            stateData = showErrorMessage(selection.size(), layer,f);
        } else {
            stateData = null;
        }
       
        if( stateData == null || stateData.getRight() == Window.CANCEL ){
            return; // thanks for playing
        }
       
        for( Iterator<?> iter = selection.iterator(); iter.hasNext(); ) {
            Object element = iter.next();

            if (canDeleteProjectElements && element instanceof Project) {
                operate((Project) element, stateData);
            } else if (canDeleteProjectElements && element instanceof IProjectElement) {
                operate((ProjectElement) element, stateData);
            } else if (element instanceof Layer) {
                layers.add((Layer) element);
            } else if (element instanceof SimpleFeature) {
                operate((SimpleFeature) element, stateData);
            }else if (element instanceof AdaptingFilter) {
                AdaptingFilter<?> f = (AdaptingFilter<?>) element;
                ILayer layer = (ILayer) f.getAdapter(ILayer.class);
                operate(layer,f, stateData);
            }
        }

        if (!layers.isEmpty()) {
            operate(layers.toArray(new Layer[layers.size()]), stateData);
        }

        // layers = null;
    }
   
    /**
     * @see org.locationtech.udig.project.ui.UDIGGenericAction#operate(org.locationtech.udig.project.Layer)
     */
    protected void operate( Layer layer ) {
        if (layer == null || layer.getMap() == null)
            return;

        UndoableMapCommand command = EditCommandFactory.getInstance().createDeleteLayers(
                new ILayer[]{layer});
        // UndoableMapCommand command =
        // EditCommandFactory.getInstance().createDeleteLayer((ILayer)layer);
        executeCommand(command, layer.getMapInternal());
    }

    /**
     * @see org.locationtech.udig.project.ui.UDIGGenericAction#operate(org.locationtech.udig.project.internal.Layer[])
     */
    @Override
    protected void operate( Layer[] layers, Object context ) {
        Pair<Boolean, Integer> pair = (Pair<Boolean, Integer>) context;
        if( pair == null || pair.right() == Window.CANCEL){
            return; // nothing to do
        }
        if (layers != null && layers.length > 0) {
            /*
             * Layers can exist in different maps. For each map the standalone command should be
             * used to remove only layers that are contained in this map.
             */
            HashMap<IMap, List<Layer>> distributor = new HashMap<IMap, List<Layer>>();

            for( Layer layer : layers ) {
                IMap map = layer.getMap();

                if (distributor.containsKey(map)) {
                    distributor.get(map).add(layer);

                } else {
                    List<Layer> list = new ArrayList<Layer>();
                    list.add(layer);
                    distributor.put(map, list);
                }
            }
            for( Entry<IMap, List<Layer>> entry : distributor.entrySet() ) {
                IMap map = entry.getKey();
                Layer[] removedLayers = entry.getValue().toArray(new Layer[0]);
                UndoableMapCommand command = EditCommandFactory.getInstance().createDeleteLayers(
                        removedLayers);
                executeCommand(command, map);
            }

        }
    }

    void executeCommand( MapCommand command, IMap map ) {
        if (runSync) {
            map.sendCommandSync(command);
        } else {
            map.sendCommandASync(command);
        }
    }

    /**
     * @see org.locationtech.udig.project.ui.UDIGGenericAction#operate(org.locationtech.udig.project.IProjectElement)
     */
    @SuppressWarnings("unchecked")
    protected void operate( ProjectElement element, Object context ) {
        if (element == null)
            return;
        Pair<Boolean, Integer> pair = (Pair<Boolean, Integer>) context;
        if( pair == null || pair.right() == Window.CANCEL){
            return; // nothing to do
        }
        boolean deleteFiles = pair.left();
        int returnCode = pair.right();
        doDelete(element, deleteFiles, returnCode);
    }
   
    @Override
    protected Pair<Boolean, Integer> showErrorMessage( int size, ILayer layer, AdaptingFilter firstElement ) {
        return new Pair<Boolean, Integer>(false,Window.OK);
    }
    @Override
    protected Pair<Boolean, Integer> showErrorMessage( int size, Layer firstElement ) {
        return new Pair<Boolean, Integer>(false,Window.OK);
    }
   
    @Override
    protected Pair<Boolean, Integer> showErrorMessage( int size, SimpleFeature firstElement ) {
        return new Pair<Boolean, Integer>(false,Window.OK);
    }

    @Override
    protected Pair<Boolean, Integer> showErrorMessage( int size, ProjectElement element ) {
        String deleteOne = Messages.Delete_deleteElement;
        String name = element.getName();
        String deleteMany = Messages.Delete_deleteMultipleElements;
        return dialog(size, deleteOne, name, deleteMany);
    }

    @Override
    protected Pair<Boolean, Integer> showErrorMessage( int size, Project element ) {
        String deleteOne = Messages.Delete_deleteProject;
        String name = element.getName();
        String deleteMany = Messages.Delete_deleteMultipleProjects;
        return dialog(size, deleteOne, name, deleteMany);
    }

    private Pair<Boolean, Integer> dialog( int size, String deleteOne, String name, String deleteMany ) {
        String message;
       
        if (size == 1) {
            message = MessageFormat.format(deleteOne, name);
        } else {
            message = MessageFormat.format(deleteMany, size);
        }

        /*
         *  FIXME as of https://jira.codehaus.org/browse/UDIG-1974
         *  there is a bug in the maps removal.
         *  The below should be fixed once the bug has been fixed.
         */
       
        // START OLD CODE
            //        MessageDialogWithToggle dialog = MessageDialogWithToggle.openOkCancelConfirm(Display
            //                .getCurrent().getActiveShell(), Messages.Delete_delete, message,
            //                Messages.Delete_filesystem, getDoDelete(), null, null);
                    // note: we will do our own preference store persistence, since the built in one is
                    // backwards
            //        boolean deleteFiles = dialog.getToggleState();
            //        int returnCode = dialog.getReturnCode();
            //        if (returnCode == Window.OK) {
        // END OLD CODE
       
        // START TEMPORARY NEW CODE
        boolean delete = MessageDialog.openConfirm( Display.getCurrent().getActiveShell(), Messages.Delete_delete, message );
        boolean deleteFiles = false;
        // END TEMPORARY NEW CODE
       
       
        if( delete ){
            if (deleteFiles != getDoDelete()) {
                setDoDelete(deleteFiles);
            }
            return Pair.create(deleteFiles, Window.OK);
        } else {
            // Window.CANCEL
            return Pair.create(null, Window.CANCEL);
        }
    }

    @Override
    protected void operate( ILayer layer, AdaptingFilter filter, Object context ) {
        Pair<Boolean, Integer> pair = (Pair<Boolean, Integer>) context;
        if( pair == null || pair.right() == Window.CANCEL){
            return; // nothing to do
        }
        layer.getMap().sendCommandASync(new DeleteManyFeaturesCommand(layer, filter));
    }

    protected final void doDelete( ProjectElement element, boolean deleteFiles, int returncode ) {
        if (returncode != Window.CANCEL) {
            for( UDIGEditorInputDescriptor desc : ApplicationGIS.getEditorInputs(element) ) {
                IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow()
                        .getActivePage();
                IEditorPart editor = page.findEditor(desc.createInput(element));
                if (editor != null)
                    page.closeEditor(editor, false);
            }

            List<ProjectElement> elements = element.getElements(ProjectElement.class);
            for( ProjectElement projectElement : elements ) {
                doDelete(projectElement, deleteFiles, returncode);
            }

            Project projectInternal = element.getProjectInternal();
            if (projectInternal != null)
                projectInternal.getElementsInternal().remove(element);
            else {
                Project project = findProject(element);
                if (project != null)
                    project.getElementsInternal().remove(element);
            }
            Resource resource = element.eResource();
            if (resource != null) {
                resource.getContents().remove(element);
                resource.unload();
            }
            if (deleteFiles) {
                try {
                    if (resource == null) {
                        return;
                    }
                    String path = resource.getURI().toFileString();
                    resource.unload();
                    int lastIndexOf = path.lastIndexOf('/');
                    if (lastIndexOf == -1)
                        lastIndexOf = path.length();
                    path = path.substring(0, lastIndexOf);
                    final File file = new File(path);
                    deleteFile(file);
                } catch (Exception e) {
                    ProjectUIPlugin.log("Error deleting project element file", e); //$NON-NLS-1$
                }
            }
        }
    }

    private Project findProject( ProjectElement element ) {
        List< ? extends Project> projects = ApplicationGISInternal.getProjects();
        for( Project project : projects ) {
            if (project.getElements().contains(element))
                return project;
        }
        return null;
    }

    /**
     * @see org.locationtech.udig.project.ui.UDIGGenericAction#operate(org.locationtech.udig.project.Project)
     */
    @SuppressWarnings("unchecked")
    @Override
    protected void operate( Project project, Object context ) {
        if (project == null || context == null){
            return;
        }
        Pair<Boolean, Integer> pair = (Pair<Boolean, Integer>) context;
        boolean deleteFiles = pair.left();
        int returnCode = pair.right();
        doDelete(project, deleteFiles, returnCode);
    }

    protected final void doDelete( Project project, boolean deleteProjectFiles, int returncode ) {
        if (returncode != Window.CANCEL) {
            Resource resource = project.eResource();
            if (!deleteProjectFiles) {
                try {
                    resource.save(null);
                    resource.getContents().remove(project);
                } catch (IOException e) {
                    ProjectUIPlugin.log(null, e);
                }
            }

            List<ProjectElement> toRemove = new ArrayList<ProjectElement>();
            toRemove.addAll(project.getElementsInternal());
            boolean oldrunSyn = runSync;

            this.runSync = true;
            for( ProjectElement element : toRemove ) {
                doDelete(element, deleteProjectFiles, returncode);
            }
            runSync = oldrunSyn;

            resource.setModified(false);
            if (ApplicationGIS.getActiveProject() == project)
                ProjectPlugin.getPlugin().getProjectRegistry().setCurrentProject(null);

            ProjectPlugin.getPlugin().getProjectRegistry().getProjects().remove(project);
            resource.getContents().clear();
            ResourceSet resourceSet = resource.getResourceSet();
            String path = resource.getURI().toFileString();

            resource.unload();

            if (deleteProjectFiles) {
                try {
                    resourceSet.getResources().remove(resource);
                    resource.unload();
                    int lastIndexOf = path.lastIndexOf('/');
                    if (lastIndexOf == -1)
                        lastIndexOf = path.length();
                    path = path.substring(0, lastIndexOf);
                    final File file = new File(path);
                    deleteFile(file);
                } catch (Exception e) {
                    ProjectUIPlugin.log("Error deleting project file", e); //$NON-NLS-1$
                }
            }
        }
    }

    private void deleteFile( File file ) {
        if (!file.exists())
            return;
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for( File file2 : files ) {
                deleteFile(file2);
            }
        }

        file.delete();

    }

    /**
     * @see org.locationtech.udig.project.ui.UDIGGenericAction#operate(org.geotools.feature.SimpleFeature)
     */
    @Override
    protected void operate( final SimpleFeature feature, Object c ) {
        IAdaptable adaptableFeature = null;
        if (feature instanceof IAdaptable) {
            adaptableFeature = (IAdaptable) feature;
        }
        if (adaptableFeature == null) {
            adaptableFeature = (IAdaptable) Platform.getAdapterManager().getAdapter(feature,
                    IAdaptable.class);
        }
        if (adaptableFeature == null)
            return;

        final Layer layer = (Layer) adaptableFeature.getAdapter(Layer.class);

        IDrawCommand command = DrawCommandFactory.getInstance().createDrawFeatureCommand(feature,
                layer);

        ViewportPane pane = (ViewportPane) layer.getMapInternal().getRenderManager()
                .getMapDisplay();
        pane.addDrawCommand(command);

        PlatformGIS.syncInDisplayThread(PlatformUI.getWorkbench().getDisplay(), new Runnable(){
            public void run() {

                boolean result;
                result = MessageDialog.openConfirm(PlatformUI.getWorkbench().getDisplay()
                        .getActiveShell(), Messages.DeleteFeature_confirmation_title,
                        Messages.DeleteFeature_confirmation_text);

                if (result) {
                    UndoableMapCommand c = EditCommandFactory.getInstance().createDeleteFeature(
                            feature, layer);
                    executeCommand(c, layer.getMap());
                }
            }
        });
        command.setValid(false);
        pane.repaint();

    }

    /**
     * Determines whether the command executions should happen synchronously or not.
     *
     * @param runSync
     */
    public void setRunSync( boolean runSync ) {
        this.runSync = runSync;
    }

    private boolean getDoDelete() {
        return ProjectPlugin.getPlugin().getPreferenceStore().getBoolean(
                PreferenceConstants.P_PROJECT_DELETE_FILES);
    }

    private void setDoDelete( boolean deleteFiles ) {
        ProjectPlugin.getPlugin().getPreferenceStore().setValue(
                PreferenceConstants.P_PROJECT_DELETE_FILES, deleteFiles);
    }

}
TOP

Related Classes of org.locationtech.udig.project.ui.internal.actions.Delete

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.