/**
* 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.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.daikit.commons.shared.bean.AbstractDkBeanWithId;
import com.daikit.daikit4gxt.client.DkMain;
import com.daikit.daikit4gxt.client.model.propertyaccess.EditDeletePropertyAccess;
import com.daikit.daikit4gxt.client.ui.UIInvalidatable;
import com.daikit.daikit4gxt.client.ui.cell.IconButtonCell;
import com.daikit.daikit4gxt.client.ui.cell.ListStoreIconButtonCell;
import com.daikit.daikit4gxt.client.ui.edit.AddButtonSelectEvent;
import com.daikit.daikit4gxt.client.ui.edit.AddButtonSelectEvent.AddButtonSelectHandler;
import com.daikit.daikit4gxt.client.ui.edit.AddButtonSelectEvent.HasAddButtonSelectHandlers;
import com.daikit.daikit4gxt.client.ui.edit.CreateButtonSelectEvent;
import com.daikit.daikit4gxt.client.ui.edit.CreateButtonSelectEvent.CreateButtonSelectHandler;
import com.daikit.daikit4gxt.client.ui.edit.CreateButtonSelectEvent.HasCreateButtonSelectHandlers;
import com.daikit.daikit4gxt.client.ui.edit.DeleteButtonSelectEvent;
import com.daikit.daikit4gxt.client.ui.edit.DeleteButtonSelectEvent.DeleteButtonSelectHandler;
import com.daikit.daikit4gxt.client.ui.edit.DeleteButtonSelectEvent.HasDeleteButtonSelectHandlers;
import com.daikit.daikit4gxt.client.ui.edit.EditButtonSelectEvent;
import com.daikit.daikit4gxt.client.ui.edit.EditButtonSelectEvent.EditButtonSelectHandler;
import com.daikit.daikit4gxt.client.ui.edit.EditButtonSelectEvent.HasEditButtonSelectHandlers;
import com.daikit.daikit4gxt.client.utils.miscs.UIUtils;
import com.google.gwt.event.shared.HandlerRegistration;
import com.sencha.gxt.data.shared.ListStore;
import com.sencha.gxt.widget.core.client.ContentPanel;
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;
/**
* Grid for bean sub-types
*
* @author tcaselli
* @version $Revision$ Last modifier: $Author$ Last commit: $Date$
* @param <M>
*/
public abstract class MyEditorGrid<M extends AbstractDkBeanWithId> extends AbstractDkHideableAdapterField<List<M>> implements
HasAddButtonSelectHandlers, HasCreateButtonSelectHandlers, HasDeleteButtonSelectHandlers<M>,
HasEditButtonSelectHandlers<M>, UIInvalidatable
{
private final Grid<M> grid;
private final ListStore<M> store;
private IconButtonCell editCell = null;
private IconButtonCell deleteCell = null;
private TextButton buttonAdd = null;
private TextButton buttonCreate = null;
private final ToolBar toolbar;
private final ToolBar bottomToolbar;
private final boolean topToolbarVisible;
private boolean headerVisible = false;
private boolean enabled = true;
private final VerticalLayoutContainer verticalLayoutContainer;
/**
* Functionality for the EditorGrid
*
* @author tcaselli
* @version $Revision$ Last modifier: $Author$ Last commit: $Date$
*/
public enum Functionality
{
/**
* To add an edition column and provide the possibility to edit row
*/
EDIT,
/**
* To add a delete column and provide the possibility to delete a row
*/
DELETE,
/**
* To add a button to provide the possibility to open selector to add a field. this will change the behavior of
* delete by remove.
*/
ADD,
/**
* To add a create to provide the possibility to open a creation popup.
*/
CREATE
}
/**
* Create an Editor grid
*
* @param listStore
* the store
* @param columnConfigs
* the list of column configs
* @param props
* the property access
* @param functionalities
* any number of functionalities in {@link Functionality}
*/
public MyEditorGrid(final ListStore<M> listStore, final List<ColumnConfig<M, ?>> columnConfigs,
final EditDeletePropertyAccess<M> props, final Functionality... functionalities)
{
this(listStore, columnConfigs, props, convertArrayToSet(functionalities));
}
private static final Set<Functionality> convertArrayToSet(final Functionality[] functionalities)
{
final Set<Functionality> setOfFunctionalities = new HashSet<MyEditorGrid.Functionality>();
for (final Functionality functionality : functionalities)
{
setOfFunctionalities.add(functionality);
}
return setOfFunctionalities;
}
/**
* Create an Editor grid
*
* @param listStore
* the store
* @param columnConfigs
* the list of column configs
* @param props
* the property access
* @param functionalities
* any number of functionalities in {@link Functionality}
*/
public MyEditorGrid(final ListStore<M> listStore, final List<ColumnConfig<M, ?>> columnConfigs,
final EditDeletePropertyAccess<M> props, final Set<Functionality> functionalities)
{
this(listStore, columnConfigs, props, functionalities, false, !functionalities.isEmpty());
}
/**
* Create an Editor grid
*
* @param listStore
* the store
* @param columnConfigs
* the list of column configs
* @param props
* the property access
* @param functionalities
* any number of functionalities in {@link Functionality}
* @param bottomToolbarVisible
* indicating whether to show or not the bottom toolbar (default is false)
* @param topToolbarVisible
* indicating whether to show or not the top toolbar (default is true if at least 1 {@link Functionality}
* in ADD and CREATE, else false)
*/
public MyEditorGrid(final ListStore<M> listStore, final List<ColumnConfig<M, ?>> columnConfigs,
final EditDeletePropertyAccess<M> props, final Set<Functionality> functionalities, final boolean bottomToolbarVisible,
final boolean topToolbarVisible)
{
super(new ContentPanel());
this.topToolbarVisible = topToolbarVisible;
verticalLayoutContainer = new VerticalLayoutContainer();
getContentPanel().add(verticalLayoutContainer);
getContentPanel().setHeaderVisible(false);
setHeight(DkMain.config().getEditorGridHeight());
this.store = listStore;
final List<ColumnConfig<M, ?>> columns = new ArrayList<ColumnConfig<M, ?>>(columnConfigs);
if (functionalities.contains(Functionality.EDIT))
{
final ColumnConfig<M, String> columnEdit = new ColumnConfig<M, String>(props.edit(), 30, "");
columnEdit.setMenuDisabled(true);
columnEdit.setResizable(false);
columnEdit.setSortable(false);
columnEdit.setFixed(true);
editCell = new ListStoreIconButtonCell<M>(DkMain.icons().file_edit_16(), getEditTooltip(), listStore)
{
@Override
protected void onClick(final M model, final int column, final int row, final String modelKey)
{
if (isEnabled())
{
MyEditorGrid.this.fireEvent(new EditButtonSelectEvent<M>(model));
}
}
@Override
protected boolean isCellIconVisible(final M model, final int column, final int row, final String modelKey)
{
return isModelEditable(model, column, row, modelKey);
}
};
columnEdit.setCell(editCell);
columns.add(columnEdit);
}
if (functionalities.contains(Functionality.DELETE))
{
final ColumnConfig<M, String> columnDelete = new ColumnConfig<M, String>(props.delete(), 30, "");
columnDelete.setMenuDisabled(true);
columnDelete.setResizable(false);
columnDelete.setSortable(false);
columnDelete.setFixed(true);
deleteCell = new ListStoreIconButtonCell<M>(DkMain.icons().delete2_16(), getDeleteTooltip(), listStore)
{
@Override
protected void onClick(final M model, final int column, final int row, final String modelKey)
{
if (isEnabled())
{
MyEditorGrid.this.fireEvent(new DeleteButtonSelectEvent<M>(model));
}
}
@Override
protected boolean isCellIconVisible(final 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<M> cm = new ColumnModel<M>(columns);
grid = new Grid<M>(listStore, cm);
new QuickTip(grid);
grid.setBorders(false);
verticalLayoutContainer.setBorders(false);
toolbar = new ToolBar();
toolbar.add(new FillToolItem());
bottomToolbar = new ToolBar();
if (functionalities.contains(Functionality.ADD) || functionalities.contains(Functionality.CREATE))
{
if (functionalities.contains(Functionality.ADD))
{
buttonAdd = new TextButton(DkMain.i18n().label_add(), new SelectEvent.SelectHandler()
{
@Override
public void onSelect(final SelectEvent event)
{
fireEvent(new AddButtonSelectEvent());
}
});
buttonAdd.setIcon(DkMain.icons().file_plus_16());
toolbar.add(buttonAdd);
}
if (functionalities.contains(Functionality.CREATE))
{
buttonCreate = new TextButton(DkMain.i18n().label_create(), new SelectEvent.SelectHandler()
{
@Override
public void onSelect(final SelectEvent event)
{
fireEvent(new CreateButtonSelectEvent());
}
});
buttonCreate.setIcon(DkMain.icons().file_plus_16());
toolbar.add(buttonCreate);
}
}
if (topToolbarVisible)
{
toolbar.setHeight(29);
verticalLayoutContainer.add(toolbar, new VerticalLayoutData(1, 29));
}
verticalLayoutContainer.add(grid, new VerticalLayoutData(1, 1));
if (bottomToolbarVisible)
{
bottomToolbar.setHeight(27);
UIUtils.updateBottomToolbarStyle(bottomToolbar);
verticalLayoutContainer.add(bottomToolbar, new VerticalLayoutData(1, 27));
}
}
protected boolean isModelEditable(final M model, final int column, final int row, final String modelKey)
{
return true;
};
protected boolean isModelDeletable(final M model, final int column, final int row, final String modelKey)
{
return true;
};
/**
* Editor.forceLayout -> ResizeContainer.forceLayout -> SimpleContainer.forceLayout -> ResizeContainer.applyLayout ->
* ContentPanel.setPixelSize<br>
*
* if(lastSize != new size) ContentPanel.onResize -> Dans cette methode on a getContainerTarget().setHeight(...)<br>
* <br>
* The ContentPanel onResize method was not called when the ContentPanel becomes visible due to size caching
*/
@Override
public void setVisible(final boolean visible)
{
// if (visible && !isVisible())
// {
// getContentPanel().clearSizeCache();
// }
super.setVisible(visible);
}
/**
* @return this editor grid {@link ContentPanel}
*/
public ContentPanel getContentPanel()
{
return (ContentPanel) getWidget();
}
/**
* Sets the heading of the {@link ContentPanel}
*
* @param heading
* the heading to be set
*/
public void setHeadingHtml(final String heading)
{
getContentPanel().setHeaderVisible(true);
getContentPanel().setHeadingHtml(heading);
headerVisible = true;
}
/**
* Enable or disable buttons
*
* @param enabled
*/
@Override
public void setEnabled(final boolean enabled)
{
if (buttonAdd != null)
{
buttonAdd.setEnabled(enabled);
}
if (buttonCreate != null)
{
buttonCreate.setEnabled(enabled);
}
this.enabled = enabled;
UIUtils.setGridContentEnabled(grid, enabled, disabledStyle);
}
/**
* Is enabled coherent with {@link #setEnabled(boolean)}
*/
@Override
public final boolean isEnabled()
{
return enabled;
}
/**
* @return the edit tooltip, no tooltip (null) by default
*/
protected String getEditTooltip()
{
return null;
}
/**
* @return the delete tooltip, no tooltip (null) by default
*/
public String getDeleteTooltip()
{
return null;
}
/**
* Set the add button tooltip
*
* @param tooltip
* the tooltip
*/
public void setAddTooltip(final String tooltip)
{
if (buttonAdd != null)
{
buttonAdd.setTitle(tooltip);
}
}
/**
* Set the add button label
*
* @param label
* the label
*/
public void setAddLabel(final String label)
{
if (buttonAdd != null)
{
buttonAdd.setText(label);
}
}
/**
* Set the add button tooltip
*
* @param tooltip
* the tooltip
*/
public void setCreateTooltip(final String tooltip)
{
if (buttonCreate != null)
{
buttonCreate.setTitle(tooltip);
}
}
/**
* Set the add button label
*
* @param label
* the label
*/
public void setCreateLabel(final String label)
{
if (buttonCreate != null)
{
buttonCreate.setText(label);
}
}
/**
* Add a select handler on Add button
*/
@Override
public HandlerRegistration addAddSelectHandler(final AddButtonSelectHandler handler)
{
return addHandler(handler, AddButtonSelectEvent.getType());
}
/**
* Add a select handler on edit button
*/
@Override
public HandlerRegistration addEditSelectHandler(final EditButtonSelectHandler<M> handler)
{
return addHandler(handler, EditButtonSelectEvent.getType());
}
/**
* Add a select handler on delete button
*/
@Override
public HandlerRegistration addDeleteSelectHandler(final DeleteButtonSelectHandler<M> handler)
{
return addHandler(handler, DeleteButtonSelectEvent.getType());
}
/**
* Add a select handler on create button
*/
@Override
public HandlerRegistration addCreateSelectHandler(final CreateButtonSelectHandler handler)
{
return addHandler(handler, CreateButtonSelectEvent.getType());
}
/**
* @return the store
*/
public ListStore<M> getStore()
{
return store;
}
/**
* @return the grid
*/
public Grid<M> getGrid()
{
return grid;
}
/**
* Get the value
*/
@Override
public List<M> getValue()
{
return getStore().getAll();
}
/**
* Set the value
*/
@Override
public void setValue(final List<M> value)
{
getStore().clear();
getStore().addAll(value);
}
/**
* @return the toolbar
*/
public ToolBar getToolbar()
{
return toolbar;
}
/**
* @return the bottomToolbar
*/
public ToolBar getBottomToolbar()
{
return bottomToolbar;
}
/**
* @return the topToolbarVisible
*/
public boolean isTopToolbarVisible()
{
return topToolbarVisible;
}
/**
* @return the headerVisible
*/
public boolean isHeaderVisible()
{
return headerVisible;
}
/**
* @return the verticalLayoutContainer
*/
public VerticalLayoutContainer getVerticalLayoutContainer()
{
return verticalLayoutContainer;
}
/**
* @return the buttonAdd
*/
public TextButton getButtonAdd()
{
return buttonAdd;
}
/**
* @return the buttonCreate
*/
public TextButton getButtonCreate()
{
return buttonCreate;
}
}