Package org.openquark.gems.client.valueentry

Source Code of org.openquark.gems.client.valueentry.TupleValueEditor$TupleValueEditorProvider

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


/*
* TupleValueEditor.java
* Created: Feb 13, 2002
* By: Michael Cheng
*/

package org.openquark.gems.client.valueentry;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragSource;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.table.JTableHeader;
import javax.swing.table.TableColumnModel;

import org.openquark.cal.compiler.FieldName;
import org.openquark.cal.compiler.TypeExpr;
import org.openquark.cal.valuenode.NTupleValueNode;
import org.openquark.cal.valuenode.ValueNode;
import org.openquark.cal.valuenode.ValueNodeBuilderHelper;


/**
* A TupleValueEditor displays a list (in order) of the ValueEntryPanels representing the elements of the tuple.
* @author Michael Cheng
*/
public class TupleValueEditor extends TableValueEditor {

    private static final long serialVersionUID = 8431190568858778573L;

    /**
     * This interface defines what drag operations are supported by the
     * <code>TupleValueEditor</code>.  Implementors of this interface will be
     * called when a certain drag operation is initiated by the user.
     */
    public interface TupleValueDragPointHandler extends ValueEditorDragPointHandler {
    /**
     * This method defines the behaviour when the user attempts to drag a portion
     * of a tuple from the <code>TupleValueEditor</code>.  By default, this
     * method is empty and subclasses are encouraged to override this class to
     * specify their own drag handling code.
     * @param dge
     * @param parentEditor
     * @param tupleElementIndex
     * @return boolean
     */
    boolean dragTupleItem(DragGestureEvent dge,
                          TupleValueEditor parentEditor,
                          int tupleElementIndex);
    }

    /**
     * A custom value editor provider for the TupleValueEditor.
     */
    public static class TupleValueEditorProvider extends ValueEditorProvider<TupleValueEditor> {

        public TupleValueEditorProvider(ValueEditorManager valueEditorManager) {
            super(valueEditorManager);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean canHandleValue(ValueNode valueNode, SupportInfo providerSupportInfo) {
            return valueNode instanceof NTupleValueNode && hasSupportedTupleTypes((NTupleValueNode)valueNode, providerSupportInfo);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public TupleValueEditor getEditorInstance(ValueEditorHierarchyManager valueEditorHierarchyManager,
                                             ValueNode valueNode) {
           
            TupleValueEditor editor = new TupleValueEditor(valueEditorHierarchyManager, null);
            editor.setOwnerValueNode(valueNode);
            return editor;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public TupleValueEditor getEditorInstance(ValueEditorHierarchyManager valueEditorHierarchyManager,
                                             ValueNodeBuilderHelper valueNodeBuilderHelper,
                                             ValueEditorDragManager dragManager,
                                             ValueNode valueNode) {
            TupleValueEditor editor = new TupleValueEditor(valueEditorHierarchyManager,
                                                      getListTupleDragPointHandler(dragManager));
            editor.setOwnerValueNode(valueNode);
            return editor;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean usableForOutput() {
            return true;
        }
       
        /**
         * Checks if the value nodes for the tuple elements are supported by value editors.
         * @param valueNode the tuple value node to check for
         * @return true if all element value nodes are supported
         */
        private boolean hasSupportedTupleTypes(NTupleValueNode valueNode, SupportInfo providerSupportInfo) {

            // Notify the info object that the value node's type is supported..
            providerSupportInfo.markSupported(valueNode.getTypeExpr());
           
            ValueEditorManager valueEditorManager = getValueEditorManager();
           
            for (int i = 0, size = valueNode.getTupleSize(); i < size; i++) {
           
                ValueNode elementValueNode = valueNode.getValueAt(i);
               
                if (!valueEditorManager.isSupportedValueNode(elementValueNode, providerSupportInfo)) {
                    return false;
                }
            }
           
            return true;
        }

        /**
         * A convenient method for casting the drag point handler to the type that is
         * suitable for the <code>TupleValueEditor</code> to use.  If such conversion is not
         * possible, then this method should return <code>null</code>.
         * @param dragManager
         * @return TupleDragPointHandler
         */
        private TupleValueDragPointHandler getListTupleDragPointHandler(ValueEditorDragManager dragManager) {
            ValueEditorDragPointHandler handler = getDragPointHandler(dragManager);
            if (handler instanceof TupleValueDragPointHandler) {
                return (TupleValueDragPointHandler) handler;
            }
            return null;
        }
    }

    /**
     * Listens to drag events from the tuple table header an delegates to the drag point handler
     * to do the actual work.
     */
    private class TupleDragGestureListener implements DragGestureListener {
       
        /**
         * @see java.awt.dnd.DragGestureListener#dragGestureRecognized(java.awt.dnd.DragGestureEvent)
         */
        public void dragGestureRecognized(DragGestureEvent dge) {
            if (dge.getTriggerEvent() instanceof MouseEvent) {
                JTableHeader header = getTableHeader();
                TableColumnModel model = header.getColumnModel();

                int xPos = ((MouseEvent)dge.getTriggerEvent()).getX();
                if (dragPointHandler != null) {
                    dragPointHandler.dragTupleItem(dge,
                                                   TupleValueEditor.this,
                                                   model.getColumnIndexAtX(xPos));
                }
            }
        }
    }

    /** The minimum size of this editor. */
    private static final Dimension MIN_SIZE = new Dimension(200, -1);
   
    /** The maximum size of this editor. */
    private static final Dimension MAX_SIZE = new Dimension(600, -1);

    // Allow this value editor to initiate drag events
    private final TupleValueDragPointHandler dragPointHandler;

    /**
     * TupleValueEditor constructor comment.
     * @param valueEditorHierarchyManager
     * @param dragPointHandler
     */
    protected TupleValueEditor(ValueEditorHierarchyManager valueEditorHierarchyManager,
                               TupleValueDragPointHandler dragPointHandler) {

        super(valueEditorHierarchyManager);
        this.dragPointHandler = dragPointHandler;
       
        setLayout(new BorderLayout());
        add(tableScrollPane, BorderLayout.CENTER);

        // Attach a listener for drag events
        if (dragPointHandler != null) {
            JTableHeader tableHeader = getTableHeader();
            DragSource.getDefaultDragSource().createDefaultDragGestureRecognizer(
                tableHeader,
                DnDConstants.ACTION_COPY_OR_MOVE,
                new TupleDragGestureListener());
        }
    }

    /**
     * @see org.openquark.gems.client.valueentry.ValueEditor#setInitialValue()
     */
    @Override
    public void setInitialValue() {
       
        initSize(MIN_SIZE, MAX_SIZE);
       
        // We only care about maximum width for the initial display.
        // After that we allow the user to resize the editor to any width.
        setMaxResizeDimension(new Dimension(2048, getSize().height));
    }

    /**
     * @see org.openquark.gems.client.valueentry.ValueEditor#refreshDisplay()
     */
    @Override
    public void refreshDisplay() {
       
        // Reselect the cell that was previously being edited.
        selectCell(getSelectedRow(), getSelectedColumn());
    }

    /**
     * @see org.openquark.gems.client.valueentry.TableValueEditor#createTableModel(org.openquark.cal.valuenode.ValueNode)
     */
    @Override
    protected ValueEditorTableModel createTableModel(ValueNode valueNode) {
        return new TupleTableModel((NTupleValueNode) valueNode, valueEditorHierarchyManager);
    }
   
    /**
     * Get a map from every value node managed by this editor to its least constrained type.
     * @return Map from every value node managed by this editor to its least constrained type.
     */
    private Map<ValueNode, TypeExpr> getValueNodeToUnconstrainedTypeMap() {
       
        Map<ValueNode, TypeExpr> returnMap = new HashMap<ValueNode, TypeExpr>();
       
        // Get the value nodes for the tuple and the items in the tuple.
        NTupleValueNode currentTupleValue = (NTupleValueNode)getValueNode();
        int tupleSize = currentTupleValue.getTupleSize();

        // Populate the map
       
        // Tuple
        TypeExpr unconstrainedTupleType = getContext().getLeastConstrainedTypeExpr();
        if (unconstrainedTupleType.rootTypeVar() != null) {
            // not constrained by the context to be a tuple
            unconstrainedTupleType = TypeExpr.makeTupleType(tupleSize);
        }
        returnMap.put(currentTupleValue, unconstrainedTupleType);
       
        // Tuple elements
        Map<FieldName, TypeExpr> hasFieldsMap = unconstrainedTupleType.rootRecordType().getHasFieldsMap();
        int j = 0;
        for (final TypeExpr unconstrainedTupleElementType : hasFieldsMap.values()) {
            ValueNode currentTupleItem = currentTupleValue.getValueAt(j);
            returnMap.put(currentTupleItem, unconstrainedTupleElementType);
            ++j;
        }

        return returnMap;
    }
   
    /**
     * {@inheritDoc}
     */
    @Override
    public void commitChildChanges(ValueNode oldChild, ValueNode newChild) {
               
        // Get the copy of the current value node, type switched if necessary.
       
        NTupleValueNode oldValueNode = (NTupleValueNode)getValueNode();
        NTupleValueNode newValueNode;
        if (!oldChild.getTypeExpr().sameType(newChild.getTypeExpr())) {
            Map<ValueNode, TypeExpr> valueNodeToUnconstrainedTypeMap = getValueNodeToUnconstrainedTypeMap();
            Map<ValueNode, ValueNode>  commitValueMap = valueEditorManager.getValueNodeCommitHelper().getCommitValues(oldChild, newChild, valueNodeToUnconstrainedTypeMap);
           
            newValueNode = (NTupleValueNode)commitValueMap.get(oldValueNode);

        } else {
            newValueNode = (NTupleValueNode)oldValueNode.copyValueNode();
        }       
       
        // Modify the new value node so that the old child is replaced by the new child.
        // Note that the cell editor may now be editing a different column so we have to search for the row that changed
        //   This can happen if one clicks from an editor for one cell to another cell
        //   (eg. in a list of colours, from a colour value editor for one cell, onto the cell editor for another cell.)

        List<ValueNode> currentChildrenList = oldValueNode.getValue();

        for (int i = 0, listSize = newValueNode.getTupleSize(); i < listSize; i++) {
            if (currentChildrenList.get(i) == oldChild) {
                TypeExpr childType = newValueNode.getValueAt(i).getTypeExpr();
                newValueNode.setValueNodeAt(i, newChild.copyValueNode(childType));
                break;
            }
        }

        // Set the value node
        replaceValueNode(newValueNode, true);
    }
}
TOP

Related Classes of org.openquark.gems.client.valueentry.TupleValueEditor$TupleValueEditorProvider

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.
div>