use of org.javarosa.form.api.FormEntryCaption in project collect by opendatakit.
the class ODKView method getGroupsPath.
@NonNull
public static String getGroupsPath(FormEntryCaption[] groups) {
StringBuilder path = new StringBuilder("");
if (groups != null) {
String longText;
int multiplicity;
int index = 1;
// list all groups in one string
for (FormEntryCaption group : groups) {
multiplicity = group.getMultiplicity() + 1;
longText = group.getLongText();
if (longText != null) {
path.append(longText);
if (group.repeats() && multiplicity > 0) {
path.append(" (").append(multiplicity).append(")");
}
if (index < groups.length) {
path.append(" > ");
}
index++;
}
}
}
return path.toString();
}
use of org.javarosa.form.api.FormEntryCaption in project collect by opendatakit.
the class FormEntryActivity method createView.
/**
* Creates a view given the View type and an event
*
* @param advancingPage -- true if this results from advancing through the form
* @return newly created View
*/
private View createView(int event, boolean advancingPage) {
FormController formController = getFormController();
setTitle(formController.getFormTitle());
formController.getTimerLogger().logTimerEvent(TimerLogger.EventTypes.FEC, event, formController.getFormIndex().getReference(), advancingPage, true);
switch(event) {
case FormEntryController.EVENT_BEGINNING_OF_FORM:
return createViewForFormBeginning(event, true, formController);
case FormEntryController.EVENT_END_OF_FORM:
View endView = View.inflate(this, R.layout.form_entry_end, null);
((TextView) endView.findViewById(R.id.description)).setText(getString(R.string.save_enter_data_description, formController.getFormTitle()));
// checkbox for if finished or ready to send
final CheckBox instanceComplete = endView.findViewById(R.id.mark_finished);
instanceComplete.setChecked(InstancesDaoHelper.isInstanceComplete(true));
if (!(boolean) AdminSharedPreferences.getInstance().get(AdminKeys.KEY_MARK_AS_FINALIZED)) {
instanceComplete.setVisibility(View.GONE);
}
// edittext to change the displayed name of the instance
final EditText saveAs = endView.findViewById(R.id.save_name);
// disallow carriage returns in the name
InputFilter returnFilter = new InputFilter() {
public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) {
for (int i = start; i < end; i++) {
if (Character.getType((source.charAt(i))) == Character.CONTROL) {
return "";
}
}
return null;
}
};
saveAs.setFilters(new InputFilter[] { returnFilter });
if (formController.getSubmissionMetadata().instanceName == null) {
// no meta/instanceName field in the form -- see if we have a
// name for this instance from a previous save attempt...
String uriMimeType = null;
Uri instanceUri = getIntent().getData();
if (instanceUri != null) {
uriMimeType = getContentResolver().getType(instanceUri);
}
if (saveName == null && uriMimeType != null && uriMimeType.equals(InstanceColumns.CONTENT_ITEM_TYPE)) {
Cursor instance = null;
try {
instance = getContentResolver().query(instanceUri, null, null, null, null);
if (instance != null && instance.getCount() == 1) {
instance.moveToFirst();
saveName = instance.getString(instance.getColumnIndex(InstanceColumns.DISPLAY_NAME));
}
} finally {
if (instance != null) {
instance.close();
}
}
}
if (saveName == null) {
// last resort, default to the form title
saveName = formController.getFormTitle();
}
// present the prompt to allow user to name the form
TextView sa = endView.findViewById(R.id.save_form_as);
sa.setVisibility(View.VISIBLE);
saveAs.setText(saveName);
saveAs.setEnabled(true);
saveAs.setVisibility(View.VISIBLE);
saveAs.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
saveName = String.valueOf(s);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
} else {
// if instanceName is defined in form, this is the name -- no
// revisions
// display only the name, not the prompt, and disable edits
saveName = formController.getSubmissionMetadata().instanceName;
TextView sa = endView.findViewById(R.id.save_form_as);
sa.setVisibility(View.GONE);
saveAs.setText(saveName);
saveAs.setEnabled(false);
saveAs.setVisibility(View.VISIBLE);
}
// override the visibility settings based upon admin preferences
if (!(boolean) AdminSharedPreferences.getInstance().get(AdminKeys.KEY_SAVE_AS)) {
saveAs.setVisibility(View.GONE);
TextView sa = endView.findViewById(R.id.save_form_as);
sa.setVisibility(View.GONE);
}
// Create 'save' button
endView.findViewById(R.id.save_exit_button).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Collect.getInstance().getActivityLogger().logInstanceAction(this, "createView.saveAndExit", instanceComplete.isChecked() ? "saveAsComplete" : "saveIncomplete");
// Form is marked as 'saved' here.
if (saveAs.getText().length() < 1) {
ToastUtils.showShortToast(R.string.save_as_error);
} else {
saveDataToDisk(EXIT, instanceComplete.isChecked(), saveAs.getText().toString());
}
}
});
if (showNavigationButtons) {
backButton.setEnabled(allowMovingBackwards);
nextButton.setEnabled(false);
}
return endView;
case FormEntryController.EVENT_QUESTION:
case FormEntryController.EVENT_GROUP:
case FormEntryController.EVENT_REPEAT:
releaseOdkView();
// should only be a group here if the event_group is a field-list
try {
FormEntryPrompt[] prompts = formController.getQuestionPrompts();
FormEntryCaption[] groups = formController.getGroupsForCurrentIndex();
odkView = new ODKView(this, prompts, groups, advancingPage);
Timber.i("Created view for group %s %s", (groups.length > 0 ? groups[groups.length - 1].getLongText() : "[top]"), (prompts.length > 0 ? prompts[0].getQuestionText() : "[no question]"));
} catch (RuntimeException e) {
Timber.e(e);
// this is badness to avoid a crash.
try {
event = formController.stepToNextScreenEvent();
createErrorDialog(e.getMessage(), DO_NOT_EXIT);
} catch (JavaRosaException e1) {
Timber.d(e1);
createErrorDialog(e.getMessage() + "\n\n" + e1.getCause().getMessage(), DO_NOT_EXIT);
}
return createView(event, advancingPage);
}
// Makes a "clear answer" menu pop up on long-click
for (QuestionWidget qw : odkView.getWidgets()) {
if (!qw.getFormEntryPrompt().isReadOnly()) {
// we want to enable paste option after long click on the EditText
if (qw instanceof StringWidget) {
for (int i = 0; i < qw.getChildCount(); i++) {
if (!(qw.getChildAt(i) instanceof EditText)) {
registerForContextMenu(qw.getChildAt(i));
}
}
} else {
registerForContextMenu(qw);
}
}
}
if (showNavigationButtons) {
backButton.setEnabled(!formController.isCurrentQuestionFirstInForm() && allowMovingBackwards);
nextButton.setEnabled(true);
}
return odkView;
case FormEntryController.EVENT_PROMPT_NEW_REPEAT:
createRepeatDialog();
return new EmptyView(this);
default:
Timber.e("Attempted to create a view that does not exist.");
// this is badness to avoid a crash.
try {
event = formController.stepToNextScreenEvent();
createErrorDialog(getString(R.string.survey_internal_error), EXIT);
} catch (JavaRosaException e) {
Timber.d(e);
createErrorDialog(e.getCause().getMessage(), EXIT);
}
return createView(event, advancingPage);
}
}
use of org.javarosa.form.api.FormEntryCaption in project collect by opendatakit.
the class FormHierarchyActivity method getCurrentPath.
private String getCurrentPath() {
FormController formController = Collect.getInstance().getFormController();
FormIndex index = formController.getFormIndex();
// move to enclosing group...
index = formController.stepIndexOut(index);
List<FormEntryCaption> groups = new ArrayList<>();
while (index != null) {
groups.add(0, formController.getCaptionPrompt(index));
index = formController.stepIndexOut(index);
}
return ODKView.getGroupsPath(groups.toArray(new FormEntryCaption[groups.size()]));
}
use of org.javarosa.form.api.FormEntryCaption in project collect by opendatakit.
the class FormHierarchyActivity method refreshView.
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>();
// 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);
// 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);
}
// 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);
path.setVisibility(View.GONE);
jumpPreviousButton.setEnabled(false);
} else {
path.setVisibility(View.VISIBLE);
path.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;
} 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.
String answerDisplay = FormEntryPromptUtils.getAnswerText(fp, this, formController);
formList.add(new HierarchyElement(FormEntryPromptUtils.markQuestionIfIsRequired(label, fp.isRequired()), answerDisplay, null, Color.WHITE, QUESTION, fp.getIndex()));
}
break;
case FormEntryController.EVENT_GROUP:
// ignore group events
break;
case FormEntryController.EVENT_PROMPT_NEW_REPEAT:
// ignore it.
break;
case FormEntryController.EVENT_REPEAT:
FormEntryCaption fc = formController.getCaptionPrompt();
// push this repeat onto the stack.
repeatGroupRef = currentRef;
if (fc.getMultiplicity() == 0) {
// Display the repeat header for the group.
HierarchyElement group = new HierarchyElement(fc.getLongText(), null, ContextCompat.getDrawable(getApplicationContext(), R.drawable.expander_ic_minimized), Color.WHITE, COLLAPSED, fc.getIndex());
formList.add(group);
}
String repeatLabel = mIndent + fc.getLongText();
if (fc.getFormElement().getChildren().size() == 1 && fc.getFormElement().getChild(0) instanceof GroupDef) {
formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
FormEntryCaption fc2 = formController.getCaptionPrompt();
if (fc2.getLongText() != null) {
repeatLabel = fc2.getLongText();
}
}
repeatLabel += " (" + (fc.getMultiplicity() + 1) + ")";
// Add this group name to the drop down list for this repeating group.
HierarchyElement h = formList.get(formList.size() - 1);
h.addChild(new HierarchyElement(repeatLabel, null, null, Color.WHITE, CHILD, fc.getIndex()));
break;
}
event = formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
}
HierarchyListAdapter itla = new HierarchyListAdapter(this);
itla.setListItems(formList);
listView.setAdapter(itla);
// set the controller back to the current index in case the user hits 'back'
formController.jumpToIndex(currentIndex);
} catch (Exception e) {
Timber.e(e);
createErrorDialog(e.getMessage());
}
}
use of org.javarosa.form.api.FormEntryCaption in project collect by opendatakit.
the class FormController method stepToPreviousScreenEvent.
/**
* Move the current form index to the index of the previous question in the form.
* Step backward out of repeats and groups as needed. If the resulting question
* is itself within a field-list, move upward to the group or repeat defining that
* field-list.
*/
public int stepToPreviousScreenEvent() throws JavaRosaException {
try {
if (getEvent() != FormEntryController.EVENT_BEGINNING_OF_FORM) {
int event = stepToPreviousEvent();
while (event == FormEntryController.EVENT_REPEAT_JUNCTURE || event == FormEntryController.EVENT_PROMPT_NEW_REPEAT || (event == FormEntryController.EVENT_QUESTION && indexIsInFieldList()) || ((event == FormEntryController.EVENT_GROUP || event == FormEntryController.EVENT_REPEAT) && !indexIsInFieldList())) {
event = stepToPreviousEvent();
}
// Handle nested field-list group
if (getEvent() == FormEntryController.EVENT_GROUP) {
FormIndex currentIndex = getFormIndex();
IFormElement element = formEntryController.getModel().getForm().getChild(currentIndex);
if (element instanceof GroupDef) {
GroupDef gd = (GroupDef) element;
if (ODKView.FIELD_LIST.equalsIgnoreCase(gd.getAppearanceAttr())) {
// jump to outermost containing field-list
FormEntryCaption[] fclist = this.getCaptionHierarchy(currentIndex);
for (FormEntryCaption caption : fclist) {
if (groupIsFieldList(caption.getIndex())) {
formEntryController.jumpToIndex(caption.getIndex());
break;
}
}
}
}
}
}
return getEvent();
} catch (RuntimeException e) {
throw new JavaRosaException(e);
}
}
Aggregations