com.ephesoft.gxt.core.client.ui.widget.Grid.java Source code

Java tutorial

Introduction

Here is the source code for com.ephesoft.gxt.core.client.ui.widget.Grid.java

Source

/********************************************************************************* 
* Ephesoft is a Intelligent Document Capture and Mailroom Automation program 
* developed by Ephesoft, Inc. Copyright (C) 2015 Ephesoft Inc. 
* 
* This program is free software; you can redistribute it and/or modify it under 
* the terms of the GNU Affero General Public License version 3 as published by the 
* Free Software Foundation with the addition of the following permission added 
* to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK 
* IN WHICH THE COPYRIGHT IS OWNED BY EPHESOFT, EPHESOFT DISCLAIMS THE WARRANTY 
* OF NON INFRINGEMENT OF THIRD PARTY RIGHTS. 
* 
* This program is distributed in the hope that it will be useful, but WITHOUT 
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
* FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
* details. 
* 
* You should have received a copy of the GNU Affero General Public License along with 
* this program; if not, see http://www.gnu.org/licenses or write to the Free 
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 
* 02110-1301 USA. 
* 
* You can contact Ephesoft, Inc. headquarters at 111 Academy Way, 
* Irvine, CA 92617, USA. or at email address info@ephesoft.com. 
* 
* The interactive user interfaces in modified source and object code versions 
* of this program must display Appropriate Legal Notices, as required under 
* Section 5 of the GNU Affero General Public License version 3. 
* 
* In accordance with Section 7(b) of the GNU Affero General Public License version 3, 
* these Appropriate Legal Notices must retain the display of the "Ephesoft" logo. 
* If the display of the logo is not reasonably feasible for 
* technical reasons, the Appropriate Legal Notices must display the words 
* "Powered by Ephesoft". 
********************************************************************************/

package com.ephesoft.gxt.core.client.ui.widget;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.ephesoft.gxt.core.client.constant.PropertyAccessModel;
import com.ephesoft.gxt.core.client.i18n.CoreCommonConstants;
import com.ephesoft.gxt.core.client.i18n.LocaleCommonConstants;
import com.ephesoft.gxt.core.client.i18n.LocaleDictionary;
import com.ephesoft.gxt.core.client.ui.factory.GridAttributeFactory;
import com.ephesoft.gxt.core.client.ui.widget.constant.WidgetPropertiesConstant;
import com.ephesoft.gxt.core.client.ui.widget.window.DialogIcon;
import com.ephesoft.gxt.core.client.util.DialogUtil;
import com.ephesoft.gxt.core.client.validator.Validator;
import com.ephesoft.gxt.core.client.validator.Validator.Severity;
import com.ephesoft.gxt.core.shared.constant.CoreCommonConstant;
import com.ephesoft.gxt.core.shared.dto.DirtyCell;
import com.ephesoft.gxt.core.shared.dto.Selectable;
import com.ephesoft.gxt.core.shared.util.CollectionUtil;
import com.ephesoft.gxt.core.shared.util.StringUtil;
import com.google.gwt.cell.client.Cell;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.logical.shared.BeforeSelectionEvent;
import com.google.gwt.event.logical.shared.BeforeSelectionHandler;
import com.google.gwt.event.logical.shared.ResizeEvent;
import com.google.gwt.event.logical.shared.ResizeHandler;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.event.logical.shared.ValueChangeHandler;
import com.google.gwt.safehtml.shared.SafeHtmlUtils;
import com.google.gwt.user.client.Timer;
import com.google.gwt.user.client.ui.Widget;
import com.sencha.gxt.cell.core.client.form.CheckBoxCell;
import com.sencha.gxt.core.client.ValueProvider;
import com.sencha.gxt.data.client.loader.RpcProxy;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.data.shared.ModelKeyProvider;
import com.sencha.gxt.data.shared.SortInfo;
import com.sencha.gxt.data.shared.Store.StoreFilter;
import com.sencha.gxt.data.shared.Store.StoreSortInfo;
import com.sencha.gxt.data.shared.loader.DataProxy;
import com.sencha.gxt.data.shared.loader.FilterPagingLoadConfig;
import com.sencha.gxt.data.shared.loader.FilterPagingLoadConfigBean;
import com.sencha.gxt.data.shared.loader.LoadEvent;
import com.sencha.gxt.data.shared.loader.LoadHandler;
import com.sencha.gxt.data.shared.loader.LoadResultListStoreBinding;
import com.sencha.gxt.data.shared.loader.Loader;
import com.sencha.gxt.data.shared.loader.MemoryProxy;
import com.sencha.gxt.data.shared.loader.PagingLoadResult;
import com.sencha.gxt.data.shared.loader.PagingLoadResultBean;
import com.sencha.gxt.data.shared.loader.PagingLoader;
import com.sencha.gxt.widget.core.client.ContentPanel;
import com.sencha.gxt.widget.core.client.event.BeforeStartEditEvent;
import com.sencha.gxt.widget.core.client.event.BeforeStartEditEvent.BeforeStartEditHandler;
import com.sencha.gxt.widget.core.client.event.CompleteEditEvent;
import com.sencha.gxt.widget.core.client.event.CompleteEditEvent.CompleteEditHandler;
import com.sencha.gxt.widget.core.client.form.CheckBox;
import com.sencha.gxt.widget.core.client.form.Field;
import com.sencha.gxt.widget.core.client.form.IsField;
import com.sencha.gxt.widget.core.client.grid.CellSelectionModel;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnHeader;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.GridSelectionModel;
import com.sencha.gxt.widget.core.client.grid.GridViewConfig;
import com.sencha.gxt.widget.core.client.grid.editing.GridEditing;
import com.sencha.gxt.widget.core.client.grid.editing.GridInlineEditing;
import com.sencha.gxt.widget.core.client.grid.filters.Filter;
import com.sencha.gxt.widget.core.client.grid.filters.GridFilters;
import com.sencha.gxt.widget.core.client.selection.CellSelection;
import com.sencha.gxt.widget.core.client.selection.CellSelectionChangedEvent;
import com.sencha.gxt.widget.core.client.selection.CellSelectionChangedEvent.CellSelectionChangedHandler;
import com.sencha.gxt.widget.core.client.tips.ToolTip;
import com.sencha.gxt.widget.core.client.tips.ToolTipConfig;

@SuppressWarnings({ "rawtypes", "unchecked" })
public class Grid<T extends Selectable> extends com.sencha.gxt.widget.core.client.grid.Grid<T> {

    private boolean editable = true;

    private boolean isGridValidated = false;

    protected GridInlineEditing<T> editingGrid;

    private GridView<T> gridView;

    private Map<String, ValueProvider<? super T, ?>> valueProviderMap;

    private List<ValueProvider<T, ?>> nonEditableVPList;

    private List<Filter<T, ?>> filtersList;

    private Map<ValueProvider, Set<T>> forcefullyInValidModels;

    private DataProxy<FilterPagingLoadConfig, PagingLoadResult<T>> proxy;

    private PagingLoader<FilterPagingLoadConfig, PagingLoadResult<T>> loader;

    private boolean firstRowSelectedOnLoad = false;

    private boolean hasPagination = true;

    private GridFilter gridFilter;

    private ContentPanel resizablePanel;

    private CheckBox selectAllCheckBox;

    private Map<ValueProvider<? super T, ?>, List<Validator<T>>> validatorsMap;

    private FilterPagingLoadConfigBean configBean;

    private ValueProvider<T, String> idProvider;

    private ColumnConfig<T, ?> currentColumnConfig;

    private GridCell currentSelectedCell;

    private T currentSelectedModel;

    private static int EDITING_DELAY = 100;

    private Element lastSelectedRow;

    private Element lastSelectedColumn;

    private PropertyAccessModel propertyAccessModel;

    private static final String COLUMN_HEADER = "filterEnableColumnHeader";

    public Grid(final PropertyAccessModel propertyAccessModel) {
        this(null, propertyAccessModel);
    }

    /**
     * Scrolls the selected grid cell into view.
     * 
     * @param selectionModel
     */
    private void addGridSelectionHandler(GridSelectionModel<T> selectionModel) {
        if (selectionModel instanceof CellSelectionModel) {
            CellSelectionModel<T> cellSelectionModel = (CellSelectionModel<T>) selectionModel;
            cellSelectionModel.addCellSelectionChangedHandler(new CellSelectionChangedHandler<T>() {

                @Override
                public void onCellSelectionChanged(CellSelectionChangedEvent<T> cellSelectionEvent) {
                    List<CellSelection<T>> list = cellSelectionEvent.getSelection();
                    if (!CollectionUtil.isEmpty(list)) {
                        int colId = list.get(0).getCell();
                        int rowId = list.get(0).getRow();
                        Grid.this.getView().getCell(rowId, colId).scrollIntoView();
                    }
                }
            });
        }
    }

    public Grid(final List<T> dataToAdd, final PropertyAccessModel propertyAccessModel) {
        this(dataToAdd, propertyAccessModel, true, null);
    }

    public Grid(final RpcProxy<FilterPagingLoadConfig, PagingLoadResult<T>> proxy,
            final PropertyAccessModel propertyAccessModel, final boolean isEditable) {
        this(null, propertyAccessModel, isEditable, proxy);
    }

    public Grid(final List<T> dataToAdd, final PropertyAccessModel propertyAccessModel, final boolean isEditable,
            final RpcProxy<FilterPagingLoadConfig, PagingLoadResult<T>> proxy) {
        super(Grid.<T>createListStore(propertyAccessModel), Grid.<T>createColumnModel(propertyAccessModel),
                new GridView<T>());
        this.editable = isEditable;
        this.proxy = proxy;
        this.propertyAccessModel = propertyAccessModel;
        if (isEditable) {
            this.setEditable(propertyAccessModel);
        }
        gridView = (GridView<T>) this.getView();
        this.addStyleName("gridStyle");
        configBean = new FilterPagingLoadConfigBean();
        valueProviderMap = new HashMap<String, ValueProvider<? super T, ?>>();
        nonEditableVPList = new ArrayList<ValueProvider<T, ?>>();
        validatorsMap = new HashMap<ValueProvider<? super T, ?>, List<Validator<T>>>();
        gridView.setShowDirtyCells(false);
        gridView.setTrackMouseOver(false);
        this.mapValueProviders(propertyAccessModel);
        gridView.setStripeRows(true);
        gridView.setColumnLines(true);
        gridView.setAutoExpandMin(10);
        this.setPagination(dataToAdd, propertyAccessModel);
        this.applyFilter(propertyAccessModel);
        this.setLazyRowRender(WidgetPropertiesConstant.DEFAULT_GRID_LAZY_ROW_RENDER);
        this.getView().setEmptyText(LocaleDictionary.getConstantValue(CoreCommonConstants.NO_RECORDS_FOUND));
        this.setAutoFit(true);
        Grid.this.setToolTipConfig(new ToolTipConfig());
        this.validateValueProviders();
        this.addDefaultToolTip();
        setHeaderTooltip();
        forcefullyInValidModels = new HashMap<ValueProvider, Set<T>>();
        this.addGridSelectionHandler(this.getSelectionModel());
        Grid.this.addDomHandler(new MouseMoveHandler() {

            @Override
            public void onMouseMove(MouseMoveEvent event) {
                NativeEvent natev = event.getNativeEvent();
                if (Element.is(natev.getEventTarget())) {
                    int hoverCellIdx = Grid.this.getView().findCellIndex(Element.as(natev.getEventTarget()), null);
                    int hoverRowIdx = Grid.this.getView().findRowIndex(Element.as(natev.getEventTarget()));
                    ValueProvider<? super T, Object> valueProvider = cm.getValueProvider(hoverCellIdx);
                    T model = getStore().get(hoverRowIdx);
                    ListWidget errorList = getErrors(valueProvider, model);
                    Element cellElement = getView().getCell(hoverRowIdx, hoverCellIdx);
                    setToolTip(cellElement, errorList);
                }
            }
        }, MouseMoveEvent.getType());
        this.addKeyDownHandler();
    }

    public void setIdProvider(ValueProvider<T, String> idProvider) {
        this.idProvider = idProvider;
    }

    private void setHeaderTooltip() {
        ColumnModel<T> columnModel = getColumnModel();
        List<ColumnConfig<T, ?>> columnConfigList = null;
        if (columnModel != null) {
            columnConfigList = columnModel.getColumns();
            if (!CollectionUtil.isEmpty(columnConfigList)) {
                for (ColumnConfig<T, ?> columnConfig : columnConfigList) {
                    columnConfig.setToolTip(columnConfig.getHeader());
                }
            }
        }
    }

    public void addDirtyCellValueProvider(final ValueProvider valueProvder) {
        if (null != valueProvder && !forcefullyInValidModels.containsKey(valueProvder)) {
            forcefullyInValidModels.put(valueProvder, new HashSet<T>());
        }
    }

    private boolean isDirty(T modelToCheck, ValueProvider valueProviderToValidate) {
        boolean isDirty = false;
        if (null != modelToCheck && valueProviderToValidate != null) {
            Set<T> invalidModelsList = forcefullyInValidModels.get(valueProviderToValidate);
            if (!CollectionUtil.isEmpty(invalidModelsList)) {
                for (T model : invalidModelsList) {
                    if (model == modelToCheck) {
                        isDirty = true;
                        break;
                    }
                }
            }
        }
        return isDirty;
    }

    public Map<String, List<DirtyCell>> getDityCells() {
        Map<String, List<DirtyCell>> dirtyCellsMap = new HashMap<String, List<DirtyCell>>();
        for (final Entry<ValueProvider, Set<T>> entry : forcefullyInValidModels.entrySet()) {
            Set<T> modelsList = entry.getValue();
            ValueProvider valueProvider = entry.getKey();
            if (!CollectionUtil.isEmpty(modelsList) && null != valueProvider) {
                String path = valueProvider.getPath();
                ModelKeyProvider<? super T> keyProvider = store.getKeyProvider();
                if (!StringUtil.isNullOrEmpty(path)) {
                    for (final T model : modelsList) {
                        if (null != model) {
                            Object cellValue = valueProvider.getValue(model);
                            String modelKey = keyProvider.getKey(model);
                            addDirtCellEntry(dirtyCellsMap, cellValue, path, modelKey);
                        }
                    }
                }
            }
        }
        return dirtyCellsMap;
    }

    public void removeDirtyCell(final ValueProvider<T, ?> valueProvider, T model) {
        if (null != model && null != valueProvider) {
            Set<T> invalidModelsSet = forcefullyInValidModels.get(valueProvider);
            if (!CollectionUtil.isEmpty(invalidModelsSet)) {
                invalidModelsSet.remove(model);
                // Don't remove this code. This is done for invalid validation.
                // int rowIndex = store.indexOf(model);
                // int columnCount = cm.getColumnCount();
                // int columnIndex = -1;
                // for (int i = 0; i < columnCount; i++) {
                // if (cm.getValueProvider(i) == valueProvider) {
                // columnIndex = i;
                // break;
                // }
                // }
                // if (rowIndex > -1 && columnIndex > -1) {
                // Element cell = view.getCell(rowIndex, columnIndex);
                // }
            }
        }
    }

    public void setDirtyCells(Map<String, List<DirtyCell>> dirtyCellMap) {
        for (Set<T> entry : forcefullyInValidModels.values()) {
            if (null != entry) {
                entry.clear();
            }
        }
        if (!CollectionUtil.isEmpty(dirtyCellMap)) {
            for (Entry<String, List<DirtyCell>> invalidColumnEntry : dirtyCellMap.entrySet()) {
                List<DirtyCell> invalidCells = invalidColumnEntry.getValue();
                if (!CollectionUtil.isEmpty(invalidCells)) {
                    ValueProvider modelValueProvider = getValueProvider(invalidColumnEntry.getKey());
                    if (null != modelValueProvider) {
                        addDirtyCellEntry(modelValueProvider, invalidCells);
                    }
                }
            }
        }
    }

    private void addDirtyCellEntry(ValueProvider modelValueProvider, List<DirtyCell> invalidCells) {
        Set<T> modelsSet = forcefullyInValidModels.get(modelValueProvider);
        if (null != modelsSet) {
            for (DirtyCell cell : invalidCells) {
                String key = cell.getKey();
                if (!StringUtil.isNullOrEmpty(key)) {
                    T model = store.findModelWithKey(key);

                    if (null != model) {
                        modelsSet.add(model);
                    }
                }
            }
        }
    }

    public ValueProvider getValueProvider(final String path) {
        ValueProvider valueProviderToFind = null;
        if (!StringUtil.isNullOrEmpty(path)) {
            int totalColumns = cm.getColumnCount();
            for (int i = 0; i < totalColumns; i++) {
                ValueProvider currentValueProvider = cm.getValueProvider(i);
                if (path.equals(currentValueProvider.getPath())) {
                    valueProviderToFind = currentValueProvider;
                    break;
                }
            }
        }
        return valueProviderToFind;
    }

    private void addDirtCellEntry(Map<String, List<DirtyCell>> dirtyCellsMap, Object cellValue, String path,
            String modelKey) {
        String value = cellValue == null ? CoreCommonConstant.EMPTY_STRING : cellValue.toString();
        List<DirtyCell> dirtyCellList = dirtyCellsMap.get(path);
        if (null == dirtyCellList) {
            dirtyCellList = new ArrayList<DirtyCell>();
            dirtyCellsMap.put(path, dirtyCellList);
        }
        dirtyCellList.add(new DirtyCell(modelKey, value));
    }

    private int getDirtyCellsCount() {
        int count = 0;
        for (Entry<ValueProvider, Set<T>> entry : forcefullyInValidModels.entrySet()) {
            Set<T> modelsList = entry.getValue();
            if (!CollectionUtil.isEmpty(modelsList)) {
                count += modelsList.size();
            }
        }
        return count;
    }

    private void addKeyDownHandler() {
        this.addDomHandler(new KeyDownHandler() {

            @Override
            public void onKeyDown(KeyDownEvent event) {
                switch (event.getNativeKeyCode()) {
                case KeyCodes.KEY_SPACE:
                    if (currentColumnConfig != null && null != currentSelectedModel
                            && null != currentSelectedCell) {
                        Cell<?> cell = currentColumnConfig.getCell();
                        if (cell instanceof CheckBoxCell) {
                            store.commitChanges();
                            ValueProvider valueProvider = currentColumnConfig.getValueProvider();
                            Object value = valueProvider.getValue(currentSelectedModel);
                            if (value instanceof Boolean) {
                                event.preventDefault();
                                valueProvider.setValue(currentSelectedModel, !((Boolean) value));
                                refreshRow(currentSelectedCell.getRow());
                            }
                        }
                    }
                    break;

                }
            }
        }, KeyDownEvent.getType());
    }

    /**
     * 
     */
    private void validateValueProviders() {
        this.getView().setViewConfig(new GridViewConfig<T>() {

            @Override
            public String getColStyle(T model, ValueProvider<? super T, ?> valueProvider, int rowIndex,
                    int colIndex) {
                String cssStyle = StringUtil.concatenate(cm.getColumnHeader(colIndex).asString(),
                        CoreCommonConstant.SPACE);
                if (getErrors(valueProvider, model) != null) {
                    cssStyle = "styleName";
                }
                return cssStyle;
            }

            @Override
            public String getRowStyle(T model, int rowIndex) {
                String style = rowIndex % 2 == 1 ? "evenRow" : CoreCommonConstant.EMPTY_STRING;
                if (null != idProvider) {
                    style = StringUtil.concatenate(style, CoreCommonConstant.SPACE, idProvider.getValue(model));
                }
                return style;
            }
        });
    }

    private void addDefaultToolTip() {
        GridSelectionModel<T> selectionModel = this.getSelectionModel();
        if (selectionModel instanceof CellSelectionModel<?>) {
            CellSelectionModel<T> cellSelectionModel = (CellSelectionModel<T>) selectionModel;
            addBeforeCellSelectionChangeEvent(cellSelectionModel);
            cellSelectionModel.addCellSelectionChangedHandler(new CellSelectionChangedHandler<T>() {

                @Override
                public void onCellSelectionChanged(CellSelectionChangedEvent<T> event) {
                    List<CellSelection<T>> gridSelection = event.getSelection();
                    if (!CollectionUtil.isEmpty(gridSelection)) {
                        CellSelection<T> currentSelection = gridSelection.get(0);
                        if (null != currentSelection) {
                            int column = currentSelection.getCell();
                            int row = currentSelection.getRow();
                            T model = currentSelection.getModel();
                            ValueProvider<? super T, Object> valueProvider = cm.getValueProvider(column);
                            currentColumnConfig = getColumn(valueProvider);
                            currentSelectedModel = model;
                            onCellSelectionChange(model);
                            currentSelectedCell = new GridCell(row, column);
                            Element rowElement = gridView.getRow(row);
                            Element columnElement = gridView.getCell(row, column);
                            if (null != rowElement) {
                                if (null != lastSelectedRow && null != lastSelectedColumn) {
                                    lastSelectedRow.removeClassName("selectedRow");
                                    lastSelectedColumn.removeClassName("selectedColumn");
                                }
                                lastSelectedRow = rowElement;
                                lastSelectedColumn = columnElement;
                                lastSelectedRow.addClassName("selectedRow");
                                lastSelectedColumn.addClassName("selectedColumn");
                            }
                            ListWidget errorsList = getErrors(valueProvider, model);
                            Element cellElement = getView().getCell(row, column);
                            setToolTip(cellElement, errorsList);

                        }
                    }
                }
            });
        }
    }

    private void addBeforeCellSelectionChangeEvent(final CellSelectionModel<T> cellSelectionModel) {
        cellSelectionModel.addBeforeSelectionHandler(new BeforeSelectionHandler<T>() {

            @Override
            public void onBeforeSelection(BeforeSelectionEvent<T> event) {
                onBeforeCellSelectionChange(event, currentSelectedModel);
            }
        });
    }

    private void setToolTip(final Element cellElement, final ListWidget errorList) {
        ToolTip toolTip = this.getToolTip();
        if (null != cellElement && null != errorList) {
            if (null == toolTip) {
                ToolTipConfig config = new ToolTipConfig();
                toolTip = new ToolTip(config);
            }
            if (null != errorList) {
                String htmlText = errorList.getElement().getInnerHTML();
                ToolTipConfig config = new ToolTipConfig();
                config.setBodyHtml(htmlText);
                toolTip.update(config);
                toolTip.showAt(cellElement.getAbsoluteLeft() + 5, cellElement.getAbsoluteTop() + 40);
            }
        } else {
            if (null != toolTip) {
                toolTip.hide();
            }
        }
    }

    private ListWidget getErrors(ValueProvider<? super T, ?> valueProvider, T model) {
        ListWidget htmlErrorList = null;
        if (null != validatorsMap && !validatorsMap.isEmpty()) {
            if (validatorsMap.containsKey(valueProvider)) {
                List<Validator<T>> listOfValidators = validatorsMap.get(valueProvider);
                ListStore<T> memoryData = getMemoryData();
                memoryData = memoryData == null ? getStore() : memoryData;
                if (null != listOfValidators && !listOfValidators.isEmpty() && null != memoryData) {
                    for (Validator<T> validator : listOfValidators) {
                        if (!validator.validate(memoryData.getAll(), model, (ValueProvider<T, ?>) valueProvider)) {
                            if (htmlErrorList == null) {
                                htmlErrorList = new ListWidget();
                            }
                            htmlErrorList.addItem(validator.getErrorMessage(), validator.getSeverity().name());
                        }
                    }
                }
            }
            if (isDirty(model, valueProvider)) {
                if (htmlErrorList == null) {
                    htmlErrorList = new ListWidget();
                }
                htmlErrorList.addItem("Either the value is invalid or it requires explicit validation",
                        Severity.HIGH.name());
            }
        }
        return htmlErrorList;
    }

    public void addNonEditableValueProviders(List<ValueProvider<T, ?>> valueProviders) {
        nonEditableVPList.addAll(valueProviders);
    }

    public void addNonEditableValueProviders(ValueProvider<T, ?> valueProvider) {
        if (null != valueProvider) {
            nonEditableVPList.add(valueProvider);
        }
    }

    public void beforeStartEditing(BeforeStartEditEvent<T> beforeEditEvent) {
        final int colIndex = beforeEditEvent.getEditCell().getCol();
        final int rowIndex = beforeEditEvent.getEditCell().getRow();
        if (!CollectionUtil.isEmpty(nonEditableVPList)) {
            for (ValueProvider<T, ?> valueProvider : nonEditableVPList) {
                if (Grid.this.getColumnModel().getColumns().get(colIndex).getValueProvider() == valueProvider) {
                    if (!Grid.this.getStore().get(rowIndex).isNew()) {
                        beforeEditEvent.setCancelled(true);
                        break;
                    }
                }
            }
        }
    }

    public void completeEditing(final CompleteEditEvent<T> completeEditEvent) {
        if (null != completeEditEvent) {
            GridCell editCell = completeEditEvent.getEditCell();
            if (null != editCell) {
                int row = editCell.getRow();
                int column = editCell.getCol();
                validateDirtyCell(row, column);
            }
        }
    }

    private void validateDirtyCell(final int row, final int column) {
        // Issue with Sencha's library firing complete edit 2 times on Selection.
        Timer timer = new Timer() {

            @Override
            public void run() {
                com.sencha.gxt.widget.core.client.grid.Grid.GridCell activeCell = editingGrid.getActiveCell();
                if (!editingGrid.isEditing()
                        || !(activeCell != null && activeCell.getRow() == row && activeCell.getCol() == column)) {
                    if (row >= 0 && column >= 0) {
                        T model = store.get(row);
                        ValueProvider valueProvider = cm.getValueProvider(column);
                        Set<T> invalidModelsSet = forcefullyInValidModels.get(valueProvider);
                        if (null != invalidModelsSet) {
                            Element cellElement = gridView.getCell(row, column);
                            if (null != cellElement) {
                                cellElement.addClassName("styleName");
                            }
                            invalidModelsSet.add(model);
                        }
                    }
                }
            }
        };
        timer.schedule(5);
    }

    public PagingLoader<FilterPagingLoadConfig, PagingLoadResult<T>> getPaginationLoader() {
        return loader;
    }

    public void setResizeHandler(final ContentPanel contentPanel, final float width, final float height) {
        if (null != contentPanel && null == this.resizablePanel && width <= 1.0 && height <= 1.0) {
            this.resizablePanel = contentPanel;
            final int contentPanelWidth = contentPanel.getOffsetWidth();
            final int contentPanelHeight = contentPanel.getOffsetHeight();
            final int gridNewHeight = (int) Math.round((contentPanelHeight * height));
            final int gridNewWidth = (int) Math.round((contentPanelWidth * width));
            setPixelSize(gridNewWidth, gridNewHeight);

            if (hasPagination) {
                int gridHeight = this.getOffsetHeight();
                int gridWidth = this.getOffsetWidth();
                this.setPixelSize(gridWidth - 4, gridHeight - 37);
            }
            contentPanel.addResizeHandler(new ResizeHandler() {

                @Override
                public void onResize(final ResizeEvent event) {
                    setGridDimension(contentPanel, width, height);
                }
            });
        }
    }

    private void setGridDimension(final ContentPanel contentPanel, final float width, final float height) {
        final int contentPanelWidth = contentPanel.getOffsetWidth();
        final int contentPanelHeight = contentPanel.getOffsetHeight();
        final int gridNewHeight = (int) Math.round((contentPanelHeight * height));
        final int gridNewWidth = (int) Math.round((contentPanelWidth * width));
        setPixelSize(gridNewWidth, gridNewHeight);
        if (hasPagination) {
            int newHeight = Grid.this.getOffsetHeight();
            int newWidth = Grid.this.getOffsetWidth();
            Grid.this.setPixelSize(newWidth - 4, newHeight - 37);
        }
    }

    public FilterPagingLoadConfigBean getConfigBean() {
        return configBean;
    }

    public void setCell(ValueProvider valueProvider, Cell cell, String className) {
        ColumnConfig columnConfig = getColumn(valueProvider);
        if (null != columnConfig) {
            columnConfig.setCell(cell);
            columnConfig.setCellClassName(className);
        }
    }

    private static <T> ColumnModel<T> createColumnModel(final PropertyAccessModel propertyAccessModel) {
        ColumnModel<T> columnModel = null;
        final List<ColumnConfig<T, ?>> columnConfigList = GridAttributeFactory
                .<T>getColumnConfig(propertyAccessModel);
        if (!CollectionUtil.isEmpty(columnConfigList)) {
            columnModel = new ColumnModel<T>(columnConfigList);
        }
        return columnModel;
    }

    private void applyFilter(final PropertyAccessModel propertyAccessModel) {
        gridFilter = new GridFilter(loader);
        gridFilter.initPlugin(this);

        // Removing this will improve efficiency of filters
        // gridFilter.setUpdateBuffer(WidgetPropertiesConstant.DEFAULT_UPDATE_BUFFER);
        filtersList = GridAttributeFactory.<T>getFilters(propertyAccessModel);
        gridFilter.addFilters(filtersList);
    }

    private void setPagination(final List<T> dataToAdd, final PropertyAccessModel propertyAccessModel) {
        final ModelKeyProvider<T> keyProvider = GridAttributeFactory.<T>getKeyProvider(propertyAccessModel);
        if (null == proxy) {
            this.proxy = new PagingMemoryProxy(dataToAdd, keyProvider);
        }

        loader = new PagingLoader<FilterPagingLoadConfig, PagingLoadResult<T>>(proxy) {

            @Override
            protected FilterPagingLoadConfig newLoadConfig() {
                return configBean;
            }
        };
        loader.setRemoteSort(true);
        loader.addLoadHandler(
                new LoadResultListStoreBinding<FilterPagingLoadConfig, T, PagingLoadResult<T>>(this.store));
        this.setLoader(loader);
        loader.addLoadHandler(new LoadHandler<FilterPagingLoadConfig, PagingLoadResult<T>>() {

            @Override
            public void onLoad(LoadEvent<FilterPagingLoadConfig, PagingLoadResult<T>> event) {
                if (Grid.this.store != null && Grid.this.store.size() > 0 && firstRowSelectedOnLoad) {
                    ((CellSelectionModel<T>) Grid.this.getSelectionModel()).selectCell(0, 0);
                }
                if (null != selectAllCheckBox) {
                    /*
                     * It is done to make sure whenever a grid is loaded it is loaded with no selection. Explicitly firing value change
                     * event.
                     */
                    selectAllCheckBox.setValue(true);
                    selectAllCheckBox.setValue(false);
                }
                onGridLoad();
            }
        });
    }

    protected void onGridLoad() {

    }

    private static <T> ListStore<T> createListStore(final PropertyAccessModel propertyAccessModel) {
        ListStore<T> listStore = null;
        final ModelKeyProvider<T> keyProvider = GridAttributeFactory.<T>getKeyProvider(propertyAccessModel);
        if (null != keyProvider) {
            listStore = CollectionUtil.createListStore(keyProvider);
        }
        return listStore;
    }

    public void setSelectedAllModels(final boolean selected) {
        List<T> modelsList = this.store.getAll();
        if (!CollectionUtil.isEmpty(modelsList)) {
            for (T selectableModel : modelsList) {
                if (null != selectableModel) {
                    selectableModel.setSelected(selected);
                }
            }
        }
    }

    public void selectGridCell(int rowId, int cellId) {
        ((CellSelectionModel<T>) Grid.this.getSelectionModel()).selectCell(rowId, cellId);
    }

    public void startEditing(final int row, final int column) {
        if (editingGrid != null) {
            editingGrid.startEditing(new GridCell(row, column));
        }
    }

    private void mapValueProviders(final PropertyAccessModel propertyAccessModel) {
        final List<ColumnConfig<T, ?>> columnConfigList = GridAttributeFactory
                .<T>getColumnConfig(propertyAccessModel);
        if (!CollectionUtil.isEmpty(columnConfigList)) {
            ValueProvider<? super T, ?> valueProvider = null;
            String path = null;
            for (ColumnConfig<T, ?> columnConfig : columnConfigList) {
                valueProvider = columnConfig == null ? null : columnConfig.getValueProvider();
                path = valueProvider == null ? null : valueProvider.getPath();
                if (!StringUtil.isNullOrEmpty(path)) {
                    valueProviderMap.put(path, valueProvider);
                }
            }
        }
    }

    public ColumnConfig<T, Comparable> getColumn(ValueProvider<?, ?> valueProvider) {
        ColumnConfig<T, Comparable> colConfig = null;
        if (null != valueProvider) {
            int totalColumn = cm.getColumnCount();
            ValueProvider<? super T, Object> currentValueProvider = null;
            for (int columnIndex = 0; columnIndex < totalColumn; columnIndex++) {
                currentValueProvider = cm.getValueProvider(columnIndex);
                if (currentValueProvider == valueProvider) {
                    colConfig = cm.getColumn(columnIndex);
                    break;
                }
            }
        }
        return colConfig;
    }

    public int getColumnIndex(ValueProvider<?, ?> valueProvider) {
        int index = -1;
        if (null != valueProvider) {
            int totalColumn = cm.getColumnCount();
            ValueProvider<? super T, Object> currentValueProvider = null;
            for (int columnIndex = 0; columnIndex < totalColumn; columnIndex++) {
                currentValueProvider = cm.getValueProvider(columnIndex);
                if (currentValueProvider == valueProvider) {
                    index = columnIndex;
                    break;
                }
            }
        }
        return index;
    }

    @Override
    protected void onLoad() {
        super.onLoad();
        addFilterHeader();

    }

    @Override
    protected void onAttach() {
        super.onAttach();
        Timer timer = new Timer() {

            @Override
            public void run() {
                setGridDimension(resizablePanel, 0.9999f, 0.9999f);
            }
        };
        timer.schedule(80);
    }

    private void addFilterHeader() {
        Timer timer = new Timer() {

            @Override
            public void run() {
                if (!CollectionUtil.isEmpty(filtersList)) {
                    for (final Filter<T, ?> gridFilter : filtersList) {
                        if (null != gridFilter) {
                            ValueProvider<? super T, ?> valueProvider = gridFilter.getValueProvider();
                            if (null != valueProvider) {
                                int columnIndex = getColumnIndex(valueProvider);
                                if (columnIndex != -1) {
                                    ColumnHeader<T> header = view.getHeader();
                                    if (null != header) {
                                        header.getHead(columnIndex).addStyleName(COLUMN_HEADER);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        };
        timer.schedule(100);
    }

    public void addEditor(ValueProvider valueProvider, Field field) {
        ColumnConfig<T, ?> columnConfig = getColumn(valueProvider);
        if (null != columnConfig && editingGrid != null) {
            addEditor(columnConfig, field);
        }
    }

    public List<T> getSelectedModels() {
        List<T> componentsList = this.store.getAll();
        this.store.commitChanges();
        List<T> selectedComponentList = new ArrayList<T>();
        if (!CollectionUtil.isEmpty(componentsList)) {
            for (T component : componentsList) {
                if (component != null && component.isSelected()) {
                    selectedComponentList.add(component);
                }
            }
        }
        return selectedComponentList;
    }

    private GridInlineEditing<T> getGridEditing() {
        return new GridInlineEditing<T>(this) {

            @Override
            protected <N, O> void doStartEditing(com.sencha.gxt.widget.core.client.grid.Grid.GridCell cell) {
                super.doStartEditing(cell);
                ColumnModel<T> columnModel = getColumnModel();
                if (null != columnModel) {
                    ColumnConfig<T, ?> columnConfig = columnModel.getColumn(cell.getCol());
                    if (null != columnConfig) {
                        IsField<T> editor = getEditor(columnConfig);
                        Element cellElement = Grid.this.getView().getCell(cell.getRow(), cell.getCol());
                        if (editor instanceof Field) {
                            Field<T> field = (Field<T>) editor;
                            Widget editorWidget = editor.asWidget();
                            int client_y = cellElement.getOffsetTop();
                            int client_x = cellElement.getOffsetLeft();
                            int width = cellElement.getAbsoluteRight() - cellElement.getAbsoluteLeft();
                            int height = cellElement.getAbsoluteBottom() - cellElement.getAbsoluteTop() + 3;
                            field.setPixelSize(width, height);
                            editorWidget.getElement().getStyle().setTop(client_y, Unit.PX);
                            editorWidget.getElement().getStyle().setLeft(client_x, Unit.PX);
                        }
                    }
                }
            }
        };
    }

    public void setEditable(final PropertyAccessModel propertyAccessor) {
        if (editingGrid == null) {
            this.editable = true;
            editingGrid = getGridEditing();
            this.setSelectionModel(new CellSelectionModel<T>());
            Map<ColumnConfig<T, Comparable>, IsField<Comparable>> editorMap = GridAttributeFactory
                    .getEditors(propertyAccessor);
            this.addEditor(editorMap);
            editingGrid.addBeforeStartEditHandler(new BeforeStartEditHandler<T>() {

                @Override
                public void onBeforeStartEdit(BeforeStartEditEvent<T> event) {
                    Grid.this.beforeStartEditing(event);
                }
            });
            editingGrid.addCompleteEditHandler(new CompleteEditHandler<T>() {

                @Override
                public void onCompleteEdit(CompleteEditEvent<T> event) {
                    Grid.this.completeEditing(event);
                }
            });
        }
    }

    public void startEditing(final GridCell cell) {
        if (editingGrid != null && cell != null) {

            Timer timer = new Timer() {

                @Override
                public void run() {
                    editingGrid.startEditing(cell);
                }
            };
            timer.schedule(300);
        }
    }

    public void refreshRow(int rowIndex) {
        if (gridView != null && !(rowIndex < 0)) {
            gridView.refreshGridRow(rowIndex);

            // Added missing null check for selected row.
            if (null != currentSelectedCell) {
                int row = currentSelectedCell.getRow();
                int col = currentSelectedCell.getCol();
                selectGridCell(row, col);
                Element rowElement = gridView.getRow(row);
                Element columnElement = gridView.getCell(row, col);
                if (null != rowElement && null != columnElement) {
                    if (null != lastSelectedRow && null != lastSelectedColumn) {
                        lastSelectedRow.removeClassName("selectedRow");
                        lastSelectedColumn.removeClassName("selectedColumn");
                    }
                    lastSelectedRow = rowElement;
                    lastSelectedColumn = columnElement;
                    lastSelectedRow.addClassName("selectedRow");
                    lastSelectedColumn.addClassName("selectedColumn");
                }
            }
        }
    }

    public void reLoad() {
        this.getView().refresh(false);
    }

    /**
     * @return the editable
     */
    public boolean isEditable() {
        return editable;
    }

    public <W> void addEditor(final ColumnConfig<T, W> columnConfig, final IsField<W> editorWidget) {
        if (editingGrid != null && columnConfig != null && editorWidget != null) {
            editingGrid.addEditor(columnConfig, editorWidget);
        }
    }

    public void addEditor(final Map<ColumnConfig<T, Comparable>, IsField<Comparable>> editorsMap) {
        if (!CollectionUtil.isEmpty(editorsMap)) {
            ColumnConfig<T, Comparable> columnConfigEntry;
            IsField<Comparable> fieldWidget;
            for (final Entry<ColumnConfig<T, Comparable>, IsField<Comparable>> editorEntry : editorsMap
                    .entrySet()) {
                columnConfigEntry = editorEntry.getKey();
                fieldWidget = editorEntry.getValue();
                addEditor(columnConfigEntry, fieldWidget);
            }
        }
    }

    public void setAutoFit(boolean isAutoFilt) {
        if (gridView != null) {
            gridView.setForceFit(isAutoFilt);
        }
    }

    public void setMemoryData(Collection<T> dataToSet) {
        if (proxy instanceof Grid.PagingMemoryProxy) {
            if (hasPagination) {
                PagingMemoryProxy memoryProxy = (PagingMemoryProxy) proxy;
                memoryProxy.setData(dataToSet);
            } else {
                store.clear();
                if (!CollectionUtil.isEmpty(dataToSet)) {
                    store.addAll(dataToSet);
                }
            }
        }
    }

    public ListStore<T> getMemoryData() {
        ListStore<T> dataList = null;
        if (proxy instanceof Grid.PagingMemoryProxy) {
            if (hasPagination) {
                PagingMemoryProxy memoryProxy = (PagingMemoryProxy) proxy;
                dataList = memoryProxy.getDataItems();
            } else {
                dataList = store;
            }
        }
        return dataList;
    }

    /**
     * 
     * @author Ephesoft.
     * @version 1.0.
     * 
     */
    private class PagingMemoryProxy extends MemoryProxy<FilterPagingLoadConfig, PagingLoadResult<T>> {

        private ListStore<T> totalList;

        public PagingMemoryProxy(List<T> totalList, ModelKeyProvider<T> keyProvider) {
            super(null);
            this.totalList = CollectionUtil.createListStore(keyProvider);
            if (!CollectionUtil.isEmpty(totalList)) {
                this.totalList.addAll(totalList);
            }
        }

        public void setData(Collection<T> dataToSet) {
            totalList.clear();
            if (!CollectionUtil.isEmpty(dataToSet)) {
                totalList.addAll(dataToSet);
            }
        }

        @Override
        public void load(FilterPagingLoadConfig loadConfig,
                com.google.gwt.core.client.Callback<PagingLoadResult<T>, Throwable> callback) {
            if (loadConfig != null && callback != null && totalList != null) {
                ListStore<T> proxyStore = null;

                proxyStore = hasPagination ? totalList : store;
                if (gridFilter != null) {
                    StoreFilter<T> currentFilterStore = gridFilter.getCurrentFilters();
                    proxyStore.addFilter(currentFilterStore);
                }
                int totalRows = proxyStore.size();
                int offset = loadConfig.getOffset();
                int totalDisplayableRows = loadConfig.getLimit();
                int upperRowLimit = totalRows == 0 ? 0 : offset + totalDisplayableRows;
                if (hasPagination) {
                    upperRowLimit = upperRowLimit > totalRows ? totalRows : upperRowLimit;
                } else {
                    upperRowLimit = store.size();
                }
                List<? extends SortInfo> sortInfoList = loadConfig.getSortInfo();
                this.applySort(proxyStore, loadConfig, sortInfoList);

                List<T> results = proxyStore.subList(offset, upperRowLimit);
                PagingLoadResultBean<T> bean = new PagingLoadResultBean<T>(results, totalRows, offset);
                callback.onSuccess(bean);
            }
        }

        private void applySort(ListStore<T> proxyStore, FilterPagingLoadConfig loadConfig,
                List<? extends SortInfo> sortInfoList) {
            if (!CollectionUtil.isEmpty(sortInfoList)) {
                proxyStore.clearSortInfo();
                for (SortInfo sortInfo : loadConfig.getSortInfo()) {
                    this.applySort(proxyStore, sortInfo);
                }
            }
        }

        private void applySort(ListStore<T> proxyStore, SortInfo sortInfo) {
            if (sortInfo != null) {
                Map<String, ValueProvider<? super T, ?>> valueProviderMap = Grid.this.valueProviderMap;
                String fieldPath = sortInfo.getSortField();
                ValueProvider<? super T, Comparable> fieldValueProvider = (ValueProvider<? super T, Comparable>) valueProviderMap
                        .get(fieldPath);
                if (null != fieldValueProvider) {
                    StoreSortInfo<T> sortField = new StoreSortInfo<T>(fieldValueProvider, sortInfo.getSortDir());
                    proxyStore.addSortInfo(sortField);
                }
            }
        }

        public ListStore<T> getDataItems() {
            return totalList;
        }
    }

    private class GridFilter extends GridFilters<T> {

        public GridFilter(Loader<FilterPagingLoadConfig, ?> loader) {
            super(loader);
        }

        public StoreFilter<T> getCurrentFilters() {
            return this.getModelFilter();
        }

        public void addFilters(List<Filter<T, ?>> filtersList) {
            if (!CollectionUtil.isEmpty(filtersList)) {
                for (Filter<T, ?> gridFilter : filtersList) {
                    if (null != gridFilter) {
                        this.addFilter(gridFilter);
                    }
                }
            }
        }

        @Override
        protected void onStateChange(Filter<T, ?> filter) {
            super.onStateChange(filter);
        }

    }

    public int getGridRowCount() {
        int size = 0;
        if (null != store)
            size = store.size();
        return size;
    }

    public void clearFilter() {
        if (null != gridFilter) {
            gridFilter.clearFilters();
        }
    }

    public void addLoadHandler(LoadHandler<FilterPagingLoadConfig, PagingLoadResult<T>> loadHandler) {
        if (null != loader) {
            loader.addLoadHandler(loadHandler);
        }
    }

    public void removeItemsFromGrid(List<T> itemList) {
        ListStore<T> componentsList = getMemoryData();
        if (!CollectionUtil.isEmpty(itemList)) {
            for (T component : itemList) {
                componentsList.remove(component);
            }
        }
        componentsList.commitChanges();
    }

    public boolean addNewItemInGrid(T item) {
        boolean itemAdded = false;
        if (null != item) {
            if (isGridValidated()) {
                ListStore<T> componentsList = getMemoryData();
                componentsList.clearSortInfo();
                componentsList.commitChanges();
                int activePage = (loader.getOffset() / loader.getLimit()) + 1;
                int insertionIndex = getInsertionIndexForItem(activePage, loader.getLimit());
                componentsList.add(insertionIndex, item);
                itemAdded = true;
                componentsList.commitChanges();
                List<? extends SortInfo> sortList = new ArrayList<SortInfo>(this.loader.getSortInfo());
                this.loader.clearSortInfo();
                this.loader.load(loader.getOffset(), loader.getLimit());
                addSortInfosToLoader(sortList);
                startEditing(this.store.indexOf(item));
            } else {
                DialogUtil.showMessageDialog(LocaleDictionary.getConstantValue(LocaleCommonConstants.ERROR_TITLE),
                        LocaleDictionary.getConstantValue(CoreCommonConstants.VALIDATE_GRID_ERR_MSG),
                        DialogIcon.ERROR);
            }
        }
        return itemAdded;
    }

    private void addSortInfosToLoader(List<? extends SortInfo> sortInfos) {
        if (!CollectionUtil.isEmpty(sortInfos)) {
            for (SortInfo sortInfo : sortInfos) {
                this.loader.addSortInfo(sortInfo);
            }
        }
    }

    public void startEditing(final int rowIndex) {
        Timer timer = new Timer() {

            @Override
            public void run() {
                if (null != editingGrid) {
                    int totalColumn = cm.getColumnCount();
                    for (int index = 0; index < totalColumn; index++) {
                        ColumnConfig<T, ?> columnConfig = cm.getColumn(index);
                        if (null != columnConfig && editingGrid.getEditor(columnConfig) != null) {
                            GridCell cell = new GridCell(rowIndex, index);
                            editingGrid.startEditing(cell);
                            break;
                        }
                    }
                }
            }
        };
        timer.schedule(EDITING_DELAY);
    }

    public void addSelectAllFunctionality(final ValueProvider<T, ?> valueProvider) {
        if (null != valueProvider) {
            ColumnConfig<T, ?> columnConfig = getColumn(valueProvider);
            if (null != columnConfig) {
                columnConfig.setSortable(false);
                columnConfig.setMenuDisabled(true);
                columnConfig.setHideable(false);
                columnConfig.setWidget(getAllModelsSelector(), SafeHtmlUtils.fromSafeConstant("."));
            }
        }
    }

    private Widget getAllModelsSelector() {
        if (null == selectAllCheckBox) {
            selectAllCheckBox = new CheckBox();
            selectAllCheckBox.addStyleName("selectAllCheckBox");
            selectAllCheckBox.addValueChangeHandler(new ValueChangeHandler<Boolean>() {

                @Override
                public void onValueChange(ValueChangeEvent<Boolean> event) {
                    setSelectedAllModels(selectAllCheckBox.getValue());
                    reLoad();
                    store.commitChanges();
                }
            });
        }
        return selectAllCheckBox;
    }

    public int getInsertionIndexForItem(int currentPage, int pageSize) {
        int count = 0;
        boolean isSelected = false;
        int totalItems = this.store.size();
        List<T> componentsList = this.store.getAll();
        this.store.commitChanges();
        if (!CollectionUtil.isEmpty(componentsList)) {
            for (T component : componentsList) {
                count++;
                if (component != null && component.isSelected()) {
                    isSelected = true;
                    break;
                }
            }
        } else {
            return count;
        }
        return isSelected ? (currentPage - 1) * pageSize + count - 1
                : (pageSize > totalItems ? (currentPage - 1) * pageSize + totalItems
                        : (currentPage - 1) * pageSize + totalItems - 1);
    }

    public void deSelectModels() {
        List<T> componentsList = this.store.getAll();
        this.store.commitChanges();
        if (!CollectionUtil.isEmpty(componentsList)) {
            for (T component : componentsList) {
                if (component != null && component.isSelected()) {
                    component.setSelected(false);
                }
            }
        }
        this.store.commitChanges();
    }

    public void addValidators(ValueProvider<T, ?> key, Validator<T> value) {
        if (validatorsMap.containsKey(key)) {
            validatorsMap.get(key).add(value);
        } else {
            List<Validator<T>> validators = new ArrayList<Validator<T>>();
            validators.add(value);
            validatorsMap.put(key, validators);
        }
    }

    public void setFirstRowSelectedOnLoad(boolean firstRowSelectedOnLoad) {
        this.firstRowSelectedOnLoad = firstRowSelectedOnLoad;
    }

    public void finishEditing() {
        if (null != editingGrid) {
            editingGrid.completeEditing();
        }
    }

    public boolean isHasPagination() {
        return hasPagination;
    }

    public void setHasPagination(boolean hasPagination) {
        this.hasPagination = hasPagination;
    }

    public boolean isGridValidated() {
        int totalModels = store.size();
        int totalColumn = cm.getColumnCount();
        boolean isGridValidated = true;
        gridValidationLoop: for (int currentModel = 0; currentModel < totalModels; currentModel++) {
            for (int currrentColumn = 0; currrentColumn < totalColumn; currrentColumn++) {
                ValueProvider<? super T, Object> currentValueProvider = cm.getValueProvider(currrentColumn);
                isGridValidated = getErrors(currentValueProvider, store.get(currentModel)) == null;
                if (!isGridValidated) {
                    break gridValidationLoop;
                }
            }
        }
        return isGridValidated;
    }

    public void setGridValidated(boolean isGridValidated) {
        // this.isGridValidated = isGridValidated;
    }

    public T getModel(int index) {
        T model = null;
        if (store.size() > index) {
            model = store.get(index);
        }
        return model;
    }

    public void addEditorWidget(ValueProvider<T, ?> valueProvider, IsField<Comparable> fieldWidget) {
        if (null != valueProvider && null != fieldWidget) {
            ColumnConfig<T, Comparable> columnConfig = getColumn(valueProvider);
            if (null != columnConfig) {
                addEditor(columnConfig, fieldWidget);
            }
        }
    }

    public void setCell(ValueProvider<T, ?> valueProvider, Cell cell) {
        if (null != valueProvider && null != cell) {
            ColumnConfig<T, Comparable> columnConfig = getColumn(valueProvider);
            if (null != columnConfig) {
                columnConfig.setCell(cell);
            }
        }
    }

    public <W> IsField<W> getEditorWidget(ValueProvider<T, ?> valueProvider) {
        IsField<W> editorWidget = null;
        if (editingGrid != null && valueProvider != null) {
            ColumnConfig<T, Comparable> columnConfig = getColumn(valueProvider);
            if (null != columnConfig) {
                editorWidget = editingGrid.getEditor(columnConfig);
            }
        }
        return editorWidget;
    }

    public void refreshGrid(T modelToCheck, boolean isCurrentSelectedRefreshed) {
        if (isCurrentSelectedRefreshed) {
            reLoad();
        } else {
            ListStore<T> listStore = getStore();
            if (null != listStore && listStore.size() > 0) {
                List<T> modelList = listStore.getAll();
                if (!CollectionUtil.isEmpty(modelList)) {
                    int rowIndex = 0;
                    for (T model : modelList) {
                        if (null != modelToCheck && modelToCheck != model) {
                            refreshRow(rowIndex);
                        }
                        rowIndex++;
                    }
                }
            }

        }
    }

    public void cancelEditing() {
        if (null != editingGrid) {
            editingGrid.cancelEditing();
        }
    }

    /**
     * Returns the index of the first occurrence of the specified element in this list, or -1 if this list does not contain the
     * element.
     * 
     * @param item the visible item
     * @return the index of the item
     */
    public int getRowIndex(T modelToCheck) {
        int rowIndex = -1;
        final ListStore<T> listStore = getStore();
        if (null != listStore && listStore.size() > 0) {
            rowIndex = listStore.indexOf(modelToCheck);
        }
        return rowIndex;
    }

    public boolean isValid(T model) {
        boolean isModelValid = true;
        if (null != model) {
            int totalColumn = cm.getColumnCount();
            for (int currrentColumn = 0; currrentColumn < totalColumn; currrentColumn++) {
                ValueProvider<? super T, Object> currentValueProvider = cm.getValueProvider(currrentColumn);
                isModelValid = getErrors(currentValueProvider, model) == null;
                if (!isModelValid) {
                    break;
                }
            }
        }
        return isModelValid;
    }

    /**
     * @return the currentSelectedModel
     */
    public T getCurrentSelectedModel() {
        return currentSelectedModel;
    }

    protected void setCurrentModel(T model) {
        this.currentSelectedModel = null;
    }

    protected void onCellSelectionChange(T model) {

    }

    protected void onBeforeCellSelectionChange(BeforeSelectionEvent<T> event, T model) {

    }

    public GridCell getCurrentSelectedCell() {
        return currentSelectedCell;
    }

    public PropertyAccessModel getPropertyAccessModel() {
        return propertyAccessModel;
    }

    public CheckBox getSelectAllCheckBox() {
        return selectAllCheckBox;
    }

}