diff --git a/client/src/org/compiere/apps/APanel.java b/client/src/org/compiere/apps/APanel.java index 989583a1a9..815f048b5c 100644 --- a/client/src/org/compiere/apps/APanel.java +++ b/client/src/org/compiere/apps/APanel.java @@ -159,9 +159,11 @@ public final class APanel extends CPanel } // jbInit private AppsAction aPrevious, aNext, aParent, aDetail, aFirst, aLast, - aNew, aCopy, aDelete, aIgnore, aPrint, + aNew, aCopy, aDelete, aPrint, aRefresh, aHistory, aAttachment, aChat, aMulti, aFind, aWorkflow, aZoomAcross, aRequest, aWinSize, aArchive; + /** Ignore Button */ + public AppsAction aIgnore; /** Save Button */ public AppsAction aSave; /** Private Lock Button */ @@ -1077,6 +1079,11 @@ public final class APanel extends CPanel m_curAPanelTab = (APanelTab)m_curWinTab.getSelectedComponent(); m_curAPanelTab.registerAPanel(this); m_curAPanelTab.loadData(); + // Consider that APanelTab (e.g. VSortTab) is not navigable - teo_sarca [ 1705444 ] + aFirst.setEnabled(false); + aPrevious.setEnabled(false); + aNext.setEnabled(false); + aLast.setEnabled(false); } else // Cur Tab Setting { @@ -1644,6 +1651,11 @@ public final class APanel extends CPanel private void cmd_ignore() { m_curGC.stopEditor(false); + // Ignore changes in APanelTab (e.g. VSortTab) - teo_sarca [ 1705429 ] + if (m_curAPanelTab != null) + { + m_curAPanelTab.loadData(); + } m_curTab.dataIgnore(); m_curGC.dynamicDisplay(0); } // cmd_ignore diff --git a/client/src/org/compiere/grid/VSortTab.java b/client/src/org/compiere/grid/VSortTab.java index 4ca20d8937..d606d3bc74 100644 --- a/client/src/org/compiere/grid/VSortTab.java +++ b/client/src/org/compiere/grid/VSortTab.java @@ -18,10 +18,16 @@ package org.compiere.grid; import java.awt.*; import java.awt.event.*; +import java.net.*; import java.sql.*; +import java.util.*; import java.util.logging.*; + import javax.swing.*; +import javax.swing.event.*; + import org.compiere.apps.*; +import org.compiere.model.MRole; import org.compiere.swing.*; import org.compiere.util.*; @@ -29,10 +35,12 @@ import org.compiere.util.*; * Tab to maintain Order/Sequence * * @author Jorg Janke + * @author Teo Sarca * @version $Id: VSortTab.java,v 1.2 2006/07/30 00:51:28 jjanke Exp $ */ -public class VSortTab extends CPanel implements APanelTab, ActionListener +public class VSortTab extends CPanel implements APanelTab { + /** * Tab Order Constructor * @@ -57,19 +65,19 @@ public class VSortTab extends CPanel implements APanelTab, ActionListener } } // VSortTab + /** Logger */ + static CLogger log = CLogger.getCLogger(VSortTab.class); private int m_WindowNo; + private int m_AD_Table_ID; private String m_TableName = null; private String m_ColumnSortName= null; private String m_ColumnYesNoName = null; private String m_KeyColumnName = null; private String m_IdentifierColumnName = null; private boolean m_IdentifierTranslated = false; - private String m_ParentColumnName = null; - private boolean m_saveSequence = false; + private String m_ParentColumnName = null; private APanel m_aPanel = null; - /** Logger */ - private static CLogger log = CLogger.getCLogger(VSortTab.class); // UI variables private GridBagLayout mainLayout = new GridBagLayout(); @@ -80,62 +88,45 @@ public class VSortTab extends CPanel implements APanelTab, ActionListener private CButton bUp = new CButton(); private CButton bDown = new CButton(); // - private DefaultListModel noModel = new DefaultListModel(); - private DefaultListModel yesModel = new DefaultListModel(); - private JList noList = new JList(noModel); - private JList yesList = new JList(yesModel); + DefaultListModel noModel = new DefaultListModel() + { + public void addElement(Object obj) + { + Object[] elements = toArray(); + Arrays.sort(elements); + int index = Arrays.binarySearch(elements, obj); + if (index < 0) + index = -1 * index - 1; + if (index > elements.length) + super.addElement(obj); + else + super.add(index, obj); + } + + public void add(int index, Object obj) + { + addElement(obj); + } + }; + DefaultListModel yesModel = new DefaultListModel(); + DefaultListCellRenderer listRenderer = new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value != null && value instanceof ListItem && !((ListItem)value).isUpdateable()) { + Font f = c.getFont(); + c.setFont(f.deriveFont(f.getStyle() | Font.ITALIC)); + c.setFocusable(false); + } + return c; + } + + }; + JList noList = new JList(noModel); + JList yesList = new JList(yesModel); private JScrollPane noPane = new JScrollPane(noList); private JScrollPane yesPane = new JScrollPane(yesList); - /** - * Static Layout - * @throws Exception - */ - private void jbInit() throws Exception - { - this.setLayout(mainLayout); - // - noLabel.setText("No"); - yesLabel.setText("Yes"); - // - bAdd.setIcon(Env.getImageIcon("Detail24.gif")); - bAdd.setMargin(new Insets(2, 2, 2, 2)); - bAdd.addActionListener(this); - bRemove.setIcon(Env.getImageIcon("Parent24.gif")); - bRemove.setMargin(new Insets(2, 2, 2, 2)); - bRemove.addActionListener(this); - bUp.setIcon(Env.getImageIcon("Previous24.gif")); - bUp.setMargin(new Insets(2, 2, 2, 2)); - bUp.addActionListener(this); - bDown.setIcon(Env.getImageIcon("Next24.gif")); - bDown.setMargin(new Insets(2, 2, 2, 2)); - bDown.addActionListener(this); - // - // yesList.setBorder(BorderFactory.createLoweredBevelBorder()); - yesPane.setPreferredSize(new Dimension(200, 300)); - yesList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - // noList.setBorder(BorderFactory.createLoweredBevelBorder()); - noPane.setPreferredSize(new Dimension(200, 300)); - noList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); - // - this.add(noLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); - this.add(yesLabel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); - this.add(bDown, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); - this.add(noPane, new GridBagConstraints(0, 1, 1, 3, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); - this.add(yesPane, new GridBagConstraints(2, 1, 1, 3, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); - this.add(bUp, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); - this.add(bRemove, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); - this.add(bAdd, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0 - ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); - } // jbInit - /** * Dyanamic Init * @param AD_Table_ID Table No @@ -144,6 +135,7 @@ public class VSortTab extends CPanel implements APanelTab, ActionListener */ private void dynInit (int AD_Table_ID, int AD_ColumnSortOrder_ID, int AD_ColumnSortYesNo_ID) { + m_AD_Table_ID = AD_Table_ID; String sql = "SELECT t.TableName, c.AD_Column_ID, c.ColumnName, e.Name," // 1..4 + "c.IsParent, c.IsKey, c.IsIdentifier, c.IsTranslated " // 4..8 + "FROM AD_Table t, AD_Column c, AD_Element e " @@ -219,127 +211,142 @@ public class VSortTab extends CPanel implements APanelTab, ActionListener log.log(Level.SEVERE, sql.toString(), e); } noLabel.setText(Msg.getMsg(Env.getCtx(), "Available")); - log.info(m_ColumnSortName); + log.fine(m_ColumnSortName); } // dynInit /** - * Register APanel - * @param panel panel + * Static Layout + * @throws Exception */ - public void registerAPanel (APanel panel) + private void jbInit() throws Exception { - m_aPanel = panel; - } // registerAPanel + this.setLayout(mainLayout); + // + noLabel.setText("No"); + yesLabel.setText("Yes"); - /** - * Unregister APanel - */ - public void unregisterPanel () - { - saveData(); - m_aPanel = null; - } // dispoase + for (MouseMotionListener mml : noList.getMouseMotionListeners()) + noList.removeMouseMotionListener(mml); + for (MouseMotionListener mml : yesList.getMouseMotionListeners()) + yesList.removeMouseMotionListener(mml); - /************************************************************************** - * ActionPerformed - * @param e event - */ - public void actionPerformed(ActionEvent e) - { - // ADD -> - if (e.getSource() == bAdd) + MouseListener mouseListener = new MouseAdapter() { - Object objects[] = noList.getSelectedValues(); - for (int i = 0; i < objects.length; i++) + public void mouseClicked(MouseEvent me) { - if (objects[i] != null && noModel.removeElement(objects[i])) + if (me.getClickCount() > 1) { - log.config("Add=" + objects[i]); - yesModel.addElement(objects[i]); - yesList.setSelectedValue(objects[i], true); - m_saveSequence = true; + JList list = (JList)me.getComponent(); + Point p = me.getPoint(); + int index = list.locationToIndex(p); + if (index > -1 && list.getCellBounds(index, index).contains(p)) + migrateValueAcrossLists(me); } } - } - // REMOVE <- - else if (e.getSource() == bRemove) - { - Object objects[] = yesList.getSelectedValues(); - for (int i = 0; i < objects.length; i++) - { - if (objects[i] != null && yesModel.removeElement(objects[i])) - { - log.config("Remove=" + objects[i]); - noModel.addElement(objects[i]); - m_saveSequence = true; - } - } - } - // UP | - else if (e.getSource() == bUp) - { - int indexes[] = yesList.getSelectedIndices(); - Object objects[] = yesList.getSelectedValues(); - for (int i = 0; i < indexes.length; i++) - { - if (indexes[i] > 0) - { - Object obj = yesList.getSelectedValue(); - log.config("Up=" + obj); - if (yesModel.removeElement(obj)) - yesModel.insertElementAt(obj, indexes[i]-1); - m_saveSequence = true; - indexes[i]--; - } - } - yesList.setSelectedIndices(indexes); - } - // DOWN | - else if (e.getSource() == bDown) - { - int indexes[] = yesList.getSelectedIndices(); - for (int i = 0; i < indexes.length; i++) - { - if (indexes[i] != -1 && indexes[i] < yesModel.size()-1) - { - Object obj = yesList.getSelectedValue(); - log.config("Down=" + obj); - if (yesModel.removeElement(obj)) - yesModel.insertElementAt(obj, indexes[i]+1); - m_saveSequence = true; - indexes[i]++; - } - } - yesList.setSelectedIndices(indexes); - } + }; + yesList.addMouseListener(mouseListener); + noList.addMouseListener(mouseListener); + // + yesList.setCellRenderer(listRenderer); + noList.setCellRenderer(listRenderer); - // Enable explicit Save - if (m_saveSequence && m_aPanel != null) - m_aPanel.aSave.setEnabled(true); + ActionListener actionListener = new ActionListener() + { + public void actionPerformed(ActionEvent ae) + { + migrateValueAcrossLists(ae); + } + }; - } // actionPerformed + bAdd.setIcon(Env.getImageIcon("Detail24.gif")); + bAdd.setMargin(new Insets(2, 2, 2, 2)); + bAdd.addActionListener(actionListener); - - /************************************************************************** - * Load Data + bRemove.setIcon(Env.getImageIcon("Parent24.gif")); + bRemove.setMargin(new Insets(2, 2, 2, 2)); + bRemove.addActionListener(actionListener); + + MouseInputListener crossListMouseListener = new DragListener(); + yesList.addMouseListener(crossListMouseListener); + yesList.addMouseMotionListener(crossListMouseListener); + noList.addMouseListener(crossListMouseListener); + noList.addMouseMotionListener(crossListMouseListener); + + actionListener = new ActionListener() + { + public void actionPerformed(ActionEvent ae) + { + migrateValueWithinYesList(ae); + } + }; + + bUp.setIcon(Env.getImageIcon("Previous24.gif")); + bUp.setMargin(new Insets(2, 2, 2, 2)); + bUp.addActionListener(actionListener); + + bDown.setIcon(Env.getImageIcon("Next24.gif")); + bDown.setMargin(new Insets(2, 2, 2, 2)); + bDown.addActionListener(actionListener); + + MouseMotionListener yesListMouseMotionListener = new MouseMotionAdapter() + { + public void mouseDragged(MouseEvent me) + { + JList list = (JList)me.getComponent(); + Point p = me.getPoint(); + int index = list.locationToIndex(p); + if (index > -1 && list.getCellBounds(index, index).contains(p)) + migrateValueWithinYesList(me); + } + }; + yesList.addMouseMotionListener(yesListMouseMotionListener); + + yesPane.setPreferredSize(new Dimension(200, 300)); + yesList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + noPane.setPreferredSize(new Dimension(200, 300)); + noList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); + + this.add(noLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + this.add(yesLabel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); + this.add(bDown, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); + this.add(noPane, new GridBagConstraints(0, 1, 1, 3, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); + this.add(yesPane, new GridBagConstraints(2, 1, 1, 3, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); + this.add(bUp, new GridBagConstraints(3, 1, 1, 1, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); + this.add(bAdd, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); + this.add(bRemove, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0 + ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0)); + } // jbInit + + /* (non-Javadoc) + * @see org.compiere.grid.APanelTab#loadData() */ public void loadData() { yesModel.removeAllElements(); noModel.removeAllElements(); - + + boolean isReadWrite = true; // SELECT t.AD_Field_ID,t.Name,t.SeqNo,t.IsDisplayed FROM AD_Field t WHERE t.AD_Tab_ID=? ORDER BY 4 DESC,3,2 // SELECT t.AD_PrintFormatItem_ID,t.Name,t.SeqNo,t.IsPrinted FROM AD_PrintFormatItem t WHERE t.AD_PrintFormat_ID=? ORDER BY 4 DESC,3,2 // SELECT t.AD_PrintFormatItem_ID,t.Name,t.SortNo,t.IsOrderBy FROM AD_PrintFormatItem t WHERE t.AD_PrintFormat_ID=? ORDER BY 4 DESC,3,2 StringBuffer sql = new StringBuffer(); // Columns sql.append("SELECT t.").append(m_KeyColumnName) // 1 - .append(m_IdentifierTranslated ? ",tt." : ",t.") - .append(m_IdentifierColumnName) // 2 - .append(",t.").append(m_ColumnSortName); // 3 + .append(m_IdentifierTranslated ? ",tt." : ",t.") + .append(m_IdentifierColumnName) // 2 + .append(",t.").append(m_ColumnSortName) // 3 + .append(", t.AD_Client_ID, t.AD_Org_ID"); // 4, 5 if (m_ColumnYesNoName != null) - sql.append(",t.").append(m_ColumnYesNoName); // 4 + sql.append(",t.").append(m_ColumnYesNoName); // 6 // Tables sql.append(" FROM ").append(m_TableName).append( " t"); if (m_IdentifierTranslated) @@ -348,14 +355,14 @@ public class VSortTab extends CPanel implements APanelTab, ActionListener sql.append(" WHERE t.").append(m_ParentColumnName).append("=?"); if (m_IdentifierTranslated) sql.append(" AND t.").append(m_KeyColumnName).append("=tt.").append(m_KeyColumnName) - .append(" AND tt.AD_Language=?"); + .append(" AND tt.AD_Language=?"); // Order sql.append(" ORDER BY "); if (m_ColumnYesNoName != null) - sql.append("4 DESC,"); // t.IsDisplayed DESC + sql.append("6 DESC,"); // t.IsDisplayed DESC sql.append("3,2"); // t.SeqNo, tt.Name int ID = Env.getContextAsInt(Env.getCtx(), m_WindowNo, m_ParentColumnName); - log.config(sql.toString() + " - ID=" + ID); + log.fine(sql.toString() + " - ID=" + ID); try { PreparedStatement pstmt = DB.prepareStatement(sql.toString(), null); @@ -369,14 +376,21 @@ public class VSortTab extends CPanel implements APanelTab, ActionListener String name = rs.getString(2); int seq = rs.getInt(3); boolean isYes = seq != 0; + int AD_Client_ID = rs.getInt(4); + int AD_Org_ID = rs.getInt(5); if (m_ColumnYesNoName != null) - isYes = rs.getString(4).equals("Y"); + isYes = rs.getString(6).equals("Y"); + // - KeyNamePair pp = new KeyNamePair(key, name); + ListItem pp = new ListItem(key, name, seq, isYes, AD_Client_ID, AD_Org_ID); if (isYes) yesModel.addElement(pp); else noModel.addElement(pp); + // If the one item from "Yes" list is readonly make entire tab readonly + if (isYes && !pp.isUpdateable()) { + isReadWrite = false; + } } rs.close(); pstmt.close(); @@ -385,45 +399,412 @@ public class VSortTab extends CPanel implements APanelTab, ActionListener { log.log(Level.SEVERE, sql.toString(), e); } - m_saveSequence = false; + + setIsChanged(false); + bAdd.setEnabled(isReadWrite); + bRemove.setEnabled(isReadWrite); + bUp.setEnabled(isReadWrite); + bDown.setEnabled(isReadWrite); + yesList.setEnabled(isReadWrite); + noList.setEnabled(isReadWrite); } // loadData /** - * Save Data + * Set tab change status. + * @param value + */ + private void setIsChanged(boolean value) { + if (m_aPanel != null) { + m_aPanel.aSave.setEnabled(value); + m_aPanel.aIgnore.setEnabled(value); + } + } + + /** + * @param event + */ + void migrateValueAcrossLists (AWTEvent event) + { + Object source = event.getSource(); + Object[] selObjects = (source == bAdd || source == noList) ? + noList.getSelectedValues() : yesList.getSelectedValues(); + for (int i = 0; i < selObjects.length; i++) + { + ListItem selObject = (ListItem)selObjects[i]; + if (selObject == null || !selObject.isUpdateable()) + continue; + + DefaultListModel lmFrom = (source == bAdd || source == noList) ? + noModel : yesModel; + DefaultListModel lmTo = (lmFrom == yesModel) ? noModel : yesModel; + lmFrom.removeElement(selObject); + lmTo.addElement(selObject); + + JList list = (source == bAdd || source == noList) ? + yesList : noList; + list.setSelectedValue(selObject, true); + + // Enable explicit Save + setIsChanged(true); + } + } // migrateValueAcrossLists + + /** + * Move within Yes List + * @param event event + */ + void migrateValueWithinYesList (AWTEvent event) + { + Object[] selObjects = yesList.getSelectedValues(); + if (selObjects == null) + return; + int length = selObjects.length; + if (length == 0) + return; +// Object selObject = selObjects[0]; +// if (selObject == null) +// return; + // + int[] indices = yesList.getSelectedIndices(); + // + boolean change = false; + // + Object source = event.getSource(); + if (source == bUp) + { + for (int i = 0; i < length; i++) { + ListItem selObject = (ListItem)selObjects[i]; + int index = indices[i]; + if (index == 0) + break; + ListItem newObject = (ListItem)yesModel.getElementAt(index - 1); + if (!selObject.isUpdateable() || !newObject.isUpdateable()) + break; + yesModel.setElementAt(newObject, index); + yesModel.setElementAt(selObject, index - 1); + indices[i] = index - 1; + change = true; + } + } // up + + else if (source == bDown) + { + for (int i = length - 1; i >= 0; i--) { + ListItem selObject = (ListItem)selObjects[i]; + int index = indices[i]; + if (index >= yesModel.size () - 1) + break; + ListItem newObject = (ListItem)yesModel.getElementAt(index + 1); + if (!selObject.isUpdateable() || !newObject.isUpdateable()) + break; + yesModel.setElementAt(newObject, index); + yesModel.setElementAt(selObject, index + 1); + yesList.setSelectedIndex(index + 1); + indices[i] = index + 1; + change = true; + } + } // down + + else if (source == yesList) + { + // see org.compiere.grid.VSortTab.DragListener#mouseReleased(MouseEvent) + } + else + log.severe("Unknown source: " + source); + // + if (change) { + yesList.setSelectedIndices(indices); + setIsChanged(true); + } + } // migrateValueWithinYesList + + /* (non-Javadoc) + * @see org.compiere.grid.APanelTab#registerAPanel(APanel) + */ + public void registerAPanel (APanel panel) + { + m_aPanel = panel; + } // registerAPanel + + + /** (non-Javadoc) + * @see org.compiere.grid.APanelTab#saveData() */ public void saveData() { - if (!m_saveSequence) + if (!m_aPanel.aSave.isEnabled()) return; - log.info(""); + log.fine(""); + boolean ok = true; + StringBuffer info = new StringBuffer(); StringBuffer sql = null; // noList - Set SortColumn to null and optional YesNo Column to 'N' for (int i = 0; i < noModel.getSize(); i++) { - KeyNamePair pp = (KeyNamePair)noModel.getElementAt(i); + ListItem pp = (ListItem)noModel.getElementAt(i); + if (!pp.isUpdateable()) + continue; + if(pp.getSortNo() == 0 && (m_ColumnYesNoName == null || !pp.isYes())) + continue; // no changes + // sql = new StringBuffer(); sql.append("UPDATE ").append(m_TableName) - .append(" SET ").append(m_ColumnSortName).append("=0"); + .append(" SET ").append(m_ColumnSortName).append("=0"); if (m_ColumnYesNoName != null) sql.append(",").append(m_ColumnYesNoName).append("='N'"); sql.append(" WHERE ").append(m_KeyColumnName).append("=").append(pp.getKey()); - if (DB.executeUpdate(sql.toString(), null) != 1) + if (DB.executeUpdate(sql.toString(), null) == 1) { + pp.setSortNo(0); + pp.setIsYes(false); + } + else { + ok = false; + if (info.length() > 0) + info.append(", "); + info.append(pp.getName()); log.log(Level.SEVERE, "NoModel - Not updated: " + m_KeyColumnName + "=" + pp.getKey()); + } } // yesList - Set SortColumn to value and optional YesNo Column to 'Y' + int index = 0; for (int i = 0; i < yesModel.getSize(); i++) { - KeyNamePair pp = (KeyNamePair)yesModel.getElementAt(i); + ListItem pp = (ListItem)yesModel.getElementAt(i); + if (!pp.isUpdateable()) + continue; + index += 10; + if(pp.getSortNo() == index && (m_ColumnYesNoName == null || pp.isYes())) + continue; // no changes + // sql = new StringBuffer(); sql.append("UPDATE ").append(m_TableName) - .append(" SET ").append(m_ColumnSortName).append("=").append(i+1).append("0"); // 10 steps + .append(" SET ").append(m_ColumnSortName).append("=").append(index); if (m_ColumnYesNoName != null) sql.append(",").append(m_ColumnYesNoName).append("='Y'"); sql.append(" WHERE ").append(m_KeyColumnName).append("=").append(pp.getKey()); - if (DB.executeUpdate(sql.toString(), null) != 1) + if (DB.executeUpdate(sql.toString(), null) == 1) { + pp.setSortNo(index); + pp.setIsYes(true); + } + else { + ok = false; + if (info.length() > 0) + info.append(", "); + info.append(pp.getName()); log.log(Level.SEVERE, "YesModel - Not updated: " + m_KeyColumnName + "=" + pp.getKey()); + } + } + // + if (ok) { + setIsChanged(false); + } + else { + ADialog.error(m_WindowNo, null, "SaveError", info.toString()); } } // saveData + /* (non-Javadoc) + * @see org.compiere.grid.APanelTab#unregisterPanel() + */ + public void unregisterPanel () + { + saveData(); + m_aPanel = null; + } // dispoase + + /** + * List Item + * @author Teo Sarca + */ + private class ListItem extends NamePair { + private int m_key; + private int m_AD_Client_ID; + private int m_AD_Org_ID; + /** Initial seq number */ + private int m_sortNo; + /** Initial selection flag */ + private boolean m_isYes; + private boolean m_updateable; + + public ListItem(int key, String name, int sortNo, boolean isYes, int AD_Client_ID, int AD_Org_ID) { + super(name); + this.m_key = key; + this.m_AD_Client_ID = AD_Client_ID; + this.m_AD_Org_ID = AD_Org_ID; + this.m_sortNo = sortNo; + this.m_isYes = isYes; + this.m_updateable = MRole.getDefault().canUpdate(m_AD_Client_ID, m_AD_Org_ID, m_AD_Table_ID, m_key, false); + } + public int getKey() { + return m_key; + } + public void setSortNo(int sortNo) { + m_sortNo = sortNo; + } + public int getSortNo() { + return m_sortNo; + } + public void setIsYes(boolean value) { + m_isYes = value; + } + public boolean isYes() { + return m_isYes; + } + public int getAD_Client_ID() { + return m_AD_Client_ID; + } + public int getAD_Org_ID() { + return m_AD_Org_ID; + } + public boolean isUpdateable() { + return m_updateable; + } + @Override + public String getID() { + return m_key != -1 ? String.valueOf(m_key) : null; + } + @Override + public int hashCode() { + return m_key; + } + @Override + public boolean equals(Object obj) + { + if (obj instanceof ListItem) + { + ListItem li = (ListItem)obj; + return + li.getKey() == m_key + && li.getName() != null + && li.getName().equals(getName()) + && li.getAD_Client_ID() == m_AD_Client_ID + && li.getAD_Org_ID() == m_AD_Org_ID; + } + return false; + } // equals + } + + /** + * @author eslatis + * + */ + private class DragListener extends MouseInputAdapter + { + + /** + * Creates a VSortTab.DragListener. + */ + public DragListener() + { + URL url = VSortTab.class.getResource(cursorName); + Toolkit toolkit = Toolkit.getDefaultToolkit(); + Image image = toolkit.getImage(url); + customCursor = toolkit.createCustomCursor(image, new Point(0, 0), "Howdy"); + } + + /** The cursorName. */ + private String cursorName = "/org/compiere/images/DragCursor32.gif"; + + /** StartList */ + private JList startList = null; + + /** The startModel. */ + private DefaultListModel startModel = null; + + /** The selObject. */ + private Object selObject = null; + + private boolean moved = false; + + /** The customCursor. */ + private Cursor customCursor; + + /* (non-Javadoc) + * @see javax.swing.event.MouseInputAdapter#mousePressed(java.awt.event.MouseEvent) + */ + public void mousePressed(MouseEvent me) + { + JList list = (JList)me.getComponent(); + Point p = me.getPoint(); + int index = list.locationToIndex(p); + if (index > -1 && list.getCellBounds(index, index).contains(p)) + { + startList = list; + startModel = (list == noList) ? noModel : yesModel; + selObject = list.getModel().getElementAt(index); + } + if (list == noList) + yesList.clearSelection(); + else + noList.clearSelection(); + moved = false; + } // mousePressed + + /* (non-Javadoc) + * @see javax.swing.event.MouseInputAdapter#mouseDragged(java.awt.event.MouseEvent) + */ + public void mouseDragged(MouseEvent me) + { + if (selObject == null || !((ListItem)selObject).isUpdateable()) { + moved = false; + return; + } + moved = true; + if (getCursor() != customCursor) + setCursor(customCursor); + } // mouseDragged + + /* (non-Javadoc) + * @see javax.swing.event.MouseInputAdapter#mouseReleased(java.awt.event.MouseEvent) + */ + public void mouseReleased(MouseEvent me) + { + if (startModel != null && moved) + { + Point p = me.getPoint(); + + JList endList = yesList; + DefaultListModel endModel = yesModel; + + if (me.getComponent() == yesList) + { + if (!yesList.contains (p)) + { + endList = noList; + endModel = noModel; + } + } + else + { + if (noList.contains (p)) + { + setCursor(Cursor.getDefaultCursor()); + moved = false; + return; // move within noList + } + p = SwingUtilities.convertPoint (noList, p, yesList); + } + int index = endList.locationToIndex(p); + if (index > -1) // && endList.getCellBounds(index, index).contains(p)) + { + startModel.removeElement(selObject); + endModel.add(index, selObject); + // + startList.clearSelection(); + endList.clearSelection(); + endList.setSelectedValue(selObject, true); + // + setIsChanged(true); + } + } + + startList = null; + startModel = null; + selObject = null; + moved = false; + setCursor(Cursor.getDefaultCursor()); + } // mouseReleased + } + } // VSortTab diff --git a/client/src/org/compiere/images/DragCursor32.gif b/client/src/org/compiere/images/DragCursor32.gif new file mode 100644 index 0000000000..94a646189d Binary files /dev/null and b/client/src/org/compiere/images/DragCursor32.gif differ