Package org.locationtech.udig.tool.select

Source Code of org.locationtech.udig.tool.select.TableView$PromoteSelectionAction

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

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.locationtech.udig.aoi.AOIListener;
import org.locationtech.udig.aoi.IAOIService;
import org.locationtech.udig.core.IBlockingProvider;
import org.locationtech.udig.core.IProvider;
import org.locationtech.udig.core.StaticBlockingProvider;
import org.locationtech.udig.core.feature.AdaptableFeatureCollection;
import org.locationtech.udig.core.filter.AdaptingFilter;
import org.locationtech.udig.core.filter.AdaptingFilterFactory;
import org.locationtech.udig.internal.ui.UDIGDropHandler;
import org.locationtech.udig.project.EditManagerEvent;
import org.locationtech.udig.project.IEditManagerListener;
import org.locationtech.udig.project.ILayer;
import org.locationtech.udig.project.ILayerListener;
import org.locationtech.udig.project.IMapCompositionListener;
import org.locationtech.udig.project.LayerEvent;
import org.locationtech.udig.project.MapCompositionEvent;
import org.locationtech.udig.project.command.AbstractCommand;
import org.locationtech.udig.project.command.CompositeCommand;
import org.locationtech.udig.project.command.MapCommand;
import org.locationtech.udig.project.command.UndoableCommand;
import org.locationtech.udig.project.command.UndoableComposite;
import org.locationtech.udig.project.command.factory.EditCommandFactory;
import org.locationtech.udig.project.command.factory.SelectionCommandFactory;
import org.locationtech.udig.project.command.provider.FIDFeatureProvider;
import org.locationtech.udig.project.internal.Layer;
import org.locationtech.udig.project.internal.Map;
import org.locationtech.udig.project.internal.ProjectPlugin;
import org.locationtech.udig.project.internal.commands.edit.DeleteFeatureCommand;
import org.locationtech.udig.project.internal.commands.edit.DeleteManyFeaturesCommand;
import org.locationtech.udig.project.ui.ApplicationGIS;
import org.locationtech.udig.project.ui.IUDIGView;
import org.locationtech.udig.project.ui.internal.MapEditor;
import org.locationtech.udig.project.ui.internal.MapPart;
import org.locationtech.udig.project.ui.internal.tool.display.ToolManager;
import org.locationtech.udig.project.ui.tool.IToolContext;
import org.locationtech.udig.project.ui.tool.ToolsConstants;
import org.locationtech.udig.tool.select.internal.Messages;
import org.locationtech.udig.tool.select.internal.ZoomSelection;
import org.locationtech.udig.ui.FeatureTableControl;
import org.locationtech.udig.ui.IDropAction;
import org.locationtech.udig.ui.IDropHandlerListener;
import org.locationtech.udig.ui.IFeatureTableLoadingListener;
import org.locationtech.udig.ui.PlatformGIS;
import org.locationtech.udig.ui.ProgressManager;
import org.eclipse.core.commands.AbstractHandler;
import org.eclipse.core.commands.ExecutionEvent;
import org.eclipse.core.commands.ExecutionException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.Status;
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.preference.PreferenceConverter;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ICellEditorListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Item;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IKeyBindingService;
import org.eclipse.ui.IPartListener2;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchPartReference;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.actions.ActionFactory.IWorkbenchAction;
import org.eclipse.ui.internal.UIPlugin;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.geotools.data.DefaultQuery;
import org.geotools.data.FeatureEvent;
import org.geotools.data.FeatureSource;
import org.geotools.data.FeatureStore;
import org.geotools.data.Query;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.factory.GeoTools;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.geotools.feature.Schema;
import org.geotools.filter.FilterAttributeExtractor;
import org.geotools.filter.IllegalFilterException;
import org.geotools.geometry.jts.JTS;
import org.geotools.referencing.CRS;
import org.opengis.feature.Feature;
import org.opengis.feature.FeatureVisitor;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.GeometryDescriptor;
import org.opengis.filter.Filter;
import org.opengis.filter.FilterFactory;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.Id;
import org.opengis.filter.IncludeFilter;
import org.opengis.filter.identity.FeatureId;
import org.opengis.filter.spatial.BBOX;
import org.opengis.filter.spatial.Intersects;
import org.opengis.referencing.FactoryException;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.operation.MathTransform;
import org.opengis.referencing.operation.TransformException;

import com.vividsolutions.jts.geom.Envelope;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;

/**
* Table view for selected Layer, may choose
* to display FeatureSource with out supporting selection
* in the future.
* </p>
* Currently this is a playground using the FeatureTable
* to look at a FeautreSource, syncing up the slection
* with the Layer's filter will come next.
* </p>
* <p>
* Long term responsibilities include:
* <ul>
* <li>Access to a Filter editor for selection specification
* <li>Allowing in view edits
* <li>Real random access for shapefile allowing the table view
*     everyone expects (tm)
* </ul>
* @author Jody Garnett, Refractions Research, Inc.
* @since 0.6
* @version 1.3.0
*/
public class TableView extends ViewPart implements ISelectionProvider, IUDIGView {

    private static final String INITIAL_TEXT = Messages.TableView_search;

    protected static final String ANY = Messages.TableView_search_any;
    protected static final String CQL = "CQL";
   
    /** filter the content by the current AOI */
    private boolean aoiFilter = false;


    /** Used to show the current feature source */
    FeatureTableControl table;
   
    /** Current editor */
    MapPart currentEditor;
   
    /** Current layer under study */
    Layer layer;
   
    /** Toolbar entry used to turn on selection mode */
    private IAction select;

    /**
     * This listener watches the workbench selection and reports
     * back anything that.
     */
    private ISelectionListener workbenchSelectionListener = new ISelectionListener(){
        public void selectionChanged( IWorkbenchPart part, ISelection selection ) {
            if (part instanceof MapPart) {
                editorActivated((MapPart) part);
                return; // we already have sorted out map / layer
            }
            if (!(selection instanceof IStructuredSelection)){
                return;
            }
            if( part == getSite().getPart() ){
                // we are swapping to ourself!
                return; // ignore
            }
           
            Object selected = ((IStructuredSelection) selection).getFirstElement();

            final Layer selectedLayer;
            // this is horribly inelegant. is there not some other way?
            if (selected instanceof Map) {
                selectedLayer = ((Map) selected).getEditManagerInternal().getSelectedLayer();
            } else if (selected instanceof Layer) {
                selectedLayer = (Layer) selected;
            } else if (selected instanceof IAdaptable) {
                // This is often an AdaptableFilter
                IAdaptable adaptable = (IAdaptable) selected;
                selectedLayer = (Layer) adaptable.getAdapter(Layer.class);
            } else {
                return;
            }

            if (selectedLayer != null) {
                PlatformGIS.run(new ISafeRunnable(){
                    public void handleException( Throwable exception ) {
                        SelectPlugin.log("error selecting layer", exception); //$NON-NLS-1$
                    }
                    public void run() throws Exception {
                        layerSelected(selectedLayer);
                    }
                });
               
                //todo add layer event
            }
        }
    };
   
    /**
     * page that the part listener and the workbenchSelectionListener are listening to.
     */
    private IWorkbenchPage page;

    /**
     * Listener that deactivates/reactivates view when it is hidden/shown
     */
    private IPartListener2 activePartListener;

    private MenuManager contextMenu;

    /**
     * Indicates whether the view is visible and therefore is active
     */
    private volatile boolean active=false;
   
    /**
     * Indicates that the features in the view need to be reloaded when the view is visible again.
     */
    protected volatile boolean reloadNeeded=false;

    /**
     * Indicates that the selection filter has changed while inactive
     */
    protected volatile boolean filterChange=false;
   
    /**
     * Indicates that the a feature is being updated by the table view so
     * it is not necessary to load the change indicated by the feature event.
     */
    protected volatile boolean editing=false;

    /**
     * Indicates that the selection of the table is being updated by the view because
     * the filter has been updated on the layer.
     */
    private volatile boolean updatingSelection=false;

    /**
     * Indicates that the view is updating the layer's filter because the selection on the table has changed.
     */
    protected volatile boolean updatingLayerFilter;

    private PromoteSelectionAction promoteSelection;

    private Label featuresSelected;

    private Combo attributeCombo;

    private IAction zoom;
    private IAction deleteAction;

  private Button selectAllCheck;

  private Text searchWidget;

    private AOIListener aoiServiceListener;

    /**
     * Construct <code>SelectView</code>.
     * <p>
     * Don't do setup here - there is an init method you can override that has
     * access to configuration and stuff.
     * </p>
     */
    public TableView() {
        super();
    }
   
    @Override
    public void createPartControl( Composite parent ) {
        active=true;
               
        featuresSelected = new Label(parent, SWT.NONE);
        featuresSelected.setText(Messages.TableView_featureSelected+0);
       
        attributeCombo=new Combo(parent, SWT.DROP_DOWN|SWT.READ_ONLY);
        attributeCombo.setItems(new String[]{ANY, CQL});
        attributeCombo.select(0);
        attributeCombo.setEnabled(false);
       
        SearchBox search = new SearchBox();
        searchWidget = search.createPart(parent);

        IProvider<IProgressMonitor> provider = new IProvider<IProgressMonitor>(){
       
            public IProgressMonitor get(Object... params) {
                IStatusLineManager statusLineManager = getViewSite().getActionBars().getStatusLineManager();
                statusLineManager.setCancelEnabled(true);
                return statusLineManager.getProgressMonitor();
            }
           
        };
       
        // Select All Button
        selectAllCheck=new Button(parent, SWT.CHECK);
        selectAllCheck.setText(Messages.TableView_allCheckText);
        selectAllCheck.setToolTipText(Messages.TableView_allToolTip);
        selectAllCheck.setEnabled(false);
        selectAllCheck.setSelection(true);
       
        table = new FeatureTableControl(provider);       
        table.createTableControl( parent );
        table.setSelectionColor(new IProvider<RGB>(){

            public RGB get(Object... params) {
                ScopedPreferenceStore store = ProjectPlugin.getPlugin().getPreferenceStore();
                String key = org.locationtech.udig.project.preferences.PreferenceConstants.P_SELECTION_COLOR;
                RGB color = PreferenceConverter.getColor(store, key);
                return color;
            }
           
        });
       
        IAOIService aOIService = PlatformGIS.getAOIService();
       
        aoiServiceListener = new AOIListener(){
            @Override
            public void handleEvent( Event event ) {
                if(isAOIFilter()){
                    reloadFeatures(layer);
                }
            }           
        };
       
        aOIService.addListener(aoiServiceListener);
       
        table.addLoadingListener(new IFeatureTableLoadingListener(){

            public void loadingStarted( IProgressMonitor monitor ) {
                searchWidget.setEnabled(false);
                selectAllCheck.setEnabled(false);
                attributeCombo.setEnabled(false);
            }

            public void loadingStopped( boolean canceled ) {
                searchWidget.setEnabled(true);
                selectAllCheck.setEnabled(true);
                attributeCombo.setEnabled(true);
            }
           
        });
        layoutComponents(parent);
       
        // Create menu and toolbars
        createActions();
        createMenu();
        createToolbar();
        hookGlobalActions();
        createContextMenu();
       
        // restore state (from previous session)
       
        page = getSite().getPage();
       
        if( page.getActiveEditor() instanceof MapPart ){           
            editorActivated( (MapPart) page.getActiveEditor() );
        }
       
        addTableSelectionListener();
        addWorkbenchSelectionListener();
        addPageListener();       
       
        //provide workbench selections
        getSite().setSelectionProvider( this );

        ApplicationGIS.getToolManager().registerActionsWithPart(this);

    }
   
    public boolean isAOIFilter() {
        return aoiFilter;
    }

    public void setAOIFilter( boolean aoiFilter ) {
        this.aoiFilter = aoiFilter;
        reloadFeatures(layer);
    }


    private void addTableSelectionListener() {
        table.addSelectionChangedListener(new ISelectionChangedListener(){

            public void selectionChanged( SelectionChangedEvent event ) {
                if( event.getSource()==table)
                    featuresSelected.setText(Messages.TableView_featureSelected+table.getSelectionCount());
                if( updatingSelection ){
                  updatingSelection=false;
                    return;
                }
               
                ISelection selection = getSelection();
                if( selection.isEmpty() ){
                    updateLayerFilter((Filter)Filter.EXCLUDE);
                }else if( selection instanceof IStructuredSelection ){
                    IStructuredSelection structuredSelection = (IStructuredSelection) selection;
                    Filter firstElement = (Filter) structuredSelection.getFirstElement();
                    updateLayerFilter(firstElement);
                }
                //TODO Sprint Mauricio Aritz: The next line provoke the SelectionTool cannot execute the commit operation (acceptChangeBehaviour line 109).
                // Actually we do not understand the purpose of this line, but it is the source of problem. 
                //layer.getMapInternal().getEditManagerInternal().setEditFeature(null, null);
               
                fireSelectionChanged();
            }
        });
    }

    private void updateLayerFilter( Filter filter ) {
        updatingLayerFilter=true;
        MapCommand createSelectCommand = SelectionCommandFactory.getInstance().createSelectCommand(layer, filter);
        layer.getMap().sendCommandSync(createSelectCommand);
        updatingLayerFilter=false;

        setZoomToSelectionToolEnablement();
    }
   
    private void layoutComponents( Composite parent ) {
        FormLayout layout = new FormLayout();
        layout.marginHeight = 0;
        layout.marginWidth = 0;
        layout.spacing = 0;
        parent.setLayout(layout);
       
        FormData dLabel = new FormData(); // bind to left & text
        dLabel.left = new FormAttachment(0,5);
        dLabel.top = new FormAttachment(attributeCombo,2);
        dLabel.right = new FormAttachment(100,-5);
        featuresSelected.setLayoutData(dLabel);
       
        FormData dCombo = new FormData(); // bind to label and text
        dCombo.left = new FormAttachment(0,5);
        dCombo.top = new FormAttachment(0);
        dCombo.right = new FormAttachment(30, -5);
        attributeCombo.setLayoutData(dCombo);
       
        FormData dText = new FormData(); // bind to label and text
        dText.left = new FormAttachment(attributeCombo);
        dText.top = new FormAttachment(0);
        dText.right = new FormAttachment(95,-5);
        searchWidget.setLayoutData(dText);
       
        FormData dCheck = new FormData(); // bind to top, label, bbox
        dCheck.top = new FormAttachment(2);
        dCheck.left = new FormAttachment(searchWidget, 5);
        dCheck.right = new FormAttachment( 100,-5);
        selectAllCheck.setLayoutData(dCheck);
       
        FormData dContents = new FormData(100, 100); // text & bottom
        dContents.right = new FormAttachment(100); // bind to right of form
        dContents.left = new FormAttachment(0); // bind to left of form
        dContents.top = new FormAttachment(featuresSelected, 2); // attach with 2 pixel offset
        dContents.bottom = new FormAttachment(100); // bind to bottom of form       
        table.getControl().setLayoutData(dContents);
    }

    /**
     * Adds a post selection listener that listens to the workbench's selection for maps, layers or MapEditor.
     */
    private void addWorkbenchSelectionListener() {
        // page.addPostSelectionListener(workbenchSelectionListener);       
        ISelectionService selectionService = getSite().getWorkbenchWindow().getSelectionService();
        selectionService.addPostSelectionListener(workbenchSelectionListener);
    }

    /**
     * Adds a listener to {@link #page} that deactivates the view when part is hidden and reactivates it when it is made
     * visible.  This is to prevent a bunch of featurestore accesses when view is not visible.
     */
    private void addPageListener( ) {
        activePartListener = new IPartListener2(){
            public void partActivated( IWorkbenchPartReference partRef ) {
            }
            public void partBroughtToTop( IWorkbenchPartReference partRef ) {
            }
            public void partClosed( IWorkbenchPartReference partRef ) {
            }
            public void partDeactivated( IWorkbenchPartReference partRef ) {
            }
            public void partOpened( IWorkbenchPartReference partRef ) {
            }
            public void partHidden( IWorkbenchPartReference partRef ) {
                if (partRef.getPart(false) == TableView.this)
                    deactivate();
            }
            public void partVisible( IWorkbenchPartReference partRef ) {
                if (partRef.getPart(false) == TableView.this)
                    activate();
            }
            public void partInputChanged( IWorkbenchPartReference partRef ) {
            }
        };
        // listen for editor changes
        page.addPartListener(activePartListener);
    }

    protected void activate() {
        if( active )
            return;
       
        PlatformGIS.run(new ISafeRunnable(){

            public void handleException( Throwable exception ) {
                SelectPlugin.log("error activating table", exception); //$NON-NLS-1$
            }

            public void run() throws Exception {
                active=true;
                if( reloadNeeded )
                    reloadFeatures(layer);
                if( !updates.isEmpty() )
                    updateTable(layer);
                if ( filterChange )
                    updateSelection(layer);
            }
           
        });
    }

    protected void deactivate() {
        active=false;
    }

    private void hookGlobalActions() {
        ApplicationGIS.getToolManager().contributeGlobalActions(this, getViewSite().getActionBars());
        IKeyBindingService service = getSite().getKeyBindingService();
        IAction action = deleteAction;
        getViewSite().getActionBars().setGlobalActionHandler(ActionFactory.DELETE.getId(), action);
        service.registerAction(action);
       

    }

    /**
     * Create actions, linking view to current map.
     */
    private void createActions() {
        select=ApplicationGIS.getToolManager().createToolAction(BBoxSelection.ID, ToolsConstants.SELECTION_CATEGORY);
        ImageDescriptor icon = AbstractUIPlugin.imageDescriptorFromPlugin( SelectPlugin.ID, "icons/eview16/select_view.gif"); //$NON-NLS-1$
        select.setImageDescriptor( icon );
       
        this.promoteSelection=new PromoteSelectionAction();
       
        zoom=((ToolManager) ApplicationGIS.getToolManager()).createToolAction(ZoomSelection.ID, ToolsConstants.ZOOM_CATEGORY);
        icon = AbstractUIPlugin.imageDescriptorFromPlugin( SelectPlugin.ID, "icons/elcl16/zoom_select_co.png"); //$NON-NLS-1$
        zoom.setImageDescriptor( icon );
        zoom.setText(Messages.TableView_zoomToolText);
        zoom.setToolTipText(Messages.TableView_zoomToolToolTip);
       
        deleteAction = new DeleteAction();
    }

    /* Called when a Layer is selected - will need to check if we care */
    void layerSelected( ILayer selected ){
        if( layer == selected ) {
            return; // we already know
        }       
        if( layer!=null ){
            layer.removeListener(layerListener);
            if( layer.getMap()!=null ){
                layer.getMap().removeMapCompositionListener(compositionListener);
                layer.getMap().getEditManager().removeListener(editManagerListener);
            }
        }
       
        if( selected==null || !selected.hasResource( FeatureSource.class ) || selected.getMap()==null ){
            if( currentEditor!=null ){
                currentEditor.getMap().getEditManager().addListener(editManagerListener);
            }
            layer = null;
            filterChange=false;
            reloadNeeded=false;
            table.getControl().getDisplay().asyncExec(new Runnable(){
                public void run() {
                    table.clear();
                    table.message(Messages.TableView_noFeatureWarning );
                }
            });
            return;
        }
       
        layer = (Layer) selected; 
        layer.addListener(layerListener);
        layer.getMap().addMapCompositionListener(compositionListener);
        layer.getMap().getEditManager().addListener(editManagerListener);

        if( !active ){
            filterChange=true;
            reloadNeeded=true;
            return;
        }
       
        setZoomToSelectionToolEnablement();
        reloadFeatures(layer);
        updateSelection(layer);
    }

    private void setZoomToSelectionToolEnablement() {
        final boolean enabled;
       
        if( layer.getMap()==ApplicationGIS.getActiveMap() && layer.getFilter()!=Filter.EXCLUDE )
            enabled=true;
        else
            enabled=false;
       
        table.getControl().getDisplay().asyncExec(new Runnable(){
            public void run() {
                zoom.setEnabled(enabled);
            }
        });
    }
   
    /**
     * The list of updates that have occurred but have not yet been applied to the FeatureTable
     */
    private List<FeatureEvent> updates=Collections.synchronizedList(new ArrayList<FeatureEvent>());
   
    /**
     * Listener that watches the current layer; and will update the table selection to match
     */
    private ILayerListener layerListener = new ILayerListener(){

        public void refresh( LayerEvent event ) {
            final ILayer notifierLayer = event.getSource();
            assert layer == notifierLayer;
           
            switch( event.getType() ) {
            case EDIT_EVENT:
                if (!editing) {
                    if (event.getNewValue() == null) {
                        // there are now bounds associated with this event so we are going to have to reload everyone!
                        reloadFeatures(notifierLayer);
                        return;
                    }
                    // okay we will add these bounds to the list of "updates" and updateTable can fetch everything
                    // when we are back to being "active"
                    updates.add((FeatureEvent) event.getNewValue());
                    if (active) {
                        updateTable(notifierLayer);
                    }
                }
                break;
            case FILTER:
                if (active) {
                    updateSelection(notifierLayer);
                } else {
                    filterChange = true;
                }
                break;
            }

        }

    };
   
    private IMapCompositionListener compositionListener=new IMapCompositionListener(){

        public void changed( MapCompositionEvent event ) {

            if( event.getType()==MapCompositionEvent.EventType.REMOVED ){
                if( event.getLayer()==layer ){
                    layerSelected(null);
                }
            }else if( event.getType()==MapCompositionEvent.EventType.MANY_REMOVED ){
                if( ((List<?>)event.getNewValue()).contains(layer) )
                    layerSelected(null);
            }
        }
       
    };

    private IEditManagerListener editManagerListener=new IEditManagerListener(){

        public void changed( EditManagerEvent event ) {
            assert layer==null || (layer!=null && layer.getMap()==event.getSource().getMap());

            switch( event.getType() ) {
            case EditManagerEvent.POST_COMMIT:
            case EditManagerEvent.POST_ROLLBACK:
                if( !active ){
                    reloadNeeded=true;
                    return;
                }
                reloadFeatures(layer);
                break;
            case EditManagerEvent.SELECTED_LAYER:
                layerSelected((ILayer) event.getNewValue());
                break;
            default:
                break;
            }
        }
       
    };
    private Set<ISelectionChangedListener> selectionChangeListeners=new CopyOnWriteArraySet<ISelectionChangedListener>();
   
    private IToolContext currentContext;

    /**
     * Watch current editor to indicate current selectable layers.
     *
     * @param editor
     */
    protected void editorActivated( MapPart editor ) {
        if( currentEditor == editor ) return;
       
        currentEditor=editor;
        if( editor == null ){
            select.setEnabled(false);
            table.clear();
            table.update();
            return;
        }
       
        Map map = currentEditor.getMap();
        final ILayer selectedLayer = map.getEditManager().getSelectedLayer();
        // layerSelecte returns if layer==newLayer.  If both are null we still want to listen to map for a
        // layer being added (and selected).
        if( selectedLayer==null && layer == null ){
            map.getEditManager().addListener(editManagerListener);
            return;
        }
       
        PlatformGIS.run(new ISafeRunnable(){

            public void handleException( Throwable exception ) {
                SelectPlugin.log("error selecting layer", exception); //$NON-NLS-1$
            }

            public void run() throws Exception {
                layerSelected(selectedLayer);
            }
           
        });
        if( selectedLayer!=null )
            select.setEnabled(true);
    }

    private void createToolbar() {
        IToolBarManager toolbar = getViewSite().getActionBars().getToolBarManager();               
        toolbar.add( select );            
        toolbar.add( zoom );
        toolbar.add( promoteSelection );
    }
   
    private void createContextMenu() {
        contextMenu = new MenuManager();

        contextMenu.setRemoveAllWhenShown(true);
        contextMenu.addMenuListener(new IMenuListener() {
           
            public void menuAboutToShow(IMenuManager mgr) {
                contextMenu.add(deleteAction);
                contextMenu.add(zoom);
                contextMenu.add(promoteSelection);
                contextMenu.add(new GroupMarker(
                        IWorkbenchActionConstants.MB_ADDITIONS));
                contextMenu.add(ApplicationGIS.getToolManager().createOperationsContextMenu(getSelection()));
                contextMenu.add(ActionFactory.EXPORT.create(getSite().getWorkbenchWindow()));
            }

        });

        // Create menu.
        table.setMenuManager(contextMenu);
        getSite().registerContextMenu(contextMenu, this);
    }

    private void createMenu() {
        // create view menu, consider sync
    }

    @Override
    public void setFocus() {
        hookGlobalActions();
        // select your "main" control
        if(table.getControl()!=null)
            table.getControl().setFocus();
    }
   
    @Override
    public void dispose() {
        if( table!=null)
            table.dispose();
       
        if( aoiServiceListener!=null){
            IAOIService aOIService = PlatformGIS.getAOIService();
            aOIService.removeListener(aoiServiceListener);
        }
       
        super.dispose();
        if( activePartListener!=null )
            page.removePartListener(activePartListener);
        if( workbenchSelectionListener!=null ){
            ISelectionService selectionService = getSite().getWorkbenchWindow().getSelectionService();
            selectionService.removePostSelectionListener(workbenchSelectionListener);
        }
        if( layer!=null && layerListener!=null )
            layer.removeListener(layerListener);
        table = null;
        activePartListener = null;
        workbenchSelectionListener = null;
        layer = null;
        layerListener = null;
    }

    protected void updateSelection( final ILayer notifierLayer ) {
        if (!active) {
            filterChange = true;
            return;
        }
        if (updatingLayerFilter) {
            return; // our own table view is updating the selection (so we can ignore this
                    // notification)
        }

        try {
            final FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = notifierLayer
                    .getResource(FeatureSource.class, null);
            filterChange = false;
            Display.getDefault().asyncExec(new Runnable(){
                public void run() {
                    updatingSelection = true;
                    if (updatingLayerFilter){
                        return; // we are updating table so please ignore this one
                    }
                    Filter filter = (Filter) notifierLayer.getFilter();
                    if (filter == Filter.EXCLUDE) {
                        table.setSelection(new StructuredSelection());
                        return;
                    }
                    AdaptingFilter adaptingFilter = AdaptingFilterFactory
                            .createAdaptingFilter(filter);
                    adaptingFilter.addAdapter(featureSource);

                    StructuredSelection selection = new StructuredSelection(adaptingFilter);
                    table.setSelection(selection);
                }
            });
        } catch (IOException e) {
            SelectPlugin.log("", e); //$NON-NLS-1$
        }
    }
    protected void updateTable( final ILayer notifierLayer ) {
        try{
            // Envelope indicating the bounds of the added features from all the updates currently available in the
            // updates field;
            Envelope addedBounds = null;
            // Envelope indicating the bounds of the modified features from all the updates currently available in the
            // updates field;
            Envelope modifiedBounds = null;
           
            synchronized (updates) {
                for( FeatureEvent event : updates ) {
                    Envelope bounds = event.getBounds();
                    switch( event.getEventType() ) {
                    case FeatureEvent.FEATURES_ADDED:
                        if( bounds != null ){
                            if( addedBounds==null ){
                                addedBounds=new Envelope(bounds);
                            }else{
                                addedBounds.expandToInclude(bounds);
                            }
                        }
                        break;
                    case FeatureEvent.FEATURES_REMOVED:
                        // With current Event API there is no way to know what was removed
                        reloadNeeded=true;
                        if( active )
                            reloadFeatures(notifierLayer);
                        return;
                       
                    case FeatureEvent.FEATURES_CHANGED:
                        if (event.getBounds() == null) {
                            return;
                        }
                        if (modifiedBounds == null) {
                            modifiedBounds = new Envelope(bounds);
                        } else {
                            modifiedBounds.expandToInclude(bounds);
                        }
                        break;

                    default:
                        break;
                    }
                }
                updates.clear();
            }
            // check if we actually go something out of all that
            if( addedBounds == null && modifiedBounds == null){
                // fine we did not get anything we will need to reload
                if( active ){
                    reloadFeatures(notifierLayer);
                }else{
                    reloadNeeded=true;
                }
                return;
            }
            // okay now we will do a query for everything in the added or modified bounds
            FeatureSource<SimpleFeatureType, SimpleFeature> source = notifierLayer.getResource(FeatureSource.class, ProgressManager.instance().get());
            SimpleFeatureType schema=source.getSchema();
           
            FilterFactory fac=CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints());
            final List<String> queryAtts = obtainQueryAttributesForFeatureTable(schema);
            final DefaultQuery query=new DefaultQuery(schema.getName().getLocalPart(), Filter.EXCLUDE, queryAtts.toArray(new String[0]));

            String name = schema.getGeometryDescriptor().getName().getLocalPart();
      // add new features
            if( addedBounds!=null ){
              double minx=addedBounds.getMinX();
        double miny=addedBounds.getMinY();
        double maxx=addedBounds.getMaxX();
        double maxy=addedBounds.getMaxY();
        String srs=CRS.lookupIdentifier(schema.getCoordinateReferenceSystem(), false);
        BBOX bboxFilter = fac.bbox(name, minx, miny, maxx, maxy, srs);
       
                query.setFilter(bboxFilter);
                FeatureCollection<SimpleFeatureType, SimpleFeature>  features = source.getFeatures(query);
                this.table.update(features);
            }
            // update modified features
            if( modifiedBounds!=null ){
              double minx=modifiedBounds.getMinX();
        double miny=modifiedBounds.getMinY();
        double maxx=modifiedBounds.getMaxX();
        double maxy=modifiedBounds.getMaxY();
        String srs=CRS.lookupIdentifier(schema.getCoordinateReferenceSystem(), false);
        BBOX bboxFilter = fac.bbox(name, minx, miny, maxx, maxy, srs);

                query.setFilter(bboxFilter);
                FeatureCollection<SimpleFeatureType, SimpleFeature>  features = source.getFeatures(query);
                this.table.update(features);
            }       
        } catch (IOException e) {
            if( active ){
                reloadFeatures(notifierLayer);
            }else{
                reloadNeeded=true;
            }               
        } catch (IllegalFilterException e) {
            if( active ){
                reloadFeatures(notifierLayer);
            }else{
                reloadNeeded=true;
            }
        } catch (FactoryException e) {
            if( active ){
                reloadFeatures(notifierLayer);
            }else{
                reloadNeeded=true;
            }
        }
    }
   
    private Filter addAOIFilter(Filter filter, CoordinateReferenceSystem dataCRS){
        IAOIService aOIService = PlatformGIS.getAOIService();
        Geometry geometry = aOIService.getGeometry();
       
        if(aOIService.getExtent() == null)
            return filter;
       
        if(geometry == null){
            // note we could make a BBOX query here and go faster
            geometry = JTS.toGeometry( aOIService.getExtent());
            if(geometry == null){
                return filter; // no change!
            }
        }
        CoordinateReferenceSystem aoiCRS = aOIService.getCrs();
        if( aoiCRS != null && !CRS.equalsIgnoreMetadata(aoiCRS, dataCRS )){
            try {
                MathTransform transform = CRS.findMathTransform( aoiCRS, dataCRS);
                geometry = JTS.transform(geometry, transform);
            }
            catch( TransformException outOfBounds ){
                return filter; // unable to use this bounds
            } catch (FactoryException notSupported) {
                return filter; // unable to use this bounds
            }
        }
       
        FilterFactory2 ff = (FilterFactory2) CommonFactoryFinder.getFilterFactory(null);
       
        String geomProperty = layer.getSchema().getGeometryDescriptor().getLocalName();
        Filter aoiFilter = ff.intersects(ff.property(geomProperty), ff.literal(geometry));
       
        return ff.and(aoiFilter, filter );
    }

    protected void reloadFeatures( final ILayer notifierLayer ) {
       
       
       
        try {
        reloadNeeded = false;  
        updates.clear();
       
//        icon = getLayerIcon()
        final FeatureTypeCellModifier featureTypeCellModifier = new FeatureTypeCellModifier(notifierLayer){
            @Override
            public Object getValue( Object element, String property ) {
                ApplicationGIS.getToolManager().unregisterActions(TableView.this);

                return super.getValue(element, property);
            }
            @Override
            protected void makeModification( SimpleFeature feature, ILayer layer, String property, Object value, Item item ) {
                if( value == null ){
                    // not a valid entry.
                    return;
                }
                TableItem tableItem=(TableItem) item;
                Schema schema = new Schema();
                int columnIndex = schema.getIndexOf( feature.getFeatureType(), property );
                tableItem.setText(columnIndex+1, value.toString());
               
                UndoableComposite composite = new UndoableComposite();
                composite.getCommands().add(new SetEditingFlag(true));
               
                composite.getCommands().add(
                        EditCommandFactory.getInstance().createSetAttributeCommand(feature, layer, property, value));
                composite.getFinalizerCommands().add(new SetEditingFlag(false));
                layer.getMap().sendCommandASync(composite);
            }
        };
       
        final SimpleFeatureType schema = notifierLayer.getSchema();
        Filter filter = Filter.INCLUDE;
        final  FeatureSource<SimpleFeatureType, SimpleFeature> featureSource = notifierLayer.getResource(FeatureSource.class, null);
        final List<String> queryAtts = obtainQueryAttributesForFeatureTable(schema);

        //if the filter action is true, filter our results by the AOI service
        if(isAOIFilter()){
            filter = addAOIFilter(filter, schema.getCoordinateReferenceSystem());
        }
        final Query query = new DefaultQuery(schema.getName().getLocalPart(), filter, queryAtts.toArray(new String[0]));
        FeatureCollection<SimpleFeatureType, SimpleFeature>  featuresF = featureSource.getFeatures(query);       
        final FeatureCollection<SimpleFeatureType, SimpleFeature>  features = featuresF;
       
        Display.getDefault().asyncExec(new Runnable(){
            public void run() {
                    if (!table.showWarning(table.getControl().getDisplay())){
                        //user doesn't want to show table.
                        return;
                    }

                    // we don't need to display the geometries, that's what the map is for.
                    queryAtts.add(0,ANY);
                    queryAtts.add(CQL);
                    attributeCombo.setItems(queryAtts.toArray(new String[0]));                   
                    attributeCombo.select(0);
                   
                    AdaptableFeatureCollection adaptableCollection = new AdaptableFeatureCollection(features);
                    adaptableCollection.addAdapter(featureSource); // used to listen for changes

                    if( featureSource instanceof FeatureStore )
                        enableEditing(featureTypeCellModifier, query, adaptableCollection);

                    table.setFeatures(adaptableCollection);
            }

            private void enableEditing( final FeatureTypeCellModifier featureTypeCellModifier, final Query query, AdaptableFeatureCollection adaptableCollection ) {
                adaptableCollection.addAdapter(featureTypeCellModifier);
                ICellEditorListener[] keyBindingActivators=new ICellEditorListener[query.getPropertyNames().length];
                for( int i = 0; i < keyBindingActivators.length; i++ ) {
                    keyBindingActivators[i]=new ICellEditorListener(){
                        public void applyEditorValue() {
                            ApplicationGIS.getToolManager().registerActionsWithPart(TableView.this);
                        }

                        public void cancelEditor() {
                            applyEditorValue();
                        }

                        public void editorValueChanged( boolean oldValidState, boolean newValidState ) {

                        }
                       
                    };
                }
                adaptableCollection.addAdapter(keyBindingActivators);
            }
        }
          );
        } catch (final IOException e) {
            Display.getDefault().asyncExec(new Runnable(){
                public void run() {
                    table.message(e.getMessage());
                }
            });
        }
    }

   

    private List<String> obtainQueryAttributesForFeatureTable( final SimpleFeatureType schema ) {
        final List<String> queryAtts=new ArrayList<String>();
       
        for( int i = 0; i < schema.getAttributeCount(); i++ ) {
            AttributeDescriptor attr = schema.getDescriptor(i);
            if( !(attr instanceof GeometryDescriptor) ){
                queryAtts.add(attr.getName().getLocalPart());
            }
        }
        return queryAtts;
    }

    public void addSelectionChangedListener( ISelectionChangedListener listener ) {
        selectionChangeListeners.add(listener);
    }

    public ISelection getSelection() {
        Id firstElement=getFilter();
        if( firstElement ==null ){
            return new StructuredSelection();
        }
        AdaptingFilter filter = AdaptingFilterFactory.createAdaptingFilter(firstElement, layer);
        if (layer.getGeoResource().canResolve(FeatureSource.class)) {
            try {
                FeatureSource<?,?> resolve = layer.getGeoResource().resolve(FeatureSource.class, null);
                FeatureCollection<?,?> features = resolve.getFeatures(filter);
                filter.addAdapter(features);
            } catch (IOException e) {
                // TODO Handle IOException
                throw (RuntimeException) new RuntimeException( ).initCause( e );
            }
        }
        return new StructuredSelection( filter );
    }

    private Id getFilter() {
        IStructuredSelection selection=(IStructuredSelection) table.getSelection();
        if( selection.isEmpty() )
            return null;
       
        Id firstElement = (Id) selection.getFirstElement();
        return firstElement;
    }

    public void removeSelectionChangedListener( ISelectionChangedListener listener ) {
        selectionChangeListeners.remove(listener);
    }
    protected void fireSelectionChanged(){
        final SelectionChangedEvent event = new SelectionChangedEvent(this, getSelection());
        for( ISelectionChangedListener listener : selectionChangeListeners ){
            final ISelectionChangedListener l = listener;
            SafeRunnable.run(new SafeRunnable() {
                public void run() {
                    l.selectionChanged(event);
                }
            });
        }
    }
    public void setSelection( ISelection selection ) {
        table.setSelection(selection);
    }
   
  private class PromoteSelectionAction extends Action{
       
        public PromoteSelectionAction() {
            setText(Messages.TableView_promote_text);
            setToolTipText(Messages.TableView_promote_tooltip);
            setImageDescriptor(AbstractUIPlugin.imageDescriptorFromPlugin(SelectPlugin.ID, "icons/elcl16/promote_selection_co.gif")); //$NON-NLS-1$
        }
       
        @Override
        public void run() {
            table.promoteSelection();
        }
       
    }
    /**
     * Delete Action used to delete the currently selected feature.
     */
    private class DeleteAction extends Action{
        public DeleteAction(){
            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() {
            IStructuredSelection selection = ((IStructuredSelection)table.getSelection());
            if( selection == null || selection.isEmpty() || table.getSelectionCount()==0 )
                return;
           
            Id filter=(Id) selection.getFirstElement();

            CompositeCommand composite;
            if( table.getSelectionCount()==1 ){
                composite = deleteFeature();
            }else{
                composite = deleteManyFeatures(filter);
            }
           
            layer.getMap().sendCommandASync(composite);
        }

        private CompositeCommand deleteFeature( ) {
            CompositeCommand composite=new CompositeCommand();
            composite.setName(Messages.TableView_compositeName);
            composite.getCommands().add(new SetEditingFlag(true));
            DeleteFromTableCommand deleteFromTableCommand = new DeleteFromTableCommand(layer);
            composite.getCommands().add(deleteFromTableCommand);
            IBlockingProvider<ILayer> layerProvider=new StaticBlockingProvider<ILayer>(layer);
            composite.getCommands().add(new DeleteFeatureCommand(deleteFromTableCommand, layerProvider));
            composite.getFinalizerCommands().add(new SetEditingFlag(false));
            return composite;
        }
        private CompositeCommand deleteManyFeatures( Id filter ) {
            CompositeCommand composite=new CompositeCommand();
            composite.setName(Messages.TableView_compositeName);
            composite.getCommands().add(new SetEditingFlag(true));
            composite.getCommands().add(new DeleteManyFeaturesCommand(layer,filter));
            composite.getCommands().add(new DeleteFromTableCommand(layer));
            composite.getFinalizerCommands().add(new SetEditingFlag(false));
            return composite;
        }
    }
    private class DeleteFromTableCommand extends AbstractCommand implements UndoableCommand, IBlockingProvider<SimpleFeature>{

        private FeatureCollection<SimpleFeatureType, SimpleFeature> deletedFeatures;
        private Layer layer;

        public DeleteFromTableCommand( Layer layer ) {
            this.layer=layer;
        }

        public void rollback( IProgressMonitor monitor ) throws Exception {
            table.update(deletedFeatures);
        }

        public String getName() {
            return Messages.TableView_deleteCommandName;
        }

        public void run( IProgressMonitor monitor ) throws Exception {
            deletedFeatures=table.deleteSelection();
        }

        public SimpleFeature get( IProgressMonitor monitor, Object... params ) throws IOException {

            IBlockingProvider<ILayer> layerProvider=new StaticBlockingProvider<ILayer>(layer);
            String featureID = deletedFeatures.features().next().getID();
            IBlockingProvider<SimpleFeature> featureProvider=new FIDFeatureProvider(featureID, layerProvider);

            return featureProvider.get(monitor);
        }
       
    }
   
    private class SetEditingFlag extends AbstractCommand implements UndoableCommand{
        boolean oldState;
        final boolean newState;
        public SetEditingFlag(boolean newState){
            this.newState=newState;
        }
        public void rollback( IProgressMonitor monitor ) throws Exception {
            editing=oldState;
        }

        public String getName() {
            return "Set Editing Flag"; //$NON-NLS-1$
        }

        public void run( IProgressMonitor monitor ) throws Exception {
            oldState=editing;
            editing=newState;
        }
       
    }

    public void editFeatureChanged( SimpleFeature feature ) {
        if (feature == null ){
           return;
        }
        if( getContext().getEditManager().getSelectedLayer()!=layer || updatingLayerFilter )
            return;

        if( table.getSelectionCount()==1 && getFilter().getIDs().toArray(new String[0])[0].equals(feature.getID()) )
            return;
       
        updatingLayerFilter=true;
        try{
            StructuredSelection structuredSelection;
            structuredSelection = new StructuredSelection(feature);
   
            setSelection(structuredSelection);
        }finally{
            updatingLayerFilter=false;
        }
    }

    public IToolContext getContext() {
        return currentContext;
    }

    public void setContext( IToolContext newContext ) {
        this.currentContext=newContext;
    }
   
    private class SearchBox extends AbstractHandler implements Listener{
    private Color systemColor;

    public void handleEvent( Event e ) {
      if( e.keyCode==SWT.CR || e.keyCode==SWT.LF ){
        doSearch();
      }
    }
   
   

    public Text createPart(Composite parent) {
          final Text searchWidget = new Text(parent, SWT.BORDER|SWT.SEARCH|SWT.CANCEL );
          searchWidget.setEnabled(false);
         
          systemColor = searchWidget.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY);
         
          searchWidget.setText(INITIAL_TEXT);
          searchWidget.setForeground(systemColor);
          searchWidget.setEditable(true);
          searchWidget.addListener(SWT.FocusIn, new Listener(){
              public void handleEvent( Event e ) {
                    if( searchWidget.getForeground().equals(systemColor) ){
                        searchWidget.setForeground(e.display.getSystemColor(SWT.COLOR_BLACK));
                        searchWidget.setText(""); //$NON-NLS-1$
                    }
          ApplicationGIS.getToolManager().unregisterActions(TableView.this);
              }
          });
          searchWidget.addListener(SWT.FocusOut, new Listener(){
              public void handleEvent( Event e ) {
                      if( !searchWidget.getForeground().equals(systemColor) && searchWidget.getText().trim().length()==0 ){
                          searchWidget.setForeground(systemColor);
                          searchWidget.setText(""); //$NON-NLS-1$
                      }
                      ApplicationGIS.getToolManager().registerActionsWithPart(TableView.this);
              }
          });
      searchWidget.addListener(SWT.KeyUp, this)
      return searchWidget;
    }
   

    public Object execute(ExecutionEvent arg0) throws ExecutionException {
      doSearch();
      return null;
    }

    @SuppressWarnings("unchecked")
        private void doSearch() {
      if (searchWidget.getText().trim().length()==0 ){
            searchWidget.setText(INITIAL_TEXT);
            searchWidget.setForeground(systemColor);
        }
       
        String[] attsToSearch;
        String item = attributeCombo.getItem(attributeCombo.getSelectionIndex());
        boolean selectAll=selectAllCheck.getSelection();               
        if( item.equals(CQL) ){
            try {
                String txt = searchWidget.getText().trim();
                //table.select( txt, selectAll);
                    //searchWidget.setToolTipText(null);
                    Filter filter = (Filter) org.geotools.filter.text.cql2.CQL.toFilter( txt );
                    //updateLayerFilter( filter );
                   
                    FeatureSource<SimpleFeatureType, SimpleFeature> source = layer.getResource(FeatureSource.class, ProgressManager.instance().get());
                    SimpleFeatureType schema=source.getSchema();              
                    //FilterFactory fac=CommonFactoryFinder.getFilterFactory(GeoTools.getDefaultHints());
                    //final List<String> queryAtts = obtainQueryAttributesForFeatureTable(schema);
                   
                    Set<String> required = (Set<String>) filter.accept( new FilterAttributeExtractor(), null );
                    String[] names = required.toArray( new String[ required.size()]);
                    final DefaultQuery query=new DefaultQuery(schema.getName().getLocalPart(), filter, names );
                   
                    FeatureCollection<SimpleFeatureType, SimpleFeature> features;
                    features = source.getFeatures( query ); // we just want the FeatureID no attributes needed
                   
                    //features = source.getFeatures( filter );
                   
                    final Set<FeatureId> selection = new HashSet<FeatureId>();
                    features.accepts( new FeatureVisitor(){
                        public void visit( Feature feature) {
                            // we are using FeatureId to allow for a "temporary" FID when inserting content
                            // (a real FID is not assigned until commit)
                            //
                            FeatureId identifier = feature.getIdentifier();
                            selection.add( identifier );
                        }                       
                    }, null );
                    table.select( selection );
                } catch (Exception e ){
                    Status status = new Status(Status.WARNING, "org.locationtech.udig.ui", e.getLocalizedMessage(), e );
                    UIPlugin.getDefault().getLog().log( status );
                    searchWidget.setToolTipText( e.getLocalizedMessage() );
                }
        }
        else {
            if( item.equals(ANY) ){
                attsToSearch=FeatureTableControl.ALL;
            }
            else{
                attsToSearch=new String[]{item};
            }                   
            table.select(searchWidget.getText().trim(), attsToSearch, selectAll);
        }
    }
     
    }
   
}
TOP

Related Classes of org.locationtech.udig.tool.select.TableView$PromoteSelectionAction

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.