/** * */ package fr.lteconsulting.hexa.client.ui.Criteria; import java.util.ArrayList; import com.google.gwt.core.client.GWT; import com.google.gwt.core.client.JsArray; import com.google.gwt.core.client.JsonUtils; import com.google.gwt.dom.client.Style.FontWeight; import com.google.gwt.event.dom.client.ClickEvent; import com.google.gwt.event.dom.client.ClickHandler; import com.google.gwt.json.client.JSONArray; import com.google.gwt.json.client.JSONObject; import com.google.gwt.json.client.JSONString; import com.google.gwt.json.client.JSONValue; import com.google.gwt.uibinder.client.UiBinder; import com.google.gwt.uibinder.client.UiField; import com.google.gwt.user.client.ui.Anchor; import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Composite; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.InsertPanel; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.Widget; import fr.lteconsulting.hexa.client.comm.GenericJSO; import fr.lteconsulting.hexa.client.css.HexaCss; import fr.lteconsulting.hexa.client.interfaces.ICriteriaFieldMng; import fr.lteconsulting.hexa.client.tools.HexaTools; import fr.lteconsulting.hexa.client.ui.widget.ListBoxEx; public class CriteriaInternal extends Composite { public static String getBeautifulText( String searchString ) { GenericJSO jso = null; try { jso = JsonUtils.unsafeEval( searchString ); } catch( Exception e ) { } if( jso == null ) return null; return getBeautifulText( jso ); } private static String getBeautifulText( GenericJSO jso ) { String op = jso.getString( "op" ); if( (op.compareTo( "and" ) == 0) || (op.compareTo( "or" ) == 0) ) { JsArray<GenericJSO> ops = jso.getArray( "ops" ); StringBuilder b = new StringBuilder(); for( int i = 0; i < ops.length(); i++ ) { b.append( getBeautifulText( ops.get( i ) ) ); if( i < ops.length() - 1 ) b.append( " " + op + " " ); } return b.toString(); } if( op.compareTo( "eq" ) == 0 ) op = "="; if( op.compareTo( "ne" ) == 0 ) op = "<>"; else if( op.compareTo( "lt" ) == 0 ) op = "<"; else if( op.compareTo( "lte" ) == 0 ) op = "<="; else if( op.compareTo( "gt" ) == 0 ) op = ">"; else if( op.compareTo( "gte" ) == 0 ) op = ">="; return jso.getString( "field" ) + " " + op + " '" + jso.getString( "value" ) + "'"; } String op = "eq"; ArrayList<CriteriaInternal> ops = new ArrayList<CriteriaInternal>(); int direction = 0; ICriteriaFieldMng field; String value = ""; ICriteriaFieldMng[] criteriaMngs; public enum CriteriaOp { eq( "=" ), ne( "<>" ), gt( ">" ), gte( ">=" ), lt( "<" ), lte( "<=" ); String display; CriteriaOp( String display ) { this.display = display; } public String getDisplay() { return display; } } interface CriteriaInternalUiBinder extends UiBinder<Widget, CriteriaInternal> { } interface Css extends HexaCss { public static final Css CSS = GWT.create( Css.class ); String main(); } private static CriteriaInternalUiBinder uiBinder = GWT.create( CriteriaInternalUiBinder.class ); Widget closeButton = null; @UiField Anchor andAnchor; @UiField Anchor orAnchor; @UiField Anchor compareAnchor; @UiField SimplePanel closeSpot; @UiField SimplePanel content; public CriteriaInternal( ICriteriaFieldMng[] criteriaMngs ) { this.criteriaMngs = criteriaMngs; field = criteriaMngs[0]; initWidget( uiBinder.createAndBindUi( this ) ); addStyleName( Css.CSS.main() ); andAnchor.addClickHandler( new ClickHandler() { @Override public void onClick( ClickEvent event ) { op = "and"; UpdateInterface(); event.preventDefault(); } } ); orAnchor.addClickHandler( new ClickHandler() { @Override public void onClick( ClickEvent event ) { op = "or"; UpdateInterface(); event.preventDefault(); } } ); compareAnchor.addClickHandler( new ClickHandler() { @Override public void onClick( ClickEvent event ) { op = "eq"; UpdateInterface(); event.preventDefault(); } } ); UpdateInterface(); } private void SetFlowDirection( int dir ) { direction = dir; } private void SetCloseButton( Widget w ) { closeButton = w; } private void UpdateInterface() { andAnchor.getElement().getStyle().setFontWeight( op.compareTo( "and" ) == 0 ? FontWeight.BOLD : FontWeight.LIGHTER ); orAnchor.getElement().getStyle().setFontWeight( op.compareTo( "or" ) == 0 ? FontWeight.BOLD : FontWeight.LIGHTER ); compareAnchor.getElement().getStyle().setFontWeight( op.compareTo( "eq" ) == 0 ? FontWeight.BOLD : FontWeight.LIGHTER ); // if any, position the close button if( closeButton != null ) closeSpot.setWidget( closeButton ); else closeSpot.clear(); // different display according to node type if( (op.compareTo( "and" ) == 0) || (op.compareTo( "or" ) == 0) ) { // ops, op, ops, op, .., ops, '+' Widget realPanel = null; InsertPanel panel = null; if( direction == 0 ) { VerticalPanel vp = new VerticalPanel(); realPanel = vp; panel = vp; } else if( direction == 1 ) { HorizontalPanel hp = new HorizontalPanel(); realPanel = hp; panel = hp; } if( ops.size() < 1 ) { ops.add( new CriteriaInternal( criteriaMngs ) ); } for( int i = 0; i < ops.size(); i++ ) { // HorizontalPanel hp = new HorizontalPanel(); final CriteriaInternal criteria = ops.get( i ); // hp.add( criteria ); criteria.SetFlowDirection( (direction + 1) % 2 ); Anchor delAnchor = new Anchor( "remove" ); delAnchor.setHref( "#" ); delAnchor.addClickHandler( new ClickHandler() { @Override public void onClick( ClickEvent event ) { ops.remove( criteria ); UpdateInterface(); event.preventDefault(); } } ); criteria.SetCloseButton( delAnchor ); criteria.UpdateInterface(); // hp.add( delButton ); panel.add( criteria ); if( i < ops.size() - 1 ) { HTML ophtml = new HTML( op ); ophtml.addStyleName( "CriteriaOperator" ); panel.add( ophtml ); } } Button addButton = new Button( "..." ); addButton.addClickHandler( new ClickHandler() { @Override public void onClick( ClickEvent event ) { ops.add( new CriteriaInternal( criteriaMngs ) ); UpdateInterface(); } } ); panel.add( addButton ); content.setWidget( realPanel ); } else if( op.length() > 0 ) { // propose field and value ListBoxEx lbField = new ListBoxEx(); int curSel = -1; for( int i = 0; i < criteriaMngs.length; i++ ) { if( criteriaMngs[i] == field ) curSel = i; lbField.addItem( criteriaMngs[i].getDisplayName(), i ); } if( curSel >= 0 ) lbField.setSelected( curSel ); lbField.setCallback( new ListBoxEx.Callback() { @Override public void onListBoxExChange( ListBoxEx listBoxEx, Object cookie ) { int sel = listBoxEx.getSelected(); field = criteriaMngs[sel]; UpdateInterface(); } }, null ); HorizontalPanel hp = new HorizontalPanel(); hp.add( lbField ); ListBoxEx lbOp = new ListBoxEx(); for( CriteriaOp v : CriteriaOp.values() ) lbOp.addItem( v.getDisplay(), v.ordinal() ); try { lbOp.setSelected( CriteriaOp.valueOf( op ).ordinal() ); } catch( Exception e ) { } lbOp.setCallback( new ListBoxEx.Callback() { @Override public void onListBoxExChange( ListBoxEx listBoxEx, Object cookie ) { op = CriteriaOp.values()[listBoxEx.getSelected()].name(); UpdateInterface(); } }, null ); hp.add( lbOp ); if( field != null ) { Widget valueWidget = field.getValueWidget( value, new ICriteriaFieldMng.Callback() { @Override public void onValueChange( String newValue ) { value = newValue; } } ); hp.add( valueWidget ); } content.setWidget( hp ); } } @Override public String toString() { return getSearchString(); } public String getSearchString() { if( op.length() == 0 ) return ""; if( (op.compareTo( "and" ) == 0) || (op.compareTo( "or" ) == 0) ) { String opsSearchString = "[" + HexaTools.arrayToString( ops ) + "]"; return "{ \"op\":\"" + op + "\" , \"ops\":" + opsSearchString + " }"; } else { return "{ \"field\":\"" + field.getField() + "\", \"op\":\"" + op + "\", \"value\":\"" + value + "\" }"; } } public JSONValue getSearchJson() { if( op.length() == 0 ) return null; if( (op.compareTo( "and" ) == 0) || (op.compareTo( "or" ) == 0) ) { JSONObject obj = new JSONObject(); obj.put( "op", new JSONString( op ) ); JSONArray opsArray = new JSONArray(); for( int i = 0; i < ops.size(); i++ ) { CriteriaInternal ci = ops.get( i ); opsArray.set( i, ci.getSearchJson() ); } obj.put( "ops", opsArray ); return obj; } else { JSONObject obj = new JSONObject(); obj.put( "field", new JSONString( field.getField() ) ); obj.put( "op", new JSONString( op ) ); obj.put( "value", new JSONString( value ) ); return obj; } } private ICriteriaFieldMng findField( String field ) { for( ICriteriaFieldMng mng : criteriaMngs ) if( mng.getField().compareTo( field ) == 0 ) return mng; GWT.log( "ERROR !!! No field found for " + field ); return null; } public void setSearchString( GenericJSO jso ) { this.ops.clear(); String op = jso.getString( "op" ); if( op.compareTo( "and" ) == 0 || op.compareTo( "or" ) == 0 ) { this.op = op; JsArray<GenericJSO> ops = jso.getArray( "ops" ); for( int i = 0; i < ops.length(); i++ ) { CriteriaInternal sub = new CriteriaInternal( criteriaMngs ); sub.setSearchString( ops.get( i ) ); this.ops.add( sub ); } } else { this.field = findField( jso.getString( "field" ) ); if( this.field != null ) { this.op = op; this.value = jso.getString( "value" ); } } UpdateInterface(); } }