Package org.locationtech.udig.ui.filter

Source Code of org.locationtech.udig.ui.filter.SpinnerExpressionViewer

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

import net.miginfocom.swt.MigLayout;

import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Spinner;
import org.eclipse.swt.widgets.Text;
import org.geotools.factory.CommonFactoryFinder;
import org.geotools.filter.text.ecql.ECQL;
import org.opengis.feature.simple.SimpleFeatureType;
import org.opengis.feature.type.AttributeDescriptor;
import org.opengis.feature.type.PropertyDescriptor;
import org.opengis.filter.FilterFactory2;
import org.opengis.filter.expression.Expression;
import org.opengis.filter.expression.Literal;
import org.opengis.filter.expression.PropertyName;

/**
* ExpressionViewer compatible with how Opacity is handled in the advanced style pages.
* <p>
* The original has as spinner (from 0 to 100%) followed by an Combo to choose a PropertyName.
* <p>
* This implementation has a spinner which is enabled when a range (0 to 100%) is provided; an
* Attribute combo which is enabled when a schema is provided.
*
* @author Jody Garnett
* @since 1.3.2
*/
public class SpinnerExpressionViewer extends IExpressionViewer {
    /**
     * Used to represent "none" option; should be internationalised
     */
    public static final String NONE = "- none -";

    /**
     * Factory SpinnerExpressionViewer is restricted to working with literal numbers and numeric PropertyName expressions.
     *
     * @author Jody Garnett
     * @since 1.3.2
     */
    public static class Factory extends ExpressionViewerFactory {
        @Override
        public int score(ExpressionInput input, Expression expression) {
            if( input != null ){
                Class<?> binding = input.getBinding();
               
                if( !binding.isAssignableFrom(Double.class)){
                    return Appropriate.NOT_APPROPRIATE.getScore();
                }
            }
            if (expression instanceof Literal) {
                Literal literal = (Literal) expression;
                Double number = literal.evaluate(null, Double.class);
               
                if (number != null) {
                    if (number >= 0 && number <= 1.0) {
                        return Appropriate.APPROPRIATE.getScore();
                    }
                }
            }
            if (expression instanceof PropertyName) {
                PropertyName name = (PropertyName) expression;
                if( input != null && input.getSchema() != null ){
                    SimpleFeatureType schema = input.getSchema();
                    AttributeDescriptor descriptor = schema.getDescriptor(name.getPropertyName());
                    if (descriptor != null) {
                        Class<?> binding = descriptor.getType().getBinding();
                        if (Number.class.isAssignableFrom(binding)) {
                            return Appropriate.APPROPRIATE.getScore();
                        }
                    }
                }
            }
            return Appropriate.INCOMPLETE.getScore();
        }

        @Override
        public IExpressionViewer createViewer(Composite parent, int style) {
            return new SpinnerExpressionViewer(parent, style);
        }
    }

    Composite control;

    protected ComboViewer combo;

    protected Spinner spinner;

    protected Text text;

    private SelectionListener listener = new SelectionListener() {
        @Override
        public void widgetSelected(SelectionEvent e) {
            Expression newExpression = validate();
            internalUpdate(newExpression);
        }
        @Override
        public void widgetDefaultSelected(SelectionEvent e) {
        }
    };

    private ISelectionChangedListener comboListener = new ISelectionChangedListener() {
        public void selectionChanged(SelectionChangedEvent event) {
            Expression newExpression = validate();
            internalUpdate(newExpression);
        }
    };

    public SpinnerExpressionViewer(Composite parent, int style) {
        boolean multiLine = (SWT.MULTI & style) != 0;
        boolean readOnly = (SWT.READ_ONLY & style) != 0;
       
        control = new Composite(parent, SWT.NO_SCROLL){
          @Override
            public void setEnabled(boolean enabled) {
                super.setEnabled(enabled);
                combo.getControl().setEnabled(enabled);
                spinner.setEnabled(enabled);
                text.setEnabled(enabled);
            }
        };
        Label comboLabel=null;
        if( multiLine){
            comboLabel = new Label(control, SWT.NONE);
            comboLabel.setText("Numeric:");
        }
        combo = new ComboViewer(control, SWT.DEFAULT);
        combo.setContentProvider(ArrayContentProvider.getInstance());
        combo.setLabelProvider(new LabelProvider() {
            @Override
            public String getText(Object element) {
                if (element instanceof PropertyDescriptor) {
                    PropertyDescriptor descriptor = (PropertyDescriptor) element;
                    return descriptor.getName().getLocalPart();
                }
                return super.getText(element);
            }
        });
        combo.getControl().setEnabled(false);
       
        Label spinnerLabel=null;
        if( multiLine){
            spinnerLabel = new Label(control, SWT.NONE);
            spinnerLabel.setText("Value:");
        }
        spinner = new Spinner(control, SWT.DEFAULT);
        spinner.setMinimum(0);
        spinner.setMaximum(100);
        spinner.setIncrement(10);
        spinner.setEnabled(false);
       
        Label textLabel=null;
        if( multiLine){
            textLabel = new Label(control, SWT.NONE);
            textLabel.setText("Text:");
        }
        text = new Text(control,SWT.SINGLE | SWT.READ_ONLY | SWT.BORDER | SWT.NO_SCROLL );
        text.setEditable(false);
       
        if( multiLine ){
            control.setLayout(new MigLayout("insets 0","[][][grow]","[]"));
           
            comboLabel.setLayoutData("cell 0 0, alignx trailing");
            combo.getControl().setLayoutData("cell 1 0, width 200:30%:100%,gap related");
           
            spinnerLabel.setLayoutData("cell 0 1, alignx trailing");
            spinner.setLayoutData("cell 1 1, width 200:30%:300%,gap related");
           
            textLabel.setLayoutData("cell 0 2, alignx trailing");
            text.setLayoutData("cell 1 2, grow,width 200:pref:100%,gap related");
        }
        else {
            control.setLayout(new MigLayout("insets 0","flowx",""));
            combo.getControl().setLayoutData("width 200:30%:100%");
            spinner.setLayoutData("width 200:30%:300%,gap unrelated");
            text.setLayoutData("grow,width 200:pref:100%,gap unrelated");
        }
        listen(true);
    }

    private void listen(boolean listen) {
        if( listen){
            spinner.addSelectionListener(listener);
            combo.addSelectionChangedListener(comboListener);
        }
        else {
            spinner.removeSelectionListener(listener);
            combo.removeSelectionChangedListener(comboListener);
        }
    }

    protected Expression validate() {
        if( combo.getControl().isEnabled() &&  !combo.getSelection().isEmpty() ){
            Object selection = ((StructuredSelection)combo.getSelection()).getFirstElement();
            if( selection != NONE ){
                if ( selection instanceof String){
                    String propertyName = (String) selection;
                    FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
                   
                    return ff.property( propertyName );
                }
            }
        }
        if( spinner.isEnabled() ){
            int number = spinner.getSelection();
            FilterFactory2 ff = CommonFactoryFinder.getFilterFactory2();
           
            return ff.literal( ((double)number)/100.0);
        }
        return null;
    }

    @Override
    public Control getControl() {
        return control;
    }
   
    /**
     * Mostly used to update the combo with {@link FilterInput#getNumericPropertyList()} if available.
     */
    @Override
    public void refresh() {
        // combo update if we have numeric attributes
        try {
            listen(false);
            if( input != null ){
                combo.setInput( input.toNumericPropertyList() );
                combo.getControl().setEnabled(true);
            }
            else {
                combo.setInput(null);
                combo.getControl().setEnabled(false);
            }
            // spinner if we have min and max
            if( input != null ){
                Object min = input.getMin();
                Object max = input.getMax();
                if( min instanceof Number && max instanceof Number){
                    int minInt = ((Number)min).intValue();
                    int maxInt = ((Number)max).intValue();
                   
                    spinner.setMinimum(minInt);
                    spinner.setMaximum(maxInt);
                   
                    spinner.setEnabled( true );
                }
                else {
                    spinner.setEnabled(false);
                }
            }
            else {
                spinner.setEnabled(false);
            }
            text.setEnabled(false);
        }
        finally {
            listen(true);
        }

        refreshExpression();
    }
   
    public void refreshExpression() {
        Expression expr = getExpression();
        if (expr instanceof PropertyName) {
            PropertyName property = (PropertyName) expr;
            String name = property.getPropertyName();
            refreshControls(null, name, null);
            feedback();
            return;
        } else if (expr instanceof Literal) {
            Literal literal = (Literal) expr;
            Double percent = literal.evaluate(null, Double.class);
            if (percent != null) {
                refreshControls(percent, null, null);
                feedback();
                return;
            }
        }
        // We cannot display this expression - put up a warning
        String message = ECQL.toCQL(expr);
        refreshControls(null, null, message);
        feedbackReplace( expr );
    }

    protected void refreshControls(final Double number, final String propertyName, final String message) {
        if (control != null && !control.isDisposed()) {
            control.getDisplay().asyncExec(new Runnable() {
                public void run() {
                    if (control == null || control.isDisposed()) {
                        return; // must of been disposed while in the display thread queue
                    }
                    boolean isPercent = input != null && input.isPercent();
                   
                    combo.setInput(input.getNumericPropertyList());

                    if (number != null) {
                        spinner.setEnabled(true);
                        int value;
                        if(isPercent){
                            value = (int) (number * 100.0);
                        }
                        else {
                            value = (int) Math.round( number );
                        }
                        spinner.setSelection(value);
                        if (message == null) {
                            if( isPercent ){
                                text.setText( value +"%");
                            }
                            else {
                                text.setText( String.valueOf(value) );
                            }
                        }
                    } else {
                        spinner.setEnabled(false);
                        spinner.setSelection(0);
                    }
                   
                    if (propertyName != null) {
                        StructuredSelection selection = new StructuredSelection(propertyName);
                        combo.setSelection(selection, true);
                    } else {
                        StructuredSelection selection = new StructuredSelection(NONE);
                        combo.setSelection(selection, true);
                    }
                    if (message != null) {
                        text.setText(message);
                    }
                }
            });
        }
    }

    @Override
    public void setExpression(Expression newExpression) {
        if (!newExpression.equals(this.expression)) {
            this.expression = newExpression;
            refreshExpression();
        }
    }

}
TOP

Related Classes of org.locationtech.udig.ui.filter.SpinnerExpressionViewer

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.