Package org.locationtech.udig.ui.filter

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

/*
*    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 java.util.HashMap;
import java.util.List;

import net.miginfocom.swt.MigLayout;
import org.locationtech.udig.ui.filter.ViewerFactory.Appropriate;

import org.eclipse.jface.action.ContributionItem;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.PopupDialog;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.SelectionAdapter;
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.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.ui.part.PageBook;
import org.opengis.filter.expression.Expression;

/**
* {@link IExpressionViewer} allowing user to switch between implementations.
* <p>
* Note this implementation makes use of {@link ExpressionViewerFactory} when creating each viewer. We ask that
* you remember the "viewerId" in dialog settings or IMento so the user is not forced to choose
* which viewer is displayed each time. You can also use this facility as a hint when configuring
* the viewer for use.
*
* <pre>
* ExpressionViewer viewer = new ExpressionViewer(composite, SWT.MULTI);
* viewer.getControl().setLayoutData("grow, gap unrelated");
* </pre>
*
* You will need to consult the extension point for the list of valid viewerIds.
*
* @author Jody Garnett
* @since 1.3.2
*/
public class ExpressionViewer extends IExpressionViewer {
    /**
     * IExpressionViewer currently displayed in {@link #pageBook}.
     */
    protected IExpressionViewer delegate;

    private ISelectionChangedListener listener = new ISelectionChangedListener() {
        @Override
        public void selectionChanged(SelectionChangedEvent event) {
            internalUpdate(delegate.getExpression());
            // The above internalUpdate will issue a fireSelectionChanged(event)
        }
    };

    /** Control used to display {@link #pageBook} and {@link #viewerCombo}. */
    Composite control;

    /**
     * PageBook acting as our control; used to switch between available implementations.
     */
    private PageBook pageBook;

    /**
     * Id of the viewer set by the user using the provided combo; may be supplied as an initial hint
     * or saved and restored using IMemento or DialogSettings in order to preserve user context.
     */
    private String viewerId;
   
    /**
     * Remember the style used so we can pass it on when we create a delegate
     */
    private int style;

    private SelectionListener menuListener = new SelectionAdapter() {
        @Override
        public void widgetSelected(SelectionEvent e) {
            MenuItem menuItem = (MenuItem) e.widget;
           
            Object data = menuItem.getData();
            boolean selected = menuItem.getSelection();

            if( selected && data instanceof String ){
                showViewer( (String) data );
            }
            if( selected && data instanceof ContributionItem ){
                ContributionItem item = (ContributionItem) data;
               
                showViewer( (String) item.getId() );
            }
        }
    };

    /** Cache of viewers responsible expression display and input */
    private HashMap<String, IExpressionViewer> pages;

    /** Place holder displayed to request the user choose a viewer */
    private Label placeholder;

    /** Label offering the popup menu symbol */
    private Label config;

    public ExpressionViewer(Composite parent) {
        this( parent, SWT.DEFAULT );
    }
    /**
     * Creates an ExpressionViewer using the provided style.
     * <ul>
     * <li>SWT.SINGLE - A simple text field showing the expression using extended CQL notation
     * <li>
     * <li>SWT.MULTI - A multi line text field</li>
     * <li>SWT.READ_ONLY - read only display of a expression</li>
     * </ul>
     *
     * @param parent
     * @param style
     */
    public ExpressionViewer(Composite parent, int style) {
        control = new Composite(parent, SWT.NO_SCROLL){
            public void setEnabled(boolean enabled) {
                super.setEnabled(enabled);
                config.setEnabled(enabled);
                if( delegate != null ){
                    config.setEnabled(enabled);
                }
                if( input != null && input.getFeedback() != null && input.getFeedback().getControl() != null ){
                    input.getFeedback().getControl().setEnabled(enabled);
                }
            }
        };
       
        control.setLayout(new MigLayout("insets 0", "[fill][]", "[fill]"));

        pageBook = new PageBook(control, SWT.NO_SCROLL);
        pageBook.setLayoutData("cell 0 0,grow,width 200:100%:100%,height 18:75%:100%");
       
        placeholder = new Label( pageBook, SWT.SINGLE );
        placeholder.setText("Choose expression editor");
       
        delegate = new CQLExpressionViewer(pageBook, style);
        delegate.addSelectionChangedListener(listener);
        pageBook.showPage(delegate.getControl());
       
        this.pages = new HashMap<String,IExpressionViewer>();
        pages.put( ExpressionViewerFactory.CQL_EXPRESSION_VIEWER, delegate );
       
        config = new Label(control, SWT.SINGLE);
        config.setImage(JFaceResources.getImage(PopupDialog.POPUP_IMG_MENU));
        config.setLayoutData("cell 1 0,aligny top,height 16!, width 16!");
       
        createContextMenu( config );
        config.addMouseListener(new MouseAdapter() {
            public void mouseDown(org.eclipse.swt.events.MouseEvent e) {
                Menu menu = config.getMenu();
                if( menu != null ){
                    menu.setVisible(true);
                }
            }
        });
        this.style = style;
    }

    protected void showViewer(String newViewerId) {
        if( newViewerId == null ){
            // show place holder label or default to CQL
            newViewerId = "org.locationtech.udig.ui.cqlExpressionViewer";
        }
        this.viewerId = newViewerId;
       
        // update the pagebook if needed
        IExpressionViewer viewer = getViewer( this.viewerId );
       
        String cqlText = null;
        if( delegate instanceof CQLExpressionViewer ){
            CQLExpressionViewer cqlViewer = (CQLExpressionViewer) delegate;
            cqlText = cqlViewer.text.getText();
        }
       
        if( viewer == null ){
            pageBook.showPage(placeholder);
            // pageBook.setSize( placeholder.)
        }
        else {
            feedback(); // clear any warnings
           
            // configure viewer before display!
            ExpressionInput currentInput = getInput();
            Expression currentExpression = getExpression();
           
            viewer.setInput( currentInput );
            viewer.setExpression( currentExpression );
            viewer.refresh();
            viewer.getControl().getParent().layout();
            // if available we can carry over the users text - typos and all
            if( cqlText != null && viewer instanceof CQLExpressionViewer){
                CQLExpressionViewer cqlViewer = (CQLExpressionViewer) viewer;
                cqlViewer.text.setText( cqlText );
            }
            // show page and listen to it for changes
            pageBook.showPage(viewer.getControl());
            viewer.addSelectionChangedListener(listener);
        }
        if( delegate != null ){
            // showPage has already hidden delegate.getControl()
            // so now we need to unplug it
            delegate.removeSelectionChangedListener( listener );
            delegate.setInput(null);
        }
        delegate = viewer;
    }
    /**
     * Lookup viewer implementation for the provided viewerId.
     * <p>
     * The viewer will be created if needed; however it will not be hooked
     * up with {@link #setInput}, {@link #setExpression} and {@link #addSelectionChangedListener}
     * as this is done by {@link #showViewer(String)} when on an as needed basis.
     *
     * @param viewerId
     * @return IExpressionViewer or null if not available
     */
    private IExpressionViewer getViewer(String lookupId) {
        IExpressionViewer viewer = pages.get( lookupId );
        if( viewer != null ){
            // already constructed
            return viewer;
        }
        for( ExpressionViewerFactory factory : ExpressionViewerFactory.factoryList() ){
            if( factory.getId().equals( lookupId )){
                viewer = factory.createViewer( pageBook, this.style );
                pages.put( factory.getId(), viewer );
               
                return viewer;
            }
        }
        return null; // user has requested an unknown id - please display placeholder
    }

    /**
     * ViewerId currently shown (as selected by the user)
     *
     * @return viewerId currently shown (as selected by the user)
     */
    public String getViewerId() {
        return viewerId;
    }

    /**
     * This is the widget used to display the Expression; its parent has been provided in the
     * ExpressionViewer's constructor; but you may need direct access to it in order to set layout
     * data etc.
     *
     * @return
     */
    public Control getControl() {
        return control;
    }

    @Override
    public void refresh() {
        if( viewerId == null && getInput() != null && getInput().getViewerId() != null ){
            // if the user has not already chosen a viewer; use the one marked down from dialog settings
            showViewer( getInput().getViewerId() );
        }
        if (delegate != null) {
            delegate.refresh();
        }
        List<ExpressionViewerFactory> list = ExpressionViewerFactory.factoryList( getInput(), getExpression() );
         if( !list.isEmpty() ){
             ExpressionViewerFactory factory = list.get(0);
             showViewer(factory.getId());
         }
    }

    @Override
    public void setInput(Object expressionInput) {
        super.setInput(expressionInput);
        if (delegate != null) {
            delegate.setInput(expressionInput);
        }
    }

    /** Used to supply a expression for display or editing */
    @Override
    public void setExpression(Expression expression) {
        if (this.expression == expression) {
            return;
        }
        this.expression = expression;
        if (delegate != null && delegate.getControl() != null
                && !delegate.getControl().isDisposed()) {
            try {
                delegate.removeSelectionChangedListener(listener);
                delegate.setExpression(expression);
            } finally {
                delegate.addSelectionChangedListener(listener);
            }
        }
        fireSelectionChanged(new SelectionChangedEvent(ExpressionViewer.this, getSelection()));
    }
   
    private void createContextMenu( Control control ){
        final MenuManager menuManager = new MenuManager();
        menuManager.setRemoveAllWhenShown(true); // we are going to generate
       
        menuManager.addMenuListener( new IMenuListener() {
            public void menuAboutToShow(IMenuManager manager) {
                Appropriate current = null;
                for( ExpressionViewerFactory factory : ExpressionViewerFactory.factoryList( getInput(), getExpression() ) ){
                    int currentScore = factory.score(getInput(), getExpression() );
                    Appropriate category = Appropriate.valueOf( currentScore );
                    if( current == null ){
                        current = category;
                    }
                    else if( current != category ){
                        menuManager.add( new Separator( current.name() ));
                        current = category;
                    }
                    ExpressionViewerFactoryContributionItem contributionItem = new ExpressionViewerFactoryContributionItem(factory);
                   
                    menuManager.add( contributionItem );
                }
            }
        });
        Menu menu = menuManager.createContextMenu( control );
        control.setMenu( menu );
    }
   
    class ExpressionViewerFactoryContributionItem extends ContributionItem {
       
        private ExpressionViewerFactory factory;
       
        ExpressionViewerFactoryContributionItem( ExpressionViewerFactory factory ){
            setId( factory.getId() );
            this.factory = factory;
        }
        @Override
        public void fill(Menu menu, int index) {
            MenuItem item = new MenuItem( menu, SWT.RADIO, index );
           
            item.setText( factory.getDisplayName() );
            item.setData( factory.getId() );
            item.setSelection( factory.getId().equals( viewerId ) );
            item.addSelectionListener( menuListener );
           
            int score = factory.score( getInput(), getExpression() );
           
            if( Appropriate.valueOf(score) == Appropriate.NOT_APPROPRIATE ){
                item.setEnabled(false);
            }
        }
    }

}
TOP

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

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.