diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java index 5410f207dd..bb8132ef96 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java @@ -92,6 +92,10 @@ public class CWindowToolbar extends FToolbar implements EventListener private boolean isAllowProductInfo = MRole.getDefault().isAllow_Info_Product(); private int windowNo = 0; + + private long prevKeyEventTime = 0; + + private KeyEvent prevKeyEvent; /** Last Modifier of Action Event */ // public int lastModifiers; @@ -198,6 +202,8 @@ public class CWindowToolbar extends FToolbar implements EventListener btn.setStyle("background: transparent none"); buttons.put(name, btn); this.appendChild(btn); + //make toolbar button last to receive focus + btn.setTabindex(32767); return btn; } @@ -297,7 +303,22 @@ public class CWindowToolbar extends FToolbar implements EventListener } else if (eventName.equals(Events.ON_CTRL_KEY)) { KeyEvent keyEvent = (KeyEvent) event; - this.onCtrlKeyEvent(keyEvent); + if (isRealVisible()) { + //filter same key event that is too close + //firefox fire key event twice when grid is visible + long time = System.currentTimeMillis(); + if (prevKeyEvent != null && prevKeyEventTime > 0 && + prevKeyEvent.getKeyCode() == keyEvent.getKeyCode() && + prevKeyEvent.getTarget() == keyEvent.getTarget() && + prevKeyEvent.isAltKey() == keyEvent.isAltKey() && + prevKeyEvent.isCtrlKey() == keyEvent.isCtrlKey() && + prevKeyEvent.isShiftKey() == keyEvent.isShiftKey()) { + if ((time - prevKeyEventTime) <= 300) { + return; + } + } + this.onCtrlKeyEvent(keyEvent); + } } } @@ -475,31 +496,38 @@ public class CWindowToolbar extends FToolbar implements EventListener return event; } - private void onCtrlKeyEvent(KeyEvent keyEvent) { - if (isRealVisible()) { - ToolBarButton btn = null; - if (keyEvent.isAltKey() && !keyEvent.isCtrlKey() && !keyEvent.isShiftKey()) + private void onCtrlKeyEvent(KeyEvent keyEvent) { + ToolBarButton btn = null; + if (keyEvent.isAltKey() && !keyEvent.isCtrlKey() && !keyEvent.isShiftKey()) + { + if (keyEvent.getKeyCode() == VK_X) { - if (keyEvent.getKeyCode() == VK_X) + if (windowNo > 0) { - if (windowNo > 0) - SessionManager.getAppDesktop().closeWindow(windowNo); - } - else - { - btn = altKeyMap.get(keyEvent.getKeyCode()); + prevKeyEventTime = System.currentTimeMillis(); + prevKeyEvent = keyEvent; + keyEvent.stopPropagation(); + SessionManager.getAppDesktop().closeWindow(windowNo); } } - 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()) { + 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) { + prevKeyEventTime = System.currentTimeMillis(); + prevKeyEvent = keyEvent; + keyEvent.stopPropagation(); + if (!btn.isDisabled() && btn.isVisible()) { Events.sendEvent(btn, new Event(Events.ON_CLICK, btn)); } } - } private boolean isRealVisible() { diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridPanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridPanel.java index f372d3bac8..8bba4b9b87 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridPanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridPanel.java @@ -27,13 +27,17 @@ import org.compiere.model.GridTable; import org.compiere.model.MSysConfig; import org.compiere.util.DisplayType; import org.compiere.util.Env; +import org.zkoss.zk.au.out.AuScript; +import org.zkoss.zk.ui.Component; import org.zkoss.zk.ui.event.Event; import org.zkoss.zk.ui.event.EventListener; import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.util.Clients; import org.zkoss.zkex.zul.Borderlayout; import org.zkoss.zkex.zul.Center; import org.zkoss.zkex.zul.South; import org.zkoss.zul.Column; +import org.zkoss.zul.Div; import org.zkoss.zul.Paging; import org.zkoss.zul.event.ZulEvents; @@ -72,12 +76,12 @@ public class GridPanel extends Borderlayout implements EventListener private GridTabRowRenderer renderer; private South south; - + + private boolean modeless; + public static final String PAGE_SIZE_KEY = "ZK_PAGING_SIZE"; - //copy from org.zkoss.zul.Grid - private static final String ATTR_ON_INIT_RENDER_POSTED = - "org.zkoss.zul.Grid.onInitLaterPosted"; + public static final String MODE_LESS_KEY = "ZK_GRID_EDIT_MODELESS"; public GridPanel() { @@ -96,6 +100,9 @@ public class GridPanel extends Borderlayout implements EventListener //default paging size pageSize = MSysConfig.getIntValue(PAGE_SIZE_KEY, 100); + + //default true for backward compatibility + modeless = MSysConfig.getBooleanValue(MODE_LESS_KEY, true); } /** @@ -144,16 +151,15 @@ public class GridPanel extends Borderlayout implements EventListener * @param gridTab */ public void refresh(GridTab gridTab) { - if (this.gridTab != gridTab) + if (!gridTab.isOpen()) return; + + if (this.gridTab != gridTab || !isInit()) { init = false; init(gridTab); } else { - if (renderer != null) - renderer.stopEditing(false); - listbox.setModel(listModel); updateListIndex(); } @@ -163,54 +169,44 @@ public class GridPanel extends Borderlayout implements EventListener * Update current row from model */ public void updateListIndex() { - int rowIndex = gridTab.isOpen() ? gridTab.getCurrentRow() : -1; + if (gridTab == null) return; + + int rowIndex = gridTab.isOpen() ? gridTab.getCurrentRow() : -1; if (pageSize > 0) { if (paging.getTotalSize() != gridTab.getRowCount()) paging.setTotalSize(gridTab.getRowCount()); int pgIndex = rowIndex >= 0 ? rowIndex % pageSize : 0; int pgNo = rowIndex >= 0 ? (rowIndex - pgIndex) / pageSize : 0; - if (listModel.getPage() != pgNo) { listModel.setPage(pgNo); + if (renderer.isEditing()) { + renderer.stopEditing(false); + } + } else if (rowIndex == renderer.getCurrentRowIndex()){ + if (modeless && !renderer.isEditing()) + Events.echoEvent("onPostSelectedRowChanged", this, null); + return; + } else { + if (renderer.isEditing()) { + renderer.stopEditing(false); + if (((renderer.getCurrentRowIndex() - pgIndex) / pageSize) == pgNo) { + listModel.updateComponent(renderer.getCurrentRowIndex() % pageSize); + } + } } if (paging.getActivePage() != pgNo) { paging.setActivePage(pgNo); - } - renderer.stopEditing(false); + } if (rowIndex >= 0 && pgIndex >= 0) { - listModel.updateComponent(pgIndex); - //don't have to call renderRow if render event have been posted - if (listbox.getAttribute(ATTR_ON_INIT_RENDER_POSTED) == null) { - //this is needed to make focus and auto scroll work - org.zkoss.zul.Row row = (org.zkoss.zul.Row)listbox.getRows().getChildren().get(pgIndex); - listbox.renderRow(row); - } - Events.echoEvent("onPostRenderSelectedRow", this, null); + Events.echoEvent("onPostSelectedRowChanged", this, null); } } else { - renderer.stopEditing(false); if (rowIndex >= 0) { - listModel.updateComponent(rowIndex); - //don't have to call renderRow if render event have been posted - if (listbox.getAttribute(ATTR_ON_INIT_RENDER_POSTED) == null) { - //this is needed to make focus and auto scroll work - org.zkoss.zul.Row row = (org.zkoss.zul.Row)listbox.getRows().getChildren().get(rowIndex); - listbox.renderRow(row); - } - Events.echoEvent("onPostRenderSelectedRow", this, null); + Events.echoEvent("onPostSelectedRowChanged", this, null); } } } - - /** - * Don't call this directly, use internally to send post render event - */ - public void onPostRenderSelectedRow() { - renderer.setFocusToField(); - } - - /** * set paging size * @param pageSize @@ -307,7 +303,7 @@ public class GridPanel extends Borderlayout implements EventListener private void updateModel() { listModel = new GridTableListModel((GridTable)tableModel, windowNo); listModel.setPageSize(pageSize); - if (renderer != null) + if (renderer != null && renderer.isEditing()) renderer.stopEditing(false); renderer = new GridTabRowRenderer(gridTab, windowNo); renderer.setGridPanel(this); @@ -320,8 +316,8 @@ public class GridPanel extends Borderlayout implements EventListener * deactivate panel */ public void deactivate() { - if (renderer != null) - renderer.stopEditing(false); + if (renderer != null && renderer.isEditing()) + renderer.stopEditing(true); } public void onEvent(Event event) throws Exception @@ -333,9 +329,21 @@ public class GridPanel extends Borderlayout implements EventListener Object data = event.getData(); if (data != null && data instanceof org.zkoss.zul.Row) { - int index = listbox.getRows().getChildren().indexOf(data); - if (index >= 0 ) { - onSelectedRowChange(index); + //click on selected row to enter edit mode + if (data == renderer.getCurrentRow()) + { + if (!renderer.isEditing()) + { + renderer.editCurrentRow(); + renderer.setFocusToEditor(); + } + } + else + { + int index = listbox.getRows().getChildren().indexOf(data); + if (index >= 0 ) { + onSelectedRowChange(index); + } } } } @@ -351,13 +359,62 @@ public class GridPanel extends Borderlayout implements EventListener } private void onSelectedRowChange(int index) { - if (updateModelIndex(index)) { - listModel.updateComponent(index); - } else if (!renderer.isInitialize()) { - listModel.updateComponent(index); + if (updateModelIndex(index)) { + updateListIndex(); + } + } + + /** + * Event after the current selected row change + */ + public void onPostSelectedRowChanged() { + int rowIndex = gridTab.isOpen() ? gridTab.getCurrentRow() : -1; + if (rowIndex >= 0 && pageSize > 0) { + int pgIndex = rowIndex >= 0 ? rowIndex % pageSize : 0; + org.zkoss.zul.Row row = (org.zkoss.zul.Row) listbox.getRows().getChildren().get(pgIndex); + if (!isRowRendered(row, pgIndex)) { + listbox.renderRow(row); + } else { + renderer.setCurrentRow(row); + } + if (modeless && !renderer.isEditing()) { + renderer.editCurrentRow(); + renderer.setFocusToEditor(); + } else { + focusToRow(row); + } + } else if (rowIndex >= 0) { + org.zkoss.zul.Row row = (org.zkoss.zul.Row) listbox.getRows().getChildren().get(rowIndex); + if (!isRowRendered(row, rowIndex)) { + listbox.renderRow(row); + } else { + renderer.setCurrentRow(row); + } + if (modeless && !renderer.isEditing()) { + renderer.editCurrentRow(); + renderer.setFocusToEditor(); + } else { + focusToRow(row); + } } } + private void focusToRow(org.zkoss.zul.Row row) { + Component c = row.getFirstChild().getFirstChild().getNextSibling(); + Clients.response(new AuScript(null, "scrollToRow('" + c.getUuid() + "');")); + } + + private boolean isRowRendered(org.zkoss.zul.Row row, int index) { + if (row.getChildren().size() == 0) { + return false; + } else if (row.getChildren().size() == 1) { + if (!(row.getChildren().get(0) instanceof Div)) { + return false; + } + } + return true; + } + private boolean updateModelIndex(int rowIndex) { if (pageSize > 0) { int start = listModel.getPage() * listModel.getPageSize(); @@ -365,7 +422,6 @@ public class GridPanel extends Borderlayout implements EventListener } if (gridTab.getCurrentRow() != rowIndex) { - renderer.stopEditing(true); gridTab.navigate(rowIndex); return true; } @@ -384,7 +440,7 @@ public class GridPanel extends Borderlayout implements EventListener * @param col */ public void dynamicDisplay(int col) { - if (!gridTab.isOpen()) + if (gridTab == null || !gridTab.isOpen()) { return; } @@ -424,7 +480,18 @@ public class GridPanel extends Borderlayout implements EventListener @Override public void focus() { - if (renderer != null) - renderer.setFocusToField(); + if (renderer != null && renderer.isEditing()) { + renderer.setFocusToEditor(); + } + } + + /** + * Handle enter key event + */ + public void onEnterKey() { + if (!modeless && renderer != null && !renderer.isEditing()) { + renderer.editCurrentRow(); + renderer.setFocusToEditor(); + } } } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridTabRowRenderer.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridTabRowRenderer.java index b02dd9dd08..b1d8f96a32 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridTabRowRenderer.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridTabRowRenderer.java @@ -48,6 +48,9 @@ import org.zkoss.zul.RendererCtrl; import org.zkoss.zul.Row; import org.zkoss.zul.RowRenderer; import org.zkoss.zul.RowRendererExt; +import org.zkoss.zhtml.Input; +import org.zkoss.zhtml.Label; +import org.zkoss.zhtml.Text; /** * Row renderer for GridTab grid. @@ -56,6 +59,7 @@ import org.zkoss.zul.RowRendererExt; */ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, RendererCtrl { + private static final String CURRENT_ROW_STYLE = "border-top: 2px solid #6f97d2; border-bottom: 2px solid #6f97d2"; private static final int MAX_TEXT_LENGTH = 60; private GridTab gridTab; private int windowNo; @@ -68,6 +72,10 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer private Grid grid = null; private GridPanel gridPanel = null; + private Row currentRow; + private Object[] currentValues; + private boolean editing = false; + private int currentRowIndex = -1; /** * @@ -202,25 +210,30 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer 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); + + Label label = new Label(); + setLabelText(text, label); + component = label; } return component; } - - /** - * Is renderer initialize - * @return boolean - */ - public boolean isInitialize() { - return !editors.isEmpty(); - } + /** + * @param text + * @param label + */ + private void setLabelText(String text, Label label) { + String display = text; + if (text != null && text.length() > MAX_TEXT_LENGTH) + display = text.substring(0, MAX_TEXT_LENGTH - 3) + "..."; + label.appendChild(new Text(display)); + if (text != null && text.length() > MAX_TEXT_LENGTH) + label.setDynamicProperty("title", text); + else + label.setDynamicProperty("title", ""); + } + /** * * @return active editor list @@ -245,6 +258,11 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer * @param updateCellLabel */ public void stopEditing(boolean updateCellLabel) { + if (!editing) { + return; + } else { + editing = false; + } Row row = null; for (Entry entry : editors.entrySet()) { if (entry.getValue().getComponent().getParent() != null) { @@ -261,7 +279,9 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer if (updateCellLabel) { if (component instanceof Label) { Label label = (Label)component; - label.setValue(getDisplayText(entry.getValue().getValue(), entry.getValue().getGridField())); + label.getChildren().clear(); + String text = getDisplayText(entry.getValue().getValue(), entry.getValue().getGridField()); + setLabelText(text, label); } else if (component instanceof Checkbox) { Checkbox checkBox = (Checkbox)component; Object value = entry.getValue().getValue(); @@ -278,10 +298,11 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer entry.getValue().getComponent().detach(); entry.getKey().removePropertyChangeListener(entry.getValue()); entry.getValue().removeValuechangeListener(dataBinder); - } + } } - if (row != null) - row.setStyle(null); + + GridTableListModel model = (GridTableListModel) grid.getModel(); + model.setEditing(false); } /** @@ -301,7 +322,7 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer if (rowListener == null) rowListener = new RowListener((Grid)row.getParent().getParent()); - Object[] values = (Object[])data; + currentValues = (Object[])data; int columnCount = gridTab.getTableModel().getColumnCount(); GridField[] gridField = gridTab.getFields(); Grid grid = (Grid) row.getParent().getParent(); @@ -313,33 +334,24 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer } int colIndex = -1; + int compCount = 0; 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)); + colIndex ++; Div div = new Div(); - String divStyle = "border: none; width: 100%; "; + String divStyle = "border: none; width: 100%; height: 100%;"; org.zkoss.zul.Column column = (org.zkoss.zul.Column) columns.getChildren().get(colIndex); if (column.isVisible()) { - Component component = getDisplayComponent(values[i], gridField[i]); + compCount++; + Component component = getDisplayComponent(currentValues[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 (compCount == 1) { + //add hidden input component to help focusing to row + div.appendChild(createAnchorInput()); + } if (DisplayType.YesNo == gridField[i].getDisplayType() || DisplayType.Image == gridField[i].getDisplayType()) { divStyle += "text-align:center; "; @@ -351,16 +363,102 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer div.setStyle(divStyle); row.appendChild(div); } - + if (rowIndex == gridTab.getCurrentRow()) { - row.setStyle("border-top: 1px solid #6f97d2; border-bottom: 1px solid #6f97d2"); + setCurrentRow(row); } row.addEventListener(Events.ON_CLICK, rowListener); row.addEventListener(Events.ON_DOUBLE_CLICK, rowListener); - } + row.addEventListener(Events.ON_OK, rowListener); + } /** - * @see ListitemRendererExt#getControls() + * @param component + * @return + */ + private Input createAnchorInput() { + Input input = new Input(); + input.setDynamicProperty("type", "text"); + input.setValue(""); + input.setDynamicProperty("readonly", "readonly"); + input.setStyle("border: none; display: none; width: 3px;"); + return input; + } + + /** + * @param row + */ + public void setCurrentRow(Row row) { + if (currentRow != null && currentRow.getParent() != null && currentRow != row) { + currentRow.setStyle(null); + } + currentRow = row; + currentRow.setStyle(CURRENT_ROW_STYLE); + if (currentRowIndex == gridTab.getCurrentRow()) { + if (editing) { + stopEditing(false); + editCurrentRow(); + } + } else { + currentRowIndex = gridTab.getCurrentRow(); + } + } + + /** + * @return Row + */ + public Row getCurrentRow() { + return currentRow; + } + + /** + * @return current row index ( absolute ) + */ + public int getCurrentRowIndex() { + return currentRowIndex; + } + + /** + * Enter edit mode + */ + public void editCurrentRow() { + if (currentRow != null && currentRow.getParent() != null && currentRow.isVisible() + && grid != null && grid.isVisible() && grid.getParent() != null && grid.getParent().isVisible()) { + int columnCount = gridTab.getTableModel().getColumnCount(); + GridField[] gridField = gridTab.getFields(); + org.zkoss.zul.Columns columns = grid.getColumns(); + int colIndex = -1; + for (int i = 0; i < columnCount; i++) { + if (!gridField[i].isDisplayed(true)) { + continue; + } + if (editors.get(gridField[i]) == null) + editors.put(gridField[i], WebEditorFactory.getEditor(gridField[i], true)); + colIndex ++; + org.zkoss.zul.Column column = (org.zkoss.zul.Column) columns.getChildren().get(colIndex); + if (column.isVisible() && gridField[i].isEditable(true)) { + Div div = (Div) currentRow.getChildren().get(colIndex); + WEditor editor = getEditorCell(gridField[i], currentValues[i], i); + div.appendChild(editor.getComponent()); + WEditorPopupMenu popupMenu = editor.getPopupMenu(); + + if (popupMenu != null) + { + popupMenu.addMenuListener((ContextMenuListener)editor); + div.appendChild(popupMenu); + } + div.getFirstChild().setVisible(false); + } + } + editing = true; + + GridTableListModel model = (GridTableListModel) grid.getModel(); + model.setEditing(true); + } + } + + /** + * @see RowRendererExt#getControls() */ public int getControls() { return DETACH_ON_RENDER; @@ -404,35 +502,38 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer /** * set focus to first active editor */ - public void setFocusToField() { - WEditor toFocus = null; - Label firstLabel = null; - for (WEditor editor : getEditors()) { - if (editor.isHasFocus() && editor.isVisible() && editor.getComponent().getParent() != null) { - toFocus = editor; - break; - } - - if (toFocus == null) { - if (editor.isVisible() && editor.isReadWrite() && editor.getComponent().getParent() != null) { - toFocus = editor; + public void setFocusToEditor() { + if (currentRow != null && currentRow.getParent() != null) { + WEditor toFocus = null; + WEditor firstEditor = null; + for (WEditor editor : getEditors()) { + if (editor.isHasFocus() && editor.isVisible() && editor.getComponent().getParent() != null) { + toFocus = editor; + break; } - } - if (firstLabel == null) { - if (editor.getComponent() instanceof Label && editor.getComponent().getParent() != null) { - firstLabel = (Label) editor.getComponent(); + + if (editor.isVisible() && editor.getComponent().getParent() != null) { + if (toFocus == null && editor.isReadWrite()) { + toFocus = editor; + } + if (firstEditor == null) + firstEditor = editor; } + } + if (toFocus != null) { + Component c = toFocus.getComponent(); + if (c instanceof EditorBox) { + c = ((EditorBox)c).getTextbox(); + } + Clients.response(new AuFocus(c)); + } else if (firstEditor != null) { + Component c = firstEditor.getComponent(); + if (c instanceof EditorBox) { + c = ((EditorBox)c).getTextbox(); + } + Clients.response(new AuFocus(c)); } - } - if (toFocus != null) { - Component c = toFocus.getComponent(); - if (c instanceof EditorBox) { - c = ((EditorBox)c).getTextbox(); - } - Clients.response(new AuFocus(c)); } - else if (firstLabel != null) - Clients.response(new AuFocus(firstLabel)); } /** @@ -460,7 +561,14 @@ public class GridTabRowRenderer implements RowRenderer, RowRendererExt, Renderer Event evt = new Event(Events.ON_DOUBLE_CLICK, _grid, _grid); Events.sendEvent(_grid, evt); } + else if (Events.ON_OK.equals(event.getName())) { + Event evt = new Event(Events.ON_OK, _grid, _grid); + Events.sendEvent(_grid, evt); + } } - + } + + public boolean isEditing() { + return editing; } } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridTableListModel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridTableListModel.java index 44d6c66f04..4f78dbfc68 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridTableListModel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/GridTableListModel.java @@ -45,6 +45,8 @@ public class GridTableListModel extends AbstractListModel implements TableModelL private int pageSize = -1; private int pageNo = 0; + private boolean editing = false; + /** * * @param tableModel @@ -123,7 +125,7 @@ public class GridTableListModel extends AbstractListModel implements TableModelL */ public int getSize() { int total = tableModel.getRowCount(); - if (pageSize < 0) + if (pageSize <= 0) return total; else if ((total - ( pageNo * pageSize)) < 0) { pageNo = 0; @@ -181,15 +183,43 @@ public class GridTableListModel extends AbstractListModel implements TableModelL */ public void tableChanged(TableModelEvent e) { if (Executions.getCurrent() != null) { - if (e.getLastRow() == Integer.MAX_VALUE) + if (e.getType() == TableModelEvent.DELETE) + { + if (pageSize > 0) + { + int pgIndex = e.getFirstRow() % pageSize; + fireEvent(ListDataEvent.CONTENTS_CHANGED, pgIndex, getSize()); + } + else + fireEvent(ListDataEvent.INTERVAL_REMOVED, e.getFirstRow(), e.getLastRow()); + } + else if (e.getType() == TableModelEvent.INSERT) + { + if (pageSize > 0) + { + int pgIndex = e.getFirstRow() % pageSize; + fireEvent(ListDataEvent.CONTENTS_CHANGED, pgIndex, getSize()); + } + else + fireEvent(ListDataEvent.INTERVAL_ADDED, e.getFirstRow(), e.getLastRow()); + } + else if (e.getLastRow() == Integer.MAX_VALUE) { fireEvent(ListDataEvent.CONTENTS_CHANGED, -1, -1); } else { - fireEvent(ListDataEvent.CONTENTS_CHANGED, e.getFirstRow(), e.getLastRow()); + if (!editing) + fireEvent(ListDataEvent.CONTENTS_CHANGED, e.getFirstRow(), e.getLastRow()); } } } + /** + * @param b + */ + public void setEditing(boolean b) { + editing = b; + } + } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADSortTab.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADSortTab.java index b3f64bea64..b61d89ced9 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADSortTab.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADSortTab.java @@ -869,5 +869,7 @@ public class ADSortTab extends Panel implements IADTabpanel public void afterSave(boolean onSaveEvent) { } + public void onEnterKey() { + } } //ADSortTab diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java index 67d69b1fa3..225631997e 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADTabpanel.java @@ -165,7 +165,7 @@ DataStatusListener, IADTabpanel listPanel = new GridPanel(); listPanel.getListbox().addEventListener(Events.ON_DOUBLE_CLICK, this); - + } /** @@ -956,6 +956,8 @@ DataStatusListener, IADTabpanel listPanel.setVisible(!formComponent.isVisible()); if (listPanel.isVisible()) { listPanel.refresh(gridTab); + } else { + listPanel.deactivate(); } } @@ -1051,5 +1053,14 @@ DataStatusListener, IADTabpanel else listPanel.focus(); } + + /** + * @see IADTabpanel#onEnterKey() + */ + public void onEnterKey() { + if (listPanel.isVisible()) { + listPanel.onEnterKey(); + } + } } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java index 1b0406c69c..d979b5c6a3 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/ADWindowPanel.java @@ -33,7 +33,10 @@ import org.compiere.util.CLogger; import org.zkforge.keylistener.Keylistener; 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.zk.ui.event.KeyEvent; import org.zkoss.zkex.zul.Borderlayout; import org.zkoss.zkex.zul.Center; import org.zkoss.zkex.zul.North; @@ -67,6 +70,8 @@ public class ADWindowPanel extends AbstractADWindowPanel private Center contentArea; private West west; + + private Keylistener keyListener; public ADWindowPanel(Properties ctx, int windowNo) { @@ -132,10 +137,13 @@ public class ADWindowPanel extends AbstractADWindowPanel } if (!isEmbedded()) { - Keylistener keyListener = new Keylistener(); + if (keyListener != null) + keyListener.detach(); + keyListener = new Keylistener(); 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.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#enter"); keyListener.addEventListener(Events.ON_CTRL_KEY, toolbar); + keyListener.addEventListener(Events.ON_CTRL_KEY, this); } return layout; @@ -162,6 +170,24 @@ public class ADWindowPanel extends AbstractADWindowPanel } + /** + * @param event + * @see EventListener#onEvent(Event) + */ + public void onEvent(Event event) { + if (Events.ON_CTRL_KEY.equals(event.getName())) { + KeyEvent keyEvent = (KeyEvent) event; + //enter == 13 + if (keyEvent.getKeyCode() == 13 && this.getComponent().getParent().isVisible()) { + keyEvent.stopPropagation(); + IADTabpanel panel = adTab.getSelectedTabpanel(); + if (panel != null) + panel.onEnterKey(); + } + } else { + super.onEvent(event); + } + } class TabOnCloseHanlder implements ITabOnCloseHandler { diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/IADTabpanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/IADTabpanel.java index 0c85d22b05..38976c062f 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/IADTabpanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/IADTabpanel.java @@ -95,4 +95,9 @@ public interface IADTabpanel extends Component, Evaluatee { * @param onSaveEvent */ public void afterSave(boolean onSaveEvent); + + /** + * Enter key event + */ + public void onEnterKey(); } diff --git a/zkwebui/js/layout.js b/zkwebui/js/layout.js index ddee6f869b..da86eea6ba 100644 --- a/zkwebui/js/layout.js +++ b/zkwebui/js/layout.js @@ -18,3 +18,10 @@ function ad_closeBuble(uuid) { } } +function scrollToRow(uuid){ + var cmp = $e(uuid); + cmp.style.display="inline"; + cmp.focus(); + cmp.style.display="none"; +} + \ No newline at end of file