public BearingWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); setOrientation(LinearLayout.VERTICAL); TableLayout.LayoutParams params = new TableLayout.LayoutParams(); params.setMargins(7, 5, 7, 5); mGetBearingButton = new Button(getContext()); mGetBearingButton.setId(QuestionWidget.newUniqueId()); mGetBearingButton.setPadding(20, 20, 20, 20); mGetBearingButton.setText(getContext().getString(R.string.get_bearing)); mGetBearingButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mGetBearingButton.setEnabled(!prompt.isReadOnly()); mGetBearingButton.setLayoutParams(params); if (prompt.isReadOnly()) { mGetBearingButton.setVisibility(View.GONE); } mStringAnswer = new TextView(getContext()); mStringAnswer.setId(QuestionWidget.newUniqueId()); mAnswerDisplay = new TextView(getContext()); mAnswerDisplay.setId(QuestionWidget.newUniqueId()); mAnswerDisplay.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mAnswerDisplay.setGravity(Gravity.CENTER); String s = prompt.getAnswerText(); if (s != null && !s.equals("")) { mGetBearingButton.setText(getContext().getString(R.string.replace_bearing)); setBinaryData(s); } // when you press the button mGetBearingButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Collect.getInstance() .getActivityLogger() .logInstanceAction(this, "recordBearing", "click", mPrompt.getIndex()); Intent i = null; i = new Intent(getContext(), BearingActivity.class); Collect.getInstance().getFormController().setIndexWaitingForData(mPrompt.getIndex()); ((Activity) getContext()).startActivityForResult(i, FormEntryActivity.BEARING_CAPTURE); } }); addView(mGetBearingButton); addView(mAnswerDisplay); }
public IntegerWidget(Context context, FormEntryPrompt prompt) { super(context, prompt, true); mAnswer.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mAnswer.setInputType(InputType.TYPE_NUMBER_FLAG_SIGNED); // needed to make long readonly text scroll mAnswer.setHorizontallyScrolling(false); mAnswer.setSingleLine(false); // only allows numbers and no periods mAnswer.setKeyListener(new DigitsKeyListener(true, false)); // ints can only hold 2,147,483,648. we allow 999,999,999 InputFilter[] fa = new InputFilter[1]; fa[0] = new InputFilter.LengthFilter(9); mAnswer.setFilters(fa); if (prompt.isReadOnly()) { setBackgroundDrawable(null); setFocusable(false); setClickable(false); } Integer i = getIntegerAnswerValue(); if (i != null) { mAnswer.setText(i.toString()); } setupChangeListener(); }
public StringWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); mAnswer = new EditText(context); mAnswer.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); TableLayout.LayoutParams params = new TableLayout.LayoutParams(); params.setMargins(7, 5, 7, 5); mAnswer.setLayoutParams(params); // capitalize the first letter of the sentence mAnswer.setKeyListener(new TextKeyListener(Capitalize.SENTENCES, false)); // needed to make long read only text scroll mAnswer.setHorizontallyScrolling(false); mAnswer.setSingleLine(false); if (prompt != null) { mReadOnly = prompt.isReadOnly(); String s = prompt.getAnswerText(); if (s != null) { mAnswer.setText(s); } if (mReadOnly) { mAnswer.setBackgroundDrawable(null); mAnswer.setFocusable(false); mAnswer.setClickable(false); } } addView(mAnswer); }
public TriggerWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); mPrompt = prompt; this.setOrientation(LinearLayout.VERTICAL); mTriggerButton = new CheckBox(getContext()); mTriggerButton.setId(QuestionWidget.newUniqueId()); mTriggerButton.setText(getContext().getString(R.string.trigger)); mTriggerButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); // mActionButton.setPadding(20, 20, 20, 20); mTriggerButton.setEnabled(!prompt.isReadOnly()); mTriggerButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { if (mTriggerButton.isChecked()) { mStringAnswer.setText(mOK); Collect.getInstance() .getActivityLogger() .logInstanceAction(TriggerWidget.this, "triggerButton", "OK", mPrompt.getIndex()); } else { mStringAnswer.setText(null); Collect.getInstance() .getActivityLogger() .logInstanceAction( TriggerWidget.this, "triggerButton", "null", mPrompt.getIndex()); } } }); mStringAnswer = new TextView(getContext()); mStringAnswer.setId(QuestionWidget.newUniqueId()); mStringAnswer.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mStringAnswer.setGravity(Gravity.CENTER); String s = prompt.getAnswerText(); if (s != null) { if (s.equals(mOK)) { mTriggerButton.setChecked(true); } else { mTriggerButton.setChecked(false); } mStringAnswer.setText(s); } // finish complex layout this.addView(mTriggerButton); // this.addView(mStringAnswer); }
public UrlWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); setOrientation(LinearLayout.VERTICAL); TableLayout.LayoutParams params = new TableLayout.LayoutParams(); params.setMargins(7, 5, 7, 5); // set button formatting mOpenUrlButton = new Button(getContext()); mOpenUrlButton.setId(QuestionWidget.newUniqueId()); mOpenUrlButton.setText(getContext().getString(R.string.open_url)); mOpenUrlButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mOpenUrlButton.setPadding(20, 20, 20, 20); mOpenUrlButton.setEnabled(!prompt.isReadOnly()); mOpenUrlButton.setLayoutParams(params); mOpenUrlButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Collect.getInstance() .getActivityLogger() .logInstanceAction(this, "openUrl", "click", mPrompt.getIndex()); if (mStringAnswer != null & mStringAnswer.getText() != null && !"".equalsIgnoreCase((String) mStringAnswer.getText())) { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(Uri.parse((String) mStringAnswer.getText())); getContext().startActivity(i); } else { Toast.makeText(getContext(), "No URL set", Toast.LENGTH_SHORT).show(); } } }); // set text formatting mStringAnswer = new TextView(getContext()); mStringAnswer.setId(QuestionWidget.newUniqueId()); mStringAnswer.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mStringAnswer.setGravity(Gravity.CENTER); String s = prompt.getAnswerText(); if (s != null) { mStringAnswer.setText(s); } // finish complex layout addView(mOpenUrlButton); addView(mStringAnswer); }
public DecimalWidget(Context context, FormEntryPrompt prompt, boolean readOnlyOverride) { super(context, prompt, readOnlyOverride, true); // formatting mAnswer.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mAnswer.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL); // needed to make long readonly text scroll mAnswer.setHorizontallyScrolling(false); mAnswer.setSingleLine(false); // only numbers are allowed mAnswer.setKeyListener(new DigitsKeyListener(true, true)); // only 15 characters allowed InputFilter[] fa = new InputFilter[1]; fa[0] = new InputFilter.LengthFilter(15); mAnswer.setFilters(fa); Double d = getDoubleAnswerValue(); NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(15); nf.setMaximumIntegerDigits(15); nf.setGroupingUsed(false); if (d != null) { // truncate to 15 digits max... String dString = nf.format(d); d = Double.parseDouble(dString.replace(',', '.')); mAnswer.setText(d.toString()); } // disable if read only if (prompt.isReadOnly()) { setBackgroundDrawable(null); setFocusable(false); setClickable(false); } setupChangeListener(); }
private FieldSpec convertToFieldSpec(FormEntryPrompt questionPrompt) { QuestionDef question = questionPrompt.getQuestion(); final int dataType = questionPrompt.getDataType(); TreeReference reference = (TreeReference) question.getBind().getReference(); String tag = reference.getNameLast(); String questionLabel = questionPrompt.getQuestion().getLabelInnerText(); if (questionPrompt.isReadOnly()) return FieldSpec.createCustomField(tag, questionLabel, new FieldTypeMessage()); if (isNormalFieldType(dataType)) return FieldSpec.createCustomField(tag, questionLabel, new FieldTypeNormal()); if (dataType == Constants.DATATYPE_DATE) return FieldSpec.createCustomField(tag, questionLabel, new FieldTypeDate()); if (shouldTreatSingleItemChoiceListAsBooleanField(dataType, question)) return FieldSpec.createCustomField(tag, questionLabel, new FieldTypeBoolean()); if (dataType == Constants.DATATYPE_CHOICE) { Vector<ChoiceItem> convertedChoices = new Vector<ChoiceItem>(); List<SelectChoice> choicesToConvert = question.getChoices(); for (SelectChoice choiceToConvert : choicesToConvert) { // String choiceItemCode = choiceToConvert.getValue(); String choiceItemLabel = choiceToConvert.getLabelInnerText(); // Martus doesn't keep Code's when exporting so use Label twice instead convertedChoices.add(new ChoiceItem(choiceItemLabel, choiceItemLabel)); } FieldSpec fieldSpec = new CustomDropDownFieldSpec(convertedChoices); fieldSpec.setTag(tag); fieldSpec.setLabel(questionLabel); return fieldSpec; } MartusLogger.log( "Warning: BulletinFromXFormsLoader.convertToFieldSpec unknown Field Type:" + String.valueOf(dataType)); return null; }
public DecimalWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); // formatting mAnswer.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mAnswer.setInputType(InputType.TYPE_NUMBER_FLAG_DECIMAL); // needed to make long readonly text scroll mAnswer.setHorizontallyScrolling(false); mAnswer.setSingleLine(false); // only numbers are allowed mAnswer.setKeyListener(new DigitsKeyListener(true, true)); // only 15 characters allowed InputFilter[] fa = new InputFilter[1]; fa[0] = new InputFilter.LengthFilter(15); mAnswer.setFilters(fa); // in case xforms calcuate returns a double, convert to integer Double d = null; if (prompt.getAnswerValue() != null) d = (Double) prompt.getAnswerValue().getValue(); NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(15); nf.setMaximumIntegerDigits(15); nf.setGroupingUsed(false); if (d != null) { mAnswer.setText(nf.format(d)); } // disable if read only if (prompt.isReadOnly()) { setBackgroundDrawable(null); setFocusable(false); setClickable(false); } }
public SignatureWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); mInstanceFolder = Collect.getInstance().getFormController().getInstancePath().getParent(); setOrientation(LinearLayout.VERTICAL); TableLayout.LayoutParams params = new TableLayout.LayoutParams(); params.setMargins(7, 5, 7, 5); mErrorTextView = new TextView(context); mErrorTextView.setId(QuestionWidget.newUniqueId()); mErrorTextView.setText("Selected file is not a valid image"); // setup Blank Image Button mSignButton = new Button(getContext()); mSignButton.setId(QuestionWidget.newUniqueId()); mSignButton.setText(getContext().getString(R.string.sign_button)); mSignButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mSignButton.setPadding(20, 20, 20, 20); mSignButton.setEnabled(!prompt.isReadOnly()); mSignButton.setLayoutParams(params); // launch capture intent on click mSignButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Collect.getInstance() .getActivityLogger() .logInstanceAction(this, "signButton", "click", mPrompt.getIndex()); launchSignatureActivity(); } }); // finish complex layout addView(mSignButton); addView(mErrorTextView); // and hide the sign button if read-only if (prompt.isReadOnly()) { mSignButton.setVisibility(View.GONE); } mErrorTextView.setVisibility(View.GONE); // retrieve answer from data model and update ui mBinaryName = prompt.getAnswerText(); // Only add the imageView if the user has signed if (mBinaryName != null) { mImageView = new ImageView(getContext()); mImageView.setId(QuestionWidget.newUniqueId()); Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); int screenWidth = display.getWidth(); int screenHeight = display.getHeight(); File f = new File(mInstanceFolder + File.separator + mBinaryName); if (f.exists()) { Bitmap bmp = FileUtils.getBitmapScaledToDisplay(f, screenHeight, screenWidth); if (bmp == null) { mErrorTextView.setVisibility(View.VISIBLE); } mImageView.setImageBitmap(bmp); } else { mImageView.setImageBitmap(null); } mImageView.setPadding(10, 10, 10, 10); mImageView.setAdjustViewBounds(true); mImageView.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Collect.getInstance() .getActivityLogger() .logInstanceAction(this, "viewImage", "click", mPrompt.getIndex()); launchSignatureActivity(); } }); addView(mImageView); } }
@SuppressWarnings("unchecked") public ListMultiWidget(Context context, FormEntryPrompt prompt, boolean displayLabel) { super(context, prompt); mItems = prompt.getSelectChoices(); mCheckboxes = new ArrayList<CheckBox>(); mPrompt = prompt; // Layout holds the horizontal list of buttons LinearLayout buttonLayout = new LinearLayout(context); Vector<Selection> ve = new Vector<Selection>(); if (prompt.getAnswerValue() != null) { ve = (Vector<Selection>) prompt.getAnswerValue().getValue(); } if (mItems != null) { for (int i = 0; i < mItems.size(); i++) { CheckBox c = new CheckBox(getContext()); c.setTag(Integer.valueOf(i)); c.setId(QuestionWidget.newUniqueId()); c.setFocusable(!prompt.isReadOnly()); c.setEnabled(!prompt.isReadOnly()); for (int vi = 0; vi < ve.size(); vi++) { // match based on value, not key if (mItems.get(i).getValue().equals(ve.elementAt(vi).getValue())) { c.setChecked(true); break; } } mCheckboxes.add(c); // when clicked, check for readonly before toggling c.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!mCheckboxInit && mPrompt.isReadOnly()) { if (buttonView.isChecked()) { buttonView.setChecked(false); Collect.getInstance().getActivityLogger().logInstanceAction(this, "onItemClick.deselect", mItems.get((Integer)buttonView.getTag()).getValue(), mPrompt.getIndex()); } else { buttonView.setChecked(true); Collect.getInstance().getActivityLogger().logInstanceAction(this, "onItemClick.select", mItems.get((Integer)buttonView.getTag()).getValue(), mPrompt.getIndex()); } } } }); String imageURI = null; imageURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), FormEntryCaption.TEXT_FORM_IMAGE); // build image view (if an image is provided) ImageView mImageView = null; TextView mMissingImage = null; final int labelId = QuestionWidget.newUniqueId(); // Now set up the image view String errorMsg = null; if (imageURI != null) { try { String imageFilename = ReferenceManager._().DeriveReference(imageURI).getLocalURI(); final File imageFile = new File(imageFilename); if (imageFile.exists()) { Bitmap b = null; try { Display display = ((WindowManager) getContext().getSystemService( Context.WINDOW_SERVICE)).getDefaultDisplay(); int screenWidth = display.getWidth(); int screenHeight = display.getHeight(); b = FileUtils.getBitmapScaledToDisplay(imageFile, screenHeight, screenWidth); } catch (OutOfMemoryError e) { errorMsg = "ERROR: " + e.getMessage(); } if (b != null) { mImageView = new ImageView(getContext()); mImageView.setPadding(2, 2, 2, 2); mImageView.setAdjustViewBounds(true); mImageView.setImageBitmap(b); mImageView.setId(labelId); } else if (errorMsg == null) { // An error hasn't been logged and loading the image failed, so it's // likely // a bad file. errorMsg = getContext().getString(R.string.file_invalid, imageFile); } } else if (errorMsg == null) { // An error hasn't been logged. We should have an image, but the file // doesn't // exist. errorMsg = getContext().getString(R.string.file_missing, imageFile); } if (errorMsg != null) { // errorMsg is only set when an error has occured Log.e(t, errorMsg); mMissingImage = new TextView(getContext()); mMissingImage.setText(errorMsg); mMissingImage.setPadding(2, 2, 2, 2); mMissingImage.setId(labelId); } } catch (InvalidReferenceException e) { Log.e(t, "image invalid reference exception"); e.printStackTrace(); } } else { // There's no imageURI listed, so just ignore it. } // build text label. Don't assign the text to the built in label to he // button because it aligns horizontally, and we want the label on top TextView label = new TextView(getContext()); label.setText(prompt.getSelectChoiceText(mItems.get(i))); label.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); label.setGravity(Gravity.CENTER_HORIZONTAL); if (!displayLabel) { label.setVisibility(View.GONE); } // answer layout holds the label text/image on top and the radio button on bottom RelativeLayout answer = new RelativeLayout(getContext()); RelativeLayout.LayoutParams headerParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); headerParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); headerParams.addRule(RelativeLayout.CENTER_HORIZONTAL); RelativeLayout.LayoutParams buttonParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); buttonParams.addRule(RelativeLayout.CENTER_HORIZONTAL); if (mImageView != null) { mImageView.setScaleType(ScaleType.CENTER); if (!displayLabel) { mImageView.setVisibility(View.GONE); } answer.addView(mImageView, headerParams); } else if (mMissingImage != null) { answer.addView(mMissingImage, headerParams); } else { if (displayLabel) { label.setId(labelId); answer.addView(label, headerParams); } } if (displayLabel) { buttonParams.addRule(RelativeLayout.BELOW, labelId); } answer.addView(c, buttonParams); answer.setPadding(4, 0, 4, 0); // /Each button gets equal weight LinearLayout.LayoutParams answerParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); answerParams.weight = 1; buttonLayout.addView(answer, answerParams); } } // Align the buttons so that they appear horizonally and are right justified // buttonLayout.setGravity(Gravity.RIGHT); buttonLayout.setOrientation(LinearLayout.HORIZONTAL); // LinearLayout.LayoutParams params = new // LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); // buttonLayout.setLayoutParams(params); // The buttons take up the right half of the screen LinearLayout.LayoutParams buttonParams = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); buttonParams.weight = 1; questionLayout.addView(buttonLayout, buttonParams); addView(questionLayout); }
public AnnotateWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); mInstanceFolder = Collect.getInstance().getFormController().getInstancePath().getParent(); setOrientation(LinearLayout.VERTICAL); TableLayout.LayoutParams params = new TableLayout.LayoutParams(); params.setMargins(7, 5, 7, 5); mErrorTextView = new TextView(context); mErrorTextView.setId(QuestionWidget.newUniqueId()); mErrorTextView.setText("Selected file is not a valid image"); // setup capture button mCaptureButton = new Button(getContext()); mCaptureButton.setId(QuestionWidget.newUniqueId()); mCaptureButton.setText(getContext().getString(R.string.capture_image)); mCaptureButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mCaptureButton.setPadding(20, 20, 20, 20); mCaptureButton.setEnabled(!prompt.isReadOnly()); mCaptureButton.setLayoutParams(params); // launch capture intent on click mCaptureButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Collect.getInstance() .getActivityLogger() .logInstanceAction(this, "captureButton", "click", mPrompt.getIndex()); mErrorTextView.setVisibility(View.GONE); Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); // We give the camera an absolute filename/path where to put the // picture because of bug: // http://code.google.com/p/android/issues/detail?id=1480 // The bug appears to be fixed in Android 2.0+, but as of feb 2, // 2010, G1 phones only run 1.6. Without specifying the path the // images returned by the camera in 1.6 (and earlier) are ~1/4 // the size. boo. // if this gets modified, the onActivityResult in // FormEntyActivity will also need to be updated. i.putExtra( android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Collect.TMPFILE_PATH))); try { Collect.getInstance().getFormController().setIndexWaitingForData(mPrompt.getIndex()); ((Activity) getContext()).startActivityForResult(i, FormEntryActivity.IMAGE_CAPTURE); } catch (ActivityNotFoundException e) { Toast.makeText( getContext(), getContext().getString(R.string.activity_not_found, "image capture"), Toast.LENGTH_SHORT) .show(); Collect.getInstance().getFormController().setIndexWaitingForData(null); } } }); // setup chooser button mChooseButton = new Button(getContext()); mChooseButton.setId(QuestionWidget.newUniqueId()); mChooseButton.setText(getContext().getString(R.string.choose_image)); mChooseButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mChooseButton.setPadding(20, 20, 20, 20); mChooseButton.setEnabled(!prompt.isReadOnly()); mChooseButton.setLayoutParams(params); // launch capture intent on click mChooseButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Collect.getInstance() .getActivityLogger() .logInstanceAction(this, "chooseButton", "click", mPrompt.getIndex()); mErrorTextView.setVisibility(View.GONE); Intent i = new Intent(Intent.ACTION_GET_CONTENT); i.setType("image/*"); try { Collect.getInstance().getFormController().setIndexWaitingForData(mPrompt.getIndex()); ((Activity) getContext()).startActivityForResult(i, FormEntryActivity.IMAGE_CHOOSER); } catch (ActivityNotFoundException e) { Toast.makeText( getContext(), getContext().getString(R.string.activity_not_found, "choose image"), Toast.LENGTH_SHORT) .show(); Collect.getInstance().getFormController().setIndexWaitingForData(null); } } }); // setup Blank Image Button mAnnotateButton = new Button(getContext()); mAnnotateButton.setId(QuestionWidget.newUniqueId()); mAnnotateButton.setText(getContext().getString(R.string.markup_image)); mAnnotateButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mAnnotateButton.setPadding(20, 20, 20, 20); mAnnotateButton.setEnabled(false); mAnnotateButton.setLayoutParams(params); // launch capture intent on click mAnnotateButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Collect.getInstance() .getActivityLogger() .logInstanceAction(this, "annotateButton", "click", mPrompt.getIndex()); launchAnnotateActivity(); } }); // finish complex layout addView(mCaptureButton); addView(mChooseButton); addView(mAnnotateButton); addView(mErrorTextView); // and hide the capture, choose and annotate button if read-only if (prompt.isReadOnly()) { mCaptureButton.setVisibility(View.GONE); mChooseButton.setVisibility(View.GONE); mAnnotateButton.setVisibility(View.GONE); } mErrorTextView.setVisibility(View.GONE); // retrieve answer from data model and update ui mBinaryName = prompt.getAnswerText(); // Only add the imageView if the user has taken a picture if (mBinaryName != null) { if (!prompt.isReadOnly()) { mAnnotateButton.setEnabled(true); } mImageView = new ImageView(getContext()); mImageView.setId(QuestionWidget.newUniqueId()); Display display = ((WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE)) .getDefaultDisplay(); int screenWidth = display.getWidth(); int screenHeight = display.getHeight(); File f = new File(mInstanceFolder + File.separator + mBinaryName); if (f.exists()) { Bitmap bmp = FileUtils.getBitmapScaledToDisplay(f, screenHeight, screenWidth); if (bmp == null) { mErrorTextView.setVisibility(View.VISIBLE); } mImageView.setImageBitmap(bmp); } else { mImageView.setImageBitmap(null); } mImageView.setPadding(10, 10, 10, 10); mImageView.setAdjustViewBounds(true); mImageView.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Collect.getInstance() .getActivityLogger() .logInstanceAction(this, "viewImage", "click", mPrompt.getIndex()); launchAnnotateActivity(); } }); addView(mImageView); } }
public SelectOneAutoAdvanceWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); LayoutInflater inflater = LayoutInflater.from(getContext()); // SurveyCTO-added support for dynamic select content (from .csv files) XPathFuncExpr xPathFuncExpr = ExternalDataUtil.getSearchXPathExpression(prompt.getAppearanceHint()); if (xPathFuncExpr != null) { mItems = ExternalDataUtil.populateExternalChoices(prompt, xPathFuncExpr); } else { mItems = prompt.getSelectChoices(); } buttons = new ArrayList<RadioButton>(); listener = (AdvanceToNextListener) context; String s = null; if (prompt.getAnswerValue() != null) { s = ((Selection) prompt.getAnswerValue().getValue()).getValue(); } // use this for recycle Bitmap b = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.expander_ic_right); if (mItems != null) { for (int i = 0; i < mItems.size(); i++) { RelativeLayout thisParentLayout = (RelativeLayout) inflater.inflate(R.layout.quick_select_layout, null); LinearLayout questionLayout = (LinearLayout) thisParentLayout.getChildAt(0); ImageView rightArrow = (ImageView) thisParentLayout.getChildAt(1); RadioButton r = new RadioButton(getContext()); r.setText(prompt.getSelectChoiceText(mItems.get(i))); r.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); r.setTag(Integer.valueOf(i)); r.setId(QuestionWidget.newUniqueId()); r.setEnabled(!prompt.isReadOnly()); r.setFocusable(!prompt.isReadOnly()); rightArrow.setImageBitmap(b); buttons.add(r); if (mItems.get(i).getValue().equals(s)) { r.setChecked(true); } r.setOnCheckedChangeListener(this); String audioURI = null; audioURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), FormEntryCaption.TEXT_FORM_AUDIO); String imageURI; if (mItems.get(i) instanceof ExternalSelectChoice) { imageURI = ((ExternalSelectChoice) mItems.get(i)).getImage(); } else { imageURI = prompt.getSpecialFormSelectChoiceText( mItems.get(i), FormEntryCaption.TEXT_FORM_IMAGE); } String videoURI = null; videoURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), "video"); String bigImageURI = null; bigImageURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), "big-image"); MediaLayout mediaLayout = new MediaLayout(getContext()); mediaLayout.setAVT(prompt.getIndex(), "", r, audioURI, imageURI, videoURI, bigImageURI); if (i != mItems.size() - 1) { // Last, add the dividing line (except for the last element) ImageView divider = new ImageView(getContext()); divider.setBackgroundResource(android.R.drawable.divider_horizontal_bright); mediaLayout.addDivider(divider); } questionLayout.addView(mediaLayout); addView(thisParentLayout); } } }
public SelectOneWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); // SurveyCTO-added support for dynamic select content (from .csv files) XPathFuncExpr xPathFuncExpr = ExternalDataUtil.getSearchXPathExpression(prompt.getAppearanceHint()); if (xPathFuncExpr != null) { mItems = ExternalDataUtil.populateExternalChoices(prompt, xPathFuncExpr); } else { mItems = prompt.getSelectChoices(); } buttons = new ArrayList<RadioButton>(); // Layout holds the vertical list of buttons LinearLayout buttonLayout = new LinearLayout(context); String s = null; if (prompt.getAnswerValue() != null) { s = ((Selection) prompt.getAnswerValue().getValue()).getValue(); } if (mItems != null) { for (int i = 0; i < mItems.size(); i++) { RadioButton r = new RadioButton(getContext()); r.setText(prompt.getSelectChoiceText(mItems.get(i))); r.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); r.setTag(Integer.valueOf(i)); r.setId(QuestionWidget.newUniqueId()); r.setEnabled(!prompt.isReadOnly()); r.setFocusable(!prompt.isReadOnly()); buttons.add(r); if (mItems.get(i).getValue().equals(s)) { r.setChecked(true); } r.setOnCheckedChangeListener(this); String audioURI = null; audioURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), FormEntryCaption.TEXT_FORM_AUDIO); String imageURI; if (mItems.get(i) instanceof ExternalSelectChoice) { imageURI = ((ExternalSelectChoice) mItems.get(i)).getImage(); } else { imageURI = prompt.getSpecialFormSelectChoiceText( mItems.get(i), FormEntryCaption.TEXT_FORM_IMAGE); } String videoURI = null; videoURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), "video"); String bigImageURI = null; bigImageURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), "big-image"); MediaLayout mediaLayout = new MediaLayout(getContext()); mediaLayout.setAVT( prompt.getIndex(), "." + Integer.toString(i), r, audioURI, imageURI, videoURI, bigImageURI); if (i != mItems.size() - 1) { // Last, add the dividing line (except for the last element) ImageView divider = new ImageView(getContext()); divider.setBackgroundResource(android.R.drawable.divider_horizontal_bright); mediaLayout.addDivider(divider); } buttonLayout.addView(mediaLayout); } } buttonLayout.setOrientation(LinearLayout.VERTICAL); // The buttons take up the right half of the screen LayoutParams buttonParams = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT); addView(buttonLayout, buttonParams); }
public GeoPointWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); mWaitingForData = false; mUseMaps = false; String appearance = prompt.getAppearanceHint(); if ("maps".equalsIgnoreCase(appearance)) { try { // use google maps it exists on the device Class.forName("com.google.android.maps.MapActivity"); mUseMaps = true; } catch (ClassNotFoundException e) { mUseMaps = false; } } setOrientation(LinearLayout.VERTICAL); mStringAnswer = new TextView(getContext()); mAnswerDisplay = new TextView(getContext()); mAnswerDisplay.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); mAnswerDisplay.setGravity(Gravity.CENTER); Spannable locButtonText; boolean viewButtonEnabled; String s = prompt.getAnswerText(); if (s != null && !("".equals(s))) { setBinaryData(s); locButtonText = StringUtils.getStringSpannableRobust(getContext(), R.string.replace_location); viewButtonEnabled = true; } else { locButtonText = StringUtils.getStringSpannableRobust(getContext(), R.string.get_location); viewButtonEnabled = false; } mGetLocationButton = new Button(getContext()); WidgetUtils.setupButton( mGetLocationButton, locButtonText, mAnswerFontsize, !prompt.isReadOnly()); mGetLocationButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { Intent i; if (mUseMaps) { i = new Intent(getContext(), GeoPointMapActivity.class); } else { i = new Intent(getContext(), GeoPointActivity.class); } ((Activity) getContext()).startActivityForResult(i, FormEntryActivity.LOCATION_CAPTURE); mWaitingForData = true; } }); // setup 'view location' button mViewButton = new Button(getContext()); WidgetUtils.setupButton( mViewButton, StringUtils.getStringSpannableRobust(getContext(), R.string.show_location), mAnswerFontsize, viewButtonEnabled); // launch appropriate map viewer mViewButton.setOnClickListener( new View.OnClickListener() { @Override public void onClick(View v) { String s = mStringAnswer.getText().toString(); String[] sa = s.split(" "); double gp[] = new double[4]; gp[0] = Double.valueOf(sa[0]); gp[1] = Double.valueOf(sa[1]); gp[2] = Double.valueOf(sa[2]); gp[3] = Double.valueOf(sa[3]); Intent i = new Intent(getContext(), GeoPointMapActivity.class); i.putExtra(LOCATION, gp); getContext().startActivity(i); } }); addView(mGetLocationButton); if (mUseMaps) { addView(mViewButton); } addView(mAnswerDisplay); }
protected ItemsetWidget( Context context, FormEntryPrompt prompt, boolean readOnlyOverride, boolean derived) { super(context, prompt); mButtons = new RadioGroup(context); mButtons.setId(QuestionWidget.newUniqueId()); mReadOnly = prompt.isReadOnly() || readOnlyOverride; mAnswers = new HashMap<String, String>(); String currentAnswer = prompt.getAnswerText(); // the format of the query should be something like this: // query="instance('cities')/root/item[state=/data/state and county=/data/county]" // "query" is what we're using to notify that this is an // itemset widget. String nodesetStr = prompt.getQuestion().getAdditionalAttribute(null, "query"); // parse out the list name, between the '' String list_name = nodesetStr.substring(nodesetStr.indexOf("'") + 1, nodesetStr.lastIndexOf("'")); // isolate the string between between the [ ] characters String queryString = nodesetStr.substring(nodesetStr.indexOf("[") + 1, nodesetStr.lastIndexOf("]")); StringBuilder selection = new StringBuilder(); // add the list name as the first argument, which will always be there selection.append("list_name=?"); // check to see if there are any arguments if (queryString.indexOf("=") != -1) { selection.append(" and "); } // can't just split on 'and' or 'or' because they have different // behavior, so loop through and break them off until we don't have any // more // must include the spaces in indexOf so we don't match words like // "land" int andIndex = -1; int orIndex = -1; ArrayList<String> arguments = new ArrayList<String>(); while ((andIndex = queryString.indexOf(" and ")) != -1 || (orIndex = queryString.indexOf(" or ")) != -1) { if (andIndex != -1) { String subString = queryString.substring(0, andIndex); String pair[] = subString.split("="); if (pair.length == 2) { selection.append(pair[0].trim() + "=? and "); arguments.add(pair[1].trim()); } else { // parse error } // move string forward to after " and " queryString = queryString.substring(andIndex + 5, queryString.length()); andIndex = -1; } else if (orIndex != -1) { String subString = queryString.substring(0, orIndex); String pair[] = subString.split("="); if (pair.length == 2) { selection.append(pair[0].trim() + "=? or "); arguments.add(pair[1].trim()); } else { // parse error } // move string forward to after " or " queryString = queryString.substring(orIndex + 4, queryString.length()); orIndex = -1; } } // parse the last segment (or only segment if there are no 'and' or 'or' // clauses String pair[] = queryString.split("="); if (pair.length == 2) { selection.append(pair[0].trim() + "=?"); arguments.add(pair[1].trim()); } if (pair.length == 1) { // this is probably okay, because then you just list all items in // the list } else { // parse error } // +1 is for the list_name String[] selectionArgs = new String[arguments.size() + 1]; boolean nullArgs = false; // can't have any null arguments selectionArgs[0] = list_name; // first argument is always listname // loop through the arguments, evaluate any expressions // and build the query string for the DB for (int i = 0; i < arguments.size(); i++) { XPathExpression xpr = null; try { xpr = XPathParseTool.parseXPath(arguments.get(i)); } catch (XPathSyntaxException e) { e.printStackTrace(); TextView error = new TextView(context); error.setText("XPathParser Exception: \"" + arguments.get(i) + "\""); addView(error); break; } if (xpr != null) { FormDef form = Collect.getInstance().getFormController().getFormDef(); TreeElement mTreeElement = form.getMainInstance().resolveReference(prompt.getIndex().getReference()); EvaluationContext ec = new EvaluationContext(form.getEvaluationContext(), mTreeElement.getRef()); Object value = xpr.eval(form.getMainInstance(), ec); if (value == null) { nullArgs = true; } else { if (value instanceof XPathNodeset) { XPathNodeset xpn = (XPathNodeset) value; value = xpn.getValAt(0); } selectionArgs[i + 1] = value.toString(); } } } File itemsetFile = new File( Collect.getInstance().getFormController().getMediaFolder().getAbsolutePath() + "/itemsets.csv"); if (nullArgs) { // we can't try to query with null values else it blows up // so just leave the screen blank // TODO: put an error? } else if (itemsetFile.exists()) { ItemsetDbAdapter ida = new ItemsetDbAdapter(); ida.open(); // name of the itemset table for this form String pathHash = ItemsetDbAdapter.getMd5FromString(itemsetFile.getAbsolutePath()); try { Cursor c = ida.query(pathHash, selection.toString(), selectionArgs); if (c != null) { c.move(-1); while (c.moveToNext()) { String label = ""; String val = ""; // try to get the value associated with the label:lang // string if that doen't exist, then just use label String lang = ""; if (Collect.getInstance().getFormController().getLanguages() != null && Collect.getInstance().getFormController().getLanguages().length > 0) { lang = Collect.getInstance().getFormController().getLanguage(); } // apparently you only need the double quotes in the // column name when creating the column with a : // included String labelLang = "label" + "::" + lang; int langCol = c.getColumnIndex(labelLang); if (langCol == -1) { label = c.getString(c.getColumnIndex("label")); } else { label = c.getString(c.getColumnIndex(labelLang)); } // the actual value is stored in name val = c.getString(c.getColumnIndex("name")); mAnswers.put(label, val); RadioButton rb = new RadioButton(context); rb.setOnCheckedChangeListener(this); rb.setText(label); rb.setTextSize(mAnswerFontsize); mButtons.addView(rb); // have to add it to the radiogroup before checking it, // else it lets two buttons be checked... if (currentAnswer != null && val.compareTo(currentAnswer) == 0) { rb.setChecked(true); } } c.close(); } } finally { ida.close(); } addView(mButtons); } else { TextView error = new TextView(context); error.setText(getContext().getString(R.string.file_missing, itemsetFile.getAbsolutePath())); addView(error); } }
@SuppressWarnings("unchecked") public SelectMultiWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); mPrompt = prompt; mCheckboxes = new ArrayList<CheckBox>(); // SurveyCTO-added support for dynamic select content (from .csv files) XPathFuncExpr xPathFuncExpr = ExternalDataUtil.getSearchXPathExpression(prompt.getAppearanceHint()); if (xPathFuncExpr != null) { mItems = ExternalDataUtil.populateExternalChoices(prompt, xPathFuncExpr); } else { mItems = prompt.getSelectChoices(); } setOrientation(LinearLayout.VERTICAL); Vector<Selection> ve = new Vector<Selection>(); if (prompt.getAnswerValue() != null) { ve = (Vector<Selection>) prompt.getAnswerValue().getValue(); } if (mItems != null) { for (int i = 0; i < mItems.size(); i++) { // no checkbox group so id by answer + offset CheckBox c = new CheckBox(getContext()); c.setTag(Integer.valueOf(i)); c.setId(QuestionWidget.newUniqueId()); c.setText(prompt.getSelectChoiceText(mItems.get(i))); c.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); c.setFocusable(!prompt.isReadOnly()); c.setEnabled(!prompt.isReadOnly()); for (int vi = 0; vi < ve.size(); vi++) { // match based on value, not key if (mItems.get(i).getValue().equals(ve.elementAt(vi).getValue())) { c.setChecked(true); break; } } mCheckboxes.add(c); // when clicked, check for readonly before toggling c.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!mCheckboxInit && mPrompt.isReadOnly()) { if (buttonView.isChecked()) { buttonView.setChecked(false); Collect.getInstance() .getActivityLogger() .logInstanceAction( this, "onItemClick.deselect", mItems.get((Integer) buttonView.getTag()).getValue(), mPrompt.getIndex()); } else { buttonView.setChecked(true); Collect.getInstance() .getActivityLogger() .logInstanceAction( this, "onItemClick.select", mItems.get((Integer) buttonView.getTag()).getValue(), mPrompt.getIndex()); } } } }); String audioURI = null; audioURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), FormEntryCaption.TEXT_FORM_AUDIO); String imageURI; if (mItems.get(i) instanceof ExternalSelectChoice) { imageURI = ((ExternalSelectChoice) mItems.get(i)).getImage(); } else { imageURI = prompt.getSpecialFormSelectChoiceText( mItems.get(i), FormEntryCaption.TEXT_FORM_IMAGE); } String videoURI = null; videoURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), "video"); String bigImageURI = null; bigImageURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), "big-image"); MediaLayout mediaLayout = new MediaLayout(getContext()); mediaLayout.setAVT( prompt.getIndex(), "." + Integer.toString(i), c, audioURI, imageURI, videoURI, bigImageURI); addView(mediaLayout); // Last, add the dividing line between elements (except for the last element) ImageView divider = new ImageView(getContext()); divider.setBackgroundResource(android.R.drawable.divider_horizontal_bright); if (i != mItems.size() - 1) { addView(divider); } } } mCheckboxInit = false; }
@SuppressWarnings("unchecked") public SelectMultiWidget(Context context, FormEntryPrompt prompt) { super(context, prompt); mPrompt = prompt; mCheckboxes = new Vector<CheckBox>(); mItems = prompt.getSelectChoices(); setOrientation(LinearLayout.VERTICAL); Vector<Selection> ve = new Vector<Selection>(); if (prompt.getAnswerValue() != null) { ve = (Vector<Selection>) getCurrentAnswer().getValue(); } // Is this safe enough from collisions? buttonIdBase = Math.abs(prompt.getIndex().toString().hashCode()); if (prompt.getSelectChoices() != null) { for (int i = 0; i < mItems.size(); i++) { // no checkbox group so id by answer + offset final CheckBox c = new CheckBox(getContext()); c.setId(buttonIdBase + i); c.setText(stylize(prompt.getSelectChoiceText(mItems.get(i)))); c.setTextSize(TypedValue.COMPLEX_UNIT_DIP, mAnswerFontsize); c.setFocusable(!prompt.isReadOnly()); c.setEnabled(!prompt.isReadOnly()); int padding = (int) Math.floor(context.getResources().getDimension(R.dimen.select_padding)); c.setPadding(c.getPaddingLeft(), 0, padding, 0); for (int vi = 0; vi < ve.size(); vi++) { // match based on value, not key if (mItems.get(i).getValue().equals(ve.elementAt(vi).getValue())) { c.setChecked(true); break; } } // Note: This gets fired during setup as well, so this listener should only // be added after everything about the checkbox is set up // when clicked, check for readonly before toggling c.setOnCheckedChangeListener( new CompoundButton.OnCheckedChangeListener() { /* * (non-Javadoc) * @see android.widget.CompoundButton.OnCheckedChangeListener#onCheckedChanged(android.widget.CompoundButton, boolean) */ @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (!mCheckboxInit && mPrompt.isReadOnly()) { if (buttonView.isChecked()) { buttonView.setChecked(false); } else { buttonView.setChecked(true); } } widgetEntryChanged(); } }); mCheckboxes.add(c); String audioURI = null; audioURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), FormEntryCaption.TEXT_FORM_AUDIO); String imageURI = null; imageURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), FormEntryCaption.TEXT_FORM_IMAGE); String videoURI = null; videoURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), "video"); String bigImageURI = null; bigImageURI = prompt.getSpecialFormSelectChoiceText(mItems.get(i), "big-image"); MediaLayout mediaLayout = new MediaLayout(getContext()); mediaLayout.setAVT(c, audioURI, imageURI, videoURI, bigImageURI); addView(mediaLayout); mediaLayout.setPadding(0, padding, 0, padding); mediaLayout.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { c.performClick(); } }); // Last, add the dividing line between elements (except for the last element) ImageView divider = new ImageView(getContext()); divider.setBackgroundResource(android.R.drawable.divider_horizontal_bright); if (i != mItems.size() - 1) { addView(divider); } } } mCheckboxInit = false; }
public void refreshView() { try { FormController formController = Collect.getInstance().getFormController(); // Record the current index so we can return to the same place if the user hits 'back'. currentIndex = formController.getFormIndex(); // If we're not at the first level, we're inside a repeated group so we want to only display // everything enclosed within that group. String contextGroupRef = ""; formList = new ArrayList<HierarchyElement>(); // If we're currently at a repeat node, record the name of the node and step to the next // node to display. if (formController.getEvent() == FormEntryController.EVENT_REPEAT) { contextGroupRef = formController.getFormIndex().getReference().toString(true); formController.stepToNextEvent(FormController.STEP_INTO_GROUP); } else { FormIndex startTest = formController.stepIndexOut(currentIndex); // If we have a 'group' tag, we want to step back until we hit a repeat or the // beginning. while (startTest != null && formController.getEvent(startTest) == FormEntryController.EVENT_GROUP) { startTest = formController.stepIndexOut(startTest); } if (startTest == null) { // check to see if the question is at the first level of the hierarchy. If it is, // display the root level from the beginning. formController.jumpToIndex(FormIndex.createBeginningOfFormIndex()); } else { // otherwise we're at a repeated group formController.jumpToIndex(startTest); } // now test again for repeat. This should be true at this point or we're at the // beginning if (formController.getEvent() == FormEntryController.EVENT_REPEAT) { contextGroupRef = formController.getFormIndex().getReference().toString(true); formController.stepToNextEvent(FormController.STEP_INTO_GROUP); } } int event = formController.getEvent(); if (event == FormEntryController.EVENT_BEGINNING_OF_FORM) { // The beginning of form has no valid prompt to display. formController.stepToNextEvent(FormController.STEP_INTO_GROUP); contextGroupRef = formController.getFormIndex().getReference().getParentRef().toString(true); mPath.setVisibility(View.GONE); jumpPreviousButton.setEnabled(false); } else { mPath.setVisibility(View.VISIBLE); mPath.setText(getCurrentPath()); jumpPreviousButton.setEnabled(true); } // Refresh the current event in case we did step forward. event = formController.getEvent(); // Big change from prior implementation: // // The ref strings now include the instance number designations // i.e., [0], [1], etc. of the repeat groups (and also [1] for // non-repeat elements). // // The contextGroupRef is now also valid for the top-level form. // // The repeatGroupRef is null if we are not skipping a repeat // section. // String repeatGroupRef = null; event_search: while (event != FormEntryController.EVENT_END_OF_FORM) { // get the ref to this element String currentRef = formController.getFormIndex().getReference().toString(true); // retrieve the current group String curGroup = (repeatGroupRef == null) ? contextGroupRef : repeatGroupRef; if (!currentRef.startsWith(curGroup)) { // We have left the current group if (repeatGroupRef == null) { // We are done. break event_search; } else { // exit the inner repeat group repeatGroupRef = null; } } if (repeatGroupRef != null) { // We're in a repeat group within the one we want to list // skip this question/group/repeat and move to the next index. event = formController.stepToNextEvent(FormController.STEP_INTO_GROUP); continue; } switch (event) { case FormEntryController.EVENT_QUESTION: FormEntryPrompt fp = formController.getQuestionPrompt(); String label = fp.getLongText(); if (!fp.isReadOnly() || (label != null && label.length() > 0)) { // show the question if it is an editable field. // or if it is read-only and the label is not blank. formList.add( new HierarchyElement( fp.getLongText(), fp.getAnswerText(), null, Color.WHITE, QUESTION, fp.getIndex())); } break; case FormEntryController.EVENT_GROUP: // ignore group events break; case FormEntryController.EVENT_PROMPT_NEW_REPEAT: // this would display the 'add new repeat' dialog // ignore it. break; case FormEntryController.EVENT_REPEAT: FormEntryCaption fc = formController.getCaptionPrompt(); // push this repeat onto the stack. repeatGroupRef = currentRef; // Because of the guard conditions above, we will skip // everything until we exit this repeat. // // Note that currentRef includes the multiplicity of the // repeat (e.g., [0], [1], ...), so every repeat will be // detected as different and reach this case statement. // Only the [0] emits the repeat header. // Every one displays the descend-into action element. if (fc.getMultiplicity() == 0) { // Display the repeat header for the group. HierarchyElement group = new HierarchyElement( fc.getLongText(), null, getResources().getDrawable(R.drawable.expander_ic_minimized), Color.WHITE, COLLAPSED, fc.getIndex()); formList.add(group); } // Add this group name to the drop down list for this repeating group. HierarchyElement h = formList.get(formList.size() - 1); h.addChild( new HierarchyElement( mIndent + fc.getLongText() + " " + (fc.getMultiplicity() + 1), null, null, Color.WHITE, CHILD, fc.getIndex())); break; } event = formController.stepToNextEvent(FormController.STEP_INTO_GROUP); } HierarchyListAdapter itla = new HierarchyListAdapter(this); itla.setListItems(formList); setListAdapter(itla); // set the controller back to the current index in case the user hits 'back' formController.jumpToIndex(currentIndex); } catch (Exception e) { Log.e(t, e.getMessage(), e); createErrorDialog(e.getMessage()); } }