/****************************************************************************** * Product: Adempiere ERP & CRM Smart Business Solution * * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or modify it * * under the terms version 2 of the GNU General Public License as published * * by the Free Software Foundation. This program is distributed in the hope * * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * * with this program; if not, write to the Free Software Foundation, Inc., * * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * * For the text or an alternative of this public license, you may reach us * * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA * * or via info@compiere.org or http://www.compiere.org/license.html * *****************************************************************************/ package org.compiere.apps.search; import java.awt.BorderLayout; import java.awt.Component; import java.awt.ComponentOrientation; import java.awt.Dimension; import java.awt.Frame; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.math.BigDecimal; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.sql.Timestamp; import java.util.ArrayList; import java.util.Arrays; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import java.util.logging.Level; import java.util.regex.Pattern; import javax.swing.AbstractAction; import javax.swing.Action; import javax.swing.Box; import javax.swing.DefaultComboBoxModel; import javax.swing.ImageIcon; import javax.swing.InputMap; import javax.swing.JButton; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.JToolBar; import javax.swing.KeyStroke; import javax.swing.ListSelectionModel; import javax.swing.event.CellEditorListener; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.TableColumnModelEvent; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import org.compiere.apps.ADialog; import org.compiere.apps.AEnv; import org.compiere.apps.ConfirmPanel; import org.compiere.apps.StatusBar; import org.compiere.grid.ed.VEditor; import org.compiere.grid.ed.VEditorFactory; import org.compiere.grid.ed.VLookup; import org.compiere.model.DataStatusEvent; import org.compiere.model.DataStatusListener; import org.compiere.model.GridField; import org.compiere.model.GridFieldVO; import org.compiere.model.GridTab; import org.compiere.model.MColumn; import org.compiere.model.MLookupFactory; import org.compiere.model.MProduct; import org.compiere.model.MQuery; import org.compiere.model.MRole; import org.compiere.model.MUserQuery; import org.compiere.model.X_AD_Column; import org.compiere.swing.CButton; import org.compiere.swing.CComboBox; import org.compiere.swing.CDialog; import org.compiere.swing.CLabel; import org.compiere.swing.CPanel; import org.compiere.swing.CTabbedPane; import org.compiere.swing.CTable; import org.compiere.swing.CTextField; import org.compiere.util.AdempiereSystemError; import org.compiere.util.CLogger; import org.compiere.util.DB; import org.compiere.util.DisplayType; import org.compiere.util.Env; import org.compiere.util.Language; import org.compiere.util.Msg; import org.compiere.util.Util; import org.compiere.util.ValueNamePair; import org.omidp.util.LocaleUtil; /** * Find/Search Records. * Based on AD_Find for persistency, query is build to restrict info * * @author Jorg Janke * @version $Id: Find.java,v 1.3 2006/07/30 00:51:27 jjanke Exp $ * * @author Teo Sarca, www.arhipac.ro * <li>BF [ 2564070 ] Saving user queries can produce unnecessary db errors */ public final class Find extends CDialog implements ActionListener, ChangeListener, DataStatusListener { /** * */ private static final long serialVersionUID = -5064336990363669996L; private int m_AD_Tab_ID; /** * Find Constructor * @param owner Frame Dialog Owner * @param targetWindowNo WindowNo of target window * @param title * @param AD_Table_ID * @param tableName * @param whereExtended * @param findFields * @param minRecords number of minimum records */ public Find (Frame owner, int targetWindowNo, String title, int AD_Tab_ID, int AD_Table_ID, String tableName, String whereExtended, GridField[] findFields, int minRecords) { super(owner, Msg.getMsg(Env.getCtx(), "Find") + ": " + title, true); super.applyComponentOrientation(ComponentOrientation.getOrientation(Language.getLoginLanguage().getLocale())); log.info(title); // m_targetWindowNo = targetWindowNo; m_AD_Tab_ID = AD_Tab_ID; //red1 new field for UserQuery [ 1798539 ] m_AD_Table_ID = AD_Table_ID; m_tableName = tableName; m_whereExtended = whereExtended; m_findFields = findFields; // m_query = new MQuery (tableName); m_query.addRestriction(Env.parseContext(Env.getCtx(), m_targetWindowNo, whereExtended, false)); // Required for Column Validation Env.setContext(Env.getCtx(), m_targetWindowNo, "Find_Table_ID", m_AD_Table_ID); // Context for Advanced Search Grid is WINDOW_FIND Env.setContext(Env.getCtx(), Env.WINDOW_FIND, "Find_Table_ID", m_AD_Table_ID); // try { jbInit(); initFind(); if (m_total < minRecords) { dispose(); return; } } catch(Exception e) { log.log(Level.SEVERE, "Find", e); } // this.getRootPane().setDefaultButton(confirmPanelS.getOKButton()); AEnv.showCenterWindow(owner, this); } // Find /** Target Window No */ private int m_targetWindowNo; /** Table ID */ private int m_AD_Table_ID; /** Table Name */ private String m_tableName; /** Where */ private String m_whereExtended; /** Search Fields */ private GridField[] m_findFields; /** Resulting query */ private MQuery m_query = null; /** Is cancel ? */ private boolean m_isCancel = false; // teo_sarca [ 1708717 ] /** Logger */ private static CLogger log = CLogger.getCLogger(Find.class); /** Number of records */ private int m_total; private PreparedStatement m_pstmt; // private boolean hasValue = false; private boolean hasDocNo = false; private boolean hasName = false; private boolean hasDescription = false; /** Line in Simple Content */ private int m_sLine = 6; /** List of VEditors */ private ArrayList<VEditor> m_sEditors = new ArrayList<VEditor>(); /** Target Fields with AD_Column_ID as key */ private Hashtable<Integer,GridField> m_targetFields = new Hashtable<Integer,GridField>(); /** For Grid Controller */ public static final int TABNO = 99; /** Length of Fields on first tab */ public static final int FIELDLENGTH = 20; /** Reference ID for Yes/No */ public static final int AD_REFERENCE_ID_YESNO = 319; // private CPanel southPanel = new CPanel(); private BorderLayout southLayout = new BorderLayout(); private StatusBar statusBar = new StatusBar(); private CTabbedPane tabbedPane = new CTabbedPane(); private CPanel advancedPanel = new CPanel(); private BorderLayout advancedLayout = new BorderLayout(); private ConfirmPanel confirmPanelA = new ConfirmPanel(true, true, false, false, false, false, true); private CButton bIgnore = new CButton(); private JToolBar toolBar = new JToolBar(); private CComboBox fQueryName = new CComboBox(); private CButton bSave = new CButton(); private CButton bNew = new CButton(); private CButton bDelete = new CButton(); private ConfirmPanel confirmPanelS = new ConfirmPanel(true); private BorderLayout simpleLayout = new BorderLayout(); private CPanel scontentPanel = new CPanel(); private GridBagLayout scontentLayout = new GridBagLayout(); private CPanel simplePanel = new CPanel(); private CLabel valueLabel = new CLabel(); private CLabel nameLabel = new CLabel(); private CLabel descriptionLabel = new CLabel(); private CTextField valueField = new CTextField(); private CTextField nameField = new CTextField(); private CTextField descriptionField = new CTextField(); private CLabel docNoLabel = new CLabel(); private CTextField docNoField = new CTextField(); private Component spaceE; private Component spaceN; private Component spaceW; private Component spaceS; private JScrollPane advancedScrollPane = new JScrollPane(); private CTable advancedTable = new CTable() { private static final long serialVersionUID = -6201749159307529032L; public boolean isCellEditable(int row, int column) { boolean editable = ( column == INDEX_COLUMNNAME || column == INDEX_OPERATOR || column == INDEX_ANDOR || column == INDEX_LEFTBRACKET || column == INDEX_RIGHTBRACKET ); if (!editable && row >= 0) { String columnName = null; Object value = getModel().getValueAt(row, INDEX_COLUMNNAME); if (value != null) { if (value instanceof ValueNamePair) columnName = ((ValueNamePair)value).getValue(); else columnName = value.toString(); } // Create Editor editable = getTargetMField(columnName) != null; } if ( column == INDEX_ANDOR && row == 0 ) editable = false; return editable; } public void columnMoved(TableColumnModelEvent e) { if (isEditing()) { cellEditor.stopCellEditing(); } super.columnMoved(e); } public void columnMarginChanged(ChangeEvent e) { if (isEditing()) { cellEditor.stopCellEditing(); } super.columnMarginChanged(e); } }; /** Index AndOr = 0 */ public static final int INDEX_ANDOR = 0; /** Index LeftBracket = 1 */ public static final int INDEX_LEFTBRACKET = 1; /** Index ColumnName = 2 */ public static final int INDEX_COLUMNNAME = 2; /** Index Operator = 3 */ public static final int INDEX_OPERATOR = 3; /** Index Value = 4 */ public static final int INDEX_VALUE = 4; /** Index Value2 = 5 */ public static final int INDEX_VALUE2 = 5; /** Index RightBracket = 6 */ public static final int INDEX_RIGHTBRACKET = 6; /** Advanced Search Column */ public CComboBox columns = null; /** Advanced Search Operators */ public CComboBox operators = null; private MUserQuery[] userQueries; private ValueNamePair[] columnValueNamePairs; private CComboBox leftBrackets; private CComboBox rightBrackets; private CComboBox andOr; private static final String FIELD_SEPARATOR = "<^>"; private static final String SEGMENT_SEPARATOR = "<~>"; /** * Static Init. * <pre> * tabbedPane * simplePanel * scontentPanel * confirmPanelS * advancedPanel * toolBar * GC * confirmPanelA * southPanel * statusBar * </pre> * @throws Exception */ private void jbInit() throws Exception { //omid LocaleUtil.applyComponentOrientation(southPanel, scontentPanel); spaceE = Box.createHorizontalStrut(8); spaceN = Box.createVerticalStrut(8); spaceW = Box.createHorizontalStrut(8); spaceS = Box.createVerticalStrut(8); bIgnore.setIcon(new ImageIcon(org.compiere.Adempiere.class.getResource("images/Ignore24.gif"))); bIgnore.setMargin(new Insets(2, 2, 2, 2)); bIgnore.setToolTipText(Msg.getMsg(Env.getCtx(),"Ignore")); bIgnore.addActionListener(this); fQueryName.setToolTipText (Msg.getMsg(Env.getCtx(),"QueryName")); fQueryName.setEditable(true); fQueryName.addActionListener(this); bSave.setIcon(new ImageIcon(org.compiere.Adempiere.class.getResource("images/Save24.gif"))); bSave.setMargin(new Insets(2, 2, 2, 2)); bSave.setToolTipText(Msg.getMsg(Env.getCtx(),"Save")); bSave.addActionListener(this); bNew.setIcon(new ImageIcon(org.compiere.Adempiere.class.getResource("images/New24.gif"))); bNew.setMargin(new Insets(2, 2, 2, 2)); bNew.setToolTipText(Msg.getMsg(Env.getCtx(),"New")); bNew.addActionListener(this); bDelete.setIcon(new ImageIcon(org.compiere.Adempiere.class.getResource("images/Delete24.gif"))); bDelete.setMargin(new Insets(2, 2, 2, 2)); bDelete.setToolTipText(Msg.getMsg(Env.getCtx(),"Delete")); bDelete.addActionListener(this); // southPanel.setLayout(southLayout); valueLabel.setLabelFor(valueField); valueLabel.setText(Msg.translate(Env.getCtx(),"Value")); nameLabel.setLabelFor(nameField); nameLabel.setText(Msg.translate(Env.getCtx(),"Name")); descriptionLabel.setLabelFor(descriptionField); descriptionLabel.setText(Msg.translate(Env.getCtx(),"Description")); valueField.setText("%"); valueField.setColumns(FIELDLENGTH); nameField.setText("%"); nameField.setColumns(FIELDLENGTH); descriptionField.setText("%"); descriptionField.setColumns(FIELDLENGTH); scontentPanel.setToolTipText(Msg.getMsg(Env.getCtx(),"FindTip")); docNoLabel.setLabelFor(docNoField); docNoLabel.setText(Msg.translate(Env.getCtx(),"DocumentNo")); docNoField.setText("%"); docNoField.setColumns(FIELDLENGTH); advancedScrollPane.setPreferredSize(new Dimension(540, 410)); southPanel.add(statusBar, BorderLayout.SOUTH); this.getContentPane().add(southPanel, BorderLayout.SOUTH); // // scontentPanel.setLayout(scontentLayout); simplePanel.setLayout(simpleLayout); simplePanel.add(confirmPanelS, BorderLayout.SOUTH); simplePanel.add(scontentPanel, BorderLayout.CENTER); scontentPanel.add(valueLabel, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0 ,GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(7, 5, 0, 5), 0, 0)); scontentPanel.add(nameLabel, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0 ,GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(7, 5, 0, 5), 0, 0)); scontentPanel.add(descriptionLabel, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0 ,GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(7, 5, 5, 5), 0, 0)); scontentPanel.add(valueField, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0 ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 0, 5), 0, 0)); scontentPanel.add(descriptionField, new GridBagConstraints(2, 4, 1, 1, 0.0, 0.0 ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0)); scontentPanel.add(docNoLabel, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0 ,GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(7, 5, 0, 5), 0, 0)); scontentPanel.add(nameField, new GridBagConstraints(2, 3, 1, 1, 0.0, 0.0 ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 0, 5), 0, 0)); scontentPanel.add(docNoField, new GridBagConstraints(2, 2, 1, 1, 0.0, 0.0 ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 0, 5), 0, 0)); // scontentPanel.add(spaceE, new GridBagConstraints(3, 3, 1, 1, 0.0, 0.0 ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); scontentPanel.add(spaceN, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0 ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); scontentPanel.add(spaceW, new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0 ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); scontentPanel.add(spaceS, new GridBagConstraints(2, 15, 1, 1, 0.0, 0.0 ,GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(10, 10, 10, 10), 0, 0)); // // tabbedPane.add(simplePanel, Msg.getMsg(Env.getCtx(),"Find")); tabbedPane.add(simplePanel, Msg.getMsg(Env.getCtx(),"Find")); // toolBar.add(bIgnore, null); toolBar.addSeparator(); toolBar.add(bNew, null); toolBar.add(bDelete, null); toolBar.add(fQueryName, null); toolBar.add(bSave, null); advancedPanel.setLayout(advancedLayout); advancedPanel.add(toolBar, BorderLayout.NORTH); advancedPanel.add(confirmPanelA, BorderLayout.SOUTH); advancedPanel.add(advancedScrollPane, BorderLayout.CENTER); advancedScrollPane.getViewport().add(advancedTable, null); // tabbedPane.add(advancedPanel, Msg.getMsg(Env.getCtx(),"Advanced")); tabbedPane.add(advancedPanel, Msg.getMsg(Env.getCtx(),"Advanced")); // this.getContentPane().add(tabbedPane, BorderLayout.CENTER); // confirmPanelA.addActionListener(this); confirmPanelS.addActionListener(this); // JButton b = ConfirmPanel.createNewButton(true); confirmPanelS.addComponent (b); b.addActionListener(this); // teo_sarca, [ 1670847 ] Find dialog: closing and canceling need same functionality addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { cmd_cancel(); } }); } // jbInit /** * Dynamic Init.6 * Set up GridController */ private void initFind() { log.config(""); // Get Info from target Tab for (int i = 0; i < m_findFields.length; i++) { GridField mField = m_findFields[i]; String columnName = mField.getColumnName(); // Make Yes-No searchable as list if (mField.getVO().displayType == DisplayType.YesNo) { GridFieldVO vo = mField.getVO(); GridFieldVO ynvo = vo.clone(vo.ctx, vo.WindowNo, vo.TabNo, vo.AD_Window_ID, vo.AD_Tab_ID, vo.tabReadOnly); ynvo.IsDisplayed = true; ynvo.displayType = DisplayType.List; ynvo.AD_Reference_Value_ID = AD_REFERENCE_ID_YESNO; ynvo.lookupInfo = MLookupFactory.getLookupInfo (ynvo.ctx, ynvo.WindowNo, ynvo.AD_Column_ID, ynvo.displayType, Env.getLanguage(ynvo.ctx), ynvo.ColumnName, ynvo.AD_Reference_Value_ID, ynvo.IsParent, ynvo.ValidationCode); ynvo.lookupInfo.InfoFactoryClass = ynvo.InfoFactoryClass; GridField ynfield = new GridField(ynvo); // replace the original field by the YN List field m_findFields[i] = ynfield; mField = ynfield; } // Make Buttons searchable if ( mField.getVO().displayType == DisplayType.Button ) { GridFieldVO vo = mField.getVO(); if ( vo.AD_Reference_Value_ID > 0 ) { GridFieldVO postedvo = vo.clone(vo.ctx, vo.WindowNo, vo.TabNo, vo.AD_Window_ID, vo.AD_Tab_ID, vo.tabReadOnly); postedvo.IsDisplayed = true; postedvo.displayType = DisplayType.List; postedvo.lookupInfo = MLookupFactory.getLookupInfo (postedvo.ctx, postedvo.WindowNo, postedvo.AD_Column_ID, postedvo.displayType, Env.getLanguage(postedvo.ctx), postedvo.ColumnName, postedvo.AD_Reference_Value_ID, postedvo.IsParent, postedvo.ValidationCode); postedvo.lookupInfo.InfoFactoryClass = postedvo.InfoFactoryClass; GridField postedfield = new GridField(postedvo); // replace the original field by the Posted List field m_findFields[i] = postedfield; mField = postedfield; } } /** metas: teo_sarca: Specify exactly which are the search fields - http://sourceforge.net/projects/adempiere/forums/forum/610548/topic/3736214 if (columnName.equals("Value")) hasValue = true; else if (columnName.equals("Name")) hasName = true; else if (columnName.equals("DocumentNo")) hasDocNo = true; else if (columnName.equals("Description")) hasDescription = true; else /**/ if (mField.isSelectionColumn()) addSelectionColumn (mField); /** metas: teo_sarca: Specify exactly which are the search fields - http://sourceforge.net/projects/adempiere/forums/forum/610548/topic/3736214 else if (columnName.indexOf("Name") != -1) addSelectionColumn (mField); /**/ // TargetFields m_targetFields.put (new Integer(mField.getAD_Column_ID()), mField); } // for all target tab fields // Disable simple query fields valueLabel.setVisible(hasValue); valueField.setVisible(hasValue); if (hasValue) valueField.addActionListener(this); docNoLabel.setVisible(hasDocNo); docNoField.setVisible(hasDocNo); if (hasDocNo) docNoField.addActionListener(this); nameLabel.setVisible(hasName); nameField.setVisible(hasName); if (hasName) nameField.addActionListener(this); descriptionLabel.setVisible(hasDescription); descriptionField.setVisible(hasDescription); if (hasDescription) descriptionField.addActionListener(this); // Get Total m_total = getNoOfRecords(null, false); setStatusDB (m_total); statusBar.setStatusLine(""); tabbedPane.addChangeListener(this); // Better Labels for OK/Cancel confirmPanelA.getOKButton().setToolTipText(Msg.getMsg(Env.getCtx(),"QueryEnter")); confirmPanelA.getCancelButton().setToolTipText(Msg.getMsg(Env.getCtx(),"QueryCancel")); confirmPanelS.getOKButton().setToolTipText(Msg.getMsg(Env.getCtx(),"QueryEnter")); confirmPanelS.getCancelButton().setToolTipText(Msg.getMsg(Env.getCtx(),"QueryCancel")); } // initFind /** * Add Selection Column to first Tab * @param mField field */ private void addSelectionColumn (GridField mField) { log.config(mField.getHeader()); int displayLength = mField.getDisplayLength(); if (displayLength > FIELDLENGTH) mField.setDisplayLength(FIELDLENGTH); else displayLength = 0; // Editor VEditor editor = null; if (mField.isLookup()) { VLookup vl = new VLookup(mField.getColumnName(), false, false, true, mField.getLookup()); //setting mField to avoid NPE vl.setField(mField); vl.setName(mField.getColumnName()); editor = vl; } else { editor = VEditorFactory.getEditor(mField, false); editor.setMandatory(false); editor.setReadWrite(true); } // Add action listener to custom text fields - teo_sarca [ 1709292 ] if (editor instanceof CTextField) { ((CTextField)editor).addActionListener(this); } CLabel label = VEditorFactory.getLabel(mField); // if (displayLength > 0) // set it back mField.setDisplayLength(displayLength); // m_sLine++; if (label != null) // may be null for Y/N scontentPanel.add(label, new GridBagConstraints(1, m_sLine, 1, 1, 0.0, 0.0 ,GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(7, 5, 5, 5), 0, 0)); scontentPanel.add((Component)editor, new GridBagConstraints(2, m_sLine, 1, 1, 0.0, 0.0 ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0)); m_sEditors.add(editor); } // addSelectionColumn /** * Init Find GridController */ private void initFindAdvanced() { log.config(""); advancedTable.setModel(new DefaultTableModel(0, 7)); advancedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); advancedTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); advancedTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); TableCellRenderer renderer = new ProxyRenderer(advancedTable.getDefaultRenderer(Object.class)); advancedTable.setDefaultRenderer(Object.class, renderer); InputMap im = advancedTable.getInputMap(JTable.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0); final Action tabAction = advancedTable.getActionMap().get(im.get(tab)); Action tabActionWrapper = new AbstractAction() { private static final long serialVersionUID = -6868476640719619801L; public void actionPerformed(ActionEvent e) { tabAction.actionPerformed(e); JTable table = (JTable)e.getSource(); table.requestFocusInWindow(); } }; advancedTable.getActionMap().put(im.get(tab), tabActionWrapper); KeyStroke shiftTab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_MASK); final Action shiftTabAction = advancedTable.getActionMap().get(im.get(shiftTab)); Action shiftTabActionWrapper = new AbstractAction() { private static final long serialVersionUID = 5493691483070046620L; public void actionPerformed(ActionEvent e) { shiftTabAction.actionPerformed(e); JTable table = (JTable)e.getSource(); table.requestFocusInWindow(); } }; advancedTable.getActionMap().put(im.get(shiftTab), shiftTabActionWrapper); // 0 = Columns ArrayList<ValueNamePair> items = new ArrayList<ValueNamePair>(); for (int c = 0; c < m_findFields.length; c++) { GridField field = m_findFields[c]; String columnName = field.getColumnName(); String header = field.getHeader(); if (header == null || header.length() == 0) { header = Msg.translate(Env.getCtx(), columnName); if (header == null || header.length() == 0) continue; } if (field.isKey()) header += (" (ID)"); ValueNamePair pp = new ValueNamePair(columnName, header); // System.out.println(pp + " = " + field); items.add(pp); } columnValueNamePairs = new ValueNamePair[items.size()]; items.toArray(columnValueNamePairs); Arrays.sort(columnValueNamePairs); // sort alpha columns = new CComboBox(columnValueNamePairs); columns.addActionListener(this); TableColumn tc = advancedTable.getColumnModel().getColumn(INDEX_COLUMNNAME); tc.setPreferredWidth(120); FindCellEditor dce = new FindCellEditor(columns); dce.addCellEditorListener(new CellEditorListener() { public void editingCanceled(ChangeEvent ce) { } public void editingStopped(ChangeEvent ce) { int col = advancedTable.getSelectedColumn(); int row = advancedTable.getSelectedRow(); if (col == INDEX_COLUMNNAME && row >= 0) { advancedTable.setValueAt(null, row, INDEX_VALUE); advancedTable.setValueAt(null, row, INDEX_VALUE2); } } }); tc.setCellEditor(dce); tc.setHeaderValue(Msg.translate(Env.getCtx(), "AD_Column_ID")); // 0 = And/Or andOr = new CComboBox(new String[] {"",Msg.getMsg(Env.getCtx(),"AND"),Msg.getMsg(Env.getCtx(), "OR")}); tc = advancedTable.getColumnModel().getColumn(INDEX_ANDOR); tc.setPreferredWidth(45); dce = new FindCellEditor(andOr); tc.setCellEditor(dce); tc.setHeaderValue(Msg.getMsg(Env.getCtx(), "And/Or")); // 1 = Left Bracket leftBrackets = new CComboBox(new String[] {"","(","((","((("}); tc = advancedTable.getColumnModel().getColumn(INDEX_LEFTBRACKET); tc.setPreferredWidth(25); dce = new FindCellEditor(leftBrackets); tc.setCellEditor(dce); tc.setHeaderValue("("); // 3 = Operators operators = new CComboBox(MQuery.OPERATORS); tc = advancedTable.getColumnModel().getColumn(INDEX_OPERATOR); tc.setPreferredWidth(55); dce = new FindCellEditor(operators); tc.setCellEditor(dce); tc.setHeaderValue(Msg.getMsg(Env.getCtx(), "Operator")); // 4 = QueryValue tc = advancedTable.getColumnModel().getColumn(INDEX_VALUE); FindValueEditor fve = new FindValueEditor(this, false); tc.setCellEditor(fve); tc.setPreferredWidth(120); tc.setCellRenderer(new ProxyRenderer(new FindValueRenderer(this, false))); tc.setHeaderValue(Msg.getMsg(Env.getCtx(), "QueryValue")); // 5 = QueryValue2 tc = advancedTable.getColumnModel().getColumn(INDEX_VALUE2); tc.setPreferredWidth(120); fve = new FindValueEditor(this, true); tc.setCellEditor(fve); tc.setCellRenderer(new ProxyRenderer(new FindValueRenderer(this, false))); tc.setHeaderValue(Msg.getMsg(Env.getCtx(), "QueryValue2")); // 6 = Right Bracket rightBrackets = new CComboBox(new String[] {"",")","))",")))"}); tc = advancedTable.getColumnModel().getColumn(INDEX_RIGHTBRACKET); tc.setPreferredWidth(25); dce = new FindCellEditor(rightBrackets); tc.setCellEditor(dce); tc.setHeaderValue(")"); // phib: disabled auto-completion as it causes date fields to have to be entered twice //AutoCompletion.enable(columns); //AutoCompletion.enable(operators); //user query userQueries = MUserQuery.get(Env.getCtx(), m_AD_Tab_ID); String[] queries = new String[userQueries.length]; for (int i = 0; i < userQueries.length; i++) queries[i] = userQueries[i].getName(); fQueryName.setModel(new DefaultComboBoxModel(queries)); fQueryName.setValue(""); // No Row - Create one cmd_new(); } // initFindAdvanced /** * Dispose window */ public void dispose() { log.config(""); // Find SQL if (m_pstmt != null) { try { m_pstmt.close(); } catch (SQLException e) {} } m_pstmt = null; // Remove action listener from custom fields - teo_sarca [ 1709292 ] for (VEditor editor : m_sEditors) { if (editor instanceof CTextField) ((CTextField)editor).removeActionListener(this); } // TargetFields if (m_targetFields != null) m_targetFields.clear(); m_targetFields = null; // removeAll(); super.dispose(); } // dispose /************************************************************************** * Action Listener * @param e ActionEvent */ public void actionPerformed (ActionEvent e) { log.info(e.getActionCommand()); // if (e.getActionCommand().equals(ConfirmPanel.A_CANCEL)) cmd_cancel(); else if (e.getActionCommand().equals(ConfirmPanel.A_REFRESH)) cmd_refresh(); // else if (e.getActionCommand().equals(ConfirmPanel.A_NEW)) { m_query = MQuery.getNoRecordQuery(m_tableName, true); m_total = 0; dispose(); } // else if (e.getSource() == bIgnore) cmd_ignore(); else if (e.getSource() == bNew) cmd_new(); else if (e.getSource() == bSave) cmd_save(true); else if (e.getSource() == bDelete) cmd_delete(); // else if (e.getSource() == columns) { String columnName = null; Object selected = columns.getSelectedItem(); if (selected != null) { if (selected instanceof ValueNamePair) { ValueNamePair column = (ValueNamePair)selected; columnName = column.getValue(); } else { columnName = selected.toString(); } } if (columnName != null) { log.config("Column: " + columnName); if (columnName.endsWith("_ID") || columnName.endsWith("_Acct")) operators.setModel(new DefaultComboBoxModel(MQuery.OPERATORS_ID)); else if (columnName.startsWith("Is")) operators.setModel(new DefaultComboBoxModel(MQuery.OPERATORS_YN)); else operators.setModel(new DefaultComboBoxModel(MQuery.OPERATORS)); } } else if (e.getSource() == fQueryName) { Object o = fQueryName.getSelectedItem(); if (userQueries != null && o != null) { String selected = o.toString(); for (int i = 0; i < userQueries.length; i++) { if (userQueries[i].getName().equals(selected)) { parseUserQuery(userQueries[i]); return; } } } } else // ConfirmPanel.A_OK and enter in fields { if (e.getSource() == confirmPanelA.getOKButton()) cmd_ok_Advanced(); else if (e.getSource() == confirmPanelS.getOKButton()) cmd_ok_Simple(); else if (e.getSource() instanceof JTextField && tabbedPane.getSelectedIndex() == 0) cmd_ok_Simple(); } } // actionPerformed /** * Parse delimited string into user query * Old field sequence: column, operator, value, value to * New field sequence: column, operator, value, value to, and/or, left brackets, right brackets * @param userQuery */ private void parseUserQuery(MUserQuery userQuery) { String code = userQuery.getCode(); log.fine("Parse user query: " + code); String[] segments = code.split(Pattern.quote(SEGMENT_SEPARATOR),-1); advancedTable.stopEditor(true); DefaultTableModel model = (DefaultTableModel)advancedTable.getModel(); int cnt = model.getRowCount(); for (int i = cnt - 1; i >=0; i--) model.removeRow(i); for (int i = 0; i < segments.length; i++) { String[] fields = segments[i].split(Pattern.quote(FIELD_SEPARATOR)); model.addRow(new Object[] {"","", null, MQuery.OPERATORS[MQuery.EQUAL_INDEX], null, null, ""}); String columnName = null; for (int j = 0; j < fields.length; j++) { // column if (j == 0 ) { for (ValueNamePair vnp : columnValueNamePairs) { if (vnp.getValue().equals(fields[j])) { model.setValueAt(vnp, i, INDEX_COLUMNNAME); columnName = fields[j]; break; } } } // operator else if (j == 1) { for (ValueNamePair vnp : MQuery.OPERATORS) { if (vnp.getValue().equals(fields[j])) { model.setValueAt(vnp, i, INDEX_OPERATOR); break; } } } // value else if ( j == 2 && fields[j].length() > 0 ) { GridField field = getTargetMField(columnName); Object value = parseString(field, fields[j]); model.setValueAt(value, i, INDEX_VALUE); } // value 2 else if ( j == 3 && fields[j].length() > 0 ) { GridField field = getTargetMField(columnName); Object value = parseString(field, fields[j]); model.setValueAt(value, i, INDEX_VALUE2); } // and/or else if (j == 4 && fields[j].length() > 0 ) { if ( i != 0 ) model.setValueAt(fields[j], i, INDEX_ANDOR); } else if ( j == 5 && fields[j].length() > 0 ) { model.setValueAt(fields[j], i, INDEX_LEFTBRACKET); } else if ( j == 6 && fields[j].length() > 0 ) { model.setValueAt(fields[j], i, INDEX_RIGHTBRACKET); } } } advancedTable.invalidate(); } /** * Change Listener (tab change) * @param e ChangeEbent */ public void stateChanged(ChangeEvent e) { // log.info( "Find.stateChanged"); if (tabbedPane.getSelectedIndex() == 0) this.getRootPane().setDefaultButton(confirmPanelS.getOKButton()); else { initFindAdvanced(); this.getRootPane().setDefaultButton(confirmPanelA.getOKButton()); advancedTable.requestFocusInWindow(); } } // stateChanged /** * Simple OK Button pressed */ private void cmd_ok_Simple() { // Create Query String m_query = new MQuery(m_tableName); m_query.addRestriction(Env.parseContext(Env.getCtx(), m_targetWindowNo, m_whereExtended, false)); if (hasValue && !valueField.getText().equals("%") && valueField.getText().length() != 0) { String value = valueField.getText().toUpperCase(); if (!value.endsWith("%")) value += "%"; m_query.addRestriction("UPPER(Value)", MQuery.LIKE, value, valueLabel.getText(), value); } // if (hasDocNo && !docNoField.getText().equals("%") && docNoField.getText().length() != 0) { String value = docNoField.getText().toUpperCase(); if (!value.endsWith("%")) value += "%"; m_query.addRestriction("UPPER(DocumentNo)", MQuery.LIKE, value, docNoLabel.getText(), value); } // if ((hasName) && !nameField.getText().equals("%") && nameField.getText().length() != 0) { String value = nameField.getText().toUpperCase(); if (!value.endsWith("%")) value += "%"; m_query.addRestriction("UPPER(Name)", MQuery.LIKE, value, nameLabel.getText(), value); } // if (hasDescription && !descriptionField.getText().equals("%") && descriptionField.getText().length() != 0) { String value = descriptionField.getText().toUpperCase(); if (!value.endsWith("%")) value += "%"; m_query.addRestriction("UPPER(Description)", MQuery.LIKE, value, descriptionLabel.getText(), value); } // Special Editors for (int i = 0; i < m_sEditors.size(); i++) { VEditor ved = (VEditor)m_sEditors.get(i); Object value = ved.getValue(); if (value != null && value.toString().length() > 0) { String ColumnName = ((Component)ved).getName (); log.fine(ColumnName + "=" + value); // globalqss - Carlos Ruiz - 20060711 // fix a bug with virtualColumn + isSelectionColumn not yielding results GridField field = getTargetMField(ColumnName); boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID()); String ColumnSQL = field.getColumnSQL(false); // // Be more permissive for String columns if (isSearchLike(field)) { String valueStr = value.toString().toUpperCase(); if (!valueStr.endsWith("%")) valueStr += "%"; // ColumnSQL = "UPPER("+ColumnSQL+")"; value = valueStr; } // if (value.toString().indexOf('%') != -1) m_query.addRestriction(ColumnSQL, MQuery.LIKE, value, ColumnName, ved.getDisplay()); else if (isProductCategoryField && value instanceof Integer) m_query.addRestriction(getSubCategoryWhereClause(((Integer) value).intValue())); else m_query.addRestriction(ColumnSQL, MQuery.EQUAL, value, ColumnName, ved.getDisplay()); /* if (value.toString().indexOf('%') != -1) m_query.addRestriction(ColumnName, MQuery.LIKE, value, ColumnName, ved.getDisplay()); else m_query.addRestriction(ColumnName, MQuery.EQUAL, value, ColumnName, ved.getDisplay()); */ // end globalqss patch } } // editors m_isCancel = false; // teo_sarca [ 1708717 ] // Test for no records if (getNoOfRecords(m_query, true) != 0) dispose(); } // cmd_ok_Simple /** * Advanced OK Button pressed */ private void cmd_ok_Advanced() { m_isCancel = false; // teo_sarca [ 1708717 ] // save pending if (bSave.isEnabled()) cmd_save(false); if (getNoOfRecords(m_query, true) != 0) dispose(); } // cmd_ok_Advanced /** * Cancel Button pressed */ private void cmd_cancel() { advancedTable.stopEditor(false); log.info(""); m_query = null; m_total = 999999; m_isCancel = true; // teo_sarca [ 1708717 ] dispose(); } // cmd_ok /** * Ignore */ private void cmd_ignore() { log.info(""); } // cmd_ignore /** * New record */ private void cmd_new() { advancedTable.stopEditor(true); DefaultTableModel model = (DefaultTableModel)advancedTable.getModel(); int rows = model.getRowCount(); model.addRow(new Object[] {rows == 0 ? "" : "AND","", null, MQuery.OPERATORS[MQuery.EQUAL_INDEX], null, null,""}); advancedTable.requestFocusInWindow(); } // cmd_new /** * Save (Advanced) */ private void cmd_save(boolean saveQuery) { advancedTable.stopEditor(true); // m_query = new MQuery(m_tableName); m_query.addRestriction(Env.parseContext(Env.getCtx(), m_targetWindowNo, m_whereExtended, false)); StringBuffer code = new StringBuffer(); int openBrackets = 0; for (int row = 0; row < advancedTable.getRowCount(); row++) { // Column Object column = advancedTable.getValueAt(row, INDEX_COLUMNNAME); if (column == null) continue; String ColumnName = column instanceof ValueNamePair ? ((ValueNamePair)column).getValue() : column.toString(); String infoName = column.toString(); // GridField field = getTargetMField(ColumnName); if (field == null) continue; boolean isProductCategoryField = isProductCategoryField(field.getAD_Column_ID()); String ColumnSQL = field.getColumnSQL(false); String lBrackets = (String) advancedTable.getValueAt(row, INDEX_LEFTBRACKET); if ( lBrackets != null ) openBrackets += lBrackets.length(); String rBrackets = (String) advancedTable.getValueAt(row, INDEX_RIGHTBRACKET); if ( rBrackets != null ) openBrackets -= rBrackets.length(); boolean and = true; if ( row > 0 ) and = !"OR".equals((String) advancedTable.getValueAt(row, INDEX_ANDOR)); // Op Object op = advancedTable.getValueAt(row, INDEX_OPERATOR); if (op == null) continue; String Operator = ((ValueNamePair)op).getValue(); // Value ****** Object value = advancedTable.getValueAt(row, INDEX_VALUE); if (value == null) { if ( MQuery.OPERATORS[MQuery.EQUAL_INDEX].equals(op) || MQuery.OPERATORS[MQuery.NOT_EQUAL_INDEX].equals(op) ) { m_query.addRestriction(ColumnSQL, Operator, null, infoName, null, and, openBrackets); if (code.length() > 0) code.append(SEGMENT_SEPARATOR); code.append(ColumnName) .append(FIELD_SEPARATOR) .append(Operator) .append(FIELD_SEPARATOR) .append("") .append(FIELD_SEPARATOR) .append("") .append(FIELD_SEPARATOR) .append( and ? "AND" : "OR") .append(FIELD_SEPARATOR) .append(lBrackets != null ? lBrackets : "") .append(FIELD_SEPARATOR) .append(rBrackets != null ? rBrackets : ""); } else { continue; } } else { Object parsedValue = parseValue(field, value); if (parsedValue == null) continue; String infoDisplay = value.toString(); if (field.isLookup()) infoDisplay = field.getLookup().getDisplay(value); else if (field.getDisplayType() == DisplayType.YesNo) infoDisplay = Msg.getMsg(Env.getCtx(), infoDisplay); // Value2 ****** Object value2 = null; if (MQuery.OPERATORS[MQuery.BETWEEN_INDEX].equals(op)) { value2 = advancedTable.getValueAt(row, INDEX_VALUE2); if (value2 == null) continue; Object parsedValue2 = parseValue(field, value2); String infoDisplay_to = value2.toString(); if (parsedValue2 == null) continue; m_query.addRangeRestriction(ColumnSQL, parsedValue, parsedValue2, infoName, infoDisplay, infoDisplay_to, and, openBrackets); } else if (isProductCategoryField && MQuery.OPERATORS[MQuery.EQUAL_INDEX].equals(op)) { if (!(parsedValue instanceof Integer)) { continue; } m_query .addRestriction(getSubCategoryWhereClause(((Integer) parsedValue).intValue()), and, openBrackets); } else m_query.addRestriction(ColumnSQL, Operator, parsedValue, infoName, infoDisplay, and, openBrackets); if (code.length() > 0) code.append(SEGMENT_SEPARATOR); code.append(ColumnName) .append(FIELD_SEPARATOR) .append(Operator) .append(FIELD_SEPARATOR) .append(value.toString()) .append(FIELD_SEPARATOR) .append(value2 != null ? value2.toString() : "") .append(FIELD_SEPARATOR) .append( and ? "AND" : "OR") .append(FIELD_SEPARATOR) .append(lBrackets != null ? lBrackets : "") .append(FIELD_SEPARATOR) .append(rBrackets != null ? rBrackets : ""); } } Object selected = fQueryName.getSelectedItem(); if (selected != null && saveQuery) { String name = selected.toString(); if (Util.isEmpty(name, true)) { ADialog.warn(m_targetWindowNo, this, "FillMandatory", Msg.translate(Env.getCtx(), "Name")); return; } MUserQuery uq = MUserQuery.get(Env.getCtx(), m_AD_Tab_ID, name); if (uq == null && code.length() > 0) { uq = new MUserQuery (Env.getCtx(), 0, null); uq.setName (name); uq.setAD_Tab_ID(m_AD_Tab_ID); //red1 UserQuery [ 1798539 ] taking in new field from Compiere uq.setAD_User_ID(Env.getAD_User_ID(Env.getCtx())); //red1 - [ 1798539 ] missing in Compiere delayed source :-) } else if (uq != null && code.length() == 0) { if (uq.delete(true)) { ADialog.info (m_targetWindowNo, this, "Deleted", name); refreshUserQueries(); } else ADialog.warn (m_targetWindowNo, this, "DeleteError", name); return; } uq.setCode (code.toString()); uq.setAD_Table_ID (m_AD_Table_ID); // if (uq.save()) { ADialog.info (m_targetWindowNo, this, "Saved", name); refreshUserQueries(); } else ADialog.warn (m_targetWindowNo, this, "SaveError", name); } } // cmd_save private void refreshUserQueries() { Object selected = fQueryName.getSelectedItem(); userQueries = MUserQuery.get(Env.getCtx(), m_AD_Tab_ID); String[] queries = new String[userQueries.length]; for (int i = 0; i < userQueries.length; i++) queries[i] = userQueries[i].getName(); fQueryName.setModel(new DefaultComboBoxModel(queries)); fQueryName.setSelectedItem(selected); if (fQueryName.getSelectedIndex() < 0) fQueryName.setValue(""); } /** * Checks the given column. * @param columnId * @return true if the column is a product category column */ private boolean isProductCategoryField(int columnId) { X_AD_Column col = new X_AD_Column(Env.getCtx(), columnId, null); if (col.get_ID() == 0) { return false; // column not found... } return MProduct.COLUMNNAME_M_Product_Category_ID.equals(col.getColumnName()); } /** * Returns a sql where string with the given category id and all of its subcategory ids. * It is used as restriction in MQuery. * @param productCategoryId * @return */ private String getSubCategoryWhereClause(int productCategoryId) { //if a node with this id is found later in the search we have a loop in the tree int subTreeRootParentId = 0; String retString = " M_Product_Category_ID IN ("; String sql = " SELECT M_Product_Category_ID, M_Product_Category_Parent_ID FROM M_Product_Category"; final Vector<SimpleTreeNode> categories = new Vector<SimpleTreeNode>(100); Statement stmt = null; ResultSet rs = null; try { stmt = DB.createStatement(); rs = stmt.executeQuery(sql); while (rs.next()) { if(rs.getInt(1)==productCategoryId) { subTreeRootParentId = rs.getInt(2); } categories.add(new SimpleTreeNode(rs.getInt(1), rs.getInt(2))); } retString += getSubCategoriesString(productCategoryId, categories, subTreeRootParentId); retString += ") "; } catch (SQLException e) { log.log(Level.SEVERE, sql, e); retString = ""; } catch (AdempiereSystemError e) { log.log(Level.SEVERE, sql, e); retString = ""; } finally { DB.close(rs, stmt); rs = null; stmt = null; } return retString; } /** * Recursive search for subcategories with loop detection. * @param productCategoryId * @param categories * @param loopIndicatorId * @return comma seperated list of category ids * @throws AdempiereSystemError if a loop is detected */ private String getSubCategoriesString(int productCategoryId, Vector<SimpleTreeNode> categories, int loopIndicatorId) throws AdempiereSystemError { String ret = ""; final Iterator<SimpleTreeNode> iter = categories.iterator(); while (iter.hasNext()) { SimpleTreeNode node = (SimpleTreeNode) iter.next(); if (node.getParentId() == productCategoryId) { if (node.getNodeId() == loopIndicatorId) { throw new AdempiereSystemError("The product category tree contains a loop on categoryId: " + loopIndicatorId); } ret = ret + getSubCategoriesString(node.getNodeId(), categories, loopIndicatorId) + ","; } } log.fine(ret); return ret + productCategoryId; } /** * Simple tree node class for product category tree search. * @author Karsten Thiemann, kthiemann@adempiere.org * */ private class SimpleTreeNode { private int nodeId; private int parentId; public SimpleTreeNode(int nodeId, int parentId) { this.nodeId = nodeId; this.parentId = parentId; } public int getNodeId() { return nodeId; } public int getParentId() { return parentId; } } /** * Parse Value * @param field column * @param in value * @return data type corrected value */ private Object parseValue (GridField field, Object in) { if (in == null) return null; int dt = field.getDisplayType(); try { // Return Integer if (dt == DisplayType.Integer || (DisplayType.isID(dt) && field.getColumnName().endsWith("_ID"))) { if (in instanceof Integer) return in; int i = Integer.parseInt(in.toString()); return new Integer(i); } // Return BigDecimal else if (DisplayType.isNumeric(dt)) { if (in instanceof BigDecimal) return in; return DisplayType.getNumberFormat(dt).parse(in.toString()); } // Return Timestamp else if (DisplayType.isDate(dt)) { if (in instanceof Timestamp) return in; long time = 0; try { time = DisplayType.getDateFormat_JDBC().parse(in.toString()).getTime(); return new Timestamp(time); } catch (Exception e) { log.log(Level.SEVERE, in + "(" + in.getClass() + ")" + e); time = DisplayType.getDateFormat(dt).parse(in.toString()).getTime(); } return new Timestamp(time); } // Return Y/N for Boolean else if (in instanceof Boolean) return ((Boolean)in).booleanValue() ? "Y" : "N"; } catch (Exception ex) { log.log(Level.SEVERE, "Object=" + in, ex); String error = ex.getLocalizedMessage(); if (error == null || error.length() == 0) error = ex.toString(); StringBuffer errMsg = new StringBuffer(); errMsg.append(field.getColumnName()).append(" = ").append(in).append(" - ").append(error); // ADialog.error(0, this, "ValidationError", errMsg.toString()); return null; } return in; } // parseValue /** * Parse String * @param field column * @param in value * @return data type corrected value */ private Object parseString(GridField field, String in) { log.log(Level.FINE, "Parse: " +field + ":" + in); if (in == null) return null; int dt = field.getDisplayType(); try { // Return Integer if (dt == DisplayType.Integer || (DisplayType.isID(dt) && field.getColumnName().endsWith("_ID"))) { int i = Integer.parseInt(in); return new Integer(i); } // Return BigDecimal else if (DisplayType.isNumeric(dt)) { return DisplayType.getNumberFormat(dt).parse(in); } // Return Timestamp else if (DisplayType.isDate(dt)) { long time = 0; try { time = DisplayType.getDateFormat_JDBC().parse(in).getTime(); return new Timestamp(time); } catch (Exception e) { log.log(Level.SEVERE, in + "(" + in.getClass() + ")" + e); time = DisplayType.getDateFormat(dt).parse(in).getTime(); } return new Timestamp(time); } else if (dt == DisplayType.YesNo) return Boolean.valueOf(in); else return in; } catch (Exception ex) { log.log(Level.SEVERE, "Object=" + in, ex); return null; } } // parseValue /** * Delete */ private void cmd_delete() { advancedTable.stopEditor(false); DefaultTableModel model = (DefaultTableModel)advancedTable.getModel(); int row = advancedTable.getSelectedRow(); if (row >= 0) model.removeRow(row); cmd_refresh(); advancedTable.requestFocusInWindow(); } // cmd_delete /** * Refresh */ private void cmd_refresh() { advancedTable.stopEditor(false); int records = getNoOfRecords(m_query, true); setStatusDB (records); statusBar.setStatusLine(""); } // cmd_refresh /************************************************************************** * Get Query - Retrieve result * @return String representation of query */ public MQuery getQuery() { MRole role = MRole.getDefault(); if (role.isQueryMax(getTotalRecords()) && !m_isCancel) { m_query = MQuery.getNoRecordQuery (m_tableName, false); m_total = 0; log.warning("Query - over max"); } else log.info("Query=" + m_query); return m_query; } // getQuery /** * Get Total Records * @return no of records */ public int getTotalRecords() { return m_total; } // getTotalRecords /** * Get the number of records of target tab * @param query where clause for target tab * @param alertZeroRecords show dialog if there are no records * @return number of selected records; * if the results are more then allowed this method will return 0 */ private int getNoOfRecords (MQuery query, boolean alertZeroRecords) { log.config("" + query); StringBuffer sql = new StringBuffer("SELECT COUNT(*) FROM "); sql.append(m_tableName); boolean hasWhere = false; if (m_whereExtended != null && m_whereExtended.length() > 0) { sql.append(" WHERE ").append(m_whereExtended); hasWhere = true; } if (query != null && query.isActive()) { if (hasWhere) sql.append(" AND "); else sql.append(" WHERE "); sql.append(query.getWhereClause()); } // Add Access String finalSQL = MRole.getDefault().addAccessSQL(sql.toString(), m_tableName, MRole.SQL_NOTQUALIFIED, MRole.SQL_RO); finalSQL = Env.parseContext(Env.getCtx(), m_targetWindowNo, finalSQL, false); Env.setContext(Env.getCtx(), m_targetWindowNo, TABNO, GridTab.CTX_FindSQL, finalSQL); // Execute Qusery m_total = 999999; Statement stmt = null; ResultSet rs = null; try { stmt = DB.createStatement(); rs = stmt.executeQuery(finalSQL); if (rs.next()) m_total = rs.getInt(1); } catch (SQLException e) { log.log(Level.SEVERE, finalSQL, e); } finally { DB.close(rs, stmt); rs = null; stmt = null; } MRole role = MRole.getDefault(); // No Records if (m_total == 0 && alertZeroRecords) ADialog.info(m_targetWindowNo, this, "FindZeroRecords"); // More then allowed else if (query != null && role.isQueryMax(m_total)) { ADialog.error(m_targetWindowNo, this, "FindOverMax", m_total + " > " + role.getMaxQueryRecords()); m_total = 0; // return 0 if more then allowed - teo_sarca [ 1708717 ] } else log.config("#" + m_total); // if (query != null) statusBar.setStatusToolTip (query.getWhereClause()); return m_total; } // getNoOfRecords /** * Display current count * @param currentCount String representation of current/total */ private void setStatusDB (int currentCount) { String text = " " + currentCount + " / " + m_total + " "; statusBar.setStatusDB(text); } // setDtatusDB /************************************************************************** * Grid Status Changed. * @param e DataStatueEvent */ public void dataStatusChanged (DataStatusEvent e) { log.config(e.getMessage()); // Action control boolean changed = e.isChanged(); bIgnore.setEnabled(changed); bNew.setEnabled(!changed); bSave.setEnabled(changed); bDelete.setEnabled(!changed); } // statusChanged /** * Get Target MField * @param columnName column name * @return MField */ public GridField getTargetMField (String columnName) { if (columnName == null) return null; for (int c = 0; c < m_findFields.length; c++) { GridField field = m_findFields[c]; if (columnName.equals(field.getColumnName())) return field; } return null; } // getTargetMField private boolean isSearchLike(GridField field) { return DisplayType.isText(field.getDisplayType()) && MColumn.isSuggestSelectionColumn(field.getColumnName(), true); } private class ProxyRenderer implements TableCellRenderer { /** * Creates a Find.ProxyRenderer. */ public ProxyRenderer(TableCellRenderer renderer) { this.m_renderer = renderer; } /** The renderer. */ private TableCellRenderer m_renderer; /** * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) */ public Component getTableCellRendererComponent(final JTable table, Object value, boolean isSelected, boolean hasFocus, final int row, final int col) { Component comp = m_renderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, col); if (hasFocus && table.isCellEditable(row, col)) table.editCellAt(row, col); return comp; } } // ProxyRenderer } // Find