ca.qc.cegepoutaouais.tge.pige.client.ui.widget.ItemEditor.java Source code

Java tutorial

Introduction

Here is the source code for ca.qc.cegepoutaouais.tge.pige.client.ui.widget.ItemEditor.java

Source

/*
 * Copyright 2010, 2011 Renaud Brub
 *
 * This file is part of PIGE.
 *
 * PIGE is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * PIGE 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with PIGE.  If not, see <http://www.gnu.org/licenses/>.
 */
package ca.qc.cegepoutaouais.tge.pige.client.ui.widget;

import ca.qc.cegepoutaouais.tge.pige.client.GXTUtil;
import ca.qc.cegepoutaouais.tge.pige.client.HTMLItemFormatter;
import ca.qc.cegepoutaouais.tge.pige.client.ItemStatus;
import ca.qc.cegepoutaouais.tge.pige.client.ItemStatus.ItemStatusModel;
import ca.qc.cegepoutaouais.tge.pige.client.PIGE;
import ca.qc.cegepoutaouais.tge.pige.client.PigeMessages;
import ca.qc.cegepoutaouais.tge.pige.client.PigeUtil;
import ca.qc.cegepoutaouais.tge.pige.client.PrintViewer;
import ca.qc.cegepoutaouais.tge.pige.client.resources.Resources;
import ca.qc.cegepoutaouais.tge.pige.client.services.ManagementServiceAsync;
import ca.qc.cegepoutaouais.tge.pige.client.services.exceptions.QuerySyntaxException;
import ca.qc.cegepoutaouais.tge.pige.client.ui.AppWidgets;
import ca.qc.cegepoutaouais.tge.pige.client.ui.dialog.AbstractCEVDialog.CEV;
import ca.qc.cegepoutaouais.tge.pige.client.ui.dialog.ItemCEVDialog;
import ca.qc.cegepoutaouais.tge.pige.client.ui.dialog.RoomLayoutDialog;
import ca.qc.cegepoutaouais.tge.pige.client.ui.widget.AbstractFieldListener.FieldUpdater;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Item;
import ca.qc.cegepoutaouais.tge.pige.dao.pojos.Loan;
import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelReader;
import com.extjs.gxt.ui.client.data.FilterConfig;
import com.extjs.gxt.ui.client.data.LoadConfig;
import com.extjs.gxt.ui.client.data.Loader;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ButtonEvent;
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.event.MenuEvent;
import com.extjs.gxt.ui.client.event.MessageBoxEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.MessageBox;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnData;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridCellRenderer;
import com.extjs.gxt.ui.client.widget.layout.RowData;
import com.extjs.gxt.ui.client.widget.layout.RowLayout;
import com.extjs.gxt.ui.client.widget.menu.AdapterMenuItem;
import com.extjs.gxt.ui.client.widget.menu.HeaderMenuItem;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.extjs.gxt.ui.client.widget.menu.SeparatorMenuItem;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Renaud Brub
 *
 */
public class ItemEditor extends ContentPanel implements HasSearchSupport {

    public static EventType AfterDeleteItem = new EventType();

    public class ItemEditorEvent extends BaseEvent {

        private List<Item> items = null;

        public ItemEditorEvent(EventType type) {
            super(type);
        }

        public ItemEditorEvent(EventType type, List<Item> items) {
            super(type);
            this.items = items;
        }

        public List<Item> getItems() {
            return items;
        }

        public void setItems(List<Item> items) {
            this.items = items;
        }
    }

    final PigeMessages messages = PIGE.messages;
    private int PAGE_SIZE = 50;

    private RpcProxy<PagingLoadResult<Item>> proxy = null;
    private BasePagingLoader<PagingLoadResult<ModelData>> itemLoader = null;
    private BasePagingLoadConfig loadConfigs = null;
    private Grid<BeanModel> grid = null;
    private ListStore<BeanModel> itemStore = null;
    private PagingToolBar pagingTB = null;
    final StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR);
    private List<BeanModel> selectedItems = null;
    private List<FilterConfig> searchConfigList = new ArrayList();
    private List<FilterConfig> fieldsConfigList = new ArrayList();
    private List<FilterConfig> stateConfigList = new ArrayList();

    private EditorMode mode = EditorMode.Normal;

    public ItemEditor(EditorMode mode) {
        this.mode = mode;
        initialize();
    }

    public ItemEditor() {
        initialize();
    }

    protected void initialize() {

        setHeaderVisible(Boolean.FALSE);
        setBorders(Boolean.FALSE);

        proxy = new RpcProxy<PagingLoadResult<Item>>() {

            @Override
            protected void load(Object loadConfig, final AsyncCallback<PagingLoadResult<Item>> callback) {

                statusBar.setBusyText(messages.loading());

                // Obtenir le nombre de rle demand  partir du service RPC.
                ManagementServiceAsync rpcService = Registry.get(PIGE.MANAGEMENT_SERVICE);
                rpcService.getItems((PagingLoadConfig) loadConfig, new AsyncCallback<PagingLoadResult<Item>>() {

                    @Override
                    public void onSuccess(PagingLoadResult result) {
                        statusBar.getStatus().clearStatus(messages.loadDone());
                        callback.onSuccess(result);

                        // Corrige un problme d'affichage pour l'Inventory Explorer.
                        // Sans a, les items ne s'affichent pas dans le grid  moins
                        // de redimmensionner la bote de dialogue.
                        layout(Boolean.TRUE);
                    }

                    @Override
                    public void onFailure(Throwable caught) {
                        callback.onFailure(caught);
                        if (caught instanceof QuerySyntaxException) {
                            PIGE.handleException(caught);
                        }
                    }
                }); // getItems()
            } // load()
        }; // new RpcProxy

        loadConfigs = new BasePagingLoadConfig();
        itemLoader = new BasePagingLoader<PagingLoadResult<ModelData>>(proxy, new BeanModelReader()) {

            @Override
            protected LoadConfig newLoadConfig() {
                return loadConfigs;
            }
        };
        itemLoader.setRemoteSort(false);

        itemStore = new ListStore<BeanModel>(itemLoader);

        pagingTB = new PagingToolBar(PAGE_SIZE);
        pagingTB.bind(itemLoader);

        grid = new Grid<BeanModel>(itemStore, createColumnModel());
        grid.setLoadMask(true);
        grid.setBorders(false);
        grid.setAutoExpandColumn(Loan.DESCRIPTION_REF);
        grid.getView().setAutoFill(true);
        grid.getView().setEmptyText(messages.noItemToShow());
        grid.setTrackMouseOver(true);
        grid.getSelectionModel().addSelectionChangedListener(new SelectionChangedListener<BeanModel>() {

            @Override
            public void selectionChanged(SelectionChangedEvent<BeanModel> event) {
                selectedItems = event.getSelection();
            }
        });
        grid.addListener(Events.RowDoubleClick, new Listener<GridEvent>() {

            @Override
            public void handleEvent(GridEvent event) {
                onGridDoubleClick();
            }
        });
        grid.setContextMenu(createContextMenu());

        setLayout(new RowLayout());
        setTopComponent(createToolBar());
        setBottomComponent(pagingTB);
        RowData data = new RowData(1, 1);
        add(grid, data);

        layout();

        searchConfigList = new ArrayList<FilterConfig>();
        fieldsConfigList = new ArrayList<FilterConfig>();
        stateConfigList = new ArrayList<FilterConfig>();
        loadConfigs.set(PIGE.SEARCH_CONFIGS, searchConfigList);
        loadConfigs.set(PIGE.ITEM_FIELDS_CONFIGS, fieldsConfigList);
        loadConfigs.set(PIGE.ITEM_STATE_CONFIGS, stateConfigList);

    }

    protected ColumnModel createColumnModel() {
        List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
        ColumnConfig idCC = new ColumnConfig(Item.ID_REF, messages.id(), 30);
        ColumnConfig nameCC = new ColumnConfig(Item.NAME_REF, messages.name(), 80);
        ColumnConfig modelCC = new ColumnConfig(Item.MODEL_REF, messages.model(), 50);
        ColumnConfig quantityCC = new ColumnConfig(Item.QUANTITY_REF, messages.quantity(), 50);
        NumberFormat nf = NumberFormat.getFormat(PIGE.QUANTITY_FORMAT);
        quantityCC.setNumberFormat(nf);
        ColumnConfig descriptionCC = new ColumnConfig(Item.DESCRIPTION_REF, messages.description(), 150);
        ColumnConfig locationCC = new ColumnConfig(Item.LOCATION_REF, messages.location(), 100);
        ColumnConfig serialNumberCC = new ColumnConfig(Item.SERIA_NUMBER_REF, messages.serialNumber(), 50);
        ColumnConfig versionCC = new ColumnConfig(Item.VERSION_REF, messages.version(), 50);
        ColumnConfig statusCC = new ColumnConfig(Item.STATUS_REF, messages.status(), 50);
        statusCC.setRenderer(new GridCellRenderer<BeanModel>() {

            @Override
            public Object render(BeanModel model, String property, ColumnData config, int rowIndex, int colIndex,
                    ListStore<BeanModel> store, Grid<BeanModel> grid) {
                return (String) ItemStatus.getInstance().get((String) model.get(property));
            }
        });

        configs.add(idCC);
        configs.add(nameCC);
        configs.add(modelCC);
        configs.add(quantityCC);
        configs.add(statusCC);
        configs.add(locationCC);
        configs.add(descriptionCC);
        configs.add(serialNumberCC);
        configs.add(versionCC);

        return new ColumnModel(configs);
    }

    protected Menu createContextMenu() {

        Menu contextMenu = new Menu();
        contextMenu.add(new HeaderMenuItem(messages.itemMenu()));

        MenuItem viewItemMenu = new MenuItem(messages.view() + PIGE.DIALOG_OPENER_INDICATOR);
        viewItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() {

            @Override
            public void componentSelected(MenuEvent event) {
                viewItem();
            }
        });
        contextMenu.add(viewItemMenu);

        if (mode == EditorMode.Normal) {
            MenuItem createItemMenu = new MenuItem(messages.create() + PIGE.DIALOG_OPENER_INDICATOR);
            createItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() {

                @Override
                public void componentSelected(MenuEvent event) {
                    createItem();
                }
            });
            MenuItem copyItemMenu = new MenuItem(messages.copy() + PIGE.DIALOG_OPENER_INDICATOR);
            copyItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() {

                @Override
                public void componentSelected(MenuEvent event) {
                    copyItem();
                }
            });
            MenuItem editItemMenu = new MenuItem(messages.edit() + PIGE.DIALOG_OPENER_INDICATOR);
            editItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() {

                @Override
                public void componentSelected(MenuEvent event) {
                    editItem();
                }
            });
            MenuItem deleteItemMenu = new MenuItem(messages.delete());
            deleteItemMenu.addSelectionListener(new SelectionListener<MenuEvent>() {

                @Override
                public void componentSelected(MenuEvent event) {
                    deleteItem();
                }
            });

            MenuItem quickEditMenuItem = new MenuItem(messages.quickEdit());
            Menu quickEditMenu = new Menu();
            quickEditMenuItem.setSubMenu(quickEditMenu);
            configureQuickEditMenu(quickEditMenu, contextMenu);

            MenuItem removeItemsFromSelectedCategoryMenu = new MenuItem(messages.removeItemListFromCategory());
            removeItemsFromSelectedCategoryMenu.addSelectionListener(new SelectionListener<MenuEvent>() {

                @Override
                public void componentSelected(MenuEvent event) {
                    removeItemListFromCategory();
                }
            });

            contextMenu.add(createItemMenu);
            contextMenu.add(copyItemMenu);
            contextMenu.add(editItemMenu);
            contextMenu.add(deleteItemMenu);
            contextMenu.add(new SeparatorMenuItem());
            contextMenu.add(quickEditMenuItem);
            contextMenu.add(new SeparatorMenuItem());
            contextMenu.add(removeItemsFromSelectedCategoryMenu);
        }

        contextMenu.add(new SeparatorMenuItem());
        MenuItem printMenu = new MenuItem(messages.print() + PIGE.DIALOG_OPENER_INDICATOR);
        printMenu.addSelectionListener(new SelectionListener<MenuEvent>() {

            @Override
            public void componentSelected(MenuEvent event) {
                printSearchResult();
            }
        });
        contextMenu.add(printMenu);

        return contextMenu;
    }

    protected ToolBar createToolBar() {

        ToolBar actionTB = new ToolBar();

        Button viewBtn = new Button(messages.view());
        viewBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.eyeIcon()));
        viewBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent event) {
                viewItem();
            }
        });
        actionTB.add(viewBtn);
        actionTB.add(PigeUtil.createVerticalSeparator());

        if (mode == EditorMode.Normal) {
            Button createBtn = new Button(messages.create());
            createBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.pageAddIcon()));
            createBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {

                @Override
                public void componentSelected(ButtonEvent event) {
                    createItem();
                }
            });
            actionTB.add(createBtn);
            actionTB.add(PigeUtil.createVerticalSeparator());

            Button copyBtn = new Button(messages.copy());
            copyBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.pageCopyIcon()));
            copyBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {

                @Override
                public void componentSelected(ButtonEvent event) {
                    copyItem();
                }
            });
            actionTB.add(copyBtn);
            actionTB.add(PigeUtil.createVerticalSeparator());

            Button editBtn = new Button(messages.edit());
            editBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.pageEditIcon()));
            editBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {

                @Override
                public void componentSelected(ButtonEvent event) {
                    editItem();
                }
            });
            actionTB.add(editBtn);
            actionTB.add(PigeUtil.createVerticalSeparator());

            Button deleteBtn = new Button(messages.delete());
            deleteBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.pageDeleteIcon()));
            deleteBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {

                @Override
                public void componentSelected(ButtonEvent event) {
                    deleteItem();
                }
            });
            actionTB.add(deleteBtn);
            actionTB.add(PigeUtil.createVerticalSeparator());

            /*Button removeItemListFromCategoryBtn = new Button(
                messages.removeItemListFromCategory());
            removeItemListFromCategoryBtn.addSelectionListener(
                new SelectionListener<ButtonEvent>() {
                
            @Override
            public void componentSelected(ButtonEvent event) {
                removeItemListFromCategory();
            }
            });
            actionTB.add(removeItemListFromCategoryBtn);
            actionTB.add(PigeUtil.createVerticalSeparator());*/

            Button roomLayoutsCBxBtn = new Button(messages.roomLayouts());
            Menu roomLayoutsCBxMenu = new Menu();
            roomLayoutsCBxBtn.setMenu(roomLayoutsCBxMenu);
            Button tgeStoreLayoutBtn = new Button(messages.tgeStoreLayout());
            roomLayoutsCBxMenu.add(tgeStoreLayoutBtn);
            tgeStoreLayoutBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {

                @Override
                public void componentSelected(ButtonEvent ce) {
                    new RoomLayoutDialog("pige-tge-store-layout", messages.tgeStoreLayout()).show();
                }
            });
            actionTB.add(roomLayoutsCBxBtn);
            actionTB.add(PigeUtil.createVerticalSeparator());
        }

        Button printBtn = new Button(messages.print() + PIGE.DIALOG_OPENER_INDICATOR);
        printBtn.setIcon(AbstractImagePrototype.create(Resources.INSTANCE.printerIcon()));
        printBtn.addSelectionListener(new SelectionListener<ButtonEvent>() {

            @Override
            public void componentSelected(ButtonEvent event) {
                printSearchResult();
            }
        });
        actionTB.add(printBtn);
        actionTB.add(PigeUtil.createVerticalSeparator());

        return actionTB;
    }

    protected void printSearchResult() {
        if (itemStore.getCount() <= 0) {
            MessageBox.info(messages.information(), messages.noDataToPrint(), null);
            return;
        }
        doPrintSearchResult();
    }

    protected void doPrintSearchResult() {
        BasePagingLoadConfig config = new BasePagingLoadConfig();
        config.setProperties(getLoadConfig().getProperties());
        config.setLimit(0); // Pas de limite.
        config.setOffset(0);
        final MessageBox progressBar = MessageBox.wait(messages.fetchingData(), null, null);
        ManagementServiceAsync rpcService = (ManagementServiceAsync) Registry.get(PIGE.MANAGEMENT_SERVICE);
        rpcService.getItems(config, new AsyncCallback<PagingLoadResult<Item>>() {

            @Override
            public void onSuccess(PagingLoadResult<Item> result) {
                HTMLItemFormatter formatter = new HTMLItemFormatter();
                formatter.setTitle(messages.inventory() + " - " + messages.searchResults());
                String data = formatter.format(result.getData());
                PrintViewer viewer = new PrintViewer();
                viewer.setContent(data);
                progressBar.close();
                viewer.show();
            }

            @Override
            public void onFailure(Throwable caught) {
                PIGE.handleException(caught);
            }
        });
    }

    protected void viewItem() {
        if (!validateItemSelection()) {
            return;
        }
        ItemCEVDialog dialog = new ItemCEVDialog(CEV.VIEW);
        dialog.setData("item", getLastSelectedItem().getBean());
        dialog.showDialog();
    }

    protected void createItem() {
        new ItemCEVDialog(CEV.CREATE).showDialog();
    }

    protected void copyItem() {
        if (!validateItemSelection()) {
            return;
        }
        ItemCEVDialog dialog = new ItemCEVDialog(CEV.COPY);
        dialog.setData("item", getLastSelectedItem().getBean());
        dialog.showDialog();
    }

    protected void editItem() {
        if (!validateItemSelection()) {
            return;
        }
        ItemCEVDialog dialog = new ItemCEVDialog(CEV.EDIT);
        dialog.setData("item", getLastSelectedItem().getBean());
        dialog.showDialog();
    }

    protected void deleteItem() {
        if (!validateItemSelection()) {
            return;
        }

        final List<BeanModel> items = getSelectedItems();

        Listener listener = new Listener<MessageBoxEvent>() {

            @Override
            public void handleEvent(MessageBoxEvent event) {
                if (event.getButtonClicked().getHtml().equals(messages.yes())) {
                    doDeleteItem(items);
                }
            }
        };

        StringBuffer buffer = new StringBuffer(" [");
        if (getSelectedItems() != null) {
            for (BeanModel bm : items) {
                Item item = bm.getBean();
                buffer.append(item.getName() + ", ");
            }
            buffer.delete(buffer.length() - 2, buffer.length());
            buffer.append("]");
        }

        MessageBox.confirm(messages.warning(), messages.deleteItemConfirmation() + buffer.toString(), listener)
                .setIcon(MessageBox.WARNING);
    }

    protected void doDeleteItem(final List<BeanModel> items) {
        List ids = new ArrayList();
        final List<Item> itemz = new ArrayList();
        for (BeanModel bm : items) {
            ids.add(((Item) bm.getBean()).getId());
            itemz.add((Item) bm.getBean());
        }
        ManagementServiceAsync rpcService = Registry.get(PIGE.MANAGEMENT_SERVICE);
        rpcService.deleteItem(ids, new AsyncCallback() {

            @Override
            public void onSuccess(Object o) {
                for (BeanModel bm : items) {
                    itemStore.remove(bm);
                }
                StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR);
                statusBar.setTimedText(messages.deletionSuccessful());

                ItemEditorEvent event = new ItemEditorEvent(AfterDeleteItem, itemz);
                fireEvent(AfterDeleteItem, event);
            }

            @Override
            public void onFailure(Throwable caugth) {
                PIGE.handleException(caugth);
            }
        });
    }

    protected void removeItemListFromCategory() {
        if (!validateItemSelection()) {
            return;
        }

        Listener listener = new Listener<MessageBoxEvent>() {

            @Override
            public void handleEvent(MessageBoxEvent event) {
                if (event.getButtonClicked().getHtml().equals(messages.yes())) {
                    List<BeanModel> items = getSelectedItems();
                    doRemoveItemListFromCategory(items);
                }
            }
        };

        MessageBox.confirm(messages.warning(), messages.removeItemsFromCategoryConfirmation(), listener)
                .setIcon(MessageBox.WARNING);
    }

    protected void doRemoveItemListFromCategory(List<BeanModel> models) {
    }

    protected Boolean validateItemSelection() {
        if (getSelectedItems() != null) {
            if (getSelectedItems().size() > 0) {
                return Boolean.TRUE;
            }
        }
        MessageBox.info(messages.information(), messages.noItemSelected(), null);
        return Boolean.FALSE;
    }

    protected void onGridDoubleClick() {
        viewItem();
    }

    protected void setSelectedItems(List<BeanModel> items) {
        this.selectedItems = items;
    }

    /* private class FieldUpdater {
        
    private final String property;
    private final Field field;
        
    public FieldUpdater(String property, Field field) {
        this.property = property;
        this.field = field;
    }
        
    public Field getField() {
        return field;
    }
        
    public String getProperty() {
        return property;
    }
        
    public Object getValue() {
        if (field instanceof ComboBox) {
            ComboBox<ItemStatusModel> b = (ComboBox<ItemStatusModel>) field;
            return b.getValue().getValue();
        } else {
            return field.getValue();
        }
    }
     }*/

    private final class FieldListener extends AbstractFieldListener {

        public FieldListener(Menu rootMenu, FieldUpdater updater) {
            super(rootMenu, updater);
        }

        @Override
        protected void doFireModelsUpdate() {
            List<BeanModel> models = grid.getSelectionModel().getSelectedItems();
            for (BeanModel bm : models) {
                bm.set(updater.getProperty(), updater.getValue());
            }
            updateItems(models);
            updater.getField().clear();
            rootMenu.hide();
        }
    }

    protected void configureQuickEditMenu(Menu menu, final Menu rootMenu) {
        MenuItem nameEditMenuItem = new MenuItem(messages.name());
        MenuItem modelEditMenuItem = new MenuItem(messages.model());
        MenuItem quantityEditMenuItem = new MenuItem(messages.quantity());
        MenuItem statusEditMenuItem = new MenuItem(messages.status());
        MenuItem locationEditMenuItem = new MenuItem(messages.location());
        MenuItem descriptionEditMenuItem = new MenuItem(messages.description());
        MenuItem versionEditMenuItem = new MenuItem(messages.version());

        menu.add(nameEditMenuItem);
        menu.add(modelEditMenuItem);
        menu.add(quantityEditMenuItem);
        menu.add(statusEditMenuItem);
        menu.add(locationEditMenuItem);
        menu.add(descriptionEditMenuItem);
        menu.add(versionEditMenuItem);

        // Proprit nom.
        final TextField nameTF = new TextField<String>();
        nameTF.addListener(Events.KeyUp, new FieldListener(rootMenu, new FieldUpdater(Item.NAME_REF, nameTF)));
        nameTF.setMaxLength(100);
        AdapterMenuItem nameTFMenuAdapter = new AdapterMenuItem(nameTF);
        nameTFMenuAdapter.setManageFocus(true);
        nameTFMenuAdapter.setCanActivate(true);
        Menu nameEditMenu = new Menu();
        nameEditMenu.add(nameTFMenuAdapter);
        nameEditMenuItem.setSubMenu(nameEditMenu);

        // Proprit model/format.
        final TextField modelTF = new TextField<String>();
        modelTF.addListener(Events.KeyUp, new FieldListener(rootMenu, new FieldUpdater(Item.MODEL_REF, modelTF)));
        modelTF.setMaxLength(50);
        AdapterMenuItem modelTFMenuAdapter = new AdapterMenuItem(modelTF);
        modelTFMenuAdapter.setManageFocus(true);
        modelTFMenuAdapter.setCanActivate(true);
        Menu modelEditMenu = new Menu();
        modelEditMenu.add(modelTFMenuAdapter);
        modelEditMenuItem.setSubMenu(modelEditMenu);

        // Proprit quantit.
        NumberField quantityNF = new NumberField();
        quantityNF.setFormat(NumberFormat.getFormat(PIGE.QUANTITY_FORMAT));
        quantityNF.setPropertyEditorType(Integer.class);
        quantityNF.setAllowDecimals(Boolean.FALSE);
        quantityNF.setAllowNegative(Boolean.FALSE);
        quantityNF.setMaxLength(9);
        quantityNF.addListener(Events.KeyUp,
                new FieldListener(rootMenu, new FieldUpdater(Item.QUANTITY_REF, quantityNF)));
        AdapterMenuItem quantityTFMenuAdapter = new AdapterMenuItem(quantityNF);
        quantityTFMenuAdapter.setManageFocus(true);
        quantityTFMenuAdapter.setCanActivate(true);
        Menu quantityEditMenu = new Menu();
        quantityEditMenu.add(quantityTFMenuAdapter);
        quantityEditMenuItem.setSubMenu(quantityEditMenu);

        // Proprit tat
        ListStore statusListStore = new ListStore<ItemStatusModel>();
        statusListStore.add(ItemStatus.getInstance().getModelList());
        ComboBox statusCBx = new ComboBox<ItemStatusModel>();
        statusCBx.setStore(statusListStore);
        statusCBx.setForceSelection(true);
        statusCBx.setEditable(false);
        statusCBx.setDisplayField("label");
        statusCBx.setTriggerAction(TriggerAction.ALL);
        statusCBx.addListener(Events.Select,
                new FieldListener(rootMenu, new FieldUpdater(Item.STATUS_REF, statusCBx)));
        AdapterMenuItem statusTFMenuAdapter = new AdapterMenuItem(statusCBx);
        statusTFMenuAdapter.setManageFocus(true);
        statusTFMenuAdapter.setCanActivate(true);
        Menu statusEditMenu = new Menu();
        statusEditMenu.add(statusTFMenuAdapter);
        statusEditMenuItem.setSubMenu(statusEditMenu);

        // Proprit localisation.
        final TextField locationTF = new TextField<String>();
        locationTF.addListener(Events.KeyUp,
                new FieldListener(rootMenu, new FieldUpdater(Item.LOCATION_REF, locationTF)));
        locationTF.setMaxLength(255);
        AdapterMenuItem locationTFMenuAdapter = new AdapterMenuItem(locationTF);
        locationTFMenuAdapter.setManageFocus(true);
        locationTFMenuAdapter.setCanActivate(true);
        Menu locationEditMenu = new Menu();
        locationEditMenu.add(locationTFMenuAdapter);
        locationEditMenuItem.setSubMenu(locationEditMenu);

        // Proprit description.
        final TextField descriptionTF = new TextField<String>();
        descriptionTF.addListener(Events.KeyUp,
                new FieldListener(rootMenu, new FieldUpdater(Item.DESCRIPTION_REF, descriptionTF)));
        AdapterMenuItem descriptionTFMenuAdapter = new AdapterMenuItem(descriptionTF);
        descriptionTFMenuAdapter.setManageFocus(true);
        descriptionTFMenuAdapter.setCanActivate(true);
        Menu descriptionEditMenu = new Menu();
        descriptionEditMenu.add(descriptionTFMenuAdapter);
        descriptionEditMenuItem.setSubMenu(descriptionEditMenu);

        // Proprit version.
        final TextField versionTF = new TextField<String>();
        versionTF.addListener(Events.KeyUp,
                new FieldListener(rootMenu, new FieldUpdater(Item.VERSION_REF, versionTF)));
        versionTF.setMaxLength(30);
        AdapterMenuItem versionTFMenuAdapter = new AdapterMenuItem(versionTF);
        versionTFMenuAdapter.setManageFocus(true);
        versionTFMenuAdapter.setCanActivate(true);
        Menu versionEditMenu = new Menu();
        versionEditMenu.add(versionTFMenuAdapter);
        versionEditMenuItem.setSubMenu(versionEditMenu);

    }

    protected void updateItems(final List<BeanModel> models) {
        List<Item> items = GXTUtil.models2POJO(models);
        ManagementServiceAsync rpcService = Registry.get(PIGE.MANAGEMENT_SERVICE);
        rpcService.updateItems(items, new AsyncCallback() {

            @Override
            public void onSuccess(Object o) {
                for (BeanModel bm : models) {
                    grid.getStore().update(bm);
                }
                StatusBar statusBar = Registry.get(AppWidgets.APP_STATUS_BAR);
                statusBar.setTimedText(messages.updateSuccessful());
            }

            @Override
            public void onFailure(Throwable caugth) {
                PIGE.handleException(caugth);
            }
        });
    }

    public List<BeanModel> getSelectedItems() {
        return this.selectedItems;
    }

    public BeanModel getLastSelectedItem() {
        return getSelectedItems().get(getSelectedItems().size() - 1);
    }

    public List<FilterConfig> getFilterConfigList() {
        return loadConfigs.get(PIGE.FILTER_CONFIGS);
    }

    @Override
    public LoadConfig getLoadConfig() {
        return loadConfigs;
    }

    public void load() {
        itemLoader.load();
    }

    @Override
    public Loader getLoader() {
        return itemLoader;
    }

    public Grid getGrid() {
        return grid;
    }

    public void resetSearchConfigs() {
        searchConfigList.clear();
        fieldsConfigList.clear();
        stateConfigList.clear();
    }

}