use of org.odk.collect.android.javarosawrapper.FormController in project collect by opendatakit.
the class FormHierarchyActivity method didDeleteLastRepeatItem.
/**
* After having deleted the current index,
* returns true if the current index was the only item in the repeat group.
*/
private boolean didDeleteLastRepeatItem() {
FormController formController = Collect.getInstance().getFormController();
FormIndex index = formController.getFormIndex();
int event = formController.getEvent(index);
// it must be the last remaining item.
return event == FormEntryController.EVENT_PROMPT_NEW_REPEAT && index.getElementMultiplicity() == 0;
}
use of org.odk.collect.android.javarosawrapper.FormController in project collect by opendatakit.
the class FormHierarchyActivity method onCreate.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hierarchy_layout);
Collect.getInstance().getComponent().inject(this);
recyclerView = findViewById(R.id.list);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));
TextView emptyView = findViewById(android.R.id.empty);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FormController formController = Collect.getInstance().getFormController();
// https://github.com/getodk/collect/issues/998
if (formController == null) {
finish();
Timber.w("FormController is null");
return;
}
formEntryViewModel = new ViewModelProvider(this, formEntryViewModelFactory).get(FormEntryViewModel.class);
formEntryViewModel.formLoaded(Collect.getInstance().getFormController());
startIndex = formController.getFormIndex();
setTitle(formController.getFormTitle());
groupPathTextView = findViewById(R.id.pathtext);
jumpBeginningButton = findViewById(R.id.jumpBeginningButton);
jumpEndButton = findViewById(R.id.jumpEndButton);
configureButtons(formController);
restoreInstanceState(savedInstanceState);
refreshView();
// TODO: avoid another iteration through all displayed elements
if (recyclerView != null && recyclerView.getAdapter() != null && recyclerView.getAdapter().getItemCount() > 0) {
emptyView.setVisibility(View.GONE);
recyclerView.post(() -> {
int position = 0;
// startIndex which can either represent a question or a field list.
for (HierarchyElement hierarchyElement : elementsToDisplay) {
FormIndex indexToCheck = hierarchyElement.getFormIndex();
if (startIndex.equals(indexToCheck) || (formController.indexIsInFieldList(startIndex) && indexToCheck.toString().startsWith(startIndex.toString()))) {
position = elementsToDisplay.indexOf(hierarchyElement);
break;
}
}
((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPositionWithOffset(position, 0);
});
}
}
use of org.odk.collect.android.javarosawrapper.FormController in project collect by opendatakit.
the class FormHierarchyActivity method goToPreviousEvent.
/**
* Similar to {@link #goUpLevel}, but makes a less significant step backward.
* This is only used when the caller knows where to go back to,
* e.g. after deleting the final remaining item in a repeat group.
*/
private void goToPreviousEvent() {
FormController formController = Collect.getInstance().getFormController();
try {
formController.stepToPreviousScreenEvent();
} catch (JavaRosaException e) {
Timber.d(e);
createErrorDialog(e.getCause().getMessage());
return;
}
refreshView();
}
use of org.odk.collect.android.javarosawrapper.FormController in project collect by opendatakit.
the class FormHierarchyActivity method getCurrentPath.
/**
* Returns a string representing the 'path' of the current screen.
* Each level is separated by `>`.
*/
private String getCurrentPath() {
FormController formController = Collect.getInstance().getFormController();
FormIndex index = formController.getFormIndex();
// very first group in a form which is auto-entered).
if (formController.getEvent(index) == FormEntryController.EVENT_QUESTION || getPreviousLevel(index) == null) {
index = getPreviousLevel(index);
}
List<FormEntryCaption> groups = new ArrayList<>();
if (shouldShowRepeatGroupPicker()) {
groups.add(formController.getCaptionPrompt(repeatGroupPickerIndex));
}
while (index != null) {
groups.add(0, formController.getCaptionPrompt(index));
index = getPreviousLevel(index);
}
// If the repeat picker is showing, don't show an item number for the current index.
boolean hideLastMultiplicity = shouldShowRepeatGroupPicker();
return ODKView.getGroupsPath(groups.toArray(new FormEntryCaption[0]), hideLastMultiplicity);
}
use of org.odk.collect.android.javarosawrapper.FormController in project collect by opendatakit.
the class FormHierarchyActivity method refreshView.
/**
* @see #refreshView()
*/
private void refreshView(boolean isGoingUp) {
try {
FormController formController = Collect.getInstance().getFormController();
// Save the current index so we can return to the problematic question
// in the event of an error.
currentIndex = formController.getFormIndex();
elementsToDisplay = new ArrayList<>();
jumpToHierarchyStartIndex();
updateOptionsMenu();
int event = formController.getEvent();
if (event == FormEntryController.EVENT_BEGINNING_OF_FORM && !shouldShowRepeatGroupPicker()) {
// The beginning of form has no valid prompt to display.
groupPathTextView.setVisibility(View.GONE);
} else {
groupPathTextView.setVisibility(View.VISIBLE);
groupPathTextView.setText(getCurrentPath());
}
// Refresh the current event in case we did step forward.
event = formController.getEvent();
// Ref to the parent group that's currently being displayed.
//
// Because of the guard conditions below, we will skip
// everything until we exit this group.
TreeReference visibleGroupRef = null;
while (event != FormEntryController.EVENT_END_OF_FORM) {
// get the ref to this element
TreeReference currentRef = formController.getFormIndex().getReference();
// retrieve the current group
TreeReference curGroup = (visibleGroupRef == null) ? contextGroupRef : visibleGroupRef;
if (curGroup != null && !curGroup.isParentOf(currentRef, false)) {
// We have left the current group
if (visibleGroupRef == null) {
// We are done.
break;
} else {
// exit the inner group
visibleGroupRef = null;
}
}
if (visibleGroupRef != null) {
// We're in a 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:
{
// Nothing but repeat group instances should show up in the picker.
if (shouldShowRepeatGroupPicker()) {
break;
}
FormEntryPrompt fp = formController.getQuestionPrompt();
String label = fp.getShortText();
String answerDisplay = FormEntryPromptUtils.getAnswerText(fp, this, formController);
elementsToDisplay.add(new HierarchyElement(FormEntryPromptUtils.markQuestionIfIsRequired(label, fp.isRequired()), answerDisplay, null, HierarchyElement.Type.QUESTION, fp.getIndex()));
break;
}
case FormEntryController.EVENT_GROUP:
{
if (!formController.isGroupRelevant()) {
break;
}
// Nothing but repeat group instances should show up in the picker.
if (shouldShowRepeatGroupPicker()) {
break;
}
FormIndex index = formController.getFormIndex();
// Only display groups with a specific appearance attribute.
if (!formController.isDisplayableGroup(index)) {
break;
}
// Don't render other groups' children.
if (contextGroupRef != null && !contextGroupRef.isParentOf(currentRef, false)) {
break;
}
visibleGroupRef = currentRef;
FormEntryCaption caption = formController.getCaptionPrompt();
HierarchyElement groupElement = new HierarchyElement(caption.getShortText(), getString(R.string.group_label), ContextCompat.getDrawable(this, R.drawable.ic_folder_open), HierarchyElement.Type.VISIBLE_GROUP, caption.getIndex());
elementsToDisplay.add(groupElement);
// Skip to the next item outside the group.
event = formController.stepOverGroup();
continue;
}
case FormEntryController.EVENT_PROMPT_NEW_REPEAT:
{
// ignore it.
break;
}
case FormEntryController.EVENT_REPEAT:
{
boolean forPicker = shouldShowRepeatGroupPicker();
// Only break to exclude non-relevant repeat from picker
if (!formController.isGroupRelevant() && forPicker) {
break;
}
visibleGroupRef = currentRef;
// Don't render other groups' children.
if (contextGroupRef != null && !contextGroupRef.isParentOf(currentRef, false)) {
break;
}
FormEntryCaption fc = formController.getCaptionPrompt();
if (forPicker) {
// Don't render other groups' instances.
String repeatGroupPickerRef = repeatGroupPickerIndex.getReference().toString(false);
if (!currentRef.toString(false).equals(repeatGroupPickerRef)) {
break;
}
int itemNumber = fc.getMultiplicity() + 1;
// e.g. `friends > 1`
String repeatLabel = fc.getShortText() + " > " + itemNumber;
// If the child of the group has a more descriptive label, use that instead.
if (fc.getFormElement().getChildren().size() == 1 && fc.getFormElement().getChild(0) instanceof GroupDef) {
formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
String itemLabel = formController.getCaptionPrompt().getShortText();
if (itemLabel != null) {
// e.g. `1. Alice`
repeatLabel = itemNumber + ".\u200E " + itemLabel;
}
}
HierarchyElement instance = new HierarchyElement(repeatLabel, null, null, HierarchyElement.Type.REPEAT_INSTANCE, fc.getIndex());
elementsToDisplay.add(instance);
} else if (fc.getMultiplicity() == 0) {
// Display the repeat header for the group.
HierarchyElement group = new HierarchyElement(fc.getShortText(), getString(R.string.repeatable_group_label), ContextCompat.getDrawable(this, R.drawable.ic_repeat), HierarchyElement.Type.REPEATABLE_GROUP, fc.getIndex());
elementsToDisplay.add(group);
}
break;
}
}
event = formController.stepToNextEvent(FormController.STEP_INTO_GROUP);
}
recyclerView.setAdapter(new HierarchyListAdapter(elementsToDisplay, this::onElementClick));
formController.jumpToIndex(currentIndex);
// that use presentation groups to display labels).
if (isDisplayingSingleGroup() && !screenIndex.isBeginningOfFormIndex()) {
if (isGoingUp) {
// Back out once more.
goUpLevel();
} else {
// Enter automatically.
formController.jumpToIndex(elementsToDisplay.get(0).getFormIndex());
refreshView();
}
}
} catch (Exception e) {
Timber.e(e);
createErrorDialog(e.getMessage());
}
}
Aggregations