com.extjs.gxt.ui.client.widget.grid.EditorSupport.java Source code

Java tutorial

Introduction

Here is the source code for com.extjs.gxt.ui.client.widget.grid.EditorSupport.java

Source

/*
 * Sencha GXT 2.3.1 - Sencha for GWT
 * Copyright(c) 2007-2013, Sencha, Inc.
 * licensing@sencha.com
 * 
 * http://www.sencha.com/products/gxt/license/
 */
package com.extjs.gxt.ui.client.widget.grid;

import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.DomEvent;
import com.extjs.gxt.ui.client.event.EditorEvent;
import com.extjs.gxt.ui.client.event.EventType;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.widget.grid.EditorGrid.ClicksToEdit;
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;

@SuppressWarnings("deprecation")
public class EditorSupport<M extends ModelData> {

    protected CellEditor activeEditor;
    protected Record activeRecord;
    protected ClicksToEdit clicksToEdit = ClicksToEdit.ONE;
    protected ColumnModel cm;
    protected boolean editing;
    protected Listener<DomEvent> editorListener;
    protected Grid<M> grid;
    protected Listener<GridEvent<M>> gridListener;
    protected boolean ignoreScroll;
    protected ListStore<M> store;

    private Timer startEditTimer;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public void bind(Grid grid) {
        this.grid = grid;
        this.store = grid.getStore();
        this.cm = grid.getColumnModel();
    }

    public void doRender() {
        gridListener = new Listener<GridEvent<M>>() {
            public void handleEvent(GridEvent<M> e) {
                EventType type = e.getType();
                if (type == Events.BodyScroll) {
                    if (!ignoreScroll) {
                        stopEditing(true);
                    }
                } else if (type == Events.CellClick || type == Events.CellDoubleClick) {
                    e.cancelBubble();
                    onCellDoubleClick(e);
                }
            }
        };

        grid.addListener(Events.BodyScroll, gridListener);

        if (clicksToEdit == ClicksToEdit.ONE) {
            grid.addListener(Events.CellClick, gridListener);
        } else {
            grid.addListener(Events.CellDoubleClick, gridListener);
        }

        grid.addStyleName("x-edit-grid");
        if (GXT.isSafari) {
            grid.el().setTop(0);
            grid.el().setScrollTop(0);
            grid.el().makePositionable();
        }
    }

    public CellEditor getActiveEditor() {
        return activeEditor;
    }

    /**
     * Returns the clicks to edit.
     * 
     * @return the clicks to edit
     */
    public ClicksToEdit getClicksToEdit() {
        return clicksToEdit;
    }

    /**
     * Returns true if editing is active.
     * 
     * @return the editing state
     */
    public boolean isEditing() {
        return editing;
    }

    public boolean onDoubleClick(GridEvent<M> e) {
        if (clicksToEdit == ClicksToEdit.TWO) {
            if (e.getRowIndex() != -1) {
                grid.fireEvent(Events.RowDoubleClick, e);
                if (e.getColIndex() != -1) {
                    grid.fireEvent(Events.CellDoubleClick, e);
                }
            }
            return true;
        }
        return false;
    }

    /**
     * Sets the number of clicks to edit (defaults to ONE).
     * 
     * @param clicksToEdit the clicks to edit
     */
    public void setClicksToEdit(ClicksToEdit clicksToEdit) {
        this.clicksToEdit = clicksToEdit;
    }

    public void startEditing(final int row, final int col) {
        stopEditing();
        if (cm.isCellEditable(col)) {
            final M m = store.getAt(row);
            final String field = cm.getDataIndex(col);

            GridEvent<M> e = new GridEvent<M>(grid);
            e.setModel(m);
            e.setRecord(store.getRecord(m));
            e.setProperty(field);
            e.setRowIndex(row);
            e.setColIndex(col);
            e.setValue(m.get(field));
            if (grid.fireEvent(Events.BeforeEdit, e)) {
                ignoreScroll = true;
                grid.getView().ensureVisible(row, col, false);

                // required because of triggerfields
                startEditTimer = new Timer() {

                    @Override
                    public void run() {
                        startEditTimer = null;
                        deferStartEditing(m, field, row, col);

                    }
                };
                startEditTimer.schedule(10);

            }
        }
    }

    public void stopEditing() {
        stopEditing(false);
    }

    /**
     * Stops any active editing.
     * 
     * @param cancel true to cancel, false to complete
     */
    public void stopEditing(boolean cancel) {
        if (activeEditor != null) {
            if (cancel) {
                activeEditor.cancelEdit();
            } else {
                activeEditor.completeEdit();
            }
        }
        if (startEditTimer != null) {
            startEditTimer.cancel();
            startEditTimer = null;
        }
        ignoreScroll = false;
    }

    protected void deferStartEditing(M m, String field, int row, int col) {
        editing = true;
        CellEditor ed = cm.getEditor(col);
        ed.row = row;
        ed.col = col;
        activeRecord = store.getRecord(m);

        if (!ed.isRendered()) {
            ed.render((Element) grid.getView().getEditorParent());
        }

        if (editorListener == null) {
            editorListener = new Listener<DomEvent>() {
                public void handleEvent(DomEvent e) {
                    if (e.getType() == Events.Complete) {
                        EditorEvent ee = (EditorEvent) e;
                        onEditComplete((CellEditor) ee.getEditor(), ee.getValue(), ee.getStartValue());
                    } else if (e.getType() == Events.SpecialKey) {
                        grid.getSelectionModel().onEditorKey(e);
                    } else if (e.getType() == Events.CancelEdit) {
                        EditorEvent ee = (EditorEvent) e;
                        onEditCancel((CellEditor) ee.getEditor(), ee.getValue(), ee.getStartValue());
                    }
                }
            };
        }

        ed.addListener(Events.Complete, editorListener);
        ed.addListener(Events.SpecialKey, editorListener);
        ed.addListener(Events.CancelEdit, editorListener);

        activeEditor = ed;
        // when inserting the editor into the last row, the body is
        // scrolling and edit is being cancelled

        ed.startEdit((Element) grid.getView().getCell(row, col), m.get(field));
        DeferredCommand.addCommand(new Command() {
            public void execute() {
                ignoreScroll = false;
            }
        });

    }

    protected void onAutoEditClick(GridEvent<M> e) {
        if (e.getEvent().getButton() != Event.BUTTON_LEFT) {
            return;
        }
        int row = grid.getView().findRowIndex(e.getTarget());
        int cell = grid.getView().findRowIndex(e.getTarget());
        if (row != -1 && cell != -1) {
            stopEditing();
        }
    }

    protected void onCellDoubleClick(GridEvent<M> e) {
        startEditing(e.getRowIndex(), e.getColIndex());
    }

    protected void onEditCancel(CellEditor ed, Object value, Object startValue) {
        editing = false;
        activeEditor = null;
        activeRecord = null;
        ed.removeListener(Events.SpecialKey, editorListener);
        ed.removeListener(Events.Complete, editorListener);
        ed.removeListener(Events.CancelEdit, editorListener);
        grid.getView().focusCell(ed.row, ed.col, false);
    }

    protected void onEditComplete(CellEditor ed, Object value, Object startValue) {
        editing = false;
        activeEditor = null;
        ed.removeListener(Events.SpecialKey, editorListener);
        ed.removeListener(Events.Complete, editorListener);
        ed.removeListener(Events.CancelEdit, editorListener);
        Record r = activeRecord;
        activeRecord = null;

        String field = cm.getDataIndex(ed.col);
        GridEvent<M> ge = new GridEvent<M>(grid);
        ge.setRecord(r);
        ge.setProperty(field);
        ge.setValue(value);
        ge.setStartValue(startValue);
        ge.setRowIndex(ed.row);
        ge.setColIndex(ed.col);

        if (grid.fireEvent(Events.ValidateEdit, ge)) {
            r.setValid(ge.getProperty(), ed.getField().isValid(true));
            r.set(ge.getProperty(), ge.getValue());
            grid.fireEvent(Events.AfterEdit, ge);
        }

        grid.getView().focusCell(ed.row, ed.col, false);
    }

}