Rev. 8553
minor - avoid double registration of the same listener

Rev. 8561
[ 2617300 ] Reimplement grid view using Grid instead of Listbox
[ 2621916 ] Enhance short cut key support
This commit is contained in:
Heng Sin Low 2009-02-21 08:56:23 +00:00
parent 9699a47545
commit d5b1984d6a
14 changed files with 1480 additions and 238 deletions

View File

@ -144,5 +144,6 @@
<classpathentry kind="lib" path="posterita/posterita/web/WEB-INF/lib/poi-3.0-FINAL.jar"/> <classpathentry kind="lib" path="posterita/posterita/web/WEB-INF/lib/poi-3.0-FINAL.jar"/>
<classpathentry exported="true" kind="lib" path="tools/lib/testing/spiffy-with_source-all-0.05.jar"/> <classpathentry exported="true" kind="lib" path="tools/lib/testing/spiffy-with_source-all-0.05.jar"/>
<classpathentry exported="true" kind="lib" path="tools/lib/testing/SuperCSV-with_src-1.52.jar"/> <classpathentry exported="true" kind="lib" path="tools/lib/testing/SuperCSV-with_src-1.52.jar"/>
<classpathentry kind="lib" path="zkwebui/WEB-INF/lib/keylistener.jar"/>
<classpathentry kind="output" path="bin"/> <classpathentry kind="output" path="bin"/>
</classpath> </classpath>

View File

@ -19,7 +19,7 @@ Copyright (C) 2007 Ashley G Ramdass (ADempiere WebUI).
<version> <version>
<version-class>org.adempiere.webui.AdempiereWebUI</version-class> <version-class>org.adempiere.webui.AdempiereWebUI</version-class>
<version-uid>0.2</version-uid> <version-uid>1.0</version-uid>
</version> </version>
<javascript src="/js/calc.js" charset="UTF-8"/> <javascript src="/js/calc.js" charset="UTF-8"/>

View File

@ -27,6 +27,7 @@ import java.util.logging.Level;
import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.event.ToolbarListener; import org.adempiere.webui.event.ToolbarListener;
import org.adempiere.webui.session.SessionManager;
import org.compiere.model.MRole; import org.compiere.model.MRole;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.compiere.util.Env; import org.compiere.util.Env;
@ -80,12 +81,17 @@ public class CWindowToolbar extends FToolbar implements EventListener
private Event event; private Event event;
private Map<Integer, ToolBarButton> keyMap = new HashMap<Integer, ToolBarButton>(); private Map<Integer, ToolBarButton> keyMap = new HashMap<Integer, ToolBarButton>();
private Map<Integer, ToolBarButton> altKeyMap = new HashMap<Integer, ToolBarButton>();
private Map<Integer, ToolBarButton> ctrlKeyMap = new HashMap<Integer, ToolBarButton>();
private boolean embedded; private boolean embedded;
// Elaine 2008/12/04 // Elaine 2008/12/04
/** Show Personal Lock */ /** Show Personal Lock */
public boolean isPersonalLock = MRole.getDefault().isPersonalLock(); public boolean isPersonalLock = MRole.getDefault().isPersonalLock();
private int windowNo = 0;
/** Last Modifier of Action Event */ /** Last Modifier of Action Event */
// public int lastModifiers; // public int lastModifiers;
// //
@ -203,6 +209,34 @@ public class CWindowToolbar extends FToolbar implements EventListener
return buttons.get(name); return buttons.get(name);
} }
/** VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (0x41 - 0x5A) */
public static final int VK_A = 0x41;
public static final int VK_B = 0x42;
public static final int VK_C = 0x43;
public static final int VK_D = 0x44;
public static final int VK_E = 0x45;
public static final int VK_F = 0x46;
public static final int VK_G = 0x47;
public static final int VK_H = 0x48;
public static final int VK_I = 0x49;
public static final int VK_J = 0x4A;
public static final int VK_K = 0x4B;
public static final int VK_L = 0x4C;
public static final int VK_M = 0x4D;
public static final int VK_N = 0x4E;
public static final int VK_O = 0x4F;
public static final int VK_P = 0x50;
public static final int VK_Q = 0x51;
public static final int VK_R = 0x52;
public static final int VK_S = 0x53;
public static final int VK_T = 0x54;
public static final int VK_U = 0x55;
public static final int VK_V = 0x56;
public static final int VK_W = 0x57;
public static final int VK_X = 0x58;
public static final int VK_Y = 0x59;
public static final int VK_Z = 0x5A;
private void configureKeyMap() private void configureKeyMap()
{ {
keyMap.put(KeyEvent.F1, btnHelp); keyMap.put(KeyEvent.F1, btnHelp);
@ -216,6 +250,22 @@ public class CWindowToolbar extends FToolbar implements EventListener
keyMap.put(KeyEvent.F9, btnHistoryRecords); keyMap.put(KeyEvent.F9, btnHistoryRecords);
keyMap.put(KeyEvent.F11, btnReport); keyMap.put(KeyEvent.F11, btnReport);
keyMap.put(KeyEvent.F12, btnPrint); keyMap.put(KeyEvent.F12, btnPrint);
altKeyMap.put(KeyEvent.LEFT, btnParentRecord);
altKeyMap.put(KeyEvent.RIGHT, btnDetailRecord);
altKeyMap.put(KeyEvent.UP, btnPrevious);
altKeyMap.put(KeyEvent.DOWN, btnNext);
altKeyMap.put(KeyEvent.PAGE_UP, btnFirst);
altKeyMap.put(KeyEvent.PAGE_DOWN, btnLast);
altKeyMap.put(VK_P, btnReport);
altKeyMap.put(VK_Z, btnIgnore);
ctrlKeyMap.put(VK_I, btnProductInfo);
ctrlKeyMap.put(VK_P, btnPrint);
ctrlKeyMap.put(VK_N, btnNew);
ctrlKeyMap.put(VK_S, btnSave);
ctrlKeyMap.put(VK_X, btnDelete);
ctrlKeyMap.put(VK_F, btnFind);
} }
protected void addSeparator() protected void addSeparator()
@ -251,7 +301,7 @@ public class CWindowToolbar extends FToolbar implements EventListener
} else if (eventName.equals(Events.ON_CTRL_KEY)) } else if (eventName.equals(Events.ON_CTRL_KEY))
{ {
KeyEvent keyEvent = (KeyEvent) event; KeyEvent keyEvent = (KeyEvent) event;
this.onCtrlKeyEvent(keyEvent.getKeyCode()); this.onCtrlKeyEvent(keyEvent);
} }
} }
@ -429,9 +479,26 @@ public class CWindowToolbar extends FToolbar implements EventListener
return event; return event;
} }
public void onCtrlKeyEvent(int keycode) { private void onCtrlKeyEvent(KeyEvent keyEvent) {
if (isRealVisible()) { if (isRealVisible()) {
ToolBarButton btn = keyMap.get(keycode); ToolBarButton btn = null;
if (keyEvent.isAltKey() && !keyEvent.isCtrlKey() && !keyEvent.isShiftKey())
{
if (keyEvent.getKeyCode() == VK_X)
{
if (windowNo > 0)
SessionManager.getAppDesktop().closeWindow(windowNo);
}
else
{
btn = altKeyMap.get(keyEvent.getKeyCode());
}
}
else if (!keyEvent.isAltKey() && keyEvent.isCtrlKey() && !keyEvent.isShiftKey())
btn = ctrlKeyMap.get(keyEvent.getKeyCode());
else if (!keyEvent.isAltKey() && !keyEvent.isCtrlKey() && !keyEvent.isShiftKey())
btn = keyMap.get(keyEvent.getKeyCode());
if (btn != null && !btn.isDisabled() && btn.isVisible()) { if (btn != null && !btn.isDisabled() && btn.isVisible()) {
Events.sendEvent(btn, new Event(Events.ON_CLICK, btn)); Events.sendEvent(btn, new Event(Events.ON_CLICK, btn));
} }
@ -468,4 +535,8 @@ public class CWindowToolbar extends FToolbar implements EventListener
} }
} }
public void setWindowNo(int windowNo) {
this.windowNo = windowNo;
}
} }

View File

@ -64,7 +64,6 @@ public class CompositeADTab extends AbstractADTab
} else { } else {
window.setPage(page); window.setPage(page);
} }
window.setCtrlKeys("#f1#f2#f3#f4#f5#f6#f7#f8#f9#f10#f11#f12");
return window; return window;
} }

View File

@ -12,7 +12,6 @@
*****************************************************************************/ *****************************************************************************/
package org.adempiere.webui.component; package org.adempiere.webui.component;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -21,22 +20,25 @@ import javax.swing.table.AbstractTableModel;
import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.editor.WEditor; import org.adempiere.webui.editor.WEditor;
import org.adempiere.webui.util.SortComparator;
import org.compiere.model.GridField; import org.compiere.model.GridField;
import org.compiere.model.GridTab; import org.compiere.model.GridTab;
import org.compiere.model.GridTable; import org.compiere.model.GridTable;
import org.compiere.model.MSysConfig; import org.compiere.model.MSysConfig;
import org.compiere.util.DisplayType; import org.compiere.util.DisplayType;
import org.compiere.util.Env;
import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
import org.zkoss.zkex.zul.Borderlayout; import org.zkoss.zkex.zul.Borderlayout;
import org.zkoss.zkex.zul.Center; import org.zkoss.zkex.zul.Center;
import org.zkoss.zkex.zul.South; import org.zkoss.zkex.zul.South;
import org.zkoss.zul.Column;
import org.zkoss.zul.Paging; import org.zkoss.zul.Paging;
import org.zkoss.zul.event.ZulEvents; import org.zkoss.zul.event.ZulEvents;
/** /**
* * Grid view implemented using the Grid component.
* @author Low Heng Sin * @author Low Heng Sin
* *
*/ */
@ -48,7 +50,7 @@ public class GridPanel extends Borderlayout implements EventListener
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private Listbox listbox = null; private Grid listbox = null;
private int pageSize = 100; private int pageSize = 100;
@ -67,7 +69,7 @@ public class GridPanel extends Borderlayout implements EventListener
private Paging paging; private Paging paging;
private GridTabListItemRenderer renderer; private GridTabRowRenderer renderer;
private South south; private South south;
@ -78,10 +80,13 @@ public class GridPanel extends Borderlayout implements EventListener
this(0); this(0);
} }
/**
* @param windowNo
*/
public GridPanel(int windowNo) public GridPanel(int windowNo)
{ {
this.windowNo = windowNo; this.windowNo = windowNo;
listbox = new Listbox(); listbox = new Grid();
south = new South(); south = new South();
this.appendChild(south); this.appendChild(south);
@ -89,6 +94,10 @@ public class GridPanel extends Borderlayout implements EventListener
pageSize = MSysConfig.getIntValue(PAGE_SIZE_KEY, 100); pageSize = MSysConfig.getIntValue(PAGE_SIZE_KEY, 100);
} }
/**
*
* @param gridTab
*/
public void init(GridTab gridTab) public void init(GridTab gridTab)
{ {
if (init) return; if (init) return;
@ -108,29 +117,45 @@ public class GridPanel extends Borderlayout implements EventListener
this.init = true; this.init = true;
} }
/**
*
* @return boolean
*/
public boolean isInit() { public boolean isInit() {
return init; return init;
} }
/**
* call when tab is activated
* @param gridTab
*/
public void activate(GridTab gridTab) { public void activate(GridTab gridTab) {
if (isInit()) if (!isInit()) {
refresh(gridTab);
else
init(gridTab); init(gridTab);
} }
public void refresh(GridTab gridTab) {
this.gridTab = gridTab;
tableModel = gridTab.getTableModel();
gridField = ((GridTable)tableModel).getFields();
updateModel();
updateListIndex();
} }
/** /**
* Update listbox index to sync with grid current row pointer changes * refresh after switching from form view
* @param gridTab
*/
public void refresh(GridTab gridTab) {
if (this.gridTab != gridTab)
{
init = false;
init(gridTab);
}
else
{
if (renderer != null)
renderer.stopEditing(false);
listbox.setModel(listModel);
}
}
/**
* Update current row from model
*/ */
public void updateListIndex() { public void updateListIndex() {
int rowIndex = gridTab.isOpen() ? gridTab.getCurrentRow() : -1; int rowIndex = gridTab.isOpen() ? gridTab.getCurrentRow() : -1;
@ -139,27 +164,25 @@ public class GridPanel extends Borderlayout implements EventListener
paging.setTotalSize(gridTab.getRowCount()); paging.setTotalSize(gridTab.getRowCount());
int pgIndex = rowIndex % pageSize; int pgIndex = rowIndex % pageSize;
int pgNo = (rowIndex - pgIndex) / pageSize; int pgNo = (rowIndex - pgIndex) / pageSize;
if (listModel.getPage() != pgNo) { if (listModel.getPage() != pgNo) {
listModel.setPage(pgNo); listModel.setPage(pgNo);
} }
if (paging.getActivePage() != pgNo) if (paging.getActivePage() != pgNo) {
paging.setActivePage(pgNo); paging.setActivePage(pgNo);
if (listbox.getSelectedIndex() != pgIndex) { }
renderer.stopEditing(false); renderer.stopEditing(false);
listModel.updateComponent(listbox.getSelectedIndex());
listModel.updateComponent(pgIndex); listModel.updateComponent(pgIndex);
listbox.setSelectedIndex(pgIndex);
}
} else { } else {
if (listbox.getSelectedIndex() != rowIndex) {
renderer.stopEditing(false); renderer.stopEditing(false);
listModel.updateComponent(listbox.getSelectedIndex());
listModel.updateComponent(rowIndex); listModel.updateComponent(rowIndex);
listbox.setSelectedIndex(rowIndex);
}
} }
} }
/**
* set paging size
* @param pageSize
*/
public void setPageSize(int pageSize) public void setPageSize(int pageSize)
{ {
this.pageSize = pageSize; this.pageSize = pageSize;
@ -170,6 +193,10 @@ public class GridPanel extends Borderlayout implements EventListener
this.getChildren().clear(); this.getChildren().clear();
} }
/**
* toggle visibility
* @param bool
*/
public void showGrid(boolean bool) public void showGrid(boolean bool)
{ {
if (bool) if (bool)
@ -182,8 +209,11 @@ public class GridPanel extends Borderlayout implements EventListener
{ {
if (init) return; if (init) return;
ListHead header = new ListHead(); Columns columns = new Columns();
header.setSizable(true); listbox.appendChild(columns);
columns.setSizable(true);
columns.setMenupopup("auto");
columns.setColumnsgroup(false);
Map<Integer, String> colnames = new HashMap<Integer, String>(); Map<Integer, String> colnames = new HashMap<Integer, String>();
int index = 0; int index = 0;
@ -193,9 +223,10 @@ public class GridPanel extends Borderlayout implements EventListener
{ {
colnames.put(index, gridField[i].getHeader()); colnames.put(index, gridField[i].getHeader());
index++; index++;
ListHeader colHeader = new ListHeader(); org.zkoss.zul.Column column = new Column();
colHeader.setSort("auto"); column.setSortAscending(new SortComparator(i, true, Env.getLanguage(Env.getCtx())));
colHeader.setLabel(gridField[i].getHeader()); column.setSortDescending(new SortComparator(i, false, Env.getLanguage(Env.getCtx())));
column.setLabel(gridField[i].getHeader());
int l = DisplayType.isNumeric(gridField[i].getDisplayType()) int l = DisplayType.isNumeric(gridField[i].getDisplayType())
? 100 : gridField[i].getDisplayLength() * 9; ? 100 : gridField[i].getDisplayLength() * 9;
if (gridField[i].getHeader().length() * 9 > l) if (gridField[i].getHeader().length() * 9 > l)
@ -204,11 +235,10 @@ public class GridPanel extends Borderlayout implements EventListener
l = MAX_COLUMN_WIDTH; l = MAX_COLUMN_WIDTH;
else if ( l < MIN_COLUMN_WIDTH) else if ( l < MIN_COLUMN_WIDTH)
l = MIN_COLUMN_WIDTH; l = MIN_COLUMN_WIDTH;
colHeader.setWidth(Integer.toString(l) + "px"); column.setWidth(Integer.toString(l) + "px");
header.appendChild(colHeader); columns.appendChild(column);
} }
} }
listbox.appendChild(header);
} }
private void render() private void render()
@ -216,9 +246,8 @@ public class GridPanel extends Borderlayout implements EventListener
LayoutUtils.addSclass("adtab-grid-panel", this); LayoutUtils.addSclass("adtab-grid-panel", this);
listbox.setVflex(true); listbox.setVflex(true);
listbox.addEventListener(Events.ON_SELECT, this); listbox.setFixedLayout(true);
listbox.addEventListener(Events.ON_CLICK, this);
LayoutUtils.addSclass("adtab-grid", listbox);
updateModel(); updateModel();
@ -234,12 +263,13 @@ public class GridPanel extends Borderlayout implements EventListener
paging.setDetailed(true); paging.setDetailed(true);
south.appendChild(paging); south.appendChild(paging);
paging.addEventListener(ZulEvents.ON_PAGING, this); paging.addEventListener(ZulEvents.ON_PAGING, this);
this.getParent().invalidate(); renderer.setPaging(paging);
} }
else else
{ {
south.setVisible(false); south.setVisible(false);
} }
} }
private void updateModel() { private void updateModel() {
@ -247,12 +277,18 @@ public class GridPanel extends Borderlayout implements EventListener
listModel.setPageSize(pageSize); listModel.setPageSize(pageSize);
if (renderer != null) if (renderer != null)
renderer.stopEditing(false); renderer.stopEditing(false);
renderer = new GridTabListItemRenderer(gridTab, windowNo); renderer = new GridTabRowRenderer(gridTab, windowNo);
listbox.setItemRenderer(renderer);
listbox.setRowRenderer(renderer);
listbox.setModel(listModel); listbox.setModel(listModel);
} }
/**
* deactivate panel
*/
public void deactivate() { public void deactivate() {
if (renderer != null)
renderer.stopEditing(false);
} }
public void onEvent(Event event) throws Exception public void onEvent(Event event) throws Exception
@ -261,34 +297,33 @@ public class GridPanel extends Borderlayout implements EventListener
return; return;
else if (event.getTarget() == listbox) else if (event.getTarget() == listbox)
{ {
int index = listbox.getSelectedIndex(); Object data = event.getData();
if (data != null && data instanceof org.zkoss.zul.Row)
{
int index = listbox.getRows().getChildren().indexOf(data);
onSelectedRowChange(index); onSelectedRowChange(index);
} }
}
else if (event.getTarget() == paging) else if (event.getTarget() == paging)
{ {
int pgNo = paging.getActivePage(); int pgNo = paging.getActivePage();
if (pgNo != listModel.getPage()) if (pgNo != listModel.getPage())
{ {
listbox.clearSelection();
listModel.setPage(pgNo); listModel.setPage(pgNo);
listbox.setSelectedIndex(0);
onSelectedRowChange(0); onSelectedRowChange(0);
} }
} }
} }
private void onSelectedRowChange(int index) { private void onSelectedRowChange(int index) {
if (updateModelIndex()) { if (updateModelIndex(index)) {
listModel.updateComponent(index); listModel.updateComponent(index);
listbox.setSelectedIndex(index);
} else if (!renderer.isInitialize()) { } else if (!renderer.isInitialize()) {
listModel.updateComponent(index); listModel.updateComponent(index);
listbox.setSelectedIndex(index);
} }
} }
private boolean updateModelIndex() { private boolean updateModelIndex(int rowIndex) {
int rowIndex = listbox.getSelectedIndex();
if (pageSize > 0) { if (pageSize > 0) {
int start = listModel.getPage() * listModel.getPageSize(); int start = listModel.getPage() * listModel.getPageSize();
rowIndex = start + rowIndex; rowIndex = start + rowIndex;
@ -302,10 +337,17 @@ public class GridPanel extends Borderlayout implements EventListener
return false; return false;
} }
public Listbox getListbox() { /**
* @return Grid
*/
public Grid getListbox() {
return listbox; return listbox;
} }
/**
* Validate display properties of fields of current row
* @param col
*/
public void dynamicDisplay(int col) { public void dynamicDisplay(int col) {
if (!gridTab.isOpen()) if (!gridTab.isOpen())
{ {

View File

@ -43,19 +43,22 @@ import org.zkoss.zul.Listcell;
import org.zkoss.zul.Listitem; import org.zkoss.zul.Listitem;
import org.zkoss.zul.ListitemRenderer; import org.zkoss.zul.ListitemRenderer;
import org.zkoss.zul.ListitemRendererExt; import org.zkoss.zul.ListitemRendererExt;
import org.zkoss.zul.Paging;
import org.zkoss.zul.RendererCtrl;
/** /**
* ListItem renderer for GridTab list box. * ListItem renderer for GridTab list box.
* @author hengsin * @author hengsin
* *
*/ */
public class GridTabListItemRenderer implements ListitemRenderer, ListitemRendererExt { public class GridTabListItemRenderer implements ListitemRenderer, ListitemRendererExt, RendererCtrl {
private static final int MAX_TEXT_LENGTH = 60; private static final int MAX_TEXT_LENGTH = 60;
private GridTab gridTab; private GridTab gridTab;
private int windowNo; private int windowNo;
private GridTabDataBinder dataBinder; private GridTabDataBinder dataBinder;
private Map<GridField, WEditor> editors = new HashMap<GridField, WEditor>(); private Map<GridField, WEditor> editors = new HashMap<GridField, WEditor>();
private Paging paging;
/** /**
* *
@ -90,6 +93,9 @@ public class GridTabListItemRenderer implements ListitemRenderer, ListitemRender
editors.put(gridField[i], WebEditorFactory.getEditor(gridField[i], true)); editors.put(gridField[i], WebEditorFactory.getEditor(gridField[i], true));
int rowIndex = listitem.getIndex(); int rowIndex = listitem.getIndex();
if (paging != null && paging.getPageSize() > 0) {
rowIndex = (paging.getActivePage() * paging.getPageSize()) + rowIndex;
}
Listcell cell = null; Listcell cell = null;
if (rowIndex == gridTab.getCurrentRow() && gridField[i].isEditable(true)) { if (rowIndex == gridTab.getCurrentRow() && gridField[i].isEditable(true)) {
cell = getEditorCell(gridField[i], values[i], i); cell = getEditorCell(gridField[i], values[i], i);
@ -232,6 +238,8 @@ public class GridTabListItemRenderer implements ListitemRenderer, ListitemRender
return item; return item;
} }
private Map<Integer, Map<Object, String>> lookupCache = null;
private String getDisplayText(Object value, int columnIndex) private String getDisplayText(Object value, int columnIndex)
{ {
if (value == null) if (value == null)
@ -244,9 +252,36 @@ public class GridTabListItemRenderer implements ListitemRenderer, ListitemRender
} }
else if (gridField[columnIndex].isLookup()) else if (gridField[columnIndex].isLookup())
{ {
if (value == null) return "";
if (lookupCache != null)
{
Map<Object, String> cache = lookupCache.get(columnIndex);
if (cache != null && cache.size() >0)
{
String text = cache.get(value);
if (text != null)
{
return text;
}
}
}
NamePair namepair = gridField[columnIndex].getLookup().get(value); NamePair namepair = gridField[columnIndex].getLookup().get(value);
if (namepair != null) if (namepair != null)
return namepair.getName(); {
String text = namepair.getName();
if (lookupCache != null)
{
Map<Object, String> cache = lookupCache.get(columnIndex);
if (cache == null)
{
cache = new HashMap<Object, String>();
lookupCache.put(columnIndex, cache);
}
cache.put(value, text);
}
return text;
}
else else
return ""; return "";
} }
@ -310,4 +345,32 @@ public class GridTabListItemRenderer implements ListitemRenderer, ListitemRender
return editorList; return editorList;
} }
/**
* @param paging
*/
public void setPaging(Paging paging) {
this.paging = paging;
}
/**
* @see RendererCtrl#doCatch(Throwable)
*/
public void doCatch(Throwable ex) throws Throwable {
lookupCache = null;
}
/**
* @see RendererCtrl#doFinally()
*/
public void doFinally() {
lookupCache = null;
}
/**
* @see RendererCtrl#doTry()
*/
public void doTry() {
lookupCache = new HashMap<Integer, Map<Object,String>>();
}
} }

View File

@ -0,0 +1,410 @@
/******************************************************************************
* Copyright (C) 2008 Low Heng Sin *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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 General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.component;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import org.adempiere.webui.editor.WButtonEditor;
import org.adempiere.webui.editor.WEditor;
import org.adempiere.webui.editor.WEditorPopupMenu;
import org.adempiere.webui.editor.WebEditorFactory;
import org.adempiere.webui.event.ContextMenuListener;
import org.adempiere.webui.panel.AbstractADWindowPanel;
import org.adempiere.webui.session.SessionManager;
import org.adempiere.webui.util.GridTabDataBinder;
import org.adempiere.webui.window.ADWindow;
import org.compiere.model.GridField;
import org.compiere.model.GridTab;
import org.compiere.util.DisplayType;
import org.compiere.util.NamePair;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zul.Div;
import org.zkoss.zul.Grid;
import org.zkoss.zul.Paging;
import org.zkoss.zul.RendererCtrl;
import org.zkoss.zul.Row;
import org.zkoss.zul.RowRenderer;
import org.zkoss.zul.RowRendererExt;
/**
* Row renderer for GridTab grid.
* @author hengsin
*
*/
public class GridTabRowRenderer implements RowRenderer, RowRendererExt, RendererCtrl {
private static final int MAX_TEXT_LENGTH = 60;
private GridTab gridTab;
private int windowNo;
private GridTabDataBinder dataBinder;
private Map<GridField, WEditor> editors = new HashMap<GridField, WEditor>();
private Paging paging;
private Map<String, Map<Object, String>> lookupCache = null;
private RowListener rowListener;
/**
*
* @param gridTab
* @param windowNo
*/
public GridTabRowRenderer(GridTab gridTab, int windowNo) {
this.gridTab = gridTab;
this.windowNo = windowNo;
this.dataBinder = new GridTabDataBinder(gridTab);
}
private WEditor getEditorCell(GridField gridField, Object object, int i) {
WEditor editor = editors.get(gridField);
if (editor != null) {
if (editor instanceof WButtonEditor)
{
Object window = SessionManager.getAppDesktop().findWindow(windowNo);
if (window != null && window instanceof ADWindow)
{
AbstractADWindowPanel windowPanel = ((ADWindow)window).getADWindowPanel();
((WButtonEditor)editor).addActionListener(windowPanel);
}
}
else
{
editor.addValueChangeListener(dataBinder);
}
gridField.removePropertyChangeListener(editor);
gridField.addPropertyChangeListener(editor);
editor.setValue(gridField.getValue());
//streach component to fill grid cell
if (editor.getComponent() instanceof Textbox)
((HtmlBasedComponent)editor.getComponent()).setWidth("98%");
else
editor.fillHorizontal();
}
return editor;
}
private int getColumnIndex(GridField field) {
GridField[] fields = gridTab.getFields();
for(int i = 0; i < fields.length; i++) {
if (fields[i] == field)
return i;
}
return 0;
}
private Component createReadonlyCheckbox(Object value) {
Checkbox checkBox = new Checkbox();
if (value != null && "true".equalsIgnoreCase(value.toString()))
checkBox.setChecked(true);
else
checkBox.setChecked(false);
checkBox.setDisabled(true);
return checkBox;
}
private String getDisplayText(Object value, GridField gridField)
{
if (value == null)
return "";
if (gridField.isEncryptedField())
{
return "********";
}
else if (gridField.isLookup())
{
if (value == null) return "";
if (lookupCache != null)
{
Map<Object, String> cache = lookupCache.get(gridField.getColumnName());
if (cache != null && cache.size() >0)
{
String text = cache.get(value);
if (text != null)
{
return text;
}
}
}
NamePair namepair = gridField.getLookup().get(value);
if (namepair != null)
{
String text = namepair.getName();
if (lookupCache != null)
{
Map<Object, String> cache = lookupCache.get(gridField.getColumnName());
if (cache == null)
{
cache = new HashMap<Object, String>();
lookupCache.put(gridField.getColumnName(), cache);
}
cache.put(value, text);
}
return text;
}
else
return "";
}
else if (gridTab.getTableModel().getColumnClass(getColumnIndex(gridField)).equals(Timestamp.class))
{
SimpleDateFormat dateFormat = DisplayType.getDateFormat(DisplayType.Date);
return dateFormat.format((Timestamp)value);
}
else if (DisplayType.isNumeric(gridField.getDisplayType()))
{
return DisplayType.getNumberFormat(gridField.getDisplayType()).format(value);
}
else if (DisplayType.Button == gridField.getDisplayType())
{
return "";
}
else if (DisplayType.Image == gridField.getDisplayType())
{
if (value == null || (Integer)value <= 0)
return "";
else
return "...";
}
else
return value.toString();
}
private Component getDisplayComponent(Object value, GridField gridField) {
Component component;
if (gridField.getDisplayType() == DisplayType.YesNo) {
component = createReadonlyCheckbox(value);
} else {
String text = getDisplayText(value, gridField);
String display = text;
if (text != null && text.length() > MAX_TEXT_LENGTH)
display = text.substring(0, MAX_TEXT_LENGTH - 3) + "...";
Label label = new Label(display);
if (text != null && text.length() > MAX_TEXT_LENGTH)
label.setTooltiptext(text);
component = label;
}
return component;
}
/**
* Is renderer initialize
* @return boolean
*/
public boolean isInitialize() {
return !editors.isEmpty();
}
/**
*
* @return active editor list
*/
public List<WEditor> getEditors() {
List<WEditor> editorList = new ArrayList<WEditor>();
if (!editors.isEmpty())
editorList.addAll(editors.values());
return editorList;
}
/**
* @param paging
*/
public void setPaging(Paging paging) {
this.paging = paging;
}
/**
* Detach all editor and optionally set the current value of the editor as cell label.
* @param updateCellLabel
*/
public void stopEditing(boolean updateCellLabel) {
Row row = null;
for (Entry<GridField, WEditor> entry : editors.entrySet()) {
if (entry.getValue().getComponent().getParent() != null) {
Component child = entry.getValue().getComponent();
Div div = null;
while (div == null && child != null) {
Component parent = child.getParent();
if (parent instanceof Div && parent.getParent() instanceof Row)
div = (Div)parent;
else
child = parent;
}
Component component = div.getFirstChild();
if (updateCellLabel) {
if (component instanceof Label) {
Label label = (Label)component;
label.setValue(getDisplayText(entry.getValue().getValue(), entry.getValue().getGridField()));
} else if (component instanceof Checkbox) {
Checkbox checkBox = (Checkbox)component;
Object value = entry.getValue().getValue();
if (value != null && "true".equalsIgnoreCase(value.toString()))
checkBox.setChecked(true);
else
checkBox.setChecked(false);
}
}
component.setVisible(true);
if (row == null)
row = ((Row)div.getParent());
entry.getValue().getComponent().detach();
entry.getKey().removePropertyChangeListener(entry.getValue());
entry.getValue().removeValuechangeListener(dataBinder);
}
}
if (row != null)
row.setStyle(null);
}
/**
* @param row
* @param data
* @see RowRenderer#render(Row, Object)
*/
public void render(Row row, Object data) throws Exception {
//don't render if not visible
for(Component c = row.getParent(); c != null; c = c.getParent()) {
if (!c.isVisible())
return;
}
if (rowListener == null)
rowListener = new RowListener((Grid)row.getParent().getParent());
Object[] values = (Object[])data;
int columnCount = gridTab.getTableModel().getColumnCount();
GridField[] gridField = gridTab.getFields();
Grid grid = (Grid) row.getParent().getParent();
org.zkoss.zul.Columns columns = grid.getColumns();
int rowIndex = row.getParent().getChildren().indexOf(row);
if (paging != null && paging.getPageSize() > 0) {
rowIndex = (paging.getActivePage() * paging.getPageSize()) + rowIndex;
}
int colIndex = -1;
for (int i = 0; i < columnCount; i++) {
if (!gridField[i].isDisplayed()) {
continue;
}
colIndex ++;
if (editors.get(gridField[i]) == null)
editors.put(gridField[i], WebEditorFactory.getEditor(gridField[i], true));
Div div = new Div();
String divStyle = "border: none; width: 100%; ";
org.zkoss.zul.Column column = (org.zkoss.zul.Column) columns.getChildren().get(colIndex);
if (column.isVisible()) {
Component component = getDisplayComponent(values[i], gridField[i]);
div.appendChild(component);
if (rowIndex == gridTab.getCurrentRow() && gridField[i].isEditable(true)) {
WEditor editor = getEditorCell(gridField[i], values[i], i);
div.appendChild(editor.getComponent());
WEditorPopupMenu popupMenu = editor.getPopupMenu();
if (popupMenu != null)
{
popupMenu.addMenuListener((ContextMenuListener)editor);
div.appendChild(popupMenu);
}
component.setVisible(false);
}
if (DisplayType.YesNo == gridField[i].getDisplayType() || DisplayType.Image == gridField[i].getDisplayType()) {
divStyle += "text-align:center; ";
}
else if (DisplayType.isNumeric(gridField[i].getDisplayType())) {
divStyle += "text-align:right; ";
}
}
div.setStyle(divStyle);
row.appendChild(div);
}
if (rowIndex == gridTab.getCurrentRow()) {
row.setStyle("border-top: 1px solid #6f97d2; border-bottom: 1px solid #6f97d2");
}
row.addEventListener(Events.ON_CLICK, rowListener);
}
/**
* @see ListitemRendererExt#getControls()
*/
public int getControls() {
return DETACH_ON_RENDER;
}
/**
* @see RowRendererExt#newCell(Row)
*/
public Component newCell(Row row) {
return null;
}
/**
* @see RowRendererExt#newRow(Grid)
*/
public Row newRow(Grid grid) {
return null;
}
/**
* @see RendererCtrl#doCatch(Throwable)
*/
public void doCatch(Throwable ex) throws Throwable {
lookupCache = null;
}
/**
* @see RendererCtrl#doFinally()
*/
public void doFinally() {
lookupCache = null;
}
/**
* @see RendererCtrl#doTry()
*/
public void doTry() {
lookupCache = new HashMap<String, Map<Object,String>>();
}
class RowListener implements EventListener {
private Grid _grid;
public RowListener(Grid grid) {
_grid = grid;
}
public void onEvent(Event event) throws Exception {
if (Events.ON_CLICK.equals(event.getName())) {
Event evt = new Event(Events.ON_CLICK, _grid, event.getTarget());
Events.sendEvent(_grid, evt);
}
}
}
}

View File

@ -14,8 +14,10 @@ package org.adempiere.webui.component;
import java.util.Comparator; import java.util.Comparator;
import org.compiere.model.DataStatusEvent; import javax.swing.event.TableModelEvent;
import org.compiere.model.DataStatusListener; import javax.swing.event.TableModelListener;
import org.adempiere.webui.util.SortComparator;
import org.compiere.model.GridField; import org.compiere.model.GridField;
import org.compiere.model.GridTable; import org.compiere.model.GridTable;
import org.zkoss.zk.ui.Executions; import org.zkoss.zk.ui.Executions;
@ -30,10 +32,14 @@ import org.zkoss.zul.event.ListDataEvent;
* @author Low Heng Sin * @author Low Heng Sin
* *
*/ */
public class GridTableListModel extends AbstractListModel implements DataStatusListener, ListModelExt { public class GridTableListModel extends AbstractListModel implements TableModelListener, ListModelExt {
private static final long serialVersionUID = 1L;
private GridTable tableModel; private GridTable tableModel;
@SuppressWarnings("unused")
private GridField[] gridField; private GridField[] gridField;
@SuppressWarnings("unused")
private int windowNo; private int windowNo;
private int pageSize = -1; private int pageSize = -1;
@ -48,7 +54,7 @@ public class GridTableListModel extends AbstractListModel implements DataStatusL
this.tableModel = tableModel; this.tableModel = tableModel;
this.windowNo = windowNo; this.windowNo = windowNo;
gridField = tableModel.getFields(); gridField = tableModel.getFields();
tableModel.addDataStatusListener(this); tableModel.addTableModelListener(this);
} }
/** /**
@ -131,17 +137,6 @@ public class GridTableListModel extends AbstractListModel implements DataStatusL
} }
} }
/**
* @param e
* @see DataStatusListener#dataStatusChanged(DataStatusEvent)
*/
public void dataStatusChanged(DataStatusEvent e) {
if (Executions.getCurrent() != null) {
fireEvent(ListDataEvent.CONTENTS_CHANGED, -1, -1);
}
}
/** /**
* Request components that attached to this model to re-render a row. * Request components that attached to this model to re-render a row.
* @param row * @param row
@ -167,11 +162,34 @@ public class GridTableListModel extends AbstractListModel implements DataStatusL
* @param ascending * @param ascending
* @see ListModelExt#sort(Comparator, boolean) * @see ListModelExt#sort(Comparator, boolean)
*/ */
@SuppressWarnings("unchecked")
public void sort(Comparator cmpr, boolean ascending) { public void sort(Comparator cmpr, boolean ascending) {
//use default zk comparator //use default zk comparator
if (cmpr instanceof ListitemComparator) {
ListitemComparator lic = (ListitemComparator) cmpr; ListitemComparator lic = (ListitemComparator) cmpr;
tableModel.sort(lic.getListheader().getColumnIndex(), ascending); tableModel.sort(lic.getListheader().getColumnIndex(), ascending);
} else if (cmpr instanceof SortComparator) {
SortComparator sc = (SortComparator)cmpr;
tableModel.sort(sc.getColumnIndex(), ascending);
}
fireEvent(ListDataEvent.CONTENTS_CHANGED, -1, -1); fireEvent(ListDataEvent.CONTENTS_CHANGED, -1, -1);
} }
/**
* @param e
* @see TableModelListener#tableChanged(TableModelEvent)
*/
public void tableChanged(TableModelEvent e) {
if (Executions.getCurrent() != null) {
if (e.getLastRow() == Integer.MAX_VALUE)
{
fireEvent(ListDataEvent.CONTENTS_CHANGED, -1, -1);
}
else
{
fireEvent(ListDataEvent.CONTENTS_CHANGED, e.getFirstRow(), e.getLastRow());
}
}
}
} }

View File

@ -0,0 +1,429 @@
/******************************************************************************
* Copyright (C) 2008 Low Heng Sin *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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 General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
*****************************************************************************/
package org.adempiere.webui.component;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.table.AbstractTableModel;
import org.adempiere.webui.LayoutUtils;
import org.adempiere.webui.editor.WEditor;
import org.compiere.model.GridField;
import org.compiere.model.GridTab;
import org.compiere.model.GridTable;
import org.compiere.model.MSysConfig;
import org.compiere.util.DisplayType;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.EventListener;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zkex.zul.Borderlayout;
import org.zkoss.zkex.zul.Center;
import org.zkoss.zkex.zul.South;
import org.zkoss.zul.Paging;
import org.zkoss.zul.event.ZulEvents;
/**
* Grid view implemented using the Listbox component
* @author Low Heng Sin
*
*/
public class ListPanel extends Borderlayout implements EventListener
{
private static final int MIN_COLUMN_WIDTH = 100;
private static final int MAX_COLUMN_WIDTH = 300;
private static final long serialVersionUID = 1L;
private Listbox listbox = null;
private int pageSize = 100;
private GridField[] gridField;
private AbstractTableModel tableModel;
private int numColumns = 5;
private int windowNo;
private GridTab gridTab;
private boolean init;
private GridTableListModel listModel;
private Paging paging;
private GridTabListItemRenderer renderer;
private South south;
public static final String PAGE_SIZE_KEY = "ZK_PAGING_SIZE";
public ListPanel()
{
this(0);
}
/**
* @param windowNo
*/
public ListPanel(int windowNo)
{
this.windowNo = windowNo;
listbox = new Listbox();
south = new South();
this.appendChild(south);
//default paging size
pageSize = MSysConfig.getIntValue(PAGE_SIZE_KEY, 100);
}
/**
*
* @param gridTab
*/
public void init(GridTab gridTab)
{
if (init) return;
this.gridTab = gridTab;
tableModel = gridTab.getTableModel();
numColumns = tableModel.getColumnCount();
gridField = ((GridTable)tableModel).getFields();
setupColumns();
render();
updateListIndex(true);
this.init = true;
}
/**
*
* @return boolean
*/
public boolean isInit() {
return init;
}
/**
*
* @param gridTab
*/
public void activate(GridTab gridTab) {
if (isInit())
{
if (this.gridTab != gridTab)
{
init = false;
init(gridTab);
}
else
{
if (renderer != null)
renderer.stopEditing(false);
int oldSelected = listbox.getSelectedIndex();
updateListIndex(false);
if (listbox.getSelectedIndex() == oldSelected && oldSelected >= 0)
listModel.updateComponent(oldSelected);
}
}
else
init(gridTab);
}
/**
*
* @param gridTab
*/
public void refresh(GridTab gridTab) {
if (this.gridTab != gridTab)
{
init = false;
init(gridTab);
}
else
{
renderer.stopEditing(false);
listbox.setModel(listModel);
updateListIndex(true);
}
}
/**
* Update listbox selection to sync with grid current row pointer changes
*/
public void updateListIndex() {
updateListIndex(false);
}
/**
* Update listbox selection to sync with grid current row pointer changes
* @param updateSelectionOnly if true, doesn't attempt to refresh current row from model
*/
public void updateListIndex(boolean updateSelectionOnly) {
int rowIndex = gridTab.isOpen() ? gridTab.getCurrentRow() : -1;
if (pageSize > 0) {
if (paging.getTotalSize() != gridTab.getRowCount())
paging.setTotalSize(gridTab.getRowCount());
int pgIndex = rowIndex % pageSize;
int pgNo = (rowIndex - pgIndex) / pageSize;
boolean pgChange = false;
if (listModel.getPage() != pgNo) {
listModel.setPage(pgNo);
pgChange = true;
}
if (paging.getActivePage() != pgNo) {
paging.setActivePage(pgNo);
}
if (listbox.getSelectedIndex() != pgIndex) {
if (!updateSelectionOnly) {
renderer.stopEditing(false);
if (!pgChange) {
listModel.updateComponent(listbox.getSelectedIndex());
}
listModel.updateComponent(pgIndex);
}
listbox.setSelectedIndex(pgIndex);
}
} else {
if (listbox.getSelectedIndex() != rowIndex) {
if (!updateSelectionOnly) {
renderer.stopEditing(false);
listModel.updateComponent(listbox.getSelectedIndex());
listModel.updateComponent(rowIndex);
}
listbox.setSelectedIndex(rowIndex);
}
}
}
/**
* Set paging size
* @param pageSize
*/
public void setPageSize(int pageSize)
{
this.pageSize = pageSize;
}
public void clear()
{
this.getChildren().clear();
}
/**
*
* @param bool
*/
public void showGrid(boolean bool)
{
if (bool)
this.setVisible(true);
else
this.setVisible(false);
}
private void setupColumns()
{
if (init) return;
ListHead header = new ListHead();
header.setSizable(true);
Map<Integer, String> colnames = new HashMap<Integer, String>();
int index = 0;
for (int i = 0; i < numColumns; i++)
{
if (gridField[i].isDisplayed())
{
colnames.put(index, gridField[i].getHeader());
index++;
ListHeader colHeader = new ListHeader();
colHeader.setSort("auto");
colHeader.setLabel(gridField[i].getHeader());
int l = DisplayType.isNumeric(gridField[i].getDisplayType())
? 100 : gridField[i].getDisplayLength() * 9;
if (gridField[i].getHeader().length() * 9 > l)
l = gridField[i].getHeader().length() * 9;
if (l > MAX_COLUMN_WIDTH)
l = MAX_COLUMN_WIDTH;
else if ( l < MIN_COLUMN_WIDTH)
l = MIN_COLUMN_WIDTH;
colHeader.setWidth(Integer.toString(l) + "px");
header.appendChild(colHeader);
}
}
listbox.appendChild(header);
}
private void render()
{
LayoutUtils.addSclass("adtab-grid-panel", this);
listbox.setVflex(true);
listbox.setFixedLayout(true);
listbox.addEventListener(Events.ON_SELECT, this);
LayoutUtils.addSclass("adtab-grid", listbox);
updateModel();
Center center = new Center();
center.appendChild(listbox);
this.appendChild(center);
if (pageSize > 0)
{
paging = new Paging();
paging.setPageSize(pageSize);
paging.setTotalSize(tableModel.getRowCount());
paging.setDetailed(true);
south.appendChild(paging);
paging.addEventListener(ZulEvents.ON_PAGING, this);
renderer.setPaging(paging);
this.getParent().invalidate();
}
else
{
south.setVisible(false);
}
}
private void updateModel() {
listModel = new GridTableListModel((GridTable)tableModel, windowNo);
listModel.setPageSize(pageSize);
if (renderer != null)
renderer.stopEditing(false);
renderer = new GridTabListItemRenderer(gridTab, windowNo);
listbox.setItemRenderer(renderer);
listbox.setModel(listModel);
}
/**
* deactive panel
*/
public void deactivate() {
if (renderer != null)
renderer.stopEditing(false);
}
public void onEvent(Event event) throws Exception
{
if (event == null)
return;
else if (event.getTarget() == listbox)
{
int index = listbox.getSelectedIndex();
onSelectedRowChange(index);
}
else if (event.getTarget() == paging)
{
int pgNo = paging.getActivePage();
if (pgNo != listModel.getPage())
{
listbox.clearSelection();
listModel.setPage(pgNo);
listbox.setSelectedIndex(0);
onSelectedRowChange(0);
}
}
}
private void onSelectedRowChange(int index) {
if (updateModelIndex()) {
listModel.updateComponent(index);
listbox.setSelectedIndex(index);
} else if (!renderer.isInitialize()) {
listModel.updateComponent(index);
listbox.setSelectedIndex(index);
}
}
private boolean updateModelIndex() {
int rowIndex = listbox.getSelectedIndex();
if (pageSize > 0) {
int start = listModel.getPage() * listModel.getPageSize();
rowIndex = start + rowIndex;
}
if (gridTab.getCurrentRow() != rowIndex) {
renderer.stopEditing(true);
gridTab.navigate(rowIndex);
return true;
}
return false;
}
/**
*
* @return Listbox
*/
public Listbox getListbox() {
return listbox;
}
/**
* validate the display properties of fields of current row
* @param col
*/
public void dynamicDisplay(int col) {
if (!gridTab.isOpen())
{
return;
}
// Selective
if (col > 0)
return;
boolean noData = gridTab.getRowCount() == 0;
List<WEditor> list = renderer.getEditors();
for (WEditor comp : list)
{
GridField mField = comp.getGridField();
if (mField != null && mField.getIncluded_Tab_ID() <= 0)
{
if (noData)
{
comp.setReadWrite(false);
}
else
{
comp.dynamicDisplay();
boolean rw = mField.isEditable(true); // r/w - check Context
comp.setReadWrite(rw);
}
}
} // all components
}
/**
*
* @param windowNo
*/
public void setWindowNo(int windowNo) {
this.windowNo = windowNo;
}
}

View File

@ -252,6 +252,7 @@ public class WButtonEditor extends WEditor
public void addActionListener(ActionListener actionListener) public void addActionListener(ActionListener actionListener)
{ {
if (!actionListeners.contains(actionListener))
actionListeners.add(actionListener); actionListeners.add(actionListener);
} }

View File

@ -294,6 +294,7 @@ public abstract class WEditor implements EventListener, PropertyChangeListener
return; return;
} }
if (!listeners.contains(listener))
listeners.add(listener); listeners.add(listener);
} }

View File

@ -168,6 +168,13 @@ DataStatusListener, IADTabpanel
} }
/**
*
* @param winPanel
* @param windowNo
* @param gridTab
* @param gridWindow
*/
public void init(AbstractADWindowPanel winPanel, int windowNo, GridTab gridTab, public void init(AbstractADWindowPanel winPanel, int windowNo, GridTab gridTab,
GridWindow gridWindow) GridWindow gridWindow)
{ {
@ -218,6 +225,9 @@ DataStatusListener, IADTabpanel
listPanel.setWindowNo(windowNo); listPanel.setWindowNo(windowNo);
} }
/**
* Create UI components if not already created
*/
public void createUI() public void createUI()
{ {
if (uiCreated) return; if (uiCreated) return;
@ -489,6 +499,10 @@ DataStatusListener, IADTabpanel
return new Space(); return new Space();
} }
/**
* Validate display properties of fields of current row
* @param col
*/
public void dynamicDisplay (int col) public void dynamicDisplay (int col)
{ {
if (!gridTab.isOpen()) if (!gridTab.isOpen())
@ -595,11 +609,17 @@ DataStatusListener, IADTabpanel
logger.config(gridTab.toString() + " - fini - " + (col<=0 ? "complete" : "seletive")); logger.config(gridTab.toString() + " - fini - " + (col<=0 ? "complete" : "seletive"));
} // dynamicDisplay } // dynamicDisplay
/**
* @return String
*/
public String getDisplayLogic() public String getDisplayLogic()
{ {
return gridTab.getDisplayLogic(); return gridTab.getDisplayLogic();
} }
/**
* @return String
*/
public String getTitle() public String getTitle()
{ {
return gridTab.getName(); return gridTab.getName();
@ -621,36 +641,63 @@ DataStatusListener, IADTabpanel
return gridTab.getTabLevel(); return gridTab.getTabLevel();
} }
/**
* Is panel need refresh
* @return boolean
*/
public boolean isCurrent() public boolean isCurrent()
{ {
return gridTab != null ? gridTab.isCurrent() : false; return gridTab != null ? gridTab.isCurrent() : false;
} }
/**
*
* @return windowNo
*/
public int getWindowNo() public int getWindowNo()
{ {
return windowNo; return windowNo;
} }
/**
* Retrieve from db
*/
public void query() public void query()
{ {
gridTab.query(false); gridTab.query(false);
} }
/**
* Retrieve from db
* @param onlyCurrentRows
* @param onlyCurrentDays
* @param maxRows
*/
public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows) public void query (boolean onlyCurrentRows, int onlyCurrentDays, int maxRows)
{ {
gridTab.query(onlyCurrentRows, onlyCurrentDays, maxRows); gridTab.query(onlyCurrentRows, onlyCurrentDays, maxRows);
} }
/**
* @return GridTab
*/
public GridTab getGridTab() public GridTab getGridTab()
{ {
return gridTab; return gridTab;
} }
/**
* Refresh current row
*/
public void refresh() public void refresh()
{ {
gridTab.dataRefresh(); gridTab.dataRefresh();
} }
/**
* Activate/deactivate panel
* @param activate
*/
public void activate(boolean activate) public void activate(boolean activate)
{ {
active = activate; active = activate;
@ -693,6 +740,10 @@ DataStatusListener, IADTabpanel
} }
/**
* @param event
* @see EventListener#onEvent(Event)
*/
public void onEvent(Event event) public void onEvent(Event event)
{ {
if (event.getTarget() instanceof Listbox) if (event.getTarget() instanceof Listbox)
@ -735,6 +786,10 @@ DataStatusListener, IADTabpanel
gridTab.navigate(row); gridTab.navigate(row);
} }
/**
* @param e
* @see DataStatusListener#dataStatusChanged(DataStatusEvent)
*/
public void dataStatusChanged(DataStatusEvent e) public void dataStatusChanged(DataStatusEvent e)
{ {
//ignore background event //ignore background event
@ -863,6 +918,9 @@ DataStatusListener, IADTabpanel
} }
} }
/**
* Toggle between form and grid view
*/
public void switchRowPresentation() { public void switchRowPresentation() {
if (formComponent.isVisible()) { if (formComponent.isVisible()) {
formComponent.setVisible(false); formComponent.setVisible(false);
@ -871,7 +929,7 @@ DataStatusListener, IADTabpanel
} }
listPanel.setVisible(!formComponent.isVisible()); listPanel.setVisible(!formComponent.isVisible());
if (listPanel.isVisible()) { if (listPanel.isVisible()) {
listPanel.activate(gridTab); listPanel.refresh(gridTab);
} }
} }

View File

@ -30,6 +30,7 @@ import org.adempiere.webui.session.SessionManager;
import org.compiere.model.GridWindow; import org.compiere.model.GridWindow;
import org.compiere.model.MQuery; import org.compiere.model.MQuery;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import org.zkforge.keylistener.Keylistener;
import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.HtmlBasedComponent; import org.zkoss.zk.ui.HtmlBasedComponent;
import org.zkoss.zk.ui.event.Events; import org.zkoss.zk.ui.event.Events;
@ -39,7 +40,6 @@ import org.zkoss.zkex.zul.North;
import org.zkoss.zkex.zul.South; import org.zkoss.zkex.zul.South;
import org.zkoss.zkex.zul.West; import org.zkoss.zkex.zul.West;
import org.zkoss.zul.Tab; import org.zkoss.zul.Tab;
import org.zkoss.zul.Window;
/** /**
* *
@ -100,6 +100,7 @@ public class ADWindowPanel extends AbstractADWindowPanel
n.setHeight("30px"); n.setHeight("30px");
toolbar.setHeight("30px"); toolbar.setHeight("30px");
toolbar.setParent(n); toolbar.setParent(n);
toolbar.setWindowNo(getWindowNo());
} }
South s = new South(); South s = new South();
@ -130,9 +131,11 @@ public class ADWindowPanel extends AbstractADWindowPanel
((Tabpanel)parent).setOnCloseHandler(handler); ((Tabpanel)parent).setOnCloseHandler(handler);
} }
if (!isEmbedded() && adTab.getComponent() instanceof Window) { if (!isEmbedded()) {
Window w = (Window) adTab.getComponent(); Keylistener keyListener = new Keylistener();
w.addEventListener(Events.ON_CTRL_KEY, toolbar); statusBar.appendChild(keyListener);
keyListener.setCtrlKeys("#f1#f2#f3#f4#f5#f6#f7#f8#f9#f10#f11#f12^f^i^n^s^x@#left@#right@#up@#down@#pgup@#pgdn@p^p@z@x");
keyListener.addEventListener(Events.ON_CTRL_KEY, toolbar);
} }
return layout; return layout;

View File

@ -0,0 +1,146 @@
/******************************************************************************
* Product: Adempiere ERP & CRM Smart Business Solution *
* Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. *
* This program is free software; you can redistribute it and/or modify it *
* under the terms version 2 of the GNU General Public License as published *
* by the Free Software Foundation. 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 General Public License for more details. *
* You should have received a copy of the GNU General Public License along *
* with this program; if not, write to the Free Software Foundation, Inc., *
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. *
* For the text or an alternative of this public license, you may reach us *
* ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA *
* or via info@compiere.org or http://www.compiere.org/license.html *
*****************************************************************************/
package org.adempiere.webui.util;
import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.Collator;
import java.util.Comparator;
import org.compiere.util.Language;
import org.compiere.util.NamePair;
/**
* Default comparator, adapted from MSort
* @author hengsin
*/
public final class SortComparator implements Comparator<Object>, Serializable
{
/**
* generated
*/
private static final long serialVersionUID = 1265701980018071753L;
private int columnIndex;
/**
* @param columnIndex
* @param ascending
* @param language
*/
public SortComparator (int columnIndex, boolean ascending, Language language)
{
// Create string collator for login language - teo_sarca, [ 1672820 ]
m_collator = Collator.getInstance(language.getLocale());
setSortAsc(ascending);
this.columnIndex = columnIndex;
} // MSort
/** Multiplier */
private int m_multiplier = 1; // Asc by default
/** String Collator */
private Collator m_collator = null;
/**
* Sort Ascending
* @param ascending if true sort ascending
*/
public void setSortAsc (boolean ascending)
{
if (ascending)
m_multiplier = 1;
else
m_multiplier = -1;
} // setSortAsc
/**************************************************************************
* Compare Data of two entities
* @param o1 object
* @param o2 object
* @return comparator
*/
public int compare (Object o1, Object o2)
{
// Get Objects to compare
Object cmp1 = o1;
if (cmp1 instanceof NamePair)
cmp1 = ((NamePair)cmp1).getName();
Object cmp2 = o2;
if (cmp2 instanceof NamePair)
cmp2 = ((NamePair)cmp2).getName();
// Comparing Null values
if (cmp1 == null)
{
if (cmp2 == null)
return 0;
return -1 * m_multiplier;
}
if (cmp2 == null)
return 1 * m_multiplier;
/**
* compare different data types
*/
// String
if (cmp1 instanceof String && cmp2 instanceof String)
{
return m_collator.compare(cmp1, cmp2) * m_multiplier; // teo_sarca [ 1672820 ]
}
// Date
else if (cmp1 instanceof Timestamp && cmp2 instanceof Timestamp)
{
Timestamp t = (Timestamp)cmp1;
return t.compareTo((Timestamp)cmp2) * m_multiplier;
}
// BigDecimal
else if (cmp1 instanceof BigDecimal && cmp2 instanceof BigDecimal)
{
BigDecimal d = (BigDecimal)cmp1;
return d.compareTo((BigDecimal)cmp2) * m_multiplier;
}
// Integer
else if (cmp1 instanceof Integer && cmp2 instanceof Integer)
{
Integer d = (Integer)cmp1;
return d.compareTo((Integer)cmp2) * m_multiplier;
}
// Double
else if (cmp1 instanceof Double && cmp2 instanceof Double)
{
Double d = (Double)cmp1;
return d.compareTo((Double)cmp2) * m_multiplier;
}
// Convert to string value
String s = cmp1.toString();
return m_collator.compare(s, cmp2.toString()) * m_multiplier; // teo_sarca [ 1672820 ]
} // compare
public int getColumnIndex() {
return columnIndex;
}
} // SortComparator