diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java index 977f99307c..17151a1452 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/WListItemRenderer.java @@ -269,7 +269,7 @@ public class WListItemRenderer implements ListitemRenderer, EventListener, Listi { listcell.setValue(Boolean.valueOf(field.toString())); - if (table != null) + if (table != null && columnIndex == 0) table.setCheckmark(false); Checkbox checkbox = new Checkbox(); checkbox.setChecked(Boolean.valueOf(field.toString())); @@ -449,38 +449,46 @@ public class WListItemRenderer implements ListitemRenderer, EventListener, Listi String headerText = headerValue.toString(); if (m_headers.size() <= headerIndex || m_headers.get(headerIndex) == null) { - Comparator ascComparator = getColumnComparator(true, headerIndex); - Comparator dscComparator = getColumnComparator(false, headerIndex); - - header = new ListHeader(headerText); - - header.setSort("auto"); - header.setSortAscending(ascComparator); - header.setSortDescending(dscComparator); - - int width = headerText.trim().length() * 9; - if (width > 300) - width = 300; - else if (classType != null) - { - if (classType.equals(String.class)) - { - if (width > 0 && width < 180) - width = 180; - } - else if (classType.equals(IDColumn.class)) - { - header.setSort("none"); - if (width == 0) - width = 30; - } - else if (width > 0 && width < 100) - width = 100; - } - else if (width > 0 && width < 100) - width = 100; - - header.setWidth(width + "px"); + if (classType != null && classType.isAssignableFrom(IDColumn.class)) + { + header = new ListHeader(""); + header.setWidth("20px"); + } + else + { + Comparator ascComparator = getColumnComparator(true, headerIndex); + Comparator dscComparator = getColumnComparator(false, headerIndex); + + header = new ListHeader(headerText); + + header.setSort("auto"); + header.setSortAscending(ascComparator); + header.setSortDescending(dscComparator); + + int width = headerText.trim().length() * 9; + if (width > 300) + width = 300; + else if (classType != null) + { + if (classType.equals(String.class)) + { + if (width > 0 && width < 180) + width = 180; + } + else if (classType.equals(IDColumn.class)) + { + header.setSort("none"); + if (width == 0) + width = 30; + } + else if (width > 0 && width < 100 && (classType == null || !classType.isAssignableFrom(Boolean.class))) + width = 100; + } + else if (width > 0 && width < 100) + width = 100; + + header.setWidth(width + "px"); + } m_headers.add(header); } else @@ -738,8 +746,16 @@ public class WListItemRenderer implements ListitemRenderer, EventListener, Listi } m_listeners.add(listener); + } - return; + public void removeTableValueChangeListener(TableValueChangeListener listener) + { + if (listener == null) + { + return; + } + + m_listeners.remove(listener); } /** diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/WListbox.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/WListbox.java index efa8b49c5e..ce15dea0be 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/WListbox.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/WListbox.java @@ -56,11 +56,11 @@ import org.zkoss.zul.ListModel; * @author Sendy Yagambrum */ public class WListbox extends Listbox implements IMiniTable, TableValueChangeListener, WTableModelListener -{ +{ /** * */ - private static final long serialVersionUID = -9012847495178031267L; + private static final long serialVersionUID = 8717707799347994189L; /** Logger. */ private static CLogger logger = CLogger.getCLogger(MiniTable.class); @@ -103,16 +103,22 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis */ public void setData(ListModelTable model, List< ? extends String> columnNames) { - // instantiate our custom row renderer - WListItemRenderer rowRenderer = new WListItemRenderer(columnNames); - - // add listener for listening to component changes - rowRenderer.addTableValueChangeListener(this); + WListItemRenderer rowRenderer = null; + if (columnNames != null && columnNames.size() > 0) + { + // instantiate our custom row renderer + rowRenderer = new WListItemRenderer(columnNames); + // add listener for listening to component changes + rowRenderer.addTableValueChangeListener(this); + } // assign the model and renderer this.setModel(model); - getModel().setNoColumns(columnNames.size()); - this.setItemRenderer(rowRenderer); + if (rowRenderer != null) + { + getModel().setNoColumns(columnNames.size()); + this.setItemRenderer(rowRenderer); + } // re-render this.repaint(); @@ -1038,5 +1044,9 @@ public class WListbox extends Listbox implements IMiniTable, TableValueChangeLis public int getColumnCount() { return getModel() != null ? getModel().getNoColumns() : 0; } + + public int getKeyColumnIndex() { + return m_keyColumnIndex; + } } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java b/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java index cb2c8e686d..c9a8ad0cf1 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/editor/WSearchEditor.java @@ -402,12 +402,17 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value { log.fine("Value=" + value); - ValueChangeEvent evt = new ValueChangeEvent(this, this.getColumnName(), value, value); + ValueChangeEvent evt = new ValueChangeEvent(this, this.getColumnName(), getValue(), value); // -> ADTabpanel - valuechange fireValueChange(evt); // is the value updated ? boolean updated = false; + if (value instanceof Object[] && ((Object[])value).length > 0) + { + value = ((Object[])value)[0]; + } + if (value == null && getValue() == null) updated = true; else if (value != null && value.equals(getValue())) @@ -470,7 +475,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value * - Window closed -> ignore => result == null && !cancalled */ - Object result = null; + Object result[] = null; boolean cancelled = false; String col = lookup.getColumnName(); // fully qualified name @@ -501,7 +506,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value // Show Info InfoProductPanel ip = new InfoProductPanel (lookup.getWindowNo(), - M_Warehouse_ID, M_PriceList_ID, false,queryValue, whereClause); + M_Warehouse_ID, M_PriceList_ID, true, queryValue, whereClause); ip.setVisible(true); ip.setTitle("Product Info"); @@ -513,7 +518,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value AEnv.showWindow(ip); cancelled = ip.isCancelled(); - result = ip.getSelectedKey(); + result = ip.getSelectedKeys(); } else if (col.equals("C_BPartner_ID")) { @@ -538,7 +543,7 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value AEnv.showWindow(ip); cancelled = ip.isCancelled(); - result = ip.getSelectedKey(); + result = ip.getSelectedKeys(); } else // General Info { @@ -558,16 +563,19 @@ public class WSearchEditor extends WEditor implements ContextMenuListener, Value AEnv.showWindow(ig); cancelled = ig.isCancelled(); - result = ig.getSelectedKey(); + result = ig.getSelectedKeys(); } infoPanel = null; // Result - if (result != null) + if (result != null && result.length > 0) { //ensure data binding happen - actionCombo (result); // data binding + if (result.length > 1) + actionCombo (result); + else + actionCombo (result[0]); } else if (cancelled) { diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java index 151d2a8d1c..3511f610bf 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/InfoPanel.java @@ -67,7 +67,7 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM /** * */ - private static final long serialVersionUID = -1797443523668842806L; + private static final long serialVersionUID = 2961293943433626554L; private final static int PAGE_SIZE = 100; public static InfoPanel create (int WindowNo, @@ -355,7 +355,7 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM String orderBy) { String sql =contentPanel.prepareTable(layout, from, - where.toString(),false, + where.toString(),p_multipleSelection, getTableName(),false); p_layout = contentPanel.getLayout(); m_sqlMain = sql.toString(); @@ -490,7 +490,7 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM List subList = line.subList(0, PAGE_SIZE); model = new ListModelTable(subList); model.addTableModelListener(this); - contentPanel.setData(model, columnHeader); + contentPanel.setData(model, null); pageNo = 0; } @@ -504,7 +504,7 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM } model = new ListModelTable(line); model.addTableModelListener(this); - contentPanel.setData(model, columnHeader); + contentPanel.setData(model, null); } } int no = line.size(); @@ -609,6 +609,7 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM // Multi Selection if (p_multipleSelection) { + m_results.addAll(getSelectedRowKeys()); } else // singleSelection { @@ -634,6 +635,54 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM return key; } // getSelectedRowKey + + /** + * Get the keys of selected row/s based on layout defined in prepareTable + * @return IDs if selection present + * @author ashley + */ + protected ArrayList getSelectedRowKeys() + { + ArrayList selectedDataList = new ArrayList(); + + if (contentPanel.getKeyColumnIndex() == -1) + { + return selectedDataList; + } + + if (p_multipleSelection) + { + int[] rows = contentPanel.getSelectedIndices(); + for (int row = 0; row < rows.length; row++) + { + Object data = contentPanel.getModel().getValueAt(rows[row], contentPanel.getKeyColumnIndex()); + if (data instanceof IDColumn) + { + IDColumn dataColumn = (IDColumn)data; + selectedDataList.add(dataColumn.getRecord_ID()); + } + else + { + log.severe("For multiple selection, IDColumn should be key column for selection"); + } + } + } + + if (selectedDataList.size() == 0) + { + int row = contentPanel.getSelectedRow(); + if (row != -1 && contentPanel.getKeyColumnIndex() != -1) + { + Object data = contentPanel.getModel().getValueAt(row, contentPanel.getKeyColumnIndex()); + if (data instanceof IDColumn) + selectedDataList.add(((IDColumn)data).getRecord_ID()); + if (data instanceof Integer) + selectedDataList.add((Integer)data); + } + } + + return selectedDataList; + } // getSelectedRowKeys /** * Get selected Keys @@ -643,7 +692,7 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM { if (!m_ok || m_results.size() == 0) return null; - return m_results.toArray(); + return m_results.toArray(new Integer[0]); } // getSelectedKeys; /** @@ -912,7 +961,7 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM List subList = line.subList(start, end); model = new ListModelTable(subList); model.addTableModelListener(this); - contentPanel.setData(model, getColumnHeader(p_layout)); + contentPanel.setData(model, null); //workaround for scrollbar position problem contentPanel.renderAll(); @@ -993,14 +1042,6 @@ public abstract class InfoPanel extends Window implements EventListener, WTableM // End Worker saveSelection(); - if (contentPanel != null) - { - Object data = getSelectedKey(); - ValueChangeEvent valuechange = new ValueChangeEvent - (this, p_keyColumn , data, data); - - fireValueChange(valuechange); - } this.detach(); } // dispose diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/InfoProductPanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/InfoProductPanel.java index bf01a60755..0b07d248fa 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/InfoProductPanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/InfoProductPanel.java @@ -94,10 +94,10 @@ import org.zkoss.zkex.zul.South; */ public class InfoProductPanel extends InfoPanel implements EventListener { - /** + /** * */ - private static final long serialVersionUID = 8334769481995098193L; + private static final long serialVersionUID = 73880400775610395L; private Label lblValue = new Label(); private Textbox fieldValue = new Textbox(); private Label lblName = new Label(); @@ -451,19 +451,20 @@ public class InfoProductPanel extends InfoPanel implements EventListener contentPanel.addActionListener(new EventListener() { public void onEvent(Event event) throws Exception { int row = contentPanel.getSelectedRow(); + if (row >= 0) { + int M_Warehouse_ID = 0; + ListItem listitem = pickWarehouse.getSelectedItem(); + if (listitem != null) + M_Warehouse_ID = (Integer)listitem.getValue(); - int M_Warehouse_ID = 0; - ListItem listitem = pickWarehouse.getSelectedItem(); - if (listitem != null) - M_Warehouse_ID = (Integer)listitem.getValue(); + int M_PriceList_Version_ID = 0; + listitem = pickPriceList.getSelectedItem(); + if (listitem != null) + M_PriceList_Version_ID = (Integer)listitem.getValue(); - int M_PriceList_Version_ID = 0; - listitem = pickPriceList.getSelectedItem(); - if (listitem != null) - M_PriceList_Version_ID = (Integer)listitem.getValue(); - - refresh(contentPanel.getValueAt(row,2), M_Warehouse_ID, M_PriceList_Version_ID); - borderlayout.getSouth().setOpen(true); + refresh(contentPanel.getValueAt(row,2), M_Warehouse_ID, M_PriceList_Version_ID); + borderlayout.getSouth().setOpen(true); + } } }); } diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/util/GridTabDataBinder.java b/zkwebui/WEB-INF/src/org/adempiere/webui/util/GridTabDataBinder.java index 04d217b39f..deed332502 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/util/GridTabDataBinder.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/util/GridTabDataBinder.java @@ -12,6 +12,9 @@ *****************************************************************************/ package org.adempiere.webui.util; +import java.util.Properties; + +import org.adempiere.exceptions.AdempiereException; import org.adempiere.webui.editor.WEditor; import org.adempiere.webui.event.ValueChangeEvent; import org.adempiere.webui.event.ValueChangeListener; @@ -19,6 +22,8 @@ import org.compiere.model.GridField; import org.compiere.model.GridTab; import org.compiere.model.GridTable; import org.compiere.util.CLogger; +import org.compiere.util.Env; +import org.compiere.util.Trx; /** * Transfer data from editor to GridTab @@ -90,8 +95,33 @@ public class GridTabDataBinder implements ValueChangeListener { mTable.setValueAt (e.getNewValue(), row, col); else { - // mTable.setValueAt (e.getNewValue(), row, col, true); - mTable.setValueAt (e.getNewValue(), row, col); // -> dataStatusChanged -> dynamicDisplay + + Object newValue = e.getNewValue(); + Integer newValues[] = null; + + if (newValue instanceof Integer[]) + { + newValues = ((Integer[])newValue); + newValue = newValues[0]; + + if (newValues.length > 1) + { + Integer valuesCopy[] = new Integer[newValues.length - 1]; + System.arraycopy(newValues, 1, valuesCopy, 0, valuesCopy.length); + newValues = valuesCopy; + } + else + { + newValues = null; + } + } + else if (newValue instanceof Object[]) + { + logger.severe("Multiple values can only be processed for IDs (Integer)"); + throw new IllegalArgumentException("Multiple Selection values not available for this field. " + e.getPropertyName()); + } + + mTable.setValueAt (newValue, row, col); // Force Callout if ( e.getPropertyName().equals("S_ResourceAssignment_ID") ) { @@ -101,7 +131,86 @@ public class GridTabDataBinder implements ValueChangeListener { gridTab.processFieldChange(mField); // Dependencies & Callout } } + + if (newValues != null && newValues.length > 0) + { + // Save data, since record need to be used for generating clones. + if (!gridTab.dataSave(false)) + { + throw new AdempiereException("SaveError"); + } + + // Retrieve the current record ID + int recordId = gridTab.getKeyID(gridTab.getCurrentRow()); + + Trx trx = Trx.get(Trx.createTrxName(), true); + trx.start(); + try + { + saveMultipleRecords(Env.getCtx(), gridTab.getTableName(), e.getPropertyName(), recordId, newValues, trx.getTrxName()); + trx.commit(); + gridTab.dataRefreshAll(); + } + catch(Exception ex) + { + trx.rollback(); + logger.severe(ex.getMessage()); + throw new AdempiereException("SaveError"); + } + finally + { + trx.close(); + } + } } - } // ValueChange + } // ValueChange + + /************************************************************************** + * Save Multiple records - Clone a record and assign new values to each + * clone for a specific column. + * @param ctx context + * @param tableName Table Name + * @param columnName Column for which value need to be changed + * @param recordId Record to clone + * @param values Values to be assigned to clones for the specified column + * @param trxName Transaction + * @throws Exception If error is occured when loading the PO or saving clones + * + * @author ashley + */ + protected void saveMultipleRecords(Properties ctx, String tableName, + String columnName, int recordId, Integer[] values, + String trxName) throws Exception + { + if (values == null) + { + return ; + } + + int oldRow = gridTab.getCurrentRow(); + GridField lineField = gridTab.getField("Line"); + + for (int i = 0; i < values.length; i++) + { + if (!gridTab.dataNew(true)) + { + throw new IllegalStateException("Could not clone tab"); + } + + gridTab.setValue(columnName, values[i]); + + if (lineField != null) + { + gridTab.setValue(lineField, 0); + } + + if (!gridTab.dataSave(false)) + { + throw new IllegalStateException("Could not update tab"); + } + + gridTab.setCurrentRow(oldRow); + } + } }