package org.openrosa.client.widget.skiprule;
import org.openrosa.client.model.QuestionDef;
import org.openrosa.client.PurcConstants;
import org.openrosa.client.controller.ItemSelectionListener;
import org.openrosa.client.locale.LocaleText;
import org.openrosa.client.model.ModelConstants;
import org.openrosa.client.widget.SelectItemCommand;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Hyperlink;
import com.google.gwt.user.client.ui.MenuBar;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.ScrollPanel;
/**
* Widget used to display the condition operators (eg equal to, less than, greater than, etc)
* for skip and validation rules.
*
* @author daniel
*
*/
public class OperatorHyperlink extends Hyperlink implements ItemSelectionListener {
/** The operator text: is equal to */
public static final String OP_TEXT_EQUAL = LocaleText.get("isEqualTo");
/** The operator text: is not equal to */
public static final String OP_TEXT_NOT_EQUAL = LocaleText.get("isNotEqual");
/** The operator text: is less than */
public static final String OP_TEXT_LESS_THAN = LocaleText.get("isLessThan");
/** The operator text: is less than or equal to */
public static final String OP_TEXT_LESS_THAN_EQUAL = LocaleText.get("isLessThanOrEqual");
/** The operator text: is greater than */
public static final String OP_TEXT_GREATER_THAN = LocaleText.get("isGreaterThan");
/** The operator text: is greater than or equal to */
public static final String OP_TEXT_GREATER_THAN_EQUAL = LocaleText.get("isGreaterThanOrEqual");
/** The operator text: is null */
public static final String OP_TEXT_NULL = LocaleText.get("isNull");
/** The operator text: is null */
public static final String OP_TEXT_NOT_NULL = LocaleText.get("isNotNull");
/** The operator text: is in list */
public static final String OP_TEXT_IN_LIST = LocaleText.get("isInList");
/** The operator text: is not in list */
public static final String OP_TEXT_NOT_IN_LIST = LocaleText.get("isNotInList");
/** The operator text: starts with */
public static final String OP_TEXT_STARTS_WITH = LocaleText.get("startsWith");
/** The operator text: does not start with */
public static final String OP_TEXT_NOT_START_WITH = LocaleText.get("doesNotStartWith");
/** The operator text: contains */
public static final String OP_TEXT_CONTAINS = LocaleText.get("contains");
/** The operator text: does not contain */
public static final String OP_TEXT_NOT_CONTAIN = LocaleText.get("doesNotContain");
/** The operator text: is between */
public static final String OP_TEXT_BETWEEN = LocaleText.get("isBetween");
/** The operator text: is not between */
public static final String OP_TEXT_NOT_BETWEEN = LocaleText.get("isNotBetween");
/** The popup to display the allowed operators for the current question data type. */
private PopupPanel popup;
/** The current question data type. */
private int dataType = QuestionDef.QTN_TYPE_TEXT;
/** The selection change listener. */
private ItemSelectionListener itemSelectionListener;
/**
* Creates a new instance of the operator hyperlink.
*
* @param text the default display text.
* @param targetHistoryToken the history token to which it will link.
* @param itemSelectionListener the listener to selection change events.
*/
public OperatorHyperlink(String text, String targetHistoryToken,ItemSelectionListener itemSelectionListener){
super(text,targetHistoryToken);
this.itemSelectionListener = itemSelectionListener;
DOM.sinkEvents(getElement(), DOM.getEventsSunk(getElement()) | Event.ONMOUSEDOWN );
}
/**
* Sets the data type of the question to which the operator is being applied.
*
* @param dataType the data type.
*/
public void setDataType(int dataType){
this.dataType = dataType;
//We set the universal operator which is valid for all questions,
//as the one to start with or display by default.
setText(OP_TEXT_EQUAL);
}
@Override
public void onBrowserEvent(Event event) {
if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) {
itemSelectionListener.onStartItemSelection(this);
int height = setupPopup();
popup.setPopupPosition(event.getClientX(), event.getClientY()-height);
popup.show();
}
}
/**
* Creates the operator popup for the currently selected question.
*
* @return the height of the popup.
*/
private int setupPopup(){
popup = new PopupPanel(true,true);
int count = 0;
MenuBar menuBar = new MenuBar(true);
if(!(dataType == QuestionDef.QTN_TYPE_GPS || dataType == QuestionDef.QTN_TYPE_VIDEO ||
dataType == QuestionDef.QTN_TYPE_AUDIO || dataType == QuestionDef.QTN_TYPE_IMAGE ||
dataType == QuestionDef.QTN_TYPE_BARCODE)){
menuBar.addItem(OP_TEXT_EQUAL,true, new SelectItemCommand(OP_TEXT_EQUAL,this));
menuBar.addItem(OP_TEXT_NOT_EQUAL,true, new SelectItemCommand(OP_TEXT_NOT_EQUAL,this));
count += 2;
}
if(dataType == QuestionDef.QTN_TYPE_DATE || dataType == QuestionDef.QTN_TYPE_DATE_TIME ||
dataType == QuestionDef.QTN_TYPE_DECIMAL || dataType == QuestionDef.QTN_TYPE_NUMERIC ||
dataType == QuestionDef.QTN_TYPE_TIME || dataType == QuestionDef.QTN_TYPE_REPEAT ||
dataType == QuestionDef.QTN_TYPE_LONG){
menuBar.addItem(OP_TEXT_GREATER_THAN,true,new SelectItemCommand(OP_TEXT_GREATER_THAN,this));
menuBar.addItem(OP_TEXT_GREATER_THAN_EQUAL,true, new SelectItemCommand(OP_TEXT_GREATER_THAN_EQUAL,this));
menuBar.addItem(OP_TEXT_LESS_THAN,true,new SelectItemCommand(OP_TEXT_LESS_THAN,this));
menuBar.addItem(OP_TEXT_LESS_THAN_EQUAL,true, new SelectItemCommand(OP_TEXT_LESS_THAN_EQUAL,this));
menuBar.addItem(OP_TEXT_BETWEEN,true,new SelectItemCommand(OP_TEXT_BETWEEN,this));
menuBar.addItem(OP_TEXT_NOT_BETWEEN,true, new SelectItemCommand(OP_TEXT_NOT_BETWEEN,this));
count += 6;
}
if(dataType == QuestionDef.QTN_TYPE_LIST_EXCLUSIVE || dataType == QuestionDef.QTN_TYPE_LIST_MULTIPLE){
menuBar.addItem(OP_TEXT_IN_LIST,true,new SelectItemCommand(OP_TEXT_IN_LIST,this));
menuBar.addItem(OP_TEXT_NOT_IN_LIST,true, new SelectItemCommand(OP_TEXT_NOT_IN_LIST,this));
count += 2;
}
menuBar.addItem(OP_TEXT_NULL,true, new SelectItemCommand(OP_TEXT_NULL,this));
menuBar.addItem(OP_TEXT_NOT_NULL,true, new SelectItemCommand(OP_TEXT_NOT_NULL,this));
if(dataType == QuestionDef.QTN_TYPE_TEXT ){
menuBar.addItem(OP_TEXT_STARTS_WITH,true,new SelectItemCommand(OP_TEXT_STARTS_WITH,this));
menuBar.addItem(OP_TEXT_NOT_START_WITH,true, new SelectItemCommand(OP_TEXT_NOT_START_WITH,this));
menuBar.addItem(OP_TEXT_CONTAINS,true,new SelectItemCommand(OP_TEXT_CONTAINS,this));
menuBar.addItem(OP_TEXT_NOT_CONTAIN,true, new SelectItemCommand(OP_TEXT_NOT_CONTAIN,this));
count += 4;
}
int height = count*42;
if(height > 200)
height = 200;
ScrollPanel scrollPanel = new ScrollPanel();
scrollPanel.setWidget(menuBar);
scrollPanel.setWidth("300"+PurcConstants.UNITS);
scrollPanel.setHeight(height+PurcConstants.UNITS);
//scrollPanel.setHeight((Window.getClientHeight() - getAbsoluteTop() - 25)+PurcConstants.UNITS);
popup.setWidget(scrollPanel);
return height;
}
/**
* @see org.openrosa.client.controller.ItemSelectionListener#onItemSelected(Object, Object)
*/
public void onItemSelected(Object sender, Object item) {
if(sender instanceof SelectItemCommand){
popup.hide();
setText((String)item);
itemSelectionListener.onItemSelected(this, fromOperatorText2Value((String)item));
}
}
/**
* Converts operator text to its int representation.
*
* @param text the operator text.
* @return the operator int value.
*/
private int fromOperatorText2Value(String text){
if(text.equals(OP_TEXT_EQUAL))
return ModelConstants.OPERATOR_EQUAL;
else if(text.equals(OP_TEXT_NOT_EQUAL))
return ModelConstants.OPERATOR_NOT_EQUAL;
else if(text.equals(OP_TEXT_LESS_THAN))
return ModelConstants.OPERATOR_LESS;
else if(text.equals(OP_TEXT_LESS_THAN_EQUAL))
return ModelConstants.OPERATOR_LESS_EQUAL;
else if(text.equals(OP_TEXT_GREATER_THAN))
return ModelConstants.OPERATOR_GREATER;
else if(text.equals(OP_TEXT_GREATER_THAN_EQUAL))
return ModelConstants.OPERATOR_GREATER_EQUAL;
else if(text.equals(OP_TEXT_NULL))
return ModelConstants.OPERATOR_IS_NULL;
else if(text.equals(OP_TEXT_NOT_NULL))
return ModelConstants.OPERATOR_IS_NOT_NULL;
else if(text.equals(OP_TEXT_IN_LIST))
return ModelConstants.OPERATOR_IN_LIST;
else if(text.equals(OP_TEXT_NOT_IN_LIST))
return ModelConstants.OPERATOR_NOT_IN_LIST;
else if(text.equals(OP_TEXT_STARTS_WITH))
return ModelConstants.OPERATOR_STARTS_WITH;
else if(text.equals(OP_TEXT_NOT_START_WITH))
return ModelConstants.OPERATOR_NOT_START_WITH;
else if(text.equals(OP_TEXT_CONTAINS))
return ModelConstants.OPERATOR_CONTAINS;
else if(text.equals(OP_TEXT_NOT_CONTAIN))
return ModelConstants.OPERATOR_NOT_CONTAIN;
else if(text.equals(OP_TEXT_BETWEEN))
return ModelConstants.OPERATOR_BETWEEN;
else if(text.equals(OP_TEXT_NOT_BETWEEN))
return ModelConstants.OPERATOR_NOT_BETWEEN;
return ModelConstants.OPERATOR_NULL;
}
/**
* @see org.openrosa.client.controller.ItemSelectionListener#onStartItemSelection(Object)
*/
public void onStartItemSelection(Object sender){
}
/**
* Converts the operator int value to its text representation.
*
* @param operator the operator int value.
*/
public void setOperator(int operator){
String operatorText = null;
if(operator == ModelConstants.OPERATOR_EQUAL)
operatorText = OP_TEXT_EQUAL;
else if(operator == ModelConstants.OPERATOR_NOT_EQUAL)
operatorText = OP_TEXT_NOT_EQUAL;
else if(operator == ModelConstants.OPERATOR_LESS)
operatorText = OP_TEXT_LESS_THAN;
else if(operator == ModelConstants.OPERATOR_LESS_EQUAL)
operatorText = OP_TEXT_LESS_THAN_EQUAL;
else if(operator == ModelConstants.OPERATOR_GREATER)
operatorText = OP_TEXT_GREATER_THAN;
else if(operator == ModelConstants.OPERATOR_GREATER_EQUAL)
operatorText = OP_TEXT_GREATER_THAN_EQUAL;
else if(operator == ModelConstants.OPERATOR_IS_NULL)
operatorText = OP_TEXT_NULL;
else if(operator == ModelConstants.OPERATOR_IS_NOT_NULL)
operatorText = OP_TEXT_NOT_NULL;
else if(operator == ModelConstants.OPERATOR_IN_LIST)
operatorText = OP_TEXT_IN_LIST;
else if(operator == ModelConstants.OPERATOR_NOT_IN_LIST)
operatorText = OP_TEXT_NOT_IN_LIST;
else if(operator == ModelConstants.OPERATOR_STARTS_WITH)
operatorText = OP_TEXT_STARTS_WITH;
else if(operator == ModelConstants.OPERATOR_NOT_START_WITH)
operatorText = OP_TEXT_NOT_START_WITH;
else if(operator == ModelConstants.OPERATOR_CONTAINS)
operatorText = OP_TEXT_CONTAINS;
else if(operator == ModelConstants.OPERATOR_NOT_CONTAIN)
operatorText = OP_TEXT_NOT_CONTAIN;
else if(operator == ModelConstants.OPERATOR_BETWEEN)
operatorText = OP_TEXT_BETWEEN;
else if(operator == ModelConstants.OPERATOR_NOT_BETWEEN)
operatorText = OP_TEXT_NOT_BETWEEN;
setText(operatorText);
}
}