diff --git a/base/src/org/compiere/model/MQuery.java b/base/src/org/compiere/model/MQuery.java
index e2b02ff18d..a6b91173e0 100644
--- a/base/src/org/compiere/model/MQuery.java
+++ b/base/src/org/compiere/model/MQuery.java
@@ -40,7 +40,7 @@ import org.compiere.util.ValueNamePair;
* @version $Id: MQuery.java,v 1.4 2006/07/30 00:58:04 jjanke Exp $
*
* @author Teo Sarca
- *
BF [ 2860022 ] MQuery.get() is generating restictions for unexisting column
+ * BF [ 2860022 ] MQuery.get() is generating restrictions for non-existent column
* https://sourceforge.net/tracker/?func=detail&aid=2860022&group_id=176962&atid=879332
*/
public class MQuery implements Serializable
@@ -298,7 +298,7 @@ public class MQuery implements Serializable
* Creates columnName=value
* @param columnName columnName
* @param value value
- * @return quary
+ * @return query
*/
public static MQuery getEqualQuery (String columnName, int value)
{
@@ -357,7 +357,7 @@ public class MQuery implements Serializable
} // MQuery
/** Serialization Info **/
- private static final long serialVersionUID = 4883859385509199305L;
+ private static final long serialVersionUID = 4883859385509199306L;
/** Table Name */
private String m_TableName = "";
@@ -403,6 +403,8 @@ public class MQuery implements Serializable
public static final int EQUAL_INDEX = 0;
/** Not Equal */
public static final String NOT_EQUAL = "!=";
+ /** Not Equal - 1 */
+ public static final int NOT_EQUAL_INDEX = 1;
/** Like */
public static final String LIKE = " LIKE ";
/** Not Like */
@@ -442,6 +444,23 @@ public class MQuery implements Serializable
new ValueNamePair (EQUAL, " = ")
};
+ /*************************************************************************
+ * Add Restriction
+ * @param ColumnName ColumnName
+ * @param Operator Operator, e.g. = != ..
+ * @param Code Code, e.g 0, All%
+ * @param InfoName Display Name
+ * @param InfoDisplay Display of Code (Lookup)
+ * @param andCondition true=and, false=or
+ * @param depth ( = no open brackets )
+ */
+ public void addRestriction (String ColumnName, String Operator,
+ Object Code, String InfoName, String InfoDisplay, boolean andCondition, int depth)
+ {
+ Restriction r = new Restriction (ColumnName, Operator,
+ Code, InfoName, InfoDisplay, andCondition, depth);
+ m_list.add(r);
+ } // addRestriction
/*************************************************************************
* Add Restriction
@@ -455,7 +474,7 @@ public class MQuery implements Serializable
Object Code, String InfoName, String InfoDisplay)
{
Restriction r = new Restriction (ColumnName, Operator,
- Code, InfoName, InfoDisplay);
+ Code, InfoName, InfoDisplay, true, 0);
m_list.add(r);
} // addRestriction
@@ -469,7 +488,7 @@ public class MQuery implements Serializable
Object Code)
{
Restriction r = new Restriction (ColumnName, Operator,
- Code, null, null);
+ Code, null, null, true, 0);
m_list.add(r);
} // addRestriction
@@ -483,10 +502,30 @@ public class MQuery implements Serializable
int Code)
{
Restriction r = new Restriction (ColumnName, Operator,
- new Integer(Code), null, null);
+ new Integer(Code), null, null, true, 0);
m_list.add(r);
} // addRestriction
+ /**
+ * Add Range Restriction (BETWEEN)
+ * @param ColumnName ColumnName
+ * @param Code Code, e.g 0, All%
+ * @param Code_to Code, e.g 0, All%
+ * @param InfoName Display Name
+ * @param InfoDisplay Display of Code (Lookup)
+ * @param InfoDisplay_to Display of Code (Lookup)
+ * @param andCondition true=and, false=or
+ * @param depth ( = no open brackets )
+ */
+ public void addRangeRestriction (String ColumnName,
+ Object Code, Object Code_to,
+ String InfoName, String InfoDisplay, String InfoDisplay_to, boolean andCondition, int depth)
+ {
+ Restriction r = new Restriction (ColumnName, Code, Code_to,
+ InfoName, InfoDisplay, InfoDisplay_to, andCondition, depth);
+ m_list.add(r);
+ } // addRestriction
+
/**
* Add Range Restriction (BETWEEN)
* @param ColumnName ColumnName
@@ -501,7 +540,7 @@ public class MQuery implements Serializable
String InfoName, String InfoDisplay, String InfoDisplay_to)
{
Restriction r = new Restriction (ColumnName, Code, Code_to,
- InfoName, InfoDisplay, InfoDisplay_to);
+ InfoName, InfoDisplay, InfoDisplay_to, true, 0);
m_list.add(r);
} // addRestriction
@@ -515,7 +554,7 @@ public class MQuery implements Serializable
Object Code, Object Code_to)
{
Restriction r = new Restriction (ColumnName, Code, Code_to,
- null, null, null);
+ null, null, null, true, 0);
m_list.add(r);
} // addRestriction
@@ -528,6 +567,18 @@ public class MQuery implements Serializable
m_list.add(r);
} // addRestriction
+ /**
+ * Add Restriction
+ * @param whereClause SQL WHERE clause
+ */
+ public void addRestriction (String whereClause, boolean andCondition, int joinDepth)
+ {
+ if (whereClause == null || whereClause.trim().length() == 0)
+ return;
+ Restriction r = new Restriction (whereClause, andCondition, joinDepth);
+ m_list.add(r);
+ m_newRecord = whereClause.equals(NEWRECORD);
+ } // addRestriction
/**
* Add Restriction
* @param whereClause SQL WHERE clause
@@ -536,14 +587,14 @@ public class MQuery implements Serializable
{
if (whereClause == null || whereClause.trim().length() == 0)
return;
- Restriction r = new Restriction (whereClause);
+ Restriction r = new Restriction (whereClause, true, 0);
m_list.add(r);
m_newRecord = whereClause.equals(NEWRECORD);
} // addRestriction
/**
* New Record Query
- * @return true if new nercord query
+ * @return true if new record query
*/
public boolean isNewRecordQuery()
{
@@ -566,21 +617,39 @@ public class MQuery implements Serializable
*/
public String getWhereClause (boolean fullyQualified)
{
+ int currentDepth = 0;
boolean qualified = fullyQualified;
if (qualified && (m_TableName == null || m_TableName.length() == 0))
qualified = false;
//
StringBuffer sb = new StringBuffer();
+ sb.append('(');
for (int i = 0; i < m_list.size(); i++)
{
Restriction r = (Restriction)m_list.get(i);
if (i != 0)
sb.append(r.andCondition ? " AND " : " OR ");
+ for ( ; currentDepth < r.joinDepth; currentDepth++ )
+ {
+ sb.append('(');
+ }
if (qualified)
sb.append(r.getSQL(m_TableName));
else
sb.append(r.getSQL(null));
+
+ for ( ; currentDepth > r.joinDepth; currentDepth-- )
+ {
+ sb.append(')');
+ }
}
+
+ // close brackets
+ for ( ; currentDepth > 0; currentDepth-- )
+ {
+ sb.append(')');
+ }
+ sb.append(')');
return sb.toString();
} // getWhereClause
@@ -591,12 +660,21 @@ public class MQuery implements Serializable
public String getInfo ()
{
StringBuffer sb = new StringBuffer();
+ int currentDepth = 0;
if (m_TableName != null)
sb.append(m_TableName).append(": ");
//
for (int i = 0; i < m_list.size(); i++)
{
Restriction r = (Restriction)m_list.get(i);
+ for ( ; currentDepth < r.joinDepth; currentDepth++ )
+ {
+ sb.append('(');
+ }
+ for ( ; currentDepth > r.joinDepth; currentDepth-- )
+ {
+ sb.append(')');
+ }
if (i != 0)
sb.append(r.andCondition ? " AND " : " OR ");
//
@@ -604,6 +682,11 @@ public class MQuery implements Serializable
.append(r.getInfoOperator())
.append(r.getInfoDisplayAll());
}
+ // close brackets
+ for ( ; currentDepth > 0; currentDepth-- )
+ {
+ sb.append(')');
+ }
return sb.toString();
} // getInfo
@@ -627,7 +710,7 @@ public class MQuery implements Serializable
/**
* Get Restriction Count
- * @return number of restricctions
+ * @return number of restrictions
*/
public int getRestrictionCount()
{
@@ -636,7 +719,7 @@ public class MQuery implements Serializable
/**
* Is Query Active
- * @return true if number of restricctions > 0
+ * @return true if number of restrictions > 0
*/
public boolean isActive()
{
@@ -884,7 +967,7 @@ class Restriction implements Serializable
/**
*
*/
- private static final long serialVersionUID = -4521978087587321242L;
+ private static final long serialVersionUID = -4521978087587321243L;
/**
* Restriction
@@ -895,13 +978,18 @@ class Restriction implements Serializable
* @param infoDisplay Display of Code (Lookup)
*/
Restriction (String columnName, String operator,
- Object code, String infoName, String infoDisplay)
+ Object code, String infoName, String infoDisplay, boolean andCondition, int depth)
{
this.ColumnName = columnName.trim();
if (infoName != null)
InfoName = infoName;
else
InfoName = ColumnName;
+
+
+ this.andCondition = andCondition;
+ this.joinDepth = depth < 0 ? 0 : depth;
+
//
this.Operator = operator;
// Boolean
@@ -938,9 +1026,9 @@ class Restriction implements Serializable
*/
Restriction (String columnName,
Object code, Object code_to,
- String infoName, String infoDisplay, String infoDisplay_to)
+ String infoName, String infoDisplay, String infoDisplay_to, boolean andCondition, int depth)
{
- this (columnName, MQuery.BETWEEN, code, infoName, infoDisplay);
+ this (columnName, MQuery.BETWEEN, code, infoName, infoDisplay, andCondition, depth);
// Code_to
Code_to = code_to;
@@ -959,16 +1047,18 @@ class Restriction implements Serializable
} // Restriction
/**
- * Create Restriction with dircet WHERE clause
+ * Create Restriction with direct WHERE clause
* @param whereClause SQL WHERE Clause
*/
- Restriction (String whereClause)
+ Restriction (String whereClause, boolean andCondition, int depth)
{
- DircetWhereClause = whereClause;
+ DirectWhereClause = whereClause;
+ this.andCondition = andCondition;
+ this.joinDepth = depth;
} // Restriction
/** Direct Where Clause */
- protected String DircetWhereClause = null;
+ protected String DirectWhereClause = null;
/** Column Name */
protected String ColumnName;
/** Name */
@@ -985,6 +1075,8 @@ class Restriction implements Serializable
protected String InfoDisplay_to;
/** And/Or Condition */
protected boolean andCondition = true;
+ /** And/Or condition nesting depth ( = number of open brackets at and/or) */
+ protected int joinDepth = 0;
/**
* Return SQL construct for this restriction
@@ -993,8 +1085,8 @@ class Restriction implements Serializable
*/
public String getSQL (String tableName)
{
- if (DircetWhereClause != null)
- return DircetWhereClause;
+ if (DirectWhereClause != null)
+ return DirectWhereClause;
//
StringBuffer sb = new StringBuffer();
if (tableName != null && tableName.length() > 0)
diff --git a/client/src/org/compiere/apps/search/Find.java b/client/src/org/compiere/apps/search/Find.java
index 25316aa2fc..250b1d75de 100644
--- a/client/src/org/compiere/apps/search/Find.java
+++ b/client/src/org/compiere/apps/search/Find.java
@@ -59,6 +59,7 @@ 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;
@@ -115,12 +116,12 @@ public final class Find extends CDialog
/**
*
*/
- private static final long serialVersionUID = 6414604433732835410L;
+ private static final long serialVersionUID = 6414604433732835411L;
private int m_AD_Tab_ID;
/**
* Find Constructor
- * @param owner Frame Dialog Onwer
+ * @param owner Frame Dialog Owner
* @param targetWindowNo WindowNo of target window
* @param title
* @param AD_Table_ID
@@ -248,7 +249,10 @@ public final class Find extends CDialog
public boolean isCellEditable(int row, int column)
{
boolean editable = ( column == INDEX_COLUMNNAME
- || column == INDEX_OPERATOR );
+ || column == INDEX_OPERATOR
+ || column == INDEX_ANDOR
+ || column == INDEX_LEFTBRACKET
+ || column == INDEX_RIGHTBRACKET );
if (!editable && row >= 0)
{
String columnName = null;
@@ -265,18 +269,44 @@ public final class Find extends CDialog
// 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 ColumnName = 0 */
- public static final int INDEX_COLUMNNAME = 0;
- /** Index Operator = 1 */
- public static final int INDEX_OPERATOR = 1;
- /** Index Value = 2 */
- public static final int INDEX_VALUE = 2;
- /** Index Value2 = 3 */
- public static final int INDEX_VALUE2 = 3;
+
+ /** 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;
@@ -285,6 +315,12 @@ public final class Find extends CDialog
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 = "<~>";
@@ -348,7 +384,7 @@ public final class Find extends CDialog
docNoLabel.setText(Msg.translate(Env.getCtx(),"DocumentNo"));
docNoField.setText("%");
docNoField.setColumns(FIELDLENGTH);
- advancedScrollPane.setPreferredSize(new Dimension(450, 150));
+ advancedScrollPane.setPreferredSize(new Dimension(540, 410));
southPanel.add(statusBar, BorderLayout.SOUTH);
this.getContentPane().add(southPanel, BorderLayout.SOUTH);
//
@@ -557,7 +593,7 @@ public final class Find extends CDialog
private void initFindAdvanced()
{
log.config("");
- advancedTable.setModel(new DefaultTableModel(0, 4));
+ advancedTable.setModel(new DefaultTableModel(0, 7));
advancedTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
advancedTable.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
advancedTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
@@ -622,7 +658,7 @@ public final class Find extends CDialog
columns = new CComboBox(columnValueNamePairs);
columns.addActionListener(this);
TableColumn tc = advancedTable.getColumnModel().getColumn(INDEX_COLUMNNAME);
- tc.setPreferredWidth(150);
+ tc.setPreferredWidth(120);
FindCellEditor dce = new FindCellEditor(columns);
dce.addCellEditorListener(new CellEditorListener()
@@ -645,31 +681,58 @@ public final class Find extends CDialog
tc.setCellEditor(dce);
tc.setHeaderValue(Msg.translate(Env.getCtx(), "AD_Column_ID"));
- // 1 = Operators
+
+ // 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(40);
+ tc.setPreferredWidth(55);
dce = new FindCellEditor(operators);
tc.setCellEditor(dce);
tc.setHeaderValue(Msg.getMsg(Env.getCtx(), "Operator"));
- // 2 = QueryValue
+ // 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"));
- // 3 = QueryValue2
+ // 5 = QueryValue2
tc = advancedTable.getColumnModel().getColumn(INDEX_VALUE2);
- tc.setPreferredWidth(50);
- fve = new FindValueEditor(this, false);
+ 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"));
- AutoCompletion.enable(columns);
- AutoCompletion.enable(operators);
+ // 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);
@@ -799,9 +862,16 @@ public final class Find extends CDialog
}
} // 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();
- String[] segments = code.split(Pattern.quote(SEGMENT_SEPARATOR));
+ 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();
@@ -811,38 +881,62 @@ public final class Find extends CDialog
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});
+ model.addRow(new Object[] {"","", null, MQuery.OPERATORS[MQuery.EQUAL_INDEX], null, null, ""});
String columnName = null;
for (int j = 0; j < fields.length; j++)
{
- if (j == INDEX_COLUMNNAME)
+ // column
+ if (j == 0 )
{
for (ValueNamePair vnp : columnValueNamePairs)
{
if (vnp.getValue().equals(fields[j]))
{
- model.setValueAt(vnp, i, j);
+ model.setValueAt(vnp, i, INDEX_COLUMNNAME);
columnName = fields[j];
break;
}
}
}
- else if (j == INDEX_OPERATOR)
+ // operator
+ else if (j == 1)
{
for (ValueNamePair vnp : MQuery.OPERATORS)
{
if (vnp.getValue().equals(fields[j]))
{
- model.setValueAt(vnp, i, j);
+ model.setValueAt(vnp, i, INDEX_OPERATOR);
break;
}
}
}
- else
+ // value
+ else if ( j == 2 && fields[j].length() > 0 )
{
GridField field = getTargetMField(columnName);
Object value = parseString(field, fields[j]);
- model.setValueAt(value, i, 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);
}
}
}
@@ -987,7 +1081,8 @@ public final class Find extends CDialog
{
advancedTable.stopEditor(true);
DefaultTableModel model = (DefaultTableModel)advancedTable.getModel();
- model.addRow(new Object[] {null, MQuery.OPERATORS[MQuery.EQUAL_INDEX], null, null});
+ int rows = model.getRowCount();
+ model.addRow(new Object[] {rows == 0 ? "" : "AND","", null, MQuery.OPERATORS[MQuery.EQUAL_INDEX], null, null,""});
advancedTable.requestFocusInWindow();
} // cmd_new
@@ -1001,6 +1096,7 @@ public final class Find extends CDialog
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
@@ -1016,6 +1112,17 @@ public final class Find extends CDialog
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)
@@ -1025,7 +1132,36 @@ public final class Find extends CDialog
// 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;
@@ -1046,17 +1182,19 @@ public final class Find extends CDialog
if (parsedValue2 == null)
continue;
m_query.addRangeRestriction(ColumnSQL, parsedValue, parsedValue2,
- infoName, infoDisplay, infoDisplay_to);
+ 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()));
+ m_query
+
+ .addRestriction(getSubCategoryWhereClause(((Integer) parsedValue).intValue()), and, openBrackets);
}
else
m_query.addRestriction(ColumnSQL, Operator, parsedValue,
- infoName, infoDisplay);
+ infoName, infoDisplay, and, openBrackets);
if (code.length() > 0)
code.append(SEGMENT_SEPARATOR);
@@ -1066,7 +1204,15 @@ public final class Find extends CDialog
.append(FIELD_SEPARATOR)
.append(value.toString())
.append(FIELD_SEPARATOR)
- .append(value2 != null ? value2.toString() : "");
+ .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) {
@@ -1095,8 +1241,7 @@ public final class Find extends CDialog
ADialog.warn (m_targetWindowNo, this, "DeleteError", name);
return;
}
- else
- return;
+
uq.setCode (code.toString());
uq.setAD_Table_ID (m_AD_Table_ID);
//
@@ -1229,7 +1374,7 @@ public final class Find extends CDialog
* Parse Value
* @param field column
* @param in value
- * @return data type corected value
+ * @return data type corrected value
*/
private Object parseValue (GridField field, Object in)
{
@@ -1296,10 +1441,11 @@ public final class Find extends CDialog
* Parse String
* @param field column
* @param in value
- * @return data type corected 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();
diff --git a/client/src/org/compiere/apps/search/FindValueEditor.java b/client/src/org/compiere/apps/search/FindValueEditor.java
index 76cba4d972..92c9b5c3b1 100644
--- a/client/src/org/compiere/apps/search/FindValueEditor.java
+++ b/client/src/org/compiere/apps/search/FindValueEditor.java
@@ -116,6 +116,8 @@ public final class FindValueEditor extends AbstractCellEditor implements TableCe
boolean enabled = !m_valueToColumn || (m_valueToColumn && m_between);
log.config("(" + value + ") - Enabled=" + enabled);
+ if ( enabled )
+ {
String columnName = null;
Object column = table.getModel().getValueAt(row, Find.INDEX_COLUMNNAME);
if (column != null)
@@ -134,6 +136,11 @@ public final class FindValueEditor extends AbstractCellEditor implements TableCe
m_editor.setValue(value);
m_editor.setReadWrite(enabled);
m_editor.setBorder(null);
+ }
+ else
+ {
+ m_editor = null;
+ }
//
return (Component)m_editor;
} // getTableCellEditorComponent
diff --git a/migration/354a-trunk/oracle/661_FR_2945715_AdvancedSearchMsg.sql b/migration/354a-trunk/oracle/661_FR_2945715_AdvancedSearchMsg.sql
new file mode 100644
index 0000000000..2cd415ea08
--- /dev/null
+++ b/migration/354a-trunk/oracle/661_FR_2945715_AdvancedSearchMsg.sql
@@ -0,0 +1,30 @@
+-- Feb 8, 2010 3:00:56 PM EST
+-- Advanced search
+INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID,AD_Org_ID,Created,CreatedBy,EntityType,IsActive,MsgText,MsgType,Updated,UpdatedBy,Value) VALUES (0,53092,0,TO_DATE('2010-02-08 15:00:52','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','And/Or','I',TO_DATE('2010-02-08 15:00:52','YYYY-MM-DD HH24:MI:SS'),100,'And/Or')
+;
+
+-- Feb 8, 2010 3:00:57 PM EST
+-- Advanced search
+INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=53092 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
+;
+
+-- Feb 8, 2010 3:01:21 PM EST
+-- Advanced search
+INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID,AD_Org_ID,Created,CreatedBy,EntityType,IsActive,MsgText,MsgType,Updated,UpdatedBy,Value) VALUES (0,53093,0,TO_DATE('2010-02-08 15:01:19','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','AND','I',TO_DATE('2010-02-08 15:01:19','YYYY-MM-DD HH24:MI:SS'),100,'AND')
+;
+
+-- Feb 8, 2010 3:01:21 PM EST
+-- Advanced search
+INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=53093 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
+;
+
+-- Feb 8, 2010 3:01:42 PM EST
+-- Advanced search
+INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID,AD_Org_ID,Created,CreatedBy,EntityType,IsActive,MsgText,MsgType,Updated,UpdatedBy,Value) VALUES (0,53094,0,TO_DATE('2010-02-08 15:01:34','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','OR','I',TO_DATE('2010-02-08 15:01:34','YYYY-MM-DD HH24:MI:SS'),100,'OR')
+;
+
+-- Feb 8, 2010 3:01:42 PM EST
+-- Advanced search
+INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=53094 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
+;
+
diff --git a/migration/354a-trunk/postgresql/661_FR_2945715_AdvancedSearchMsg.sql b/migration/354a-trunk/postgresql/661_FR_2945715_AdvancedSearchMsg.sql
new file mode 100644
index 0000000000..5209053c37
--- /dev/null
+++ b/migration/354a-trunk/postgresql/661_FR_2945715_AdvancedSearchMsg.sql
@@ -0,0 +1,30 @@
+-- Feb 8, 2010 3:00:56 PM EST
+-- Advanced search
+INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID,AD_Org_ID,Created,CreatedBy,EntityType,IsActive,MsgText,MsgType,Updated,UpdatedBy,Value) VALUES (0,53092,0,TO_TIMESTAMP('2010-02-08 15:00:52','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','And/Or','I',TO_TIMESTAMP('2010-02-08 15:00:52','YYYY-MM-DD HH24:MI:SS'),100,'And/Or')
+;
+
+-- Feb 8, 2010 3:00:57 PM EST
+-- Advanced search
+INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=53092 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
+;
+
+-- Feb 8, 2010 3:01:21 PM EST
+-- Advanced search
+INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID,AD_Org_ID,Created,CreatedBy,EntityType,IsActive,MsgText,MsgType,Updated,UpdatedBy,Value) VALUES (0,53093,0,TO_TIMESTAMP('2010-02-08 15:01:19','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','AND','I',TO_TIMESTAMP('2010-02-08 15:01:19','YYYY-MM-DD HH24:MI:SS'),100,'AND')
+;
+
+-- Feb 8, 2010 3:01:21 PM EST
+-- Advanced search
+INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=53093 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
+;
+
+-- Feb 8, 2010 3:01:42 PM EST
+-- Advanced search
+INSERT INTO AD_Message (AD_Client_ID,AD_Message_ID,AD_Org_ID,Created,CreatedBy,EntityType,IsActive,MsgText,MsgType,Updated,UpdatedBy,Value) VALUES (0,53094,0,TO_TIMESTAMP('2010-02-08 15:01:34','YYYY-MM-DD HH24:MI:SS'),100,'D','Y','OR','I',TO_TIMESTAMP('2010-02-08 15:01:34','YYYY-MM-DD HH24:MI:SS'),100,'OR')
+;
+
+-- Feb 8, 2010 3:01:42 PM EST
+-- Advanced search
+INSERT INTO AD_Message_Trl (AD_Language,AD_Message_ID, MsgText,MsgTip, IsTranslated,AD_Client_ID,AD_Org_ID,Created,Createdby,Updated,UpdatedBy) SELECT l.AD_Language,t.AD_Message_ID, t.MsgText,t.MsgTip, 'N',t.AD_Client_ID,t.AD_Org_ID,t.Created,t.Createdby,t.Updated,t.UpdatedBy FROM AD_Language l, AD_Message t WHERE l.IsActive='Y' AND l.IsSystemLanguage='Y' AND l.IsBaseLanguage='N' AND t.AD_Message_ID=53094 AND NOT EXISTS (SELECT * FROM AD_Message_Trl tt WHERE tt.AD_Language=l.AD_Language AND tt.AD_Message_ID=t.AD_Message_ID)
+;
+