From dc052e684759669354ad6c25ee96bf98e07d09ee Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Tue, 9 Dec 2008 09:15:50 +0000 Subject: [PATCH] * Implemented Personal Lock --- .../webui/component/CWindowToolbar.java | 26 +- .../webui/component/ToolBarButton.java | 10 + .../webui/panel/AbstractADWindowPanel.java | 87 +++- .../webui/window/WRecordAccessDialog.java | 391 ++++++++++++++++++ 4 files changed, 506 insertions(+), 8 deletions(-) create mode 100644 zkwebui/WEB-INF/src/org/adempiere/webui/window/WRecordAccessDialog.java 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 e624652b08..7a3c9364c8 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/CWindowToolbar.java @@ -27,6 +27,7 @@ import java.util.logging.Level; import org.adempiere.webui.LayoutUtils; import org.adempiere.webui.event.ToolbarListener; +import org.compiere.model.MRole; import org.compiere.util.CLogger; import org.compiere.util.Env; import org.compiere.util.Msg; @@ -58,7 +59,7 @@ public class CWindowToolbar extends FToolbar implements EventListener private ToolBarButton btnHelp, btnNew, btnCopy, btnDelete, btnDeleteSelection, btnSave; - private ToolBarButton btnRefresh, btnFind, btnAttachment; + private ToolBarButton btnRefresh, btnFind, btnLock, btnAttachment; private ToolBarButton btnGridToggle; @@ -81,6 +82,13 @@ public class CWindowToolbar extends FToolbar implements EventListener private Map keyMap = new HashMap(); private boolean embedded; + + // Elaine 2008/12/04 + /** Show Personal Lock */ + public boolean isPersonalLock = MRole.getDefault().isPersonalLock(); + /** Last Modifier of Action Event */ +// public int lastModifiers; + // public CWindowToolbar() { @@ -124,6 +132,7 @@ public class CWindowToolbar extends FToolbar implements EventListener btnArchive = createButton("Archive", "Archive", "Archive"); btnPrint = createButton("Print", "Print", "Print"); addSeparator(); + if (isPersonalLock) btnLock = createButton("Lock", "Lock", "Lock"); // Elaine 2008/12/04 btnZoomAcross = createButton("ZoomAcross", "ZoomAcross", "ZoomAcross"); btnActiveWorkflows = createButton("ActiveWorkflows", "WorkFlow", "WorkFlow"); btnRequests = createButton("Requests", "Request", "Request"); @@ -153,6 +162,7 @@ public class CWindowToolbar extends FToolbar implements EventListener btnRequests.setDisabled(false); // Elaine 2008/07/22 btnProductInfo.setDisabled(false); // Elaine 2008/07/22 btnArchive.setDisabled(false); // Elaine 2008/07/28 + btnLock.setDisabled(false); // Elaine 2008/12/04 configureKeyMap(); @@ -192,7 +202,8 @@ public class CWindowToolbar extends FToolbar implements EventListener return buttons.get(name); } - private void configureKeyMap() { + private void configureKeyMap() + { keyMap.put(KeyEvent.F1, btnHelp); keyMap.put(KeyEvent.F2, btnNew); keyMap.put(KeyEvent.F3, btnDelete); @@ -226,7 +237,7 @@ public class CWindowToolbar extends FToolbar implements EventListener } public void onEvent(Event event) - { + { String eventName = event.getName(); Component eventComp = event.getTarget(); @@ -397,7 +408,6 @@ public class CWindowToolbar extends FToolbar implements EventListener public void enableFind(boolean enabled) { this.btnFind.setDisabled(!enabled); - } public void enableGridToggle(boolean enabled) @@ -405,6 +415,14 @@ public class CWindowToolbar extends FToolbar implements EventListener btnGridToggle.setDisabled(!enabled); } + public void lock(boolean locked) + { + this.btnLock.setPressed(locked); + + String imgURL = "/images/"+ (this.btnLock.isPressed() ? "LockX" : "Lock") + (embedded ? "16.png" : "24.png"); + this.btnLock.setImage(imgURL); + } + public Event getEvent() { return event; diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/component/ToolBarButton.java b/zkwebui/WEB-INF/src/org/adempiere/webui/component/ToolBarButton.java index 5df587f1b7..cc50392f14 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/component/ToolBarButton.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/component/ToolBarButton.java @@ -28,6 +28,8 @@ public class ToolBarButton extends org.zkoss.zul.Toolbarbutton private String name; + private boolean pressed; // Elaine 2008/12/09 + public ToolBarButton() {} @Override @@ -42,6 +44,7 @@ public class ToolBarButton extends org.zkoss.zul.Toolbarbutton } public void setPressed(boolean pressed) { + this.pressed = pressed; // Elaine 2008/12/09 if (!isDisabled()) { if (pressed) { this.setSclass("depressed"); @@ -51,6 +54,13 @@ public class ToolBarButton extends org.zkoss.zul.Toolbarbutton } } } + + // Elaine 2008/12/09 + public boolean isPressed() + { + return pressed; + } + // public ToolBarButton(String name) { super(); diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java index 24d57c35ab..798b392019 100644 --- a/zkwebui/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/panel/AbstractADWindowPanel.java @@ -49,6 +49,7 @@ import org.adempiere.webui.part.AbstractUIPart; import org.adempiere.webui.session.SessionManager; import org.adempiere.webui.window.FDialog; import org.adempiere.webui.window.FindWindow; +import org.adempiere.webui.window.WRecordAccessDialog; import org.compiere.model.DataStatusEvent; import org.compiere.model.DataStatusListener; import org.compiere.model.GridField; @@ -73,11 +74,16 @@ import org.zkoss.zk.ui.Executions; 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.InputEvent; +import org.zkoss.zk.ui.event.KeyEvent; import org.zkoss.zk.ui.util.Clients; import org.zkoss.zul.Button; import org.zkoss.zul.Div; import org.zkoss.zul.Hbox; import org.zkoss.zul.Listitem; +import org.zkoss.zul.Menuitem; +import org.zkoss.zul.Menupopup; +import org.zkoss.zul.Toolbarbutton; /** * @@ -504,6 +510,72 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To { curTab.navigateRelative(-1); } + + // Elaine 2008/12/04 + private Menupopup m_popup = null; + private Menuitem m_lock = null; + private Menuitem m_access = null; + + /** + * @see ToolbarListener#onLock() + */ + public void onLock() + { + if (!toolbar.isPersonalLock) + return; + final int record_ID = curTab.getRecord_ID(); + if (record_ID == -1) // No Key + return; + + if(m_popup == null) + { + m_popup = new Menupopup(); + + m_lock = new Menuitem(Msg.translate(Env.getCtx(), "Lock")); + m_popup.appendChild(m_lock); + m_lock.addEventListener(Events.ON_CLICK, new EventListener() + { + public void onEvent(Event event) throws Exception + { + curTab.lock(Env.getCtx(), record_ID, !toolbar.getButton("Lock").isPressed()); + curTab.loadAttachments(); // reload + + toolbar.lock(curTab.isLocked()); + } + }); + + m_access = new Menuitem(Msg.translate(Env.getCtx(), "RecordAccessDialog")); + m_popup.appendChild(m_access); + m_access.addEventListener(Events.ON_CLICK, new EventListener() + { + public void onEvent(Event event) throws Exception + { + new WRecordAccessDialog(null, curTab.getAD_Table_ID(), record_ID); + + toolbar.lock(curTab.isLocked()); + } + }); + + m_popup.setPage(toolbar.getButton("Lock").getPage()); + } + m_popup.open(toolbar.getButton("Lock")); + + /* + // Control Pressed + if (toolbar.getEvent().getName() == Events.ON_CTRL_KEY) + { + new WRecordAccessDialog(null, curTab.getAD_Table_ID(), record_ID); + } + else + { + curTab.lock(Env.getCtx(), record_ID, !toolbar.getButton("Lock").isPressed()); + curTab.loadAttachments(); // reload + } + + toolbar.lock(curTab.isLocked()); + */ + } // lock + // /** * @see ToolbarListener#onHistoryRecords() @@ -736,7 +808,11 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To toolbar.getButton("HistoryRecords").setPressed(!curTab.isOnlyCurrentRows()); } toolbar.getButton("Find").setPressed(curTab.isQueryActive()); - //TODO: personal lock + + if (toolbar.isPersonalLock) + { + toolbar.lock(curTab.isLocked()); + } } public void dataStatusChanged(DataStatusEvent e) @@ -866,11 +942,14 @@ public abstract class AbstractADWindowPanel extends AbstractUIPart implements To } toolbar.getButton("Find").setPressed(curTab.isQueryActive()); + + // Elaine 2008/12/05 // Lock Indicator - /* if (m_isPersonalLock) + if (toolbar.isPersonalLock) { - aLock.setPressed(m_curTab.isLocked()); - }*/ + toolbar.lock(curTab.isLocked()); + } + // adTab.evaluate(e); diff --git a/zkwebui/WEB-INF/src/org/adempiere/webui/window/WRecordAccessDialog.java b/zkwebui/WEB-INF/src/org/adempiere/webui/window/WRecordAccessDialog.java new file mode 100644 index 0000000000..2c80a9682c --- /dev/null +++ b/zkwebui/WEB-INF/src/org/adempiere/webui/window/WRecordAccessDialog.java @@ -0,0 +1,391 @@ +/****************************************************************************** + * Copyright (C) 2008 Elaine Tan * + * Copyright (C) 2008 Idalica Corporation + * 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.window; + +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.util.ArrayList; +import java.util.logging.Level; + +import org.adempiere.webui.apps.AEnv; +import org.adempiere.webui.component.Checkbox; +import org.adempiere.webui.component.ConfirmPanel; +import org.adempiere.webui.component.Grid; +import org.adempiere.webui.component.GridFactory; +import org.adempiere.webui.component.Label; +import org.adempiere.webui.component.ListItem; +import org.adempiere.webui.component.Listbox; +import org.adempiere.webui.component.Row; +import org.adempiere.webui.component.Rows; +import org.adempiere.webui.component.Window; +import org.compiere.model.MRecordAccess; +import org.compiere.model.MRole; +import org.compiere.util.CLogger; +import org.compiere.util.DB; +import org.compiere.util.Env; +import org.compiere.util.Msg; +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.Toolbarbutton; + +/** + * Record Access Dialog + * @author Elaine + * @date December 9, 2008 + */ +public class WRecordAccessDialog extends Window implements EventListener +{ + private static final long serialVersionUID = 1L; + + /** + * Record Access Dialog + * @param owner owner + * @param AD_Table_ID table + * @param Record_ID record + */ + public WRecordAccessDialog(Window parent, int AD_Table_ID, int Record_ID) + { + super(); + setTitle(Msg.translate(Env.getCtx(), "RecordAccessDialog")); + setAttribute("modal", Boolean.TRUE); + setBorder("normal"); + setWidth("600px"); + setSizable(true); + + log.info("AD_Table_ID=" + AD_Table_ID + ", Record_ID=" + Record_ID); + m_AD_Table_ID = AD_Table_ID; + m_Record_ID = Record_ID; + try + { + dynInit(); + jbInit(); + } + catch (Exception e) + { + log.log(Level.SEVERE, "", e); + } + AEnv.showWindow(this); + } // RecordAccessDialog + + private int m_AD_Table_ID; + private int m_Record_ID; + private ArrayList m_recordAccesss = new ArrayList(); + private int m_currentRow = 0; + private MRecordAccess m_currentData = null; + private CLogger log = CLogger.getCLogger(getClass()); + + private Label roleLabel = new Label(Msg.translate(Env.getCtx(), "AD_Role_ID")); + private Listbox roleField = null; + private Checkbox cbActive = new Checkbox();//Msg.translate(Env.getCtx(), "IsActive")); + private Checkbox cbExclude = new Checkbox();//Msg.translate(Env.getCtx(), "IsExclude")); + private Checkbox cbReadOnly = new Checkbox();//Msg.translate(Env.getCtx(), "IsReadOnly")); + private Checkbox cbDependent = new Checkbox();//Msg.translate(Env.getCtx(), "IsDependentEntities")); + private Toolbarbutton bDelete = new Toolbarbutton();//AEnv.getButton("Delete"); + private Toolbarbutton bNew = new Toolbarbutton();//AEnv.getButton("New"); + private Label rowNoLabel = new Label(); + + private Toolbarbutton bUp = new Toolbarbutton();//AEnv.getButton("Previous"); + private Toolbarbutton bDown = new Toolbarbutton();//AEnv.getButton("Next"); + + private ConfirmPanel confirmPanel = new ConfirmPanel(true); + + /** + * Dynamic Init + */ + private void dynInit() + { + // Load Roles + String sql = MRole.getDefault().addAccessSQL( + "SELECT AD_Role_ID, Name FROM AD_Role ORDER BY 2", + "AD_Role", MRole.SQL_NOTQUALIFIED, MRole.SQL_RO); + roleField = new Listbox(DB.getKeyNamePairs(sql, false)); + roleField.setMold("select"); + + // Load Record Access for all roles + sql = "SELECT * FROM AD_Record_Access " + + "WHERE AD_Table_ID=? AND Record_ID=? AND AD_Client_ID=?"; + PreparedStatement pstmt = null; + try + { + pstmt = DB.prepareStatement(sql, null); + pstmt.setInt(1, m_AD_Table_ID); + pstmt.setInt(2, m_Record_ID); + pstmt.setInt(3, Env.getAD_Client_ID(Env.getCtx())); + ResultSet rs = pstmt.executeQuery(); + while (rs.next()) + m_recordAccesss.add(new MRecordAccess(Env.getCtx(), rs, null)); + rs.close(); + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + log.log(Level.SEVERE, sql, e); + } + try + { + if (pstmt != null) + pstmt.close(); + pstmt = null; + } + catch (Exception e) + { + pstmt = null; + } + log.fine("#" + m_recordAccesss.size()); + setLine(0, false); + } // dynInit + + /** + * Static Init + * @throws Exception + */ + private void jbInit() throws Exception + { + bDelete.setImage("/images/Delete16.png"); + bDelete.setTooltiptext(Msg.getMsg(Env.getCtx(), "Delete")); + bNew.setImage("/images/New16.png"); + bNew.setTooltiptext(Msg.getMsg(Env.getCtx(), "New")); + bUp.setImage("/images/Previous16.png"); + bUp.setTooltiptext(Msg.getMsg(Env.getCtx(), "Previous")); + bDown.setImage("/images/Next16.png"); + bDown.setTooltiptext(Msg.getMsg(Env.getCtx(), "Next")); + + cbActive.setText(Msg.translate(Env.getCtx(), "IsActive")); + cbExclude.setText(Msg.translate(Env.getCtx(), "IsExclude")); + cbReadOnly.setText(Msg.translate(Env.getCtx(), "IsReadOnly")); + cbDependent.setText(Msg.translate(Env.getCtx(), "IsDependentEntities")); + + Grid grid = GridFactory.newGridLayout(); + this.appendChild(grid); + + Rows rows = new Rows(); + grid.appendChild(rows); + + Row row = new Row(); + rows.appendChild(row); + row.appendChild(bUp); + row.appendChild(new Label()); + row.appendChild(new Label()); + row.appendChild(new Label()); + row.appendChild(new Label()); + row.appendChild(new Label()); + row.appendChild(bNew); + + row = new Row(); + rows.appendChild(row); + row.appendChild(roleLabel); + row.appendChild(roleField); + row.appendChild(cbActive); + row.appendChild(cbExclude); + row.appendChild(cbReadOnly); + row.appendChild(cbDependent); + row.appendChild(bDelete); + + row = new Row(); + rows.appendChild(row); + row.appendChild(bDown); + row.appendChild(new Label()); + row.appendChild(new Label()); + row.appendChild(new Label()); + row.appendChild(new Label()); + row.appendChild(new Label()); + row.appendChild(rowNoLabel); + + row = new Row(); + rows.appendChild(row); + row.setSpans("7"); + Div div = new Div(); + div.setAlign("right"); + div.appendChild(confirmPanel); + row.appendChild(div); + + bUp.addEventListener(Events.ON_CLICK, this); + bDown.addEventListener(Events.ON_CLICK, this); + bDelete.addEventListener(Events.ON_CLICK, this); + bNew.addEventListener(Events.ON_CLICK, this); + confirmPanel.addActionListener(this); + } // jbInit + + /** + * Set Line + * @param rowDelta delta to current row + * @param newRecord new + */ + private void setLine (int rowDelta, boolean newRecord) + { + log.fine("delta=" + rowDelta + ", new=" + newRecord + + " - currentRow=" + m_currentRow + ", size=" + m_recordAccesss.size()); + int maxIndex = 0; + // nothing defined + if (m_recordAccesss.size() == 0) + { + m_currentRow = 0; + maxIndex = 0; + newRecord = true; + setLine(null); + } + else if (newRecord) + { + m_currentRow = m_recordAccesss.size(); + maxIndex = m_currentRow; + setLine(null); + } + else + { + m_currentRow += rowDelta; + maxIndex = m_recordAccesss.size() - 1; + if (m_currentRow < 0) + m_currentRow = 0; + else if (m_currentRow > maxIndex) + m_currentRow = maxIndex; + // + MRecordAccess ra = (MRecordAccess)m_recordAccesss.get(m_currentRow); + setLine(ra); + } + // Label + StringBuffer txt = new StringBuffer(); + if (newRecord) + txt.append("+"); + txt.append(m_currentRow+1).append("/").append(maxIndex+1); + rowNoLabel.setText(txt.toString()); + // set up/down + bUp.setDisabled(m_currentRow <= 0); + bDown.setDisabled(m_currentRow >= maxIndex); + } // setLine + + /** + * Set Selection + * @param ra record access + */ + private void setLine (MRecordAccess ra) + { + int AD_Role_ID = 0; + boolean active = true; + boolean exclude = true; + boolean readonly = false; + boolean dependent = false; + // + if (ra != null) + { + AD_Role_ID = ra.getAD_Role_ID(); + active = ra.isActive(); + exclude = ra.isExclude(); + readonly = ra.isReadOnly(); + dependent = ra.isDependentEntities(); + } + cbActive.setSelected(active); + cbExclude.setSelected(exclude); + cbReadOnly.setSelected(readonly); + cbDependent.setSelected(dependent); + bDelete.setDisabled(ra == null); + // + ListItem selection = null; + for (int i = 0; i < roleField.getItemCount(); i++) + { + ListItem pp = roleField.getItemAtIndex(i); + if (pp != null && (Integer)pp.getValue() != null) + { + if(((Integer)pp.getValue()).intValue() == AD_Role_ID) + selection = pp; + } + } + if (selection != null && ra != null) + { + roleField.setSelectedItem(selection); + m_currentData = ra; + log.fine("" + ra); + } + else + m_currentData = null; + } // setLine + + /** + * Action Listener + * @param e event + */ + public void onEvent(Event e) throws Exception + { + if (e.getTarget() == bUp) + setLine(-1, false); + else if (e.getTarget() == bDown) + setLine(+1, false); + else if (e.getTarget() == bNew) + setLine(0, true); + else + { + if (e.getTarget() == bDelete) + cmd_delete(); + else if (e.getTarget().getId().equals(ConfirmPanel.A_OK)) + { + if (!cmd_save()) + return; + } + dispose(); + } + } + + /** + * Save Command + * @return true if saved + */ + private boolean cmd_save() + { + ListItem pp = roleField.getSelectedItem(); + if (pp == null) + return false; + int AD_Role_ID = ((Integer)pp.getValue()).intValue(); + // + boolean isActive = cbActive.isSelected(); + boolean isExclude = cbExclude.isSelected(); + boolean isReadOnly = cbReadOnly.isSelected(); + boolean isDependentEntities = cbDependent.isSelected(); + // + if (m_currentData == null) + { + m_currentData = new MRecordAccess (Env.getCtx(), AD_Role_ID, m_AD_Table_ID, m_Record_ID, null); + m_recordAccesss.add(m_currentData); + m_currentRow = m_recordAccesss.size()-1; + } + m_currentData.setIsActive(isActive); + m_currentData.setIsExclude(isExclude); + m_currentData.setIsReadOnly(isReadOnly); + m_currentData.setIsDependentEntities(isDependentEntities); + boolean success = m_currentData.save(); + // + log.fine("Success=" + success); + return success; + } // cmd_save + + /** + * Delete Command + * @return true if deleted + */ + private boolean cmd_delete() + { + boolean success = false; + if (m_currentData == null) + log.log(Level.SEVERE, "No data"); + else + { + success = m_currentData.delete(true); + m_currentData = null; + m_recordAccesss.remove(m_currentRow); + log.fine("Success=" + success); + } + return success; + } // cmd_delete +}