package org.activityinfo.ui.client.component.table.dialog;
/*
* #%L
* ActivityInfo Server
* %%
* Copyright (C) 2009 - 2013 UNICEF
* %%
* 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 com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.DataGrid;
import com.google.gwt.user.cellview.client.RowStyles;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.view.client.ListDataProvider;
import com.google.gwt.view.client.MultiSelectionModel;
import com.google.gwt.view.client.SelectionChangeEvent;
import com.google.gwt.view.client.SimpleKeyProvider;
import org.activityinfo.i18n.shared.I18N;
import org.activityinfo.ui.client.component.table.FieldColumn;
import org.activityinfo.ui.client.component.table.InstanceTableStyle;
import org.activityinfo.ui.client.component.table.InstanceTableView;
import org.activityinfo.ui.client.style.table.DataGridResources;
import org.activityinfo.ui.client.widget.ModalDialog;
import java.util.*;
/**
* @author yuriyz on 3/21/14.
*/
public class ChooseColumnsDialog {
interface ChooseColumnsDialogUiBinder extends UiBinder<HTMLPanel, ChooseColumnsDialog> {
}
private static ChooseColumnsDialogUiBinder uiBinder = GWT.create(ChooseColumnsDialogUiBinder.class);
private final ModalDialog dialog;
private final InstanceTableView tableView;
private final ListDataProvider<FieldColumn> selectedTableDataProvider = new ListDataProvider<>();
private final MultiSelectionModel<FieldColumn> selectedSelectionModel = new MultiSelectionModel<>(
new SimpleKeyProvider<FieldColumn>());
private final DataGrid<FieldColumn> selectedTable;
private final ListDataProvider<FieldColumn> tableDataProvider = new ListDataProvider<>();
private final MultiSelectionModel<FieldColumn> selectionModel = new MultiSelectionModel<>(
new SimpleKeyProvider<FieldColumn>());
private final DataGrid<FieldColumn> table;
@UiField
HTMLPanel selectedColumnTableContainer;
@UiField
HTMLPanel columnTableContainer;
@UiField
Button rightButton;
@UiField
Button leftButton;
@UiField
TextBox filterColumnTable;
@UiField
Button upButton;
@UiField
Button downButton;
public ChooseColumnsDialog(final InstanceTableView tableView) {
this.tableView = tableView;
DataGridResources.INSTANCE.dataGridStyle().ensureInjected();
dialog = new ModalDialog(uiBinder.createAndBindUi(this));
dialog.setDialogTitle(I18N.CONSTANTS.chooseColumns());
dialog.getPrimaryButton().addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
onOk();
}
});
selectedTable = createTable();
selectedTable.setSelectionModel(selectedSelectionModel);
selectedTableDataProvider.addDataDisplay(selectedTable);
selectedTableDataProvider.setList(tableView.getSelectedColumns());
selectedTableDataProvider.refresh();
final List<FieldColumn> allColumns = Lists.newArrayList(tableView.getColumns());
table = createTable();
table.setSelectionModel(selectionModel);
table.setRowStyles(new RowStyles<FieldColumn>() {
@Override
public String getStyleNames(FieldColumn row, int rowIndex) {
if (selectedTableDataProvider.getList().contains(row)) {
return InstanceTableStyle.INSTANCE.rowPresent();
}
return null;
}
});
tableDataProvider.addDataDisplay(table);
tableDataProvider.setList(allColumns);
tableDataProvider.refresh();
selectedColumnTableContainer.add(selectedTable);
columnTableContainer.add(table);
setMoveRightButtonState();
setRemoveButtonState();
setUpButtonState();
setDownButtonState();
selectedSelectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
setRemoveButtonState();
setMoveRightButtonState();
setDownButtonState();
setUpButtonState();
}
});
selectionModel.addSelectionChangeHandler(new SelectionChangeEvent.Handler() {
@Override
public void onSelectionChange(SelectionChangeEvent event) {
setMoveRightButtonState();
setRemoveButtonState();
}
});
filterColumnTable.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
final String value = filterColumnTable.getValue();
final ArrayList<FieldColumn> columnsToShow = Lists.newArrayList();
for (FieldColumn column : tableView.getColumns()) {
final String headerLowercased = column.getHeader().toLowerCase();
if (Strings.isNullOrEmpty(value) || headerLowercased.contains(value.toLowerCase())) {
columnsToShow.add(column);
}
}
tableDataProvider.setList(columnsToShow);
tableDataProvider.refresh();
}
});
}
public void show() {
dialog.show();
}
private static DataGrid<FieldColumn> createTable() {
final Column<FieldColumn, String> labelColumn = new Column<FieldColumn, String>(
new TextCell()) {
@Override
public String getValue(FieldColumn object) {
return object.getHeader();
}
};
labelColumn.setSortable(false);
final DataGrid<FieldColumn> table = new DataGrid<>(1000, DataGridResources.INSTANCE);
table.setHeight("300px"); // need to avoid height hardcode
table.setEmptyTableWidget(new Label());
table.setAutoHeaderRefreshDisabled(true);
table.setAutoFooterRefreshDisabled(true);
table.setSkipRowHoverCheck(true);
table.setSkipRowHoverFloatElementCheck(true);
table.addColumn(labelColumn);
table.setColumnWidth(labelColumn, 100, Style.Unit.PCT);
return table;
}
private void onOk() {
tableView.setSelectedColumns(Lists.newArrayList(selectedTableDataProvider.getList()));
dialog.hide();
}
public void setMoveRightButtonState() {
final HashSet<FieldColumn> selectedSet = Sets.newHashSet(selectionModel.getSelectedSet());
selectedSet.removeAll(selectedTableDataProvider.getList());
rightButton.setEnabled(!selectedSet.isEmpty());
}
public void setRemoveButtonState() {
leftButton.setEnabled(!selectedSelectionModel.getSelectedSet().isEmpty());
}
public void setUpButtonState() {
boolean enabled = false;
if (!selectedSelectionModel.getSelectedSet().isEmpty()) {
int minIndex = -1;
for (FieldColumn column : selectedSelectionModel.getSelectedSet()) {
final int indexOf = selectedTableDataProvider.getList().indexOf(column);
if (minIndex > indexOf || minIndex == -1) {
minIndex = indexOf;
}
}
if (minIndex > 0) {
enabled = true;
}
}
upButton.setEnabled(enabled);
}
public void setDownButtonState() {
boolean enabled = false;
if (!selectedSelectionModel.getSelectedSet().isEmpty()) {
int maxIndex = -1;
for (FieldColumn column : selectedSelectionModel.getSelectedSet()) {
final int indexOf = selectedTableDataProvider.getList().indexOf(column);
if (maxIndex < indexOf || maxIndex == -1) {
maxIndex = indexOf;
}
}
if (maxIndex < (selectedTableDataProvider.getList().size() - 1)) {
enabled = true;
}
}
downButton.setEnabled(enabled);
}
@UiHandler("rightButton")
public void onMoveRight(ClickEvent event) {
final Set<FieldColumn> set = Sets.newHashSet(selectionModel.getSelectedSet());
set.removeAll(selectedTableDataProvider.getList());
selectedTableDataProvider.getList().addAll(set);
selectedTableDataProvider.refresh();
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
setMoveRightButtonState();
redrawTableRows(set);
}
});
}
public void redrawTableRows(Collection<FieldColumn> rows) {
for (FieldColumn column : rows) {
final int index = tableDataProvider.getList().indexOf(column);
if (index != -1) {
table.redrawRow(index);
}
}
}
@UiHandler("leftButton")
public void onMoveLeft(ClickEvent event) {
final Set<FieldColumn> set = selectedSelectionModel.getSelectedSet();
selectedTableDataProvider.getList().removeAll(set);
selectedTableDataProvider.refresh();
selectedSelectionModel.clear(); // remove selection explicitly
Scheduler.get().scheduleDeferred(new Scheduler.ScheduledCommand() {
@Override
public void execute() {
setUpButtonState();
setDownButtonState();
setRemoveButtonState();
redrawTableRows(set);
}
});
}
@UiHandler("upButton")
public void onUp(ClickEvent event) {
final Set<FieldColumn> set = selectedSelectionModel.getSelectedSet();
final ArrayList<FieldColumn> copy = Lists.newArrayList(selectedTableDataProvider.getList());
for (FieldColumn column : set) {
final int index = copy.indexOf(column);
if (index > 0) {
Collections.swap(copy, index, index - 1);
}
}
selectedTableDataProvider.setList(copy);
setUpButtonState();
}
@UiHandler("downButton")
public void onDown(ClickEvent event) {
final Set<FieldColumn> set = selectedSelectionModel.getSelectedSet();
final ArrayList<FieldColumn> copy = Lists.newArrayList(selectedTableDataProvider.getList());
final int size = copy.size();
for (FieldColumn column : set) {
final int index = copy.indexOf(column);
if (index < (size - 1)) {
Collections.swap(copy, index, index + 1);
}
}
selectedTableDataProvider.setList(copy);
setDownButtonState();
}
}