package org.sana.android.procedure; import org.sana.R; import org.sana.android.util.SanaUtil; import org.w3c.dom.Node; import android.content.Context; import android.text.InputType; import android.text.method.DialerKeyListener; import android.text.method.DigitsKeyListener; import android.text.method.KeyListener; import android.util.Log; import android.view.View; import android.view.ViewGroup.LayoutParams; import android.widget.EditText; /** * TextEntryElement is a ProcedureElement that contains a question and a text * box for user response. Numeric inputs can be formatted by specifying the * 'numeric' attribute in the xml. * <p/> * <ul type="none"> * <li><b>Clinical Use </b>Defined by subclasses.</li> * <li><b>Collects </b>A character sequence.</li> * </ul> * * @author Sana Development Team */ public class TextEntryElement extends ProcedureElement { public static final String TAG = TextEntryElement.class.getSimpleName(); protected EditText et; protected NumericType numericType = NumericType.NONE; /** * Available numeric types for entry. It is used to determine acceptable * values and an appropriate key listener. * * @author Sana Development Team */ public enum NumericType { /** Any character */ NONE, /** Any number that can be entered through the keypad */ DIALPAD, /** Any integer. */ INTEGER, /** Any signed integer. */ SIGNED, /** Any signed decimal value. */ DECIMAL } /** {@inheritDoc} */ @Override public ElementType getType() { return ElementType.ENTRY; } /** gets the key listener by type */ protected static KeyListener getKeyListenerForType(NumericType type) { switch (type) { case DIALPAD: return new DialerKeyListener(); case INTEGER: return new DigitsKeyListener(); case SIGNED: return new DigitsKeyListener(true, false); case DECIMAL: return new DigitsKeyListener(true, true); case NONE: default: return null; } } public static final int TYPE_TEXT_FLAG_NO_SUGGESTIONS = 0x00080000; /** {@inheritDoc} */ @Override protected View createView(Context c) { et = new EditText(c); et.setBackgroundResource(R.drawable.oval); et.setTextColor(c.getResources() .getColorStateList(R.color.primary_text_holo_light)); et.setText(answer); et.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); if (!NumericType.NONE.equals(numericType)) { KeyListener listener = getKeyListenerForType(numericType); if (listener != null) et.setKeyListener(listener); } else { et.setRawInputType(InputType.TYPE_TEXT_FLAG_CAP_SENTENCES | TYPE_TEXT_FLAG_NO_SUGGESTIONS); } return encapsulateQuestion(c, et); } /** {@inheritDoc} */ @Override public void setAnswer(String answer) { Log.i(TAG,"["+id+"]setAnswer(String)"); this.answer = new String(answer); if(isViewActive()) { et.setText(this.answer); } Log.d(TAG,"...answer='"+this.answer+"'"); } /** {@inheritDoc} */ @Override public String getAnswer() { Log.i(TAG,"["+id+"]getAnswer()"); if(isViewActive()) { // Need to be certain the answer value is stored answer = (et.getText().length() == 0)? "":et.getText().toString(); } Log.d(TAG,"...returning answer='" + answer + "'"); return answer; } /** Default constructor */ protected TextEntryElement(String id, String question, String answer, String concept, String figure, String audio, NumericType numericType) { super(id, question, answer, concept, figure, audio); this.numericType = numericType; } /** @see ProcedureElement#fromXML(String, String, String, String, String, String, Node) */ public static TextEntryElement fromXML(String id, String question, String answer, String concept, String figure, String audio, Node n) throws ProcedureParseException { String numericStr = SanaUtil.getNodeAttributeOrDefault(n, "numeric", "NONE"); NumericType numericType = NumericType.NONE; try { numericType = NumericType.valueOf(numericStr); } catch (Exception e) { Log.e(TAG, "Could not parse numeric type: " + e.toString()); e.printStackTrace(); } return new TextEntryElement(id, question, answer, concept, figure, audio, numericType); } }