/* * 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.table; import java.util.ArrayList; import java.util.List; import com.extjs.gxt.ui.client.GXT; import com.extjs.gxt.ui.client.Style; import com.extjs.gxt.ui.client.Style.LayoutRegion; import com.extjs.gxt.ui.client.Style.SortDir; import com.extjs.gxt.ui.client.core.XDOM; import com.extjs.gxt.ui.client.event.BaseEvent; import com.extjs.gxt.ui.client.event.ComponentEvent; import com.extjs.gxt.ui.client.event.Events; 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.event.TableEvent; import com.extjs.gxt.ui.client.event.TreeTableEvent; import com.extjs.gxt.ui.client.util.DelayedTask; import com.extjs.gxt.ui.client.util.IconHelper; import com.extjs.gxt.ui.client.widget.BoxComponent; import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.ComponentHelper; import com.extjs.gxt.ui.client.widget.SplitBar; import com.extjs.gxt.ui.client.widget.grid.Grid; 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.extjs.gxt.ui.client.widget.treetable.TreeTable; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DeferredCommand; import com.google.gwt.user.client.Element; /** * @deprecated see {@link Grid} */ public class TableHeader extends BoxComponent { protected static String html; static { StringBuffer sb = new StringBuffer(); sb.append("<div class=my-tbl-header style='position: relative'>"); sb.append("<table border=0 cellpadding=0 cellspacing=0 style='position:relative'><tbody><tr class=my-tbl-header-row>"); sb.append("</tr></table></div>"); html = sb.toString(); } protected List<TableColumnUI> columns; protected BaseTable table; protected TableColumnModel columnModel; protected TableColumnUI sortColumn, endColumn, hoverColumn; protected Element headerRow; private DelayedTask task = new DelayedTask(new Listener<ComponentEvent>() { public void handleEvent(ComponentEvent ce) { updateSplitBars(); } }); public TableHeader() { } public TableHeader(BaseTable table) { this.table = table; this.columnModel = this.table.getColumnModel(); } public void clearSort() { if (sortColumn != null) { sortColumn.onSortChange(SortDir.NONE); sortColumn = null; } } public void sort(int index, SortDir dir) { TableColumn column = table.getColumn(index); column.sortDir = dir; if (rendered) { onSortChange(column, dir); } } public void addColumn(TableColumnUI ui) { Element td = DOM.createTD(); td.setClassName("my-tbl-col"); ui.render(td); headerRow.appendChild(td); columns.add(ui); } public SplitBar createSplitBar(LayoutRegion direction, TableColumnUI column) { return new SplitBar(direction, column, (BoxComponent) table); } public TableColumnUI createTableColumnUI(int index) { return new TableColumnUI(table, index); } protected void doAttachChildren() { int count = columns.size() - 1; for (int i = 0; i < count; i++) { ComponentHelper.doAttach(getColumnUI(i)); } } protected void doDetachChildren() { int count = columns.size() - 1; for (int i = 0; i < count; i++) { ComponentHelper.doDetach(getColumnUI(i)); } } public TableColumnUI getColumnUI(int index) { return columns.get(index); } public void init(BaseTable table) { this.table = table; this.columnModel = this.table.getColumnModel(); columns = new ArrayList<TableColumnUI>(); int cols = columnModel.getColumnCount(); for (int i = 0; i < cols; i++) { TableColumnUI columnUI = createTableColumnUI(i); addColumn(columnUI); } endColumn = createTableColumnUI(cols); endColumn.end = true; addColumn(endColumn); } public void onColumnClick(TableColumnUI columnUI, ComponentEvent e) { BaseEvent be = null; if (table instanceof TreeTable) { TreeTableEvent tte = new TreeTableEvent((TreeTable) table); tte.setColumnIndex(columnUI.index); tte.setEvent(e.getEvent()); be = tte; } else { TableEvent ce = new TableEvent((Table) table); ce.setColumnIndex(columnUI.index); ce.setEvent(e.getEvent()); be = ce; } if (!((Component) table).fireEvent(Events.ColumnClick, be)) { return; } if (columnUI.column.isSortable()) { SortDir sortDir = SortDir.toggle(columnUI.column.sortDir); table.sort(columnUI.index, sortDir); } } protected void onColumnMouseMove(TableColumnUI column, BaseEvent be) { } @Override protected void onRender(Element target, int index) { setElement(XDOM.create(html), target, index); headerRow = el().selectNode(".my-tbl-header-row").dom; disableContextMenu(true); } protected void onRightClick(final TableColumn column, ComponentEvent ce) { ce.stopEvent(); if (!table.getColumnContextMenu()) { return; } final int x = ce.getClientX(); final int y = ce.getClientY(); DeferredCommand.addCommand(new Command() { public void execute() { onShowContextMenu(column).showAt(x, y); } }); } protected Menu onShowContextMenu(final TableColumn column) { final Menu menu = new Menu(); if (column.isSortable()) { MenuItem item = new MenuItem(); item.setText(GXT.MESSAGES.gridView_sortAscText()); item.setIcon(IconHelper.createStyle("my-icon-asc")); item.addSelectionListener(new SelectionListener<MenuEvent>() { public void componentSelected(MenuEvent ce) { table.sort(column.index, SortDir.ASC); } }); menu.add(item); item = new MenuItem(); item.setText(GXT.MESSAGES.gridView_sortDescText()); item.setIcon(IconHelper.createStyle("my-icon-desc")); item.addSelectionListener(new SelectionListener<MenuEvent>() { public void componentSelected(MenuEvent ce) { table.sort(column.index, SortDir.DESC); } }); menu.add(item); } MenuItem columns = new MenuItem(); columns.setText(GXT.MESSAGES.gridView_columnsText()); columns.setIcon(IconHelper.createStyle("icon-columns")); final Menu columnMenu = new Menu(); int cols = columnModel.getColumnCount(); for (int i = 0; i < cols; i++) { final TableColumn def = columnModel.getColumn(i); final CheckMenuItem check = new CheckMenuItem(); check.setHideOnClick(false); check.setText(def.getText()); check.setChecked(!def.isHidden()); check.addSelectionListener(new SelectionListener<MenuEvent>() { public void componentSelected(MenuEvent ce) { def.setHidden(!check.isChecked()); showColumn(def.index, !def.isHidden()); if (columnModel.getVariableColumnCount() > 0) { resizeColumns(false, true); } if (columnModel.getVisibleColumnCount() == 1) { for (Component item : columnMenu.getItems()) { CheckMenuItem check = (CheckMenuItem) item; if (check.isChecked()) { item.disable(); } } } else if (columnModel.getVisibleColumnCount() == 2) { for (Component item : columnMenu.getItems()) { item.enable(); } } } }); columnMenu.add(check); if (columnModel.getVisibleColumnCount() == 1) { for (Component item : columnMenu.getItems()) { CheckMenuItem ci = (CheckMenuItem) item; if (ci.isChecked()) { ci.disable(); } } } } columns.setSubMenu(columnMenu); menu.add(columns); if (table instanceof Table) { TableEvent e = new TableEvent((Table) table); e.setColumnIndex(column.getIndex()); e.setMenu(menu); ((Table) table).fireEvent(Events.HeaderContextMenu, e); } return menu; } public int getSortColumn() { if (sortColumn != null) { return sortColumn.index; } return Style.DEFAULT; } public void onSortChange(TableColumn column, SortDir sortDir) { column.sortDir = sortDir; if (sortColumn != null) { getColumnUI(sortColumn.index).onSortChange(SortDir.NONE); } sortColumn = getColumnUI(column.index); sortColumn.onSortChange(sortDir); } protected void resizeColumn(int index, boolean resizeBody) { TableColumn column = columnModel.getColumn(index); TableColumnUI ui = getColumnUI(index); if (column.isHidden()) { ui.setVisible(false); showColumn(index, false); return; } else { ui.setVisible(true); } int w = columnModel.getWidthInPixels(column.index); if (w < 1) { return; } if (w != ui.lastWidth) { Element td = DOM.getParent(ui.getElement()); w -= fly(td).getBorderWidth("lr"); fly(td).setWidth(w); if (td.getChildNodes().getLength() > 1) { fly(td).getChild(1).setWidth(w); } SplitBar splitBar = ui.splitBar; if (splitBar != null) { if (column.isResizable()) { splitBar.setVisible(true); } splitBar.setMinSize(column.getMinWidth()); splitBar.setMaxSize(column.getMaxWidth()); } task.delay(400); if (resizeBody) { doTableComponentResizeCells(index); } } ui.lastWidth = w; if (resizeBody) { doTableComponentResize(); } } protected void resizeColumns(boolean fireEvent, boolean resizeBody) { int tw = Math.max(columnModel.getTotalWidth(), ((Component) table).getOffsetWidth()) + 100; setWidth(tw); el().firstChild().setWidth(tw); endColumn.el().setWidth("100%"); int cols = columnModel.getColumnCount(); for (int i = 0; i < cols; i++) { resizeColumn(i, resizeBody); } task.delay(100); if (resizeBody) { doTableComponentResize(); } } protected void showColumn(int index, boolean show) { TableColumnUI ui = getColumnUI(index); ui.el().getParent().setStyleAttribute("display", show ? "" : "none"); ui.setVisible(show); doTableComponentShowColumn(index, show); updateSplitBars(); doTableComponentResize(); if (show) { resizeColumn(index, true); } } protected void updateSplitBars() { int count = columns.size() - 1; for (int i = 0; i < count; i++) { TableColumnUI ui = getColumnUI(i); if (ui.splitBar != null) { ui.splitBar.sync(); } } } protected void doTableComponentResize() { if (table instanceof Table) { ((Table) table).getView().resize(); } } protected void doTableComponentResizeCells(int columnIndex) { if (table instanceof Table) { ((Table) table).getView().resizeCells(columnIndex); } } protected void doTableComponentShowColumn(int index, boolean show) { if (table instanceof Table) { ((Table) table).getView().showColumn(index, show); } } }