/* * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * 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 Lesser General Public License for more details. * * Copyright 2008 - 2009 Pentaho Corporation. All rights reserved. */ package org.pentaho.pac.ui.gwt.table; import java.util.ArrayList; import java.util.List; import org.pentaho.pac.ui.gwt.table.model.TableDataServiceAsync; import org.pentaho.pac.ui.gwt.table.model.TableModel; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.ui.AbsolutePanel; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.Grid; import com.google.gwt.user.client.ui.ScrollListener; import com.google.gwt.user.client.ui.ScrollPanel; import com.google.gwt.user.client.ui.SourcesTableEvents; import com.google.gwt.user.client.ui.TableListener; import com.google.gwt.user.client.ui.Widget; import com.google.gwt.user.client.ui.HTMLTable.RowFormatter; public class FrozenHeaderTable extends Composite implements ScrollListener { private static final int SCRL_WIDTH = 20; private static final int NO_ROW_SELECTED = -1; private TableModel model; private AbsolutePanel root, headerContainer, header, tablePanel; private Grid table; private ScrollPanel scroller; private ColumnSupport colSupport; private RowSupport rowSupport; private int gridWidth; private boolean horizScrolling; private TableDataServiceAsync dataService; private int selectedRowIndex = NO_ROW_SELECTED; private List<NameValue> discriminators = new ArrayList<NameValue>(1); private List<RowSelectionListener> rowSelectionListeners; public FrozenHeaderTable(TableModel tableModel) { this.model = tableModel; } public void addDiscriminator(String name, String value) { discriminators.add(new NameValue(name, value)); } public void clearDiscriminators() { discriminators.clear(); } public void init() { headerContainer = new AbsolutePanel(); header = new AbsolutePanel(); headerContainer.add(header, 0, 0); table = new Grid(); tablePanel = new AbsolutePanel(); tablePanel.add(table); scroller = new ScrollPanel(tablePanel); scroller.addScrollListener(this); root = new AbsolutePanel(); root.add(headerContainer, 0, 0); root.add(scroller, 0, 20); refresh(); table.addTableListener(new TableListener() { public void onCellClicked(SourcesTableEvents sender, int row, int column) { FrozenHeaderTable.this.cellClicked(row, column); } }); initWidget(root); } public void addTableStyle(TableStyles.Type type, String styleName) { model.getStyles().addStyle(type, styleName); } private void refresh() { reloadMetaData(); redrawHeaders(); redrawData(); } private void reloadMetaData() { colSupport = new ColumnSupport(model); rowSupport = new RowSupport(model, dataService); rowSupport.setDiscriminators(this.discriminators); int modelTotalWidth = model.getTotalWidth(); gridWidth = modelTotalWidth < 0 ? colSupport.getWidth() + SCRL_WIDTH : modelTotalWidth; if (gridWidth > colSupport.getWidth() + SCRL_WIDTH) gridWidth = colSupport.getWidth() + SCRL_WIDTH; horizScrolling = gridWidth < colSupport.getWidth(); rowSupport.removeRows(table, colSupport); } private void redrawHeaders() { headerContainer.setPixelSize(gridWidth, model.getPixelHeaderHeight()); header .setPixelSize(colSupport.getWidth(), model .getPixelHeaderHeight()); colSupport.addHeaders(header); int hPos = scroller.getHorizontalScrollPosition(); if (hPos < 0) hPos = 0; headerContainer.setWidgetPosition(header, -hPos, 0); } private void redrawData() { dataService.getRowCount(new AsyncCallback<Integer>() { public void onFailure(Throwable caught) { Window.alert(caught.getMessage()); } public void onSuccess(Integer result) { int visibleRows = model.getVisibleRows(); int rowCount = result; if (rowCount < visibleRows) visibleRows = rowCount; int scrollerVertSize = visibleRows * model.getPixelRowHeight() + (horizScrolling ? SCRL_WIDTH : 0); tablePanel.setPixelSize(colSupport.getWidth(), rowCount * model.getPixelRowHeight()); table.setCellPadding(0); table.setCellSpacing(0); scroller.setPixelSize(gridWidth, scrollerVertSize); root.setWidgetPosition(scroller, 0, model .getPixelHeaderHeight()); root.setPixelSize(gridWidth, model.getPixelHeaderHeight() + scrollerVertSize); redrawCells(); } }); } private void redrawCells() { if (scroller == null) return; rowSupport.layoutRows(table, colSupport, scroller.getScrollPosition()); } public void setTableModel(TableModel tableModel) { this.model = tableModel; } public void onScroll(Widget widget, int scrollLeft, int scrollTop) { // TODO Auto-generated method stub } public void setTableDataService(TableDataServiceAsync dataService) { this.dataService = dataService; } /** * Change the CSS styles of all rows. The currently selected row gets * different CSS style. */ private void redrawSelectedRow() { String selectedStyle = getSingleStyleName(TableStyles.Type.SELECTED_ROW); String evenStyleName = getSingleStyleName(TableStyles.Type.EVEN_ROW); String oddStyleName = getSingleStyleName(TableStyles.Type.ODD_ROW); RowFormatter gridRowFormatter = table.getRowFormatter(); for (int row = 0; row <= model.getActualRowCount(); row++) { if (row == this.selectedRowIndex) { gridRowFormatter.setStyleName(row, selectedStyle); } else { gridRowFormatter.setStyleName(row, row % 2 == 0 ? evenStyleName : oddStyleName); } } } private String getSingleStyleName(TableStyles.Type type) { if (model.getStyles() == null) return ""; //$NON-NLS-1$ List<String> sstyles = model.getStyles().getStyleNames(type); return sstyles.size() > 0 ? sstyles.get(0) : ""; //$NON-NLS-1$ } private void cellClicked(int row, int column) { selectRow(row); redrawSelectedRow(); } public void selectRow(int rowIndex) { selectedRowIndex = rowIndex; String rowId = "1";// getSelectedRowId(); //$NON-NLS-1$ if (this.rowSelectionListeners != null) { for (int i = 0; i < this.rowSelectionListeners.size(); i++) { RowSelectionListener listener = (RowSelectionListener) this.rowSelectionListeners .get(i); listener.onRowSelected(this, rowId); } } } public void addRowSelectionListener(RowSelectionListener listener) { if (rowSelectionListeners == null) { rowSelectionListeners = new ArrayList<RowSelectionListener>(); } rowSelectionListeners.add(listener); } }