/*
* Copyright 2014 Red Hat, Inc. and/or its affiliates.
*
* 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 org.dashbuilder.renderer.client.table;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import com.google.gwt.cell.client.TextCell;
import com.google.gwt.cell.client.ValueUpdater;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.cellview.client.ColumnSortEvent;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Anchor;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.view.client.AsyncDataProvider;
import com.google.gwt.view.client.HasData;
import org.dashbuilder.dataset.ColumnType;
import org.dashbuilder.dataset.sort.SortOrder;
import org.dashbuilder.displayer.client.AbstractDisplayerView;
import org.dashbuilder.renderer.client.resources.i18n.TableConstants;
import org.gwtbootstrap3.client.ui.Label;
import org.uberfire.client.callbacks.Callback;
import org.uberfire.ext.widgets.common.client.tables.PagedTable;
import static com.google.gwt.dom.client.BrowserEvents.*;
public class TableDisplayerView extends AbstractDisplayerView<TableDisplayer> implements TableDisplayer.View {
protected HTML titleHtml = new HTML();
protected HorizontalPanel filterPanel;
protected TableProvider tableProvider = new TableProvider();
protected VerticalPanel rootPanel = new VerticalPanel();
protected PagedTable<Integer> table;
@Override
public void init(TableDisplayer presenter) {
super.setPresenter(presenter);
super.setVisualization(rootPanel);
rootPanel.add(titleHtml);
}
@Override
public void showTitle(String title) {
titleHtml.setText(title);
}
@Override
public String getGroupsTitle() {
return TableConstants.INSTANCE.tableDisplayer_groupsTitle();
}
@Override
public String getColumnsTitle() {
return TableConstants.INSTANCE.tableDisplayer_columnsTitle();
}
@Override
public void createTable(int pageSize) {
table = new PagedTable<Integer>(pageSize);
table.pageSizesSelector.setVisible(false);
table.setEmptyTableCaption(TableConstants.INSTANCE.tableDisplayer_noDataAvailable());
tableProvider.addDataDisplay(table);
rootPanel.add(table);
}
@Override
public void redrawTable() {
table.redraw();
}
@Override
public void setWidth(int width) {
table.setWidth(width + "px");
}
@Override
public void setSortEnabled(boolean enabled) {
table.addColumnSortHandler(new ColumnSortEvent.AsyncHandler(table) {
public void onColumnSort(ColumnSortEvent event) {
String column = ((DataColumnCell) event.getColumn().getCell()).columnId;
SortOrder order = event.isSortAscending() ? SortOrder.ASCENDING : SortOrder.DESCENDING;
getPresenter().sortBy(column, order);
}
});
}
@Override
public void setTotalRows(int rows) {
table.setRowCount(rows, true);
}
@Override
public void setPagerEnabled(boolean enabled) {
table.pager.setVisible(enabled);
int rows = table.getRowCount() > table.getPageSize() ? table.getPageSize() : table.getRowCount();
table.setHeight(calculateHeight(rows) + "px");
}
@Override
public void addColumn(ColumnType columnType, String columnId, String columnName, int index, boolean selectEnabled, boolean sortEnabled) {
Column<Integer,?> column = createColumn(columnType, columnId, selectEnabled, index);
if (column != null) {
column.setSortable(sortEnabled);
table.addColumn(column, columnName);
}
}
@Override
public void clearFilterStatus() {
if (filterPanel != null) {
table.getLeftToolbar().remove(filterPanel);
filterPanel = null;
}
}
@Override
public void addFilterValue(String value) {
if (filterPanel == null) {
filterPanel = new HorizontalPanel();
filterPanel.getElement().setAttribute("cellpadding", "2");
table.getLeftToolbar().add(filterPanel);
}
filterPanel.add(new Label(value));
}
@Override
public void addFilterReset() {
Anchor anchor = new Anchor(TableConstants.INSTANCE.tableDisplayer_reset());
filterPanel.add(anchor);
anchor.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
getPresenter().filterReset();
}
});
}
@Override
public void gotoFirstPage() {
tableProvider.gotoFirstPage();
}
@Override
public int getLastOffset() {
return tableProvider.lastOffset;
}
// Table internals
public int calculateHeight(int rows) {
int rowHeight = 39 - rows;
int offset = 20 - rows;
rowHeight = rowHeight < 30 ? 30 : rowHeight;
offset = offset < 0 ? 0 : offset;
return offset + (rowHeight * (rows == 0 ? 1 : rows));
}
protected Column<Integer,?> createColumn(ColumnType type,
String columnId,
final boolean selectable,
final int columnNumber) {
switch (type) {
case LABEL: return new Column<Integer,String>(
new DataColumnCell(columnId, selectable)) {
public String getValue(Integer row) {
return getPresenter().formatValue(row, columnNumber);
}
};
case NUMBER:
case DATE:
case TEXT: return new Column<Integer,String>(
new DataColumnCell(columnId, selectable)) {
public String getValue(Integer row) {
return getPresenter().formatValue(row, columnNumber);
}
};
}
return null;
}
protected class DataColumnCell extends TextCell {
private String columnId;
private boolean selectable = false;
DataColumnCell(String columnId, boolean selectable) {
this.columnId = columnId;
this.selectable = selectable;
}
@Override
public Set<String> getConsumedEvents() {
Set<String> consumedEvents = new HashSet<String>();
if (selectable) {
consumedEvents.add(CLICK);
}
return consumedEvents;
}
@Override
public void onBrowserEvent(Context context,
Element parent,
String value,
NativeEvent event,
ValueUpdater<String> valueUpdater) {
if (selectable) {
int rowIndexInPage = context.getIndex() - table.getPageStart();
getPresenter().selectCell(columnId, rowIndexInPage);
}
}
}
/**
* The table data provider
*/
protected class TableProvider extends AsyncDataProvider<Integer> {
protected int lastOffset = 0;
protected List<Integer> getCurrentPageRows(HasData<Integer> display) {
final int start = ((PagedTable) display).getPageStart();
int pageSize = ((PagedTable) display).getPageSize();
int end = start + pageSize;
if (end > table.getRowCount()) {
end = table.getRowCount();
}
final List<Integer> rows = new ArrayList<Integer>(end-start);
for (int i = 0; i < end-start; i++) {
rows.add(i);
}
return rows;
}
/**
* Both filter & sort invoke this method from redraw()
*/
public void gotoFirstPage() {
// Avoid fetching the data set again
lastOffset = 0;
// This calls internally to onRangeChanged() when the page changes
table.pager.setPage(0);
int start = table.getPageStart();
final List<Integer> rows = getCurrentPageRows(table);
updateRowData(start, rows);
}
/**
* Invoked from createWidget just after the data set has been fetched.
*/
public void addDataDisplay(HasData<Integer> display) {
// Avoid fetching the data set again
lastOffset = 0;
// This calls internally to onRangeChanged()
super.addDataDisplay(display);
}
/**
* This is invoked internally by the PagedTable on navigation actions.
*/
protected void onRangeChanged(final HasData<Integer> display) {
int start = ((PagedTable) display).getPageStart();
final List<Integer> rows = getCurrentPageRows(display);
if (lastOffset == start) {
updateRowData(lastOffset, rows);
}
else {
lastOffset = start;
getPresenter().lookupCurrentPage(new Callback<Integer>() {
public void callback(Integer rowsFetched) {
updateRowData(lastOffset, rows);
table.setHeight(calculateHeight(rowsFetched) + "px");
}
});
}
}
}
}