Search in sources :

Example 16 with FormIndex

use of org.javarosa.core.model.FormIndex in project javarosa by opendatakit.

the class FormEntryModel method getCompoundIndices.

public FormIndex[] getCompoundIndices(FormIndex container) {
    // ArrayLists are a no-go for J2ME
    List<FormIndex> indices = new ArrayList<FormIndex>();
    FormIndex walker = incrementIndex(container);
    while (FormIndex.isSubElement(container, walker)) {
        if (isIndexRelevant(walker)) {
            indices.add(walker);
        }
        walker = incrementIndex(walker);
    }
    FormIndex[] array = new FormIndex[indices.size()];
    for (int i = 0; i < indices.size(); ++i) {
        array[i] = indices.get(i);
    }
    return array;
}
Also used : ArrayList(java.util.ArrayList) FormIndex(org.javarosa.core.model.FormIndex)

Example 17 with FormIndex

use of org.javarosa.core.model.FormIndex 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;
}
Also used : FormController(org.odk.collect.android.javarosawrapper.FormController) FormIndex(org.javarosa.core.model.FormIndex)

Example 18 with FormIndex

use of org.javarosa.core.model.FormIndex 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);
        });
    }
}
Also used : FormController(org.odk.collect.android.javarosawrapper.FormController) HierarchyElement(org.odk.collect.android.logic.HierarchyElement) FormIndex(org.javarosa.core.model.FormIndex) TextView(android.widget.TextView) FormEntryViewModel(org.odk.collect.android.formentry.FormEntryViewModel) LinearLayoutManager(androidx.recyclerview.widget.LinearLayoutManager) DividerItemDecoration(androidx.recyclerview.widget.DividerItemDecoration) Toolbar(androidx.appcompat.widget.Toolbar) ViewModelProvider(androidx.lifecycle.ViewModelProvider)

Example 19 with FormIndex

use of org.javarosa.core.model.FormIndex 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);
}
Also used : FormController(org.odk.collect.android.javarosawrapper.FormController) FormEntryCaption(org.javarosa.form.api.FormEntryCaption) ArrayList(java.util.ArrayList) FormIndex(org.javarosa.core.model.FormIndex)

Example 20 with FormIndex

use of org.javarosa.core.model.FormIndex 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());
    }
}
Also used : FormController(org.odk.collect.android.javarosawrapper.FormController) FormEntryPrompt(org.javarosa.form.api.FormEntryPrompt) HierarchyElement(org.odk.collect.android.logic.HierarchyElement) TreeReference(org.javarosa.core.model.instance.TreeReference) HierarchyListAdapter(org.odk.collect.android.adapters.HierarchyListAdapter) FormEntryCaption(org.javarosa.form.api.FormEntryCaption) FormIndex(org.javarosa.core.model.FormIndex) GroupDef(org.javarosa.core.model.GroupDef) JavaRosaException(org.odk.collect.android.exception.JavaRosaException)

Aggregations

FormIndex (org.javarosa.core.model.FormIndex)63 GroupDef (org.javarosa.core.model.GroupDef)11 JavaRosaException (org.odk.collect.android.exception.JavaRosaException)11 FormController (org.odk.collect.android.javarosawrapper.FormController)11 ArrayList (java.util.ArrayList)10 FormEntryPrompt (org.javarosa.form.api.FormEntryPrompt)10 Test (org.junit.Test)10 IFormElement (org.javarosa.core.model.IFormElement)6 TreeReference (org.javarosa.core.model.instance.TreeReference)6 FormEntryCaption (org.javarosa.form.api.FormEntryCaption)6 File (java.io.File)5 FormController (org.odk.collect.android.logic.FormController)5 HierarchyElement (org.odk.collect.android.logic.HierarchyElement)5 IAnswerData (org.javarosa.core.model.data.IAnswerData)4 HierarchyListAdapter (org.odk.collect.android.adapters.HierarchyListAdapter)4 FormDef (org.javarosa.core.model.FormDef)3 FormEntryModel (org.javarosa.form.api.FormEntryModel)3 Intent (android.content.Intent)2 ObjectInputStream (java.io.ObjectInputStream)2 HashMap (java.util.HashMap)2