com.extjs.gxt.ui.client.widget.grid.GridView Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gxt Show documentation
Show all versions of gxt Show documentation
Rich Internet Application Framework for GWT
/*
* Ext GWT 2.2.0 - Ext for GWT
* Copyright(c) 2007-2010, Ext JS, LLC.
* [email protected]
*
* http://extjs.com/license
*/
package com.extjs.gxt.ui.client.widget.grid;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import com.extjs.gxt.ui.client.GXT;
import com.extjs.gxt.ui.client.Style;
import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.SortDir;
import com.extjs.gxt.ui.client.core.DomHelper;
import com.extjs.gxt.ui.client.core.El;
import com.extjs.gxt.ui.client.core.XDOM;
import com.extjs.gxt.ui.client.data.BaseModel;
import com.extjs.gxt.ui.client.data.ModelData;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.SortInfo;
import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.BaseObservable;
import com.extjs.gxt.ui.client.event.ColumnModelEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.EventType;
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.MenuEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.js.JsArray;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.store.Record;
import com.extjs.gxt.ui.client.store.StoreEvent;
import com.extjs.gxt.ui.client.store.StoreListener;
import com.extjs.gxt.ui.client.util.DelayedTask;
import com.extjs.gxt.ui.client.util.Point;
import com.extjs.gxt.ui.client.util.Size;
import com.extjs.gxt.ui.client.util.Util;
import com.extjs.gxt.ui.client.widget.Component;
import com.extjs.gxt.ui.client.widget.ComponentHelper;
import com.extjs.gxt.ui.client.widget.menu.CheckMenuItem;
import com.extjs.gxt.ui.client.widget.menu.Menu;
import com.extjs.gxt.ui.client.widget.menu.MenuItem;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.EventTarget;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.TableRowElement;
import com.google.gwt.dom.client.TableSectionElement;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.AbstractImagePrototype;
import com.google.gwt.user.client.ui.Widget;
/**
* This class encapsulates the user interface of an {@link Grid}. Methods of
* this class may be used to access user interface elements to enable special
* display effects. Do not change the DOM structure of the user interface.
*
* This class does not provide ways to manipulate the underlying data. The data
* model of a Grid is held in an {@link ListStore}.
*/
public class GridView extends BaseObservable {
/**
* Icons used by Grid which can be overridden as needed. s
*/
public class GridViewImages {
private AbstractImagePrototype columns = GXT.IMAGES.grid_columns();
private AbstractImagePrototype sortAsc = GXT.IMAGES.grid_sortAsc();
private AbstractImagePrototype sortDesc = GXT.IMAGES.grid_sortDesc();
public AbstractImagePrototype getColumns() {
return columns;
}
public AbstractImagePrototype getSortAsc() {
return sortAsc;
}
public AbstractImagePrototype getSortDesc() {
return sortDesc;
}
public void setColumns(AbstractImagePrototype columnsIcon) {
this.columns = columnsIcon;
}
public void setSortAsc(AbstractImagePrototype sortAscIcon) {
this.sortAsc = sortAscIcon;
}
public void setSortDesc(AbstractImagePrototype sortDescIcon) {
this.sortDesc = sortDescIcon;
}
}
private static JavaScriptObject colRe;
protected int activeHdIndex;
protected boolean autoFill;
protected int borderWidth = 2;
protected ColumnModel cm;
protected Listener columnListener;
protected boolean deferEmptyText;
protected ListStore ds;
// elements
protected El el, mainWrap, mainHd, innerHd, scroller, mainBody;
protected String emptyText = " ";
protected boolean enableHdMenu = true;
// config
protected boolean enableRowBody;
protected boolean focusEnabled = true;
protected ColumnFooter footer;
protected boolean forceFit;
protected Grid grid;
protected ColumnHeader header;
protected int headerColumnIndex;
protected boolean headerDisabled;
protected GridViewImages images;
protected int lastViewWidth;
protected StoreListener listener;
protected Element overRow;
protected boolean preventScrollToTopOnRefresh;
protected int scrollOffset = 19;
protected boolean selectable = false;
protected SortInfo sortState;
protected int splitterWidth = 5;
protected GridTemplates templates;
protected boolean userResized;
// we first render grid with a vbar, and remove as needed
protected boolean vbar = true;
protected GridViewConfig viewConfig;
protected List> widgetList = new ArrayList>();
private boolean adjustForHScroll = true;
private String cellSelector = "td.x-grid3-cell";
private int cellSelectorDepth = 4;
private DelayedTask removeTask = new DelayedTask(new Listener() {
public void handleEvent(BaseEvent be) {
calculateVBar(false);
applyEmptyText();
refreshFooterData();
processRows(0, false);
}
});
private String rowSelector = "div.x-grid3-row";
private int rowSelectorDepth = 10;
private boolean showDirtyCells = true;
private boolean showInvalidCells;
/**
* Ensured the current row and column is visible.
*
* @param row the row index
* @param col the column index
* @param hscroll true to scroll horizontally if needed
* @return the calculated point
*/
public Point ensureVisible(int row, int col, boolean hscroll) {
if (grid == null || !grid.isViewReady() || row < 0 || row > ds.getCount()) {
return null;
}
if (col == -1) {
col = 0;
}
Element rowEl = getRow(row);
Element cellEl = null;
if (!(!hscroll && col == 0)) {
while (cm.isHidden(col)) {
col++;
}
cellEl = getCell(row, col);
}
if (rowEl == null) {
return null;
}
Element c = scroller.dom;
int ctop = 0;
Element p = rowEl, stope = el.dom;
while (p != null && p != stope) {
ctop += p.getOffsetTop();
p = p.getOffsetParent().cast();
}
ctop -= mainHd.dom.getOffsetHeight();
int cbot = ctop + rowEl.getOffsetHeight();
int ch = c.getOffsetHeight();
int stop = c.getScrollTop();
int sbot = stop + ch;
if (ctop < stop) {
c.setScrollTop(ctop);
} else if (cbot > sbot) {
if (hscroll && (cm.getTotalWidth() > scroller.getWidth() - scrollOffset)) {
cbot += scrollOffset;
}
c.setScrollTop(cbot -= ch);
}
if (hscroll && cellEl != null) {
int cleft = cellEl.getOffsetLeft();
int cright = cleft + cellEl.getOffsetWidth();
int sleft = c.getScrollLeft();
int sright = sleft + c.getOffsetWidth();
if (cleft < sleft) {
c.setScrollLeft(cleft);
} else if (cright > sright) {
c.setScrollLeft(cright - scroller.getStyleWidth());
}
}
return cellEl != null ? fly(cellEl).getXY() : new Point(c.getScrollLeft(), fly(rowEl).getY());
}
/**
* Returns the cell.
*
* @param elem the cell element or a child element
* @return the cell element
*/
public Element findCell(Element elem) {
if (elem == null) {
return null;
}
return fly(elem).findParentElement(cellSelector, cellSelectorDepth);
}
/**
* Returns the cell index.
*
* @param elem the cell or child element
* @param requiredStyle an optional required style name
* @return the cell index or -1 if not found
*/
public int findCellIndex(Element elem, String requiredStyle) {
Element cell = findCell(elem);
if (cell != null && (requiredStyle == null || fly(cell).hasStyleName(requiredStyle))) {
return getCellIndex(cell);
}
return -1;
}
/**
* Returns the row element.
*
* @param el the row element or any child element
* @return the matching row element
*/
public Element findRow(Element el) {
if (el == null) {
return null;
}
return fly(el).findParentElement(rowSelector, rowSelectorDepth);
}
/**
* Returns the row index.
*
* @param elem the row or child of the row element
* @return the index
*/
public int findRowIndex(Element elem) {
Element r = findRow(elem);
return r != null ? r.getPropertyInt("rowIndex") : -1;
}
/**
* Focus the cell and scrolls into view.
*
* @param rowIndex the row index
* @param colIndex the column index
* @param hscroll true to scroll horizontally
*/
public void focusCell(int rowIndex, int colIndex, boolean hscroll) {
Point xy = ensureVisible(rowIndex, colIndex, hscroll);
if (xy != null) {
if (focusEnabled) {
focusGrid();
}
}
}
/**
* Focus the row and scrolls into view.
*
* @param rowIndex the row index
*/
public void focusRow(int rowIndex) {
focusCell(rowIndex, 0, true);
}
/**
* Returns the grid's body element.
*
* @return the body element
*/
public El getBody() {
return scroller;
}
/**
* Returns the grid's <TD> HtmlElement at the specified coordinates.
*
* @param row the row index in which to find the cell
* @param col the column index of the cell
* @return the <TD> at the specified coordinates
*/
public Element getCell(int row, int col) {
// ROW DIV TABLE TR TD
Element rowEl = getRow(row);
return (Element) ((rowEl != null && rowEl.hasChildNodes())
? rowEl.getFirstChild().getFirstChild().getFirstChild().getChildNodes().getItem(col) : null);
}
/**
* Returns the cell selector depth.
*
* @return the cell selector depth
*/
public int getCellSelectorDepth() {
return cellSelectorDepth;
}
/**
* Returns the editor parent element.
*
* @return the editor element
*/
public Element getEditorParent() {
return scroller.dom;
}
/**
* Returns the empty text.
*
* @return the empty text
*/
public String getEmptyText() {
return emptyText;
}
/**
* Returns the grid's column header.
*
* @return the header
*/
public ColumnHeader getHeader() {
return header;
}
/**
* Returns the <TD> HtmlElement which represents the Grid's header cell for
* the specified column index.
*
* @param index the column index
* @return the <TD> element.
*/
public Element getHeaderCell(int index) {
return mainHd.dom.getElementsByTagName("td").getItem(index);
}
/**
* Returns the images used by grid.
*
* @return the images
*/
public GridViewImages getImages() {
if (images == null) {
images = new GridViewImages();
}
return images;
}
/**
* Return the <TR> HtmlElement which represents a Grid row for the
* specified index.
*
* @param row the row index
* @return the <TR> element
*/
public Element getRow(int row) {
if (row < 0) {
return null;
}
return getRows().getItem(row);
}
/**
* Return the <TR> HtmlElement which represents a Grid row for the
* specified model.
*
* @param m the model
* @return the <TR> element
*/
public Element getRow(ModelData m) {
return getRow(ds.indexOf(m));
}
/**
* Returns the row selector depth.
*
* @return the row selector depth
*/
public int getRowSelectorDepth() {
return rowSelectorDepth;
}
/**
* Returns the scroll element.
*
* @return the scroll element
*/
public El getScroller() {
return scroller;
}
/**
* Returns the current scroll state.
*
* @return the scroll state
*/
public Point getScrollState() {
return new Point(scroller.getScrollLeft(), scroller.getScrollTop());
}
/**
* Returns the view config.
*
* @return the view config
*/
public GridViewConfig getViewConfig() {
return viewConfig;
}
/**
* Returns the widget at the current location.
*
* @param rowIndex the row index
* @param colIndex the column index
* @return the widget or null
*/
public Widget getWidget(int rowIndex, int colIndex) {
List map = rowIndex < widgetList.size() ? widgetList.get(rowIndex) : null;
return map != null && colIndex < map.size() ? map.get(colIndex) : null;
}
/**
* Returns true if the grid width will be adjusted based on visibility of
* horizontal scroll bar.
*
* @return true if adjusting
*/
public boolean isAdjustForHScroll() {
return adjustForHScroll;
}
/**
* Returns true if auto fill is enabled.
*
* @return true for auto fill
*/
public boolean isAutoFill() {
return autoFill;
}
/**
* Returns true if force fit is enabled.
*
* @return true for force fit
*/
public boolean isForceFit() {
return forceFit;
}
/**
* Returns true if dirty cell markers are enabled.
*
* @return true of dirty cell markers
*/
public boolean isShowDirtyCells() {
return showDirtyCells;
}
/**
* Returns true if invalid cell markers are enabled.
*
* @return true if enabled
*/
public boolean isShowInvalidCells() {
return showInvalidCells;
}
/**
* Returns true if sorting is enabled.
*
* @return true for sorting
*/
public boolean isSortingEnabled() {
return !headerDisabled;
}
public void layout() {
layout(false);
}
/**
* Rebuilds the grid using its current configuration and data.
*
* @param headerToo true to refresh the header
*/
public void refresh(boolean headerToo) {
if (grid != null && grid.isViewReady()) {
stopEditing();
detachWidgets(0, -1, true);
if (!preventScrollToTopOnRefresh) {
scrollToTop();
}
mainBody.setInnerHtml(renderRows(0, -1));
if (headerToo) {
sortState = null;
header.release();
newColumnHeader();
renderHeader();
if (grid.isAttached()) {
ComponentHelper.doAttach(header);
}
header.setEnableColumnResizing(grid.isColumnResize());
header.setEnableColumnReorder(grid.isColumnReordering());
}
processRows(0, true);
renderWidgets(0, -1);
if (footer != null) {
ComponentHelper.doDetach(footer);
footer.el().removeFromParent();
}
if (cm.getAggregationRows().size() > 0) {
footer = new ColumnFooter(grid, cm);
renderFooter();
if (grid.isAttached()) {
ComponentHelper.doAttach(footer);
}
}
calculateVBar(true);
updateHeaderSortState();
applyEmptyText();
fireEvent(Events.Refresh);
}
}
/**
* Scrolls the grid to the top.
*/
public void scrollToTop() {
scroller.setScrollTop(0);
scroller.setScrollLeft(0);
}
/**
* True to adjust the grid width when the horizontal scrollbar is hidden and
* visible (defaults to true).
*
* @param adjustForHScroll true to adjust for horizontal scroll bar
*/
public void setAdjustForHScroll(boolean adjustForHScroll) {
this.adjustForHScroll = adjustForHScroll;
}
/**
* True to auto expand the columns to fit the grid when the grid is
* created.
*
* @param autoFill true to expand
*/
public void setAutoFill(boolean autoFill) {
this.autoFill = autoFill;
}
/**
* The number of levels to search for cells in event delegation (defaults to
* 4).
*
* @param cellSelectorDepth the cell selector depth
*/
public void setCellSelectorDepth(int cellSelectorDepth) {
this.cellSelectorDepth = cellSelectorDepth;
}
/**
* Default text to display in the grid body when no rows are available
* (defaults to '').
*
* @param emptyText the empty text
*/
public void setEmptyText(String emptyText) {
this.emptyText = emptyText;
}
/**
* True to auto expand/contract the size of the columns to fit the grid width
* and prevent horizontal scrolling.
*
* @param forceFit true to force fit
*/
public void setForceFit(boolean forceFit) {
this.forceFit = forceFit;
}
/**
* The number of levels to search for rows in event delegation (defaults to
* 10).
*
* @param rowSelectorDepth the row selector depth
*/
public void setRowSelectorDepth(int rowSelectorDepth) {
this.rowSelectorDepth = rowSelectorDepth;
}
/**
* True to display a red triangle in the upper left corner of any cells which
* are "dirty" as defined by any existing records in the data store (defaults
* to true).
*
* @param showDirtyCells true to display the dirty flag
*/
public void setShowDirtyCells(boolean showDirtyCells) {
this.showDirtyCells = showDirtyCells;
}
/**
* True to enabled invalid cell markers (defaults to false).
*
* @param showInvalidCells true to enable
*/
public void setShowInvalidCells(boolean showInvalidCells) {
this.showInvalidCells = showInvalidCells;
}
/**
* True to allow column sorting when the user clicks a column (defaults to
* true).
*
* @param sortable true for sortable columns
*/
public void setSortingEnabled(boolean sortable) {
this.headerDisabled = !sortable;
}
/**
* Sets the view config.
*
* @param viewConfig the view config
*/
public void setViewConfig(GridViewConfig viewConfig) {
this.viewConfig = viewConfig;
}
protected void addRowStyle(Element elem, String style) {
if (elem != null) {
fly(elem).addStyleName(style);
}
}
protected void afterRender() {
mainBody.setInnerHtml(renderRows(0, -1));
renderWidgets(0, -1);
processRows(0, true);
int sh = scroller.getHeight();
int dh = mainBody.getHeight();
boolean vbar = dh < sh;
if (vbar) {
this.vbar = !vbar;
lastViewWidth = -1;
layout();
}
applyEmptyText();
}
protected void applyEmptyText() {
if (emptyText == null) {
emptyText = " ";
}
if (!hasRows()) {
mainBody.setInnerHtml("" + emptyText + "");
}
syncHScroll();
}
protected void autoExpand(boolean preventUpdate) {
if (!userResized && grid.getAutoExpandColumn() != null) {
int tw = cm.getTotalWidth(false);
int aw = grid.getWidth(true) - getScrollAdjust();
if (tw != aw) {
int ci = cm.getIndexById(grid.getAutoExpandColumn());
assert ci != Style.DEFAULT : "auto expand column not found";
if (cm.isHidden(ci)) {
return;
}
int currentWidth = cm.getColumnWidth(ci);
int cw = Math.min(Math.max(((aw - tw) + currentWidth), grid.getAutoExpandMin()), grid.getAutoExpandMax());
if (cw != currentWidth) {
cm.setColumnWidth(ci, cw, true);
if (!preventUpdate) {
updateColumnWidth(ci, cw);
}
}
}
}
}
protected void calculateVBar(boolean force) {
if (force) {
resize();
}
int sh = scroller.getHeight();
int dh = mainBody.getHeight();
boolean vbar = dh > sh;
if (force || this.vbar != vbar) {
this.vbar = vbar;
lastViewWidth = -1;
layout(true);
}
}
protected Menu createContextMenu(final int colIndex) {
final Menu menu = new Menu();
if (cm.isSortable(colIndex)) {
MenuItem item = new MenuItem();
item.setText(GXT.MESSAGES.gridView_sortAscText());
item.setIcon(getImages().getSortAsc());
item.addSelectionListener(new SelectionListener() {
public void componentSelected(MenuEvent ce) {
doSort(colIndex, SortDir.ASC);
}
});
menu.add(item);
item = new MenuItem();
item.setText(GXT.MESSAGES.gridView_sortDescText());
item.setIcon(getImages().getSortDesc());
item.addSelectionListener(new SelectionListener() {
public void componentSelected(MenuEvent ce) {
doSort(colIndex, SortDir.DESC);
}
});
menu.add(item);
}
MenuItem columns = new MenuItem();
columns.setText(GXT.MESSAGES.gridView_columnsText());
columns.setIcon(getImages().getColumns());
columns.setData("gxt-columns", "true");
final Menu columnMenu = new Menu();
int cols = cm.getColumnCount();
for (int i = 0; i < cols; i++) {
if (shouldNotCount(i, false)) {
continue;
}
final int fcol = i;
final CheckMenuItem check = new CheckMenuItem();
check.setHideOnClick(false);
check.setText(cm.getColumnHeader(i));
check.setChecked(!cm.isHidden(i));
check.addSelectionListener(new SelectionListener() {
public void componentSelected(MenuEvent ce) {
cm.setHidden(fcol, !cm.isHidden(fcol));
restrictMenu(columnMenu);
}
});
columnMenu.add(check);
}
restrictMenu(columnMenu);
columns.setSubMenu(columnMenu);
menu.add(columns);
return menu;
}
protected void detachWidget(int rowIndex, boolean remove) {
List m = rowIndex < widgetList.size() ? widgetList.get(rowIndex) : null;
if (m != null) {
for (Widget w : m) {
ComponentHelper.doDetach(w);
}
if (remove) {
widgetList.remove(rowIndex);
}
}
}
protected void detachWidgets(int startRow, int endRow, boolean remove) {
if (endRow == -1) {
endRow = widgetList.size() - 1;
}
for (int i = endRow; i >= startRow; i--) {
detachWidget(i, remove);
}
}
protected void doAttach() {
ComponentHelper.doAttach(header);
ComponentHelper.doAttach(footer);
resize();
renderWidgets(0, -1);
}
protected void doDetach() {
ComponentHelper.doDetach(header);
ComponentHelper.doDetach(footer);
detachWidgets(0, -1, false);
}
protected String doRender(List cs, List rows, int startRow, int colCount, boolean stripe) {
int last = colCount - 1;
String tstyle = "width:" + getTotalWidth() + "px;";
StringBuilder buf = new StringBuilder();
for (int j = 0; j < rows.size(); j++) {
ModelData model = (ModelData) rows.get(j);
model = prepareData(model);
Record r = ds.hasRecord(model) ? ds.getRecord(model) : null;
int rowBodyColSpanCount = colCount;
if (enableRowBody) {
if (grid.getSelectionModel() instanceof CheckBoxSelectionModel>) {
CheckBoxSelectionModel> sm = (CheckBoxSelectionModel>) grid.getSelectionModel();
if (cm.getColumnById(sm.getColumn().getId()) != null) {
rowBodyColSpanCount--;
}
}
for (ColumnConfig c : cm.getColumns()) {
if (c instanceof RowExpander || c instanceof RowNumberer) {
rowBodyColSpanCount--;
}
}
}
int rowIndex = (j + startRow);
if (GXT.isAriaEnabled()) {
buf.append("");
widgetList.add(rowIndex, new ArrayList());
for (int i = 0; i < colCount; i++) {
ColumnData c = cs.get(i);
c.css = c.css == null ? "" : c.css;
String rv = getRenderedValue(c, rowIndex, i, model, c.name);
String role = "gridcell";
if (GXT.isAriaEnabled()) {
ColumnConfig cc = cm.getColumn(i);
if (cc.isRowHeader()) {
role = "rowheader";
}
}
String attr = c.cellAttr != null ? c.cellAttr : "";
String cellAttr = c.cellAttr != null ? c.cellAttr : "";
buf.append("");
buf.append(rv);
buf.append(" ");
}
buf.append(" ");
if (enableRowBody) {
buf.append("${body} ");
}
buf.append("
");
}
return buf.toString();
}
protected void doSort(int colIndex, SortDir sortDir) {
ds.sort(cm.getDataIndex(colIndex), sortDir);
}
protected void fitColumns(boolean preventRefresh, boolean onlyExpand, int omitColumn) {
int tw = cm.getTotalWidth(false);
double aw = grid.el().getWidth(true) - getScrollAdjust();
if (aw <= 0) {
aw = grid.el().getStyleWidth();
}
if (aw < 20 || aw > 2000) { // not initialized, so don't screw up the
// default widths
return;
}
int extra = (int) aw - tw;
if (extra == 0) {
return;
}
int vc = cm.getColumnCount(true);
int ac = vc - (omitColumn != -1 ? 1 : 0);
if (ac == 0) {
ac = 1;
omitColumn = -1;
}
int colCount = cm.getColumnCount();
Stack cols = new Stack();
int width = 0;
int w;
for (int i = 0; i < colCount; i++) {
if (!cm.isHidden(i) && !cm.isFixed(i) && i != omitColumn) {
w = cm.getColumnWidth(i);
cols.push(i);
cols.push(w);
width += w;
}
}
double frac = (aw - cm.getTotalWidth()) / width;
while (cols.size() > 0) {
w = cols.pop();
int i = cols.pop();
int ww = Math.max(grid.getMinColumnWidth(), (int) Math.floor(w + w * frac));
cm.setColumnWidth(i, ww, true);
}
if (!preventRefresh) {
updateAllColumnWidths();
}
}
protected El fly(Element elem) {
return El.fly(elem, "grid");
}
protected void focusGrid() {
grid.el().setFocus(true);
}
protected int getCellIndex(Element elem) {
if (elem != null) {
String id = getCellIndexId(elem);
if (id != null) {
return cm.getIndexById(id);
}
}
return -1;
}
protected List getColumnData() {
int colCount = cm.getColumnCount();
List cs = new ArrayList();
for (int i = 0; i < colCount; i++) {
String name = cm.getDataIndex(i);
ColumnData data = new ColumnData();
data.name = name == null ? cm.getColumnId(i) : name;
data.renderer = cm.getRenderer(i);
data.id = cm.getColumnId(i);
data.style = getColumnStyle(i, false);
cs.add(data);
}
return cs;
}
protected String getColumnStyle(int colIndex, boolean isHeader) {
String style = !isHeader ? cm.getColumnStyle(colIndex) : "";
if (style == null) style = "";
int adj = GXT.isWebKit ? 2 : 0;
style += "width:" + (getColumnWidth(colIndex) + adj) + "px;";
if (cm.isHidden(colIndex)) {
style += "display:none;";
}
HorizontalAlignment align = cm.getColumnAlignment(colIndex);
if (align != null) {
style += "text-align:" + align.name() + ";";
}
return style;
}
protected int getColumnWidth(int col) {
int w = cm.getColumnWidth(col);
return (GXT.isBorderBox ? w : (w - borderWidth > 0 ? w - borderWidth : 0));
}
protected int getOffsetWidth() {
return (getTotalWidth() + getScrollAdjust());
}
protected String getRenderedValue(ColumnData data, int rowIndex, int colIndex, ModelData m, String property) {
GridCellRenderer r = cm.getRenderer(colIndex);
List rowMap = widgetList.get(rowIndex);
rowMap.add(colIndex, null);
if (r != null) {
Object o = r.render(ds.getAt(rowIndex), property, data, rowIndex, colIndex, ds, grid);
if (o instanceof Widget) {
Widget w = (Widget) o;
rowMap.set(colIndex, w);
return "";
} else if (o != null) {
return o.toString();
}
}
Object val = m.get(property);
ColumnConfig c = cm.getColumn(colIndex);
if (val != null && val instanceof Number && c.getNumberFormat() != null) {
Number n = (Number) val;
val = c.getNumberFormat().format(n.doubleValue());
} else if (val != null && val instanceof Date && c.getDateTimeFormat() != null) {
DateTimeFormat dtf = c.getDateTimeFormat();
val = dtf.format((Date) val);
}
String text = null;
if (val != null) {
text = val.toString();
}
return Util.isEmptyString(text) ? " " : text;
}
protected NodeList getRows() {
if (!hasRows()) {
return new JsArray().getJsObject().cast();
}
return mainBody.dom.getChildNodes().cast();
}
protected int getScrollAdjust() {
return adjustForHScroll ? (scroller != null ? (vbar ? scrollOffset : 2) : scrollOffset) : scrollOffset;
}
protected SortInfo getSortState() {
return ds.getSortState();
}
protected int getTotalWidth() {
return cm.getTotalWidth();
}
protected Element getWidgetCell(int row, int cell) {
Element cellEl = getCell(row, cell);
if (cellEl != null) {
return cellEl.getFirstChildElement();
}
return null;
}
@SuppressWarnings({"unchecked", "rawtypes"})
protected void handleComponentEvent(GridEvent ge) {
switch (ge.getEventTypeInt()) {
case Event.ONMOUSEMOVE:
Element row = getRow(ge.getRowIndex());
if (overRow != null && row == null) {
onRowOut(overRow);
} else if (row != null && overRow != row) {
if (overRow != null) {
onRowOut(overRow);
}
onRowOver(row);
}
break;
case Event.ONMOUSEOVER:
EventTarget from = ge.getEvent().getRelatedEventTarget();
if (from == null
|| (from != null && !DOM.isOrHasChild(grid.getElement(),
(com.google.gwt.user.client.Element) Element.as(from)))) {
Element r = getRow(ge.getRowIndex());
if (r != null) {
onRowOver(r);
}
}
break;
case Event.ONMOUSEOUT:
EventTarget to = ge.getEvent().getRelatedEventTarget();
if (to == null
|| (to != null && !DOM.isOrHasChild(grid.getElement(), (com.google.gwt.user.client.Element) Element.as(to)))) {
if (overRow != null) {
onRowOut(overRow);
}
}
break;
case Event.ONMOUSEDOWN:
onMouseDown(ge);
break;
case Event.ONSCROLL:
if (scroller.isOrHasChild(ge.getTarget())) {
syncScroll();
}
break;
}
}
protected boolean hasRows() {
if (mainBody == null) {
return false;
}
Element e = mainBody.dom.getFirstChildElement();
return e != null && !"x-grid-empty".equals(e.getClassName());
}
/**
* Initializes the view.
*
* @param grid the grid
*/
@SuppressWarnings({"unchecked", "rawtypes"})
protected void init(final Grid grid) {
this.grid = grid;
this.cm = grid.getColumnModel();
selectable = !grid.isDisableTextSelection();
initListeners();
initTemplates();
initData(grid.getStore(), cm);
initUI(grid);
newColumnHeader();
if (cm.getAggregationRows().size() > 0) {
footer = new ColumnFooter(grid, cm);
}
}
/**
* Initializes the data.
*
* @param ds the data store
* @param cm the column model
*/
@SuppressWarnings({"unchecked", "rawtypes"})
protected void initData(ListStore ds, ColumnModel cm) {
if (this.ds != null) {
this.ds.removeStoreListener(listener);
}
if (ds != null) {
ds.addStoreListener(listener);
}
this.ds = ds;
if (this.cm != null) {
this.cm.removeListener(Events.HiddenChange, columnListener);
this.cm.removeListener(Events.HeaderChange, columnListener);
this.cm.removeListener(Events.WidthChange, columnListener);
this.cm.removeListener(Events.ColumnMove, columnListener);
}
if (cm != null) {
cm.addListener(Events.HiddenChange, columnListener);
cm.addListener(Events.HeaderChange, columnListener);
cm.addListener(Events.WidthChange, columnListener);
cm.addListener(Events.ColumnMove, columnListener);
}
this.cm = cm;
}
protected void initElements() {
NodeList cs = grid.getElement().getFirstChild().getChildNodes();
el = grid.el().firstChild();
mainWrap = new El((com.google.gwt.user.client.Element) cs.getItem(0));
mainHd = mainWrap.firstChild();
if (grid.isHideHeaders()) {
mainHd.setVisible(false);
}
innerHd = mainHd.firstChild();
scroller = mainWrap.getChild(1);
scroller.addEventsSunk(Event.ONSCROLL);
if (forceFit) {
scroller.setStyleAttribute("overflowX", "hidden");
}
mainBody = scroller.firstChild();
}
protected void initListeners() {
listener = new StoreListener() {
@Override
public void handleEvent(StoreEvent e) {
if (grid.isViewReady()) {
super.handleEvent(e);
}
}
@Override
public void storeAdd(StoreEvent se) {
onAdd(ds, se.getModels(), se.getIndex());
}
@Override
public void storeBeforeDataChanged(StoreEvent se) {
onBeforeDataChanged(se);
}
@Override
public void storeClear(StoreEvent se) {
onClear(se);
}
@Override
public void storeDataChanged(StoreEvent se) {
onDataChanged(se);
}
@Override
public void storeFilter(StoreEvent se) {
onDataChanged(se);
}
@Override
public void storeRemove(StoreEvent se) {
onRemove(ds, se.getModel(), se.getIndex(), false);
}
@Override
public void storeUpdate(StoreEvent se) {
onUpdate(ds, se.getModel());
}
};
columnListener = new Listener() {
public void handleEvent(ColumnModelEvent e) {
if (grid.isViewReady()) {
EventType type = e.getType();
if (type == Events.HiddenChange) {
onHiddenChange(cm, e.getColIndex(), e.isHidden());
} else if (type == Events.HeaderChange) {
onHeaderChange(e.getColIndex(), e.getHeader());
} else if (type == Events.WidthChange) {
onColumnWidthChange(e.getColIndex(), e.getWidth());
} else if (type == Events.ColumnMove) {
onColumnMove(e.getColIndex());
}
}
}
};
}
protected void initTemplates() {
templates = GWT.create(GridTemplates.class);
}
protected void initUI(final Grid grid) {
}
protected void insertRows(ListStore store, int firstRow, int lastRow, boolean isUpdate) {
Element e = mainBody.dom.getFirstChildElement();
if (e != null && !hasRows()) {
mainBody.dom.setInnerHTML("");
}
String html = renderRows(firstRow, lastRow);
Element before = getRow(firstRow);
if (before != null) {
DomHelper.insertBefore((com.google.gwt.user.client.Element) before, html);
} else {
DomHelper.insertHtml("beforeEnd", mainBody.dom, html);
}
if (!isUpdate) {
processRows(firstRow, false);
}
}
protected void layout(boolean skipResize) {
if (mainBody == null) {
return;
}
El c = grid.el();
Size csize = c.getStyleSize();
int vw = csize.width;
int vh = 0;
if (vw < 10 || csize.height < 20) {
return;
}
if (!skipResize) {
resize();
}
if (forceFit || autoFill) {
if (lastViewWidth != vw) {
fitColumns(false, false, -1);
header.updateTotalWidth(getOffsetWidth(), getTotalWidth());
if (footer != null) {
footer.updateTotalWidth(getOffsetWidth(), getTotalWidth());
}
lastViewWidth = vw;
}
} else {
autoExpand(false);
header.updateTotalWidth(getOffsetWidth(), getTotalWidth());
if (footer != null) {
footer.updateTotalWidth(getOffsetWidth(), getTotalWidth());
}
syncHeaderScroll();
}
templateOnLayout(vw, vh);
}
protected ColumnHeader newColumnHeader() {
header = new ColumnHeader(grid, cm) {
@Override
protected ComponentEvent createColumnEvent(ColumnHeader header, int column, Menu menu) {
GridEvent event = new GridEvent(grid);
event.setColIndex(column);
event.setMenu(menu);
return event;
}
@Override
protected Menu getContextMenu(int column) {
return createContextMenu(column);
}
@Override
protected void onColumnSplitterMoved(int colIndex, int width) {
super.onColumnSplitterMoved(colIndex, width);
GridView.this.onColumnSplitterMoved(colIndex, width);
}
@Override
protected void onHeaderClick(ComponentEvent ce, int column) {
super.onHeaderClick(ce, column);
GridView.this.onHeaderClick(grid, column);
}
@Override
protected void onKeyDown(ComponentEvent ce, int index) {
ce.cancelBubble();
if (grid.getSelectionModel() instanceof CellSelectionModel>) {
CellSelectionModel> csm = (CellSelectionModel>) grid.getSelectionModel();
csm.selectCell(0, index);
} else {
grid.getSelectionModel().select(0, false);
}
}
};
header.setSplitterWidth(splitterWidth);
header.setMinColumnWidth(grid.getMinColumnWidth());
return header;
}
protected void notifyHide() {
}
protected void notifyShow() {
}
protected void onAdd(ListStore store, List models, int index) {
insertRows(store, index, index + (models.size() - 1), false);
renderWidgets(index, index + (models.size() - 1));
calculateVBar(false);
refreshFooterData();
}
protected void onBeforeDataChanged(StoreEvent se) {
if (grid.isLoadMask()) {
grid.mask(GXT.MESSAGES.loadMask_msg());
}
}
protected void onCellDeselect(int row, int col) {
Element cell = getCell(row, col);
if (cell != null) {
fly(cell).removeStyleName("x-grid3-cell-selected");
if (GXT.isAriaEnabled()) {
cell.setAttribute("aria-selected", "false");
}
}
}
protected void onCellSelect(int row, int col) {
Element cell = getCell(row, col);
if (cell != null) {
fly(cell).addStyleName("x-grid3-cell-selected");
if (GXT.isAriaEnabled()) {
cell.setAttribute("aria-selected", "true");
grid.getElement().setAttribute("aria-activedescendant", cell.getId());
}
}
}
protected void onClear(StoreEvent se) {
refresh(false);
}
protected void onClick(GridEvent ce) {
Element row = findRow(ce.getTarget());
if (row != null) {
ce.setRowIndex(findRowIndex(row));
grid.fireEvent(Events.RowClick, ce);
}
}
protected void onColumnMove(int newIndex) {
boolean pScroll = preventScrollToTopOnRefresh;
preventScrollToTopOnRefresh = true;
refresh(true);
preventScrollToTopOnRefresh = pScroll;
templateAfterMove(newIndex);
}
protected void onColumnSplitterMoved(int colIndex, int width) {
stopEditing();
userResized = true;
width = Math.max(grid.getMinColumnWidth(), width);
cm.setColumnWidth(colIndex, width);
GridEvent e = new GridEvent(grid);
e.setColIndex(colIndex);
e.setWidth(width);
grid.fireEvent(Events.ColumnResize, e);
}
protected void onColumnWidthChange(int column, int width) {
if (forceFit) {
fitColumns(false, false, column);
header.updateTotalWidth(getOffsetWidth(), getTotalWidth());
} else {
updateColumnWidth(column, width);
header.updateTotalWidth(getOffsetWidth(), getTotalWidth());
if (GXT.isIE) {
syncHeaderScroll();
}
}
if (grid.isStateful()) {
Map state = grid.getState();
state.put("width" + cm.getColumnId(column), width);
grid.saveState();
}
}
protected void onDataChanged(StoreEvent se) {
refresh(false);
if (grid.isLoadMask()) {
if (grid.isEnabled()) {
grid.unmask();
} else {
grid.mask();
}
}
if (grid.isStateful() && ds.getLoadConfig() != null && ds.getLoadConfig() instanceof PagingLoadConfig) {
PagingLoadConfig config = (PagingLoadConfig) ds.getLoadConfig();
Map state = grid.getState();
state.put("offset", config.getOffset());
state.put("limit", config.getLimit());
grid.saveState();
}
}
protected void onHeaderChange(int column, String text) {
header.setHeader(column, text);
}
protected void onHeaderClick(Grid grid, int column) {
this.headerColumnIndex = column;
if (!headerDisabled && cm.isSortable(column)) {
doSort(column, null);
}
}
protected void onHiddenChange(ColumnModel cm, int col, boolean hidden) {
updateColumnHidden(col, hidden);
if (grid.isStateful()) {
Map state = grid.getState();
state.put("hidden" + cm.getColumnId(col), hidden);
grid.saveState();
}
}
protected void onHighlightRow(int rowIndex, boolean highlight) {
Element row = getRow(rowIndex);
if (row != null) {
if (highlight) {
addRowStyle(row, "x-grid3-highlightrow");
if (GXT.isAriaEnabled()) {
grid.getElement().setAttribute("aria-activedescendant", row.getId());
}
} else {
removeRowStyle(row, "x-grid3-highlightrow");
}
}
}
protected void onMouseDown(GridEvent ge) {
}
protected void onRemove(ListStore ds, ModelData m, int index, boolean isUpdate) {
detachWidget(index, true);
removeRow(index);
if (!isUpdate) {
removeTask.delay(10);
} else {
removeTask.delay(0);
}
}
protected void onRowDeselect(int rowIndex) {
Element row = getRow(rowIndex);
if (row != null) {
removeRowStyle(row, "x-grid3-row-selected");
if (GXT.isAriaEnabled()) {
row.setAttribute("aria-selected", "false");
}
}
}
protected void onRowOut(Element row) {
if (grid.isTrackMouseOver()) {
removeRowStyle(row, "x-grid3-row-over");
overRow = null;
}
}
protected void onRowOver(Element row) {
if (grid.isTrackMouseOver()) {
addRowStyle(row, "x-grid3-row-over");
overRow = row;
}
}
protected void onRowSelect(int rowIndex) {
Element row = getRow(rowIndex);
if (row != null) {
onRowOut(row);
addRowStyle(row, "x-grid3-row-selected");
if (GXT.isAriaEnabled()) {
row.setAttribute("aria-selected", "true");
grid.getElement().setAttribute("aria-activedescendant", row.getId());
}
}
}
protected void onUpdate(ListStore store, ModelData model) {
refreshRow(store.indexOf(model));
}
protected ModelData prepareData(ModelData model) {
if (grid.getModelProcessor() != null) {
boolean silent = false;
if (model instanceof BaseModel) {
silent = ((BaseModel) model).isSilent();
((BaseModel) model).setSilent(true);
}
ModelData m = grid.getModelProcessor().prepareData(model);
if (model instanceof BaseModel) {
((BaseModel) model).setSilent(silent);
}
return m;
}
return model;
}
protected void processRows(int startRow, boolean skipStripe) {
if (ds.getCount() < 1) {
return;
}
skipStripe = skipStripe || !grid.isStripeRows();
NodeList rows = getRows();
String cls = "x-grid3-row-alt";
for (int i = 0, len = rows.getLength(); i < len; i++) {
Element row = rows.getItem(i);
row.setPropertyInt("rowIndex", i);
if (!skipStripe) {
boolean isAlt = (i + 1) % 2 == 0;
boolean hasAlt = row.getClassName() != null && row.getClassName().indexOf(cls) != -1;
if (isAlt == hasAlt) {
continue;
}
if (isAlt) {
El.fly(row).addStyleName(cls);
} else {
El.fly(row).removeStyleName(cls);
}
}
}
}
protected void refreshRow(int row) {
ModelData m = ds.getAt(row);
if (m != null) {
// do not change focus on refresh
// handles situation with changing cell value with field binding
focusEnabled = false;
insertRows(ds, row, row, true);
getRow(row).setPropertyInt("rowIndex", row);
onRemove(ds, m, row + 1, true);
renderWidgets(row, row);
GridEvent e = new GridEvent(grid);
e.setRowIndex(row);
e.setModel(ds.getAt(row));
fireEvent(Events.RowUpdated, e);
focusEnabled = true;
}
}
protected void removeRow(int row) {
Element r = getRow(row);
if (r != null) {
fly(r).removeFromParent();
}
}
protected void removeRowStyle(Element row, String style) {
fly(row).removeStyleName(style);
}
protected void render() {
renderUI();
grid.sinkEvents(Event.ONCLICK | Event.ONDBLCLICK | Event.MOUSEEVENTS | Event.FOCUSEVENTS);
}
protected void renderFooter() {
if (!footer.isRendered()) {
footer.disableTextSelection(true);
footer.render(mainWrap.dom);
} else {
mainWrap.appendChild(footer.getElement());
}
}
protected void renderHeader() {
El head = grid.el().selectNode(".x-grid3-hh");
head.removeChildren();
if (!header.isRendered()) {
header.render(head.dom);
} else {
head.appendChild(header.getElement());
}
}
protected String renderRows(int startRow, int endRow) {
int colCount = cm.getColumnCount();
if (ds.getCount() < 1) {
return "";
}
List cs = getColumnData();
if (endRow == -1) {
endRow = ds.getCount() - 1;
}
List rs = ds.getRange(startRow, endRow);
return doRender(cs, rs, startRow, colCount, grid.isStripeRows());
}
protected void renderUI() {
String h = "";
String body = templates.body("");
String html = templates.master(body, h);
grid.getElement().setInnerHTML(html);
renderHeader();
initElements();
header.setEnableColumnResizing(grid.isColumnResize());
header.setEnableColumnReorder(grid.isColumnReordering());
if (footer != null) {
renderFooter();
}
updateHeaderSortState();
}
protected void renderWidgets(int startRow, int endRow) {
if (grid.isViewReady()) {
if (endRow == -1) {
endRow = widgetList.size() - 1;
}
for (int i = startRow; i <= endRow; i++) {
List m = i < widgetList.size() ? widgetList.get(i) : null;
if (m != null) {
for (int j = 0; j < grid.getColumnModel().getColumnCount(); j++) {
Widget w = j < m.size() ? m.get(j) : null;
if (w != null) {
Element cell = getWidgetCell(i, j);
if (cell != null) {
if (w.getElement().getParentElement() != cell) {
fly(cell).removeChildren();
cell.appendChild(w.getElement());
}
if (grid.isAttached()) {
ComponentHelper.doAttach(w);
}
}
}
}
}
}
}
}
protected void resize() {
if (mainBody == null) {
return;
}
El c = grid.el();
Size csize = c.getStyleSize();
int vw = csize.width;
int vh = 0;
if (vw < 10 || csize.height < 20) {
return;
}
if (grid.isAutoHeight()) {
el.setWidth(csize.width);
scroller.setWidth(vw);
} else {
el.setSize(csize.width, csize.height);
}
int hdHeight = innerHd.getHeight();
vh = csize.height - hdHeight;
if (footer != null) {
vh -= footer.getHeight();
}
if (!grid.isAutoHeight()) {
scroller.setSize(vw, vh);
}
if (innerHd != null) {
innerHd.setWidth(vw);
}
if (footer != null) {
footer.setWidth(vw);
}
}
protected void restoreScroll(Point state) {
if (state.y < scroller.getWidth()) {
scroller.setScrollLeft(state.x);
}
if (state.x < scroller.getHeight()) {
scroller.setScrollTop(state.y);
}
}
protected void stopEditing() {
if (grid.editSupport != null) {
grid.editSupport.stopEditing(true);
}
}
protected void syncHeaderScroll() {
int sl = scroller.getScrollLeft();
innerHd.setScrollLeft(sl);
// second time for IE (1/2 time first fails, other browsers ignore)
innerHd.setScrollLeft(sl);
if (footer != null) {
footer.el().setScrollLeft(sl);
footer.el().setScrollLeft(sl);
}
}
protected void syncHScroll() {
if (!hasRows()) {
El child = mainBody.firstChild();
if (child != null) {
child.setWidth(cm.getTotalWidth(), true);
}
}
}
protected void syncScroll() {
syncHeaderScroll();
GridEvent ge = new GridEvent(grid);
ge.setScrollLeft(scroller.getScrollLeft());
ge.setScrollTop(scroller.getScrollTop());
grid.fireEvent(Events.BodyScroll, ge);
}
protected void templateAfterMove(int index) {
// template method
}
protected void templateOnAllColumnWidthsUpdated(List ws, int tw) {
// template method
}
protected void templateOnColumnHiddenUpdated(int col, boolean hidden, int tw) {
// template method
}
protected void templateOnColumnWidthUpdated(int col, int w, int tw) {
// template method
}
protected void templateOnLayout(int vw, int vh) {
// template method
}
protected void templateUpdateColumnText(int col, String text) {
// template method
}
protected void updateAllColumnWidths() {
int tw = getTotalWidth();
int clen = cm.getColumnCount();
Stack ws = new Stack();
for (int i = 0; i < clen; i++) {
ws.push(getColumnWidth(i));
header.updateColumnWidth(i, cm.getColumnWidth(i));
if (footer != null) {
footer.updateColumnWidth(i, cm.getColumnWidth(i));
}
}
NodeList ns = getRows();
for (int i = 0, len = ns.getLength(); i < len; i++) {
Element row = ns.getItem(i);
row.getStyle().setPropertyPx("width", tw);
if (row.getFirstChild() != null) {
row.getFirstChildElement().getStyle().setPropertyPx("width", tw);
TableSectionElement e = row.getFirstChild().cast();
TableRowElement nodeList = e.getRows().getItem(0);
for (int j = 0; j < clen; j++) {
((Element) nodeList.getChildNodes().getItem(j)).getStyle().setPropertyPx("width", ws.get(j));
}
}
}
templateOnAllColumnWidthsUpdated(ws, tw);
}
protected void updateColumnHidden(int index, boolean hidden) {
int tw = getTotalWidth();
String display = hidden ? "none" : "";
El.fly(innerHd.dom.getFirstChildElement()).setWidth(getOffsetWidth());
El.fly(innerHd.dom.getFirstChildElement().getFirstChildElement()).setWidth(tw);
header.updateColumnHidden(index, hidden);
if (footer != null) {
footer.updateTotalWidth(getOffsetWidth(), tw);
footer.updateColumnHidden(index, hidden);
}
NodeList ns = getRows();
for (int i = 0, len = ns.getLength(); i < len; i++) {
Element elem = ns.getItem(i);
elem.getStyle().setProperty("width", tw + "px");
TableSectionElement e = (TableSectionElement) elem.getFirstChild();
if (e != null) {
e.getStyle().setProperty("width", tw + "px");
Element cell = e.getRows().getItem(0).getChildNodes().getItem(index).cast();
cell.getStyle().setProperty("display", display);
}
}
templateOnColumnHiddenUpdated(index, hidden, tw);
lastViewWidth = -1;
layout();
}
protected void updateColumnWidth(int col, int width) {
int tw = getTotalWidth();
int w = getColumnWidth(col);
header.updateTotalWidth(-1, tw);
header.updateColumnWidth(col, width);
if (footer != null) {
footer.updateTotalWidth(getOffsetWidth(), tw);
footer.updateColumnWidth(col, width);
}
NodeList ns = getRows();
for (int i = 0, len = ns.getLength(); i < len; i++) {
Element row = ns.getItem(i);
row.getStyle().setPropertyPx("width", tw);
if (row.getFirstChild() != null) {
row.getFirstChildElement().getStyle().setPropertyPx("width", tw);
TableSectionElement e = row.getFirstChild().cast();
((Element) e.getRows().getItem(0).getChildNodes().getItem(col)).getStyle().setPropertyPx("width", w);
}
}
templateOnColumnWidthUpdated(col, w, tw);
syncHScroll();
}
protected void updateHeaderSortState() {
SortInfo state = getSortState();
if (state == null || Util.isEmptyString(state.getSortField())) {
return;
}
if (sortState == null || (!sortState.getSortField().equals(state.getSortField()))
|| sortState.getSortDir() != state.getSortDir()) {
GridEvent e = new GridEvent(grid);
e.setSortInfo(state);
sortState = new SortInfo(state.getSortField(), state.getSortDir());
int sortColumn = cm.findColumnIndex(state.getSortField());
if (sortColumn != -1) {
updateSortIcon(sortColumn, sortState.getSortDir());
}
if (grid.isStateful()) {
Map st = grid.getState();
st.put("sortField", sortState.getSortField());
st.put("sortDir", sortState.getSortDir().toString());
grid.saveState();
}
grid.fireEvent(Events.SortChange, e);
}
}
protected void updateSortIcon(int colIndex, SortDir dir) {
header.updateSortIcon(colIndex, dir);
}
private native String getCellIndexId(Element elem) /*-{
if ([email protected]::colRe) {
@com.extjs.gxt.ui.client.widget.grid.GridView::colRe = new RegExp("x-grid3-td-([^\\s]+)");
}
if (elem) {
var m = elem.className.match(@com.extjs.gxt.ui.client.widget.grid.GridView::colRe);
if(m && m[1]){
return m[1];
}
}
return null;
}-*/;
private void refreshFooterData() {
if (footer != null) {
footer.refresh();
}
}
private void restrictMenu(Menu columns) {
int count = 0;
for (int i = 0, len = cm.getColumnCount(); i < len; i++) {
if (!shouldNotCount(i, true)) {
count++;
}
}
if (count == 1) {
for (Component item : columns.getItems()) {
CheckMenuItem ci = (CheckMenuItem) item;
if (ci.isChecked()) {
ci.disable();
}
}
} else {
for (Component item : columns.getItems()) {
item.enable();
}
}
}
private boolean shouldNotCount(int columnIndex, boolean includeHidden) {
return cm.getColumnHeader(columnIndex) == null || cm.getColumnHeader(columnIndex).equals("")
|| (includeHidden && cm.isHidden(columnIndex)) || cm.isFixed(columnIndex);
}
}