package org.sigmah.shared.dto.element;
/*
* #%L
* Sigmah
* %%
* Copyright (C) 2010 - 2016 URD
* %%
* This program 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.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-3.0.html>.
* #L%
*/
import java.util.Arrays;
import java.util.List;
import org.sigmah.client.i18n.I18N;
import org.sigmah.client.ui.widget.FlexibleGrid;
import org.sigmah.shared.command.result.ValueResult;
import org.sigmah.shared.dto.element.event.RequiredValueEvent;
import org.sigmah.shared.dto.element.event.ValueEvent;
import org.sigmah.shared.dto.history.HistoryTokenDTO;
import org.sigmah.shared.dto.history.HistoryTokenListDTO;
import org.sigmah.shared.dto.referential.ValueEventChangeType;
import org.sigmah.shared.dto.value.ListableValue;
import org.sigmah.shared.dto.value.TripletValueDTO;
import org.sigmah.shared.util.ValueResultUtils;
import com.extjs.gxt.ui.client.event.ButtonEvent;
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.SelectionChangedEvent;
import com.extjs.gxt.ui.client.event.SelectionChangedListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.TextField;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.CheckBoxSelectionModel;
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.EditorGrid;
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.grid.GridSelectionModel;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FlowLayout;
import com.extjs.gxt.ui.client.widget.toolbar.SeparatorToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.ui.Label;
import java.util.ArrayList;
/**
* TripletsListElementDTO.
*
* @author Denis Colliot (dcolliot@ideia.fr)
* @author Renato Almeida (renatoaf.ufcg@gmail.com)
* @author Raphaƫl Calabro (rcalabro@ideia.fr)
*/
public class TripletsListElementDTO extends FlexibleElementDTO {
/**
* Serial version UID.
*/
private static final long serialVersionUID = 8520711106031085130L;
/**
* Entity name mapped by the current DTO starting from the "server.domain" package name.
*/
public static final String ENTITY_NAME = "element.TripletsListElement";
/**
* {@inheritDoc}
*/
@Override
public String getEntityName() {
// Gets the entity name mapped by the current DTO starting from the "server.domain" package name.
return "element.TripletsListElement";
}
/**
* {@inheritDoc}
*/
@Override
public boolean isCorrectRequiredValue(ValueResult result) {
if (result == null || !result.isValueDefined()) {
return false;
}
return !result.getValuesObject().isEmpty();
}
/**
* {@inheritDoc}
*/
@Override
protected Component getComponent(ValueResult valueResult, final boolean enabled) {
final boolean canEdit = enabled && userCanPerformChangeType(ValueEventChangeType.EDIT);
final boolean canDelete = enabled && userCanPerformChangeType(ValueEventChangeType.REMOVE);
final boolean canAdd = enabled && userCanPerformChangeType(ValueEventChangeType.ADD);
// Creates actions toolbar to manage the triplets list.
final Button addButton = new Button(I18N.CONSTANTS.addItem());
addButton.setEnabled(canAdd);
final Button deleteButton = new Button(I18N.CONSTANTS.remove());
deleteButton.setEnabled(false);
final ToolBar actionsToolBar = new ToolBar();
actionsToolBar.add(addButton);
if (canDelete) {
actionsToolBar.add(new SeparatorToolItem());
actionsToolBar.add(deleteButton);
}
// Creates the top panel of the grid.
final ContentPanel topPanel = new ContentPanel();
topPanel.setHeaderVisible(false);
topPanel.setLayout(new FlowLayout());
topPanel.add(actionsToolBar);
// Fills the grid store with the triplets lists
final ListStore<TripletValueDTO> store = new ListStore<TripletValueDTO>();
if (valueResult != null && valueResult.isValueDefined()) {
for (ListableValue s : valueResult.getValuesObject()) {
store.add((TripletValueDTO) s);
}
}
// Selecting the selection model based on user rights.
final GridSelectionModel<TripletValueDTO> selectionModel = canDelete ?
new CheckBoxSelectionModel<TripletValueDTO>() :
new GridSelectionModel<TripletValueDTO>();
// Creates the grid which contains the triplets list.
final FlexibleGrid<TripletValueDTO> grid = new FlexibleGrid<TripletValueDTO>(store, selectionModel,
getColumnModel(selectionModel, canEdit));
grid.setAutoExpandColumn("name");
grid.setVisibleElementsCount(5);
// Creates the main panel.
final ContentPanel panel = new ContentPanel();
panel.setHeadingText(getLabel());
panel.setBorders(true);
panel.setLayout(new FitLayout());
panel.add(grid);
if (canAdd || canDelete) {
panel.setTopComponent(topPanel);
}
grid.addListener(Events.AfterEdit, new Listener<GridEvent<TripletValueDTO>>() {
@Override
public void handleEvent(GridEvent<TripletValueDTO> be) {
// Edit an existing triplet
final TripletValueDTO valueDTO = grid.getStore().getAt(be.getRowIndex());
valueDTO.setIndex(be.getRowIndex());
handlerManager.fireEvent(new ValueEvent(TripletsListElementDTO.this, valueDTO, ValueEventChangeType.EDIT));
}
});
// Manages action buttons activations.
selectionModel.addSelectionChangedListener(new SelectionChangedListener<TripletValueDTO>() {
@Override
public void selectionChanged(SelectionChangedEvent<TripletValueDTO> se) {
final List<TripletValueDTO> selection = se.getSelection();
final boolean enabledState = selection != null && !selection.isEmpty();
deleteButton.setEnabled(enabledState);
}
});
// Buttons listeners.
addButton.addListener(Events.OnClick, new ActionListener(grid, true));
deleteButton.addListener(Events.OnClick, new ActionListener(grid, false));
return panel;
}
/**
* Defines the column model for the triplets list grid.
*
* @param selectionModel
* The grid selection model.
* @param canEdit
* editing right of the current user.
* @return The column model.
*/
private ColumnConfig[] getColumnModel(GridSelectionModel<TripletValueDTO> selectionModel, boolean canEdit) {
final ColumnConfig codeColumn = new ColumnConfig();
codeColumn.setId("code");
codeColumn.setHeaderText(I18N.CONSTANTS.flexibleElementTripletsListCode());
codeColumn.setWidth(100);
final ColumnConfig nameColumn = new ColumnConfig();
nameColumn.setId("name");
nameColumn.setHeaderText(I18N.CONSTANTS.flexibleElementTripletsListName());
nameColumn.setWidth(100);
final ColumnConfig periodColumn = new ColumnConfig();
periodColumn.setId("period");
periodColumn.setHeaderText(I18N.CONSTANTS.flexibleElementTripletsListPeriod());
periodColumn.setWidth(60);
if (canEdit) {
// Adds editors to all column configs.
for(final ColumnConfig config : Arrays.asList(codeColumn, nameColumn, periodColumn)) {
final TextField<String> text = new TextField<String>();
text.setAllowBlank(false);
config.setEditor(new CellEditor(text));
}
}
if(selectionModel instanceof CheckBoxSelectionModel) {
return new ColumnConfig[] {
((CheckBoxSelectionModel<TripletValueDTO>) selectionModel).getColumn(),
codeColumn,
nameColumn,
periodColumn
};
} else {
return new ColumnConfig[] {
codeColumn,
nameColumn,
periodColumn
};
}
}
/**
* Manages grid actions.
*
* @author tmi
*/
private class ActionListener implements Listener<ButtonEvent> {
private EditorGrid<TripletValueDTO> grid;
private boolean isAddAction;
public ActionListener(EditorGrid<TripletValueDTO> grid, boolean isAddAction) {
this.grid = grid;
this.isAddAction = isAddAction;
}
@Override
public void handleEvent(ButtonEvent be) {
// Add a new triplet
if (isAddAction) {
TripletValueDTO addedValue = new TripletValueDTO();
addedValue.setCode("-" + I18N.CONSTANTS.flexibleElementTripletsListCode() + "-");
addedValue.setName("-" + I18N.CONSTANTS.flexibleElementTripletsListName() + "-");
addedValue.setPeriod("-" + I18N.CONSTANTS.flexibleElementTripletsListPeriod() + "-");
grid.getStore().add(addedValue);
addedValue.setIndex(grid.getStore().indexOf(addedValue));
// Fires the value change event.
handlerManager.fireEvent(new ValueEvent(TripletsListElementDTO.this, addedValue, ValueEventChangeType.ADD));
}
// Remove some existing triplets
else {
final List<TripletValueDTO> selectedItems = new ArrayList<TripletValueDTO>(grid.getSelectionModel().getSelectedItems());
for (TripletValueDTO removedValue : selectedItems) {
removedValue.setIndex(grid.getStore().indexOf(removedValue));
// Fires the value change event.
handlerManager.fireEvent(new ValueEvent(TripletsListElementDTO.this, removedValue, ValueEventChangeType.REMOVE));
}
for (TripletValueDTO removedValue : selectedItems) {
grid.getStore().remove(removedValue);
}
}
// Required element ?
if (getValidates()) {
handlerManager.fireEvent(new RequiredValueEvent(grid.getStore().getCount() > 0));
}
}
}
@Override
public Object renderHistoryToken(final HistoryTokenListDTO token) {
final Label details = new Label();
details.addStyleName("history-details");
if (token.getTokens().size() == 1) {
details.setText("1 " + I18N.CONSTANTS.historyModification());
} else {
details.setText(token.getTokens().size() + " " + I18N.CONSTANTS.historyModifications());
}
details.addClickHandler(new ClickHandler() {
private Window window;
@Override
public void onClick(ClickEvent e) {
if (window == null) {
// Builds window.
window = new Window();
window.setAutoHide(true);
window.setModal(false);
window.setPlain(true);
window.setHeaderVisible(true);
window.setClosable(true);
window.setLayout(new FitLayout());
window.setWidth(750);
window.setHeight(400);
window.setBorders(false);
window.setResizable(true);
// Builds grid.
final ListStore<TripletValueDTO> store = new ListStore<TripletValueDTO>();
final com.extjs.gxt.ui.client.widget.grid.Grid<TripletValueDTO> grid =
new com.extjs.gxt.ui.client.widget.grid.Grid<TripletValueDTO>(store, new ColumnModel(Arrays.asList(getColumnModel())));
grid.getView().setForceFit(true);
grid.setBorders(false);
grid.setAutoExpandColumn("name");
window.add(grid);
// Fills store.
for (final HistoryTokenDTO t : token.getTokens()) {
final List<String> l = ValueResultUtils.splitElements(t.getValue());
final TripletValueDTO triplet = new TripletValueDTO();
triplet.setCode(l.get(0));
triplet.setName(l.get(1));
triplet.setPeriod(l.get(2));
triplet.setType(t.getType());
store.add(triplet);
}
}
window.setPagePosition(e.getNativeEvent().getClientX(), e.getNativeEvent().getClientY());
window.show();
}
private ColumnConfig[] getColumnModel() {
// Change type.
final ColumnConfig typeColumn = new ColumnConfig();
typeColumn.setId("type");
typeColumn.setHeaderText(I18N.CONSTANTS.historyModificationType());
typeColumn.setWidth(150);
typeColumn.setSortable(false);
typeColumn.setRenderer(new GridCellRenderer<TripletValueDTO>() {
@Override
public Object render(TripletValueDTO model, String property, ColumnData config, int rowIndex, int colIndex, ListStore<TripletValueDTO> store,
Grid<TripletValueDTO> grid) {
if (model.getType() != null) {
switch (model.getType()) {
case ADD:
return I18N.CONSTANTS.historyAdd();
case EDIT:
return I18N.CONSTANTS.historyEdit();
case REMOVE:
return I18N.CONSTANTS.historyRemove();
default:
return "-";
}
} else {
return "-";
}
}
});
// Code.
final ColumnConfig codeColumn = new ColumnConfig();
codeColumn.setId("code");
codeColumn.setHeaderText(I18N.CONSTANTS.flexibleElementTripletsListCode());
codeColumn.setWidth(200);
// Name.
final ColumnConfig nameColumn = new ColumnConfig();
nameColumn.setId("name");
nameColumn.setHeaderText(I18N.CONSTANTS.flexibleElementTripletsListName());
nameColumn.setWidth(200);
// Period.
final ColumnConfig periodColumn = new ColumnConfig();
periodColumn.setId("period");
periodColumn.setHeaderText(I18N.CONSTANTS.flexibleElementTripletsListPeriod());
periodColumn.setWidth(200);
return new ColumnConfig[] {
typeColumn,
codeColumn,
nameColumn,
periodColumn
};
}
});
return details;
}
}