/* * Ext GWT - Ext for GWT * Copyright(c) 2007-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ package com.extjs.gxt.ui.client.binder; import java.util.ArrayList; import java.util.List; import com.extjs.gxt.ui.client.GXT; import com.extjs.gxt.ui.client.data.ModelData; import com.extjs.gxt.ui.client.data.ModelStringProvider; import com.extjs.gxt.ui.client.event.BaseObservable; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Events; import com.extjs.gxt.ui.client.event.Listener; import com.extjs.gxt.ui.client.event.SelectionChangedEvent; import com.extjs.gxt.ui.client.event.SelectionChangedListener; import com.extjs.gxt.ui.client.event.SelectionProvider; import com.extjs.gxt.ui.client.store.Store; import com.extjs.gxt.ui.client.store.StoreEvent; import com.extjs.gxt.ui.client.store.StoreFilter; import com.extjs.gxt.ui.client.store.StoreListener; import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.ComponentHelper; /** * Abstract base class for all Store Binders. Binders provide model support to * data widgets by binding a <code>Store</code> to a component. * * @param <S> the store type * @param <C> the component being bound * @param <M> the model type */ public abstract class StoreBinder<S extends Store<M>, C extends Component, M extends ModelData> extends BaseObservable implements SelectionProvider<M> { protected S store; protected C component; protected StoreListener<M> listener = new StoreListener<M>() { @Override public void storeAdd(StoreEvent<M> se) { onAdd(se); } public void storeBeforeDataChanged(StoreEvent<M> se) { onBeforeDataChanged(se); } public void storeClear(StoreEvent<M> se) { onClear(se); } public void storeDataChanged(StoreEvent<M> se) { onDataChanged(se); } public void storeFilter(StoreEvent<M> se) { onFilter(se); } public void storeRemove(StoreEvent<M> se) { onRemove(se); } public void storeSort(StoreEvent<M> se) { onSort(se); } public void storeUpdate(StoreEvent<M> se) { onUpdate(se); } }; protected ModelStringProvider<M> stringProvider; protected ModelStringProvider<M> iconProvider; protected ModelStringProvider<M> styleProvider; protected ModelStringProvider<M> defaultStringProvider = new ModelStringProvider<M>() { public String getStringValue(M model, String property) { Object o = model.get(property); if (o == null) { return ""; } else { return String.valueOf(o); } } }; private boolean mask; private boolean autoSelect; /** * Creates a new binder instance. * * @param store the store * @param container the container */ public StoreBinder(S store, C container) { this.component = container; this.store = store; hook(); bind(store); } public void addSelectionChangedListener(SelectionChangedListener<M> listener) { addListener(Events.SelectionChange, listener); } /** * Returns the matching component for the given model. * * @param model the model * @return the component */ public abstract Component findItem(M model); public List<M> getSelection() { return getSelectionFromComponent(); } /** * Returns the binder's store. * * @return the store */ public Store<M> getStore() { return store; } /** * Must be called after the binder had been configured. */ public void init() { createAll(); } /** * Returns true if select on load is enabled. * * @return the auto select state */ public boolean isAutoSelect() { return autoSelect; } /** * Returns whether the given model is filtered. * * @param parent the model parent * @param child the child model * @return true if the child is filtered */ public boolean isFiltered(M parent, M child) { if (store.isFiltered() && store.getFilters().size() > 0) { for (StoreFilter<M> filter : store.getFilters()) { boolean result = filter.select(store, parent, child, null); if (!result) { return true; } } } return false; } /** * Returns true if masking is enabled. * * @return the mask state */ public boolean isMask() { return mask; } public void removeSelectionListener(SelectionChangedListener<M> listener) { removeListener(Events.SelectionChange, listener); } /** * True to select the first model after the store's data changes. * * @param autoSelect true to auto select */ public void setAutoSelect(boolean autoSelect) { this.autoSelect = autoSelect; } /** * Sets the binder's icon provider. * * @param iconProvider the icon provider */ public void setIconProvider(ModelStringProvider<M> iconProvider) { this.iconProvider = iconProvider; } /** * Sets whether a mask should be displayed during a load operation. * * @param mask true for mask */ public void setMask(boolean mask) { this.mask = mask; } public void setSelection(List<M> selection) { if (selection == null) { selection = new ArrayList<M>(); } setSelectionFromProvider(selection); } /** * Sets the current selection for this selection provider. * * @param selection the selection */ public void setSelection(M selection) { List<M> sel = new ArrayList<M>(); if (selection != null) { sel.add(selection); } setSelection(sel); } /** * Sets the binder's string provider. * * @param stringProvider the string provider */ public void setStringProvider(ModelStringProvider<M> stringProvider) { this.stringProvider = stringProvider; } /** * Sets the binder's style provider. * * @param styleProvider the style provider */ public void setStyleProvider(ModelStringProvider<M> styleProvider) { this.styleProvider = styleProvider; } protected void bind(S store) { if (this.store != null) { this.store.removeStoreListener(listener); } this.store = store; if (store != null) { store.addStoreListener(listener); if (component.isRendered()) { createAll(); } } } protected abstract void createAll(); protected void fireSelectionChanged(SelectionChangedEvent<M> se) { fireEvent(Events.SelectionChange, se); } protected String getIconValue(M model, String property) { if (iconProvider != null) { return iconProvider.getStringValue(model, property); } return null; } protected abstract List<M> getSelectionFromComponent(); protected String getTextValue(M model, String property) { if (stringProvider != null) { return stringProvider.getStringValue(model, property); } return null; } protected String getTextValue(M model, String property, boolean useDefault) { if (stringProvider != null) { return stringProvider.getStringValue(model, property); } if (useDefault) { return defaultStringProvider.getStringValue(model, property); } return null; } protected void hook() { component.addListener(Events.SelectionChange, new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent ce) { SelectionChangedEvent<M> se = new SelectionChangedEvent<M>(StoreBinder.this, getSelection()); fireSelectionChanged(se); } }); } protected abstract void onAdd(StoreEvent<M> se); protected void onBeforeDataChanged(StoreEvent<M> se) { if (mask && component != null) { component.mask(GXT.MESSAGES.loadMask_msg()); } } protected void onClear(StoreEvent<M> se) { removeAll(); } protected void onDataChanged(StoreEvent<M> se) { if (mask && component != null) { component.unmask(); } } protected void onFilter(StoreEvent<M> se) { } protected abstract void onRemove(StoreEvent<M> se); protected void onSort(StoreEvent<M> se) { } protected abstract void onUpdate(StoreEvent<M> se); protected abstract void removeAll(); protected void setModel(Component c, ModelData model) { ComponentHelper.setModel(c, model); } protected abstract void setSelectionFromProvider(List<M> selection); protected abstract void update(M model); }