/*
* Ext GWT - Ext for GWT
* Copyright(c) 2007-2009, Ext JS, LLC.
* licensing@extjs.com
*
* http://extjs.com/license
*/
package com.extjs.gxt.ui.client.widget.grid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.widget.BoxComponent;
import com.extjs.gxt.ui.client.widget.ComponentHelper;
import com.google.gwt.i18n.client.NumberFormat;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
/**
* Column footer widget for Grid, which renders one to many aggregation rows.
*/
class ColumnFooter extends BoxComponent {
class Foot extends SimplePanel {
public Foot(AggregationRowConfig<?> config, String id) {
setStyleName("x-grid3-cell-inner");
}
public void setHtml(String html) {
setWidget(new HTML(html));
}
public void setWidget(Widget widget) {
super.setWidget(widget);
}
}
class FooterRow extends BoxComponent {
private FlexTable table;
private AggregationRowConfig<?> config;
public FooterRow(AggregationRowConfig<?> config) {
this.config = config;
rows.add(this);
}
public void setHtml(int column, String html) {
Foot f = (Foot) table.getWidget(0, column);
f.setHtml(html);
}
public void setWidget(int column, Widget widget) {
Foot f = (Foot) table.getWidget(0, column);
f.setWidget(f);
}
@Override
protected void doAttachChildren() {
super.doAttachChildren();
ComponentHelper.doAttach(table);
}
@Override
protected void doDetachChildren() {
super.doDetachChildren();
ComponentHelper.doDetach(table);
}
@Override
protected void onRender(Element target, int index) {
super.onRender(target, index);
setElement(DOM.createDiv(), target, index);
setStyleName("x-grid3-footer-row");
table = new FlexTable();
table.setCellPadding(0);
table.setCellSpacing(0);
int cols = cm.getColumnCount();
for (int i = 0; i < cols; i++) {
Foot f = new Foot(config, cm.getDataIndex(i));
table.setWidget(0, i, f);
table.getCellFormatter().setWidth(0, i, cm.getColumnWidth(i) + "");
if (cm.getColumnAlignment(i) == HorizontalAlignment.RIGHT) {
table.getCellFormatter().setHorizontalAlignment(0, i, HasHorizontalAlignment.ALIGN_RIGHT);
}
}
el().appendChild(table.getElement());
}
}
protected Grid<ModelData> grid;
protected ColumnModel cm;
protected List<FooterRow> rows = new ArrayList<FooterRow>();
@SuppressWarnings("unchecked")
public ColumnFooter(Grid grid, ColumnModel cm) {
this.grid = grid;
this.cm = cm;
}
public void add(FooterRow row) {
rows.add(row);
}
@Override
public void onComponentEvent(ComponentEvent ce) {
super.onComponentEvent(ce);
ce.stopEvent();
}
public void remove(FooterRow row) {
rows.remove(row);
}
public void updateColumnHidden(int column, boolean hidden) {
for (int i = 0; i < rows.size(); i++) {
FooterRow footerRow = rows.get(i);
Element td = footerRow.table.getFlexCellFormatter().getElement(0, column);
td.getStyle().setProperty("display", hidden ? "none" : "");
}
}
public void updateColumnWidth(int column, int width) {
if (!cm.isHidden(column)) {
for (int i = 0; i < rows.size(); i++) {
FooterRow row = rows.get(i);
row.table.getCellFormatter().setWidth(0, column, width + "");
Widget w = row.table.getWidget(0, column);
El.fly(w.getElement()).setWidth(width, true);
}
}
}
public void updateTotalWidth(int offset, int width) {
for (int i = 0; i < rows.size(); i++) {
FooterRow row = rows.get(i);
row.setWidth(offset);
row.table.getElement().getStyle().setProperty("width", width + "px");
}
}
@Override
protected void onRender(Element target, int index) {
super.onRender(target, index);
setElement(DOM.createDiv(), target, index);
setStyleName("x-grid3-footer");
setStyleAttribute("overflow", "hidden");
int rows = cm.getAggregationRows().size();
for (int i = 0; i < rows; i++) {
FooterRow row = new FooterRow(cm.getAggregationRow(i));
row.render(getElement());
}
refresh();
sinkEvents(Event.MOUSEEVENTS);
}
@SuppressWarnings("unchecked")
protected void refresh() {
ListStore<ModelData> store = grid.getStore();
int cols = cm.getColumnCount();
int models = grid.getStore().getCount();
int rowcount = rows.size();
for (int i = 0; i < rowcount; i++) {
AggregationRowConfig<?> config = cm.getAggregationRow(i);
FooterRow footer = rows.get(i);
for (int j = 0; j < cols; j++) {
String name = cm.getDataIndex(j);
if (config.getHtml(name) != null) {
footer.setHtml(j, config.getHtml(name));
continue;
} else if (config.getWidget(name) != null) {
footer.setWidget(j, config.getWidget(name));
continue;
}
Number value = null;
SummaryType<?> type = config.getSummaryType(name);
if (type != null) {
Map<String, Object> data = new HashMap<String, Object>();
for (int k = 0; k < models; k++) {
value = type.render(value, store.getAt(k), name, data);
}
}
if (config.getModel() != null) {
Object obj = config.getModel().get(cm.getDataIndex(i));
if (obj != null && obj instanceof Number) {
value = (Number)obj;
} else if (obj != null) {
footer.setHtml(j, obj.toString());
continue;
}
}
NumberFormat format = config.getSummaryFormat(name);
if (format != null) {
String svalue = format.format(value.doubleValue());
footer.setHtml(j, svalue);
continue;
}
AggregationRenderer<?> renderer = config.getRenderer(name);
if (renderer != null) {
Object obj = renderer.render(value, j, (Grid) grid, (ListStore) store);
if (obj instanceof Widget) {
footer.setWidget(j, (Widget) obj);
} else {
footer.setHtml(j, obj.toString());
}
}
}
}
}
}