/**
* Copyright (C) 2013 DaiKit.com - daikit4gxt module (admin@daikit.com)
*
* Project home : http://code.daikit.com/daikit4gxt
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.daikit.daikit4gxt.client.ui.forms;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.daikit.daikit4gxt.client.DkMain;
import com.daikit.daikit4gxt.client.model.propertyaccess.MyValueWrapperPropertyAccess;
import com.daikit.daikit4gxt.client.ui.UIInvalidatable;
import com.daikit.daikit4gxt.client.ui.cell.CellColumnResizer;
import com.daikit.daikit4gxt.client.ui.cell.IconButtonCell;
import com.daikit.daikit4gxt.client.ui.cell.ListStoreIconButtonCell;
import com.google.gwt.cell.client.Cell;
import com.sencha.gxt.cell.core.client.form.FieldCell;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.button.TextButton;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer;
import com.sencha.gxt.widget.core.client.container.VerticalLayoutContainer.VerticalLayoutData;
import com.sencha.gxt.widget.core.client.event.SelectEvent;
import com.sencha.gxt.widget.core.client.grid.ColumnConfig;
import com.sencha.gxt.widget.core.client.grid.ColumnModel;
import com.sencha.gxt.widget.core.client.grid.Grid;
import com.sencha.gxt.widget.core.client.tips.QuickTip;
import com.sencha.gxt.widget.core.client.toolbar.FillToolItem;
import com.sencha.gxt.widget.core.client.toolbar.ToolBar;
/**
* An editor for a multiple value list
*
* @author tcaselli
* @version $Revision$ Last modifier: $Author$ Last commit: $Date$
* @param <M>
*/
public abstract class MyMultipleValueEditorGrid<M extends Serializable> extends AbstractDkHideableAdapterField<List<M>> implements
UIInvalidatable
{
protected final ListStore<MyValueWrapper<M>> store;
protected final IconButtonCell deleteCell;
protected final TextButton buttonNew;
protected final Grid<MyValueWrapper<M>> grid;
protected final MyValueWrapperPropertyAccess<M> props;
private boolean enabled = true;
protected final VerticalLayoutContainer verticalLayoutContainer;
/**
* Constructor
*
* @param props
* the {@link MyValueWrapperPropertyAccess}
*/
public MyMultipleValueEditorGrid(final MyValueWrapperPropertyAccess<M> props)
{
super(new VerticalLayoutContainer());
this.props = props;
setHeight(DkMain.config().getEditorGridHeight());
this.store = new ListStore<MyValueWrapper<M>>(props.key());
store.setAutoCommit(true);
final List<ColumnConfig<MyValueWrapper<M>, ?>> columns = getColumnConfigs();
final ColumnConfig<MyValueWrapper<M>, String> columnDelete = new ColumnConfig<MyValueWrapper<M>, String>(props.delete(),
30, "");
columnDelete.setMenuDisabled(true);
columnDelete.setResizable(false);
columnDelete.setSortable(false);
columnDelete.setFixed(true);
deleteCell = new ListStoreIconButtonCell<MyValueWrapper<M>>(DkMain.icons().delete2_16(), getDeleteTooltip(), store)
{
@Override
protected void onClick(final MyValueWrapper<M> model, final int column, final int row, final String modelKey)
{
onDeleteButtonClicked(model);
}
@Override
protected boolean isCellIconVisible(final MyValueWrapper<M> model, final int column, final int row, final String modelKey)
{
return isModelDeletable(model, column, row, modelKey);
}
};
columnDelete.setCell(deleteCell);
columns.add(columnDelete);
final ColumnModel<MyValueWrapper<M>> cm = new ColumnModel<MyValueWrapper<M>>(columns);
grid = new Grid<MyValueWrapper<M>>(store, cm);
new QuickTip(grid);
verticalLayoutContainer = (VerticalLayoutContainer) getWidget();
verticalLayoutContainer.setBorders(true);
for (final ColumnConfig<MyValueWrapper<M>, ?> columnConfig : columns)
{
if (columnConfig.getCell() instanceof FieldCell)
{
grid.getColumnModel().addColumnWidthChangeHandler(
new CellColumnResizer<MyValueWrapper<M>>(columnConfig, (FieldCell<?>) columnConfig.getCell()));
}
}
final ToolBar toolbar = new ToolBar();
toolbar.add(new FillToolItem());
buttonNew = new TextButton(DkMain.i18n().label_new(), new SelectEvent.SelectHandler()
{
@Override
public void onSelect(final SelectEvent event)
{
onNewButtonClicked();
}
});
buttonNew.setIcon(DkMain.icons().file_plus_16());
toolbar.add(buttonNew);
toolbar.setHeight(29);
verticalLayoutContainer.add(toolbar, new VerticalLayoutData(1, 29));
verticalLayoutContainer.add(grid, new VerticalLayoutData(1, 1));
}
protected List<ColumnConfig<MyValueWrapper<M>, ?>> getColumnConfigs()
{
final List<ColumnConfig<MyValueWrapper<M>, ?>> columns = new ArrayList<ColumnConfig<MyValueWrapper<M>, ?>>();
final ColumnConfig<MyValueWrapper<M>, M> columnValue = new ColumnConfig<MyValueWrapper<M>, M>(props.value(), 250, DkMain
.i18n().label_value());
columnValue.setCell(createCell());
columns.add(columnValue);
return columns;
}
/**
* Enable or disable buttons
*
* @param enabled
*/
@Override
public void setEnabled(final boolean enabled)
{
buttonNew.setEnabled(enabled);
grid.setEnabled(enabled);
this.enabled = enabled;
}
@Override
public final boolean isEnabled()
{
return enabled;
}
/**
* @return the delete tooltip
*/
protected String getDeleteTooltip()
{
return DkMain.i18n().label_delete_this_entry();
}
/**
* Nothing done by default
*/
@Override
public void invalidateUi()
{
// Nothing done by default
}
/**
* Set the new button tooltip
*
* @param tooltip
* the tooltip
*/
public void setButtonNewTooltip(final String tooltip)
{
if (buttonNew != null)
{
buttonNew.setTitle(tooltip);
}
}
/**
* Set the new button label
*
* @param label
* the label
*/
public void setButtonNewLabel(final String label)
{
if (buttonNew != null)
{
buttonNew.setText(label);
}
}
/**
* Delete button clicked
*/
protected void onDeleteButtonClicked(final MyValueWrapper<M> model)
{
store.remove(model);
}
/**
* Add button clicked
*/
protected void onNewButtonClicked()
{
final MyValueWrapper<M> newEntry = new MyValueWrapper<M>(createEntry());
store.add(newEntry);
grid.getSelectionModel().select(newEntry, false);
}
/**
* @return the store
*/
public ListStore<MyValueWrapper<M>> getStore()
{
return store;
}
protected abstract Cell<M> createCell();
protected boolean isModelDeletable(final MyValueWrapper<M> model, final int column, final int row, final String modelKey)
{
return true;
}
/**
* May be overridden to provide default value for creation
*
* @return
*/
protected M createEntry()
{
return null;
}
/**
* @return the grid
*/
public Grid<MyValueWrapper<M>> getGrid()
{
return grid;
}
@Override
public List<M> getValue()
{
store.commitChanges();
return MyValueWrapper.convertBack(store.getAll());
}
@Override
public void setValue(final List<M> value)
{
store.clear();
if (value != null && value.size() > 0)
{
store.addAll(MyValueWrapper.convert(value));
}
}
/**
* @return the button new
*/
public TextButton getButtonNew()
{
return buttonNew;
}
}