Search in sources :

Example 1 with ImmutableDisplayableQuestion

use of org.odk.collect.android.logic.ImmutableDisplayableQuestion in project collect by opendatakit.

the class FormEntryActivity method updateFieldListQuestions.

/**
 * Saves the form and updates displayed widgets accordingly:
 * - removes widgets corresponding to questions that are no longer relevant
 * - adds widgets corresponding to questions that are newly-relevant
 * - removes and rebuilds widgets corresponding to questions that have changed in some way. For
 * example, the question text or hint may have updated due to a value they refer to changing.
 * <p>
 * The widget corresponding to the {@param lastChangedIndex} is never changed.
 */
private void updateFieldListQuestions(FormIndex lastChangedIndex) throws RepeatsInFieldListException {
    // Save the user-visible state for all questions in this field-list
    FormEntryPrompt[] questionsBeforeSave = getFormController().getQuestionPrompts();
    List<ImmutableDisplayableQuestion> immutableQuestionsBeforeSave = new ArrayList<>();
    for (FormEntryPrompt questionBeforeSave : questionsBeforeSave) {
        immutableQuestionsBeforeSave.add(new ImmutableDisplayableQuestion(questionBeforeSave));
    }
    saveAnswersForCurrentScreen(questionsBeforeSave, immutableQuestionsBeforeSave);
    FormEntryPrompt[] questionsAfterSave = getFormController().getQuestionPrompts();
    Map<FormIndex, FormEntryPrompt> questionsAfterSaveByIndex = new HashMap<>();
    for (FormEntryPrompt question : questionsAfterSave) {
        questionsAfterSaveByIndex.put(question.getIndex(), question);
    }
    // Identify widgets to remove or rebuild (by removing and re-adding). We'd like to do the
    // identification and removal in the same pass but removal has to be done in a loop that
    // starts from the end and itemset-based select choices will only be correctly recomputed
    // if accessed from beginning to end because the call on sameAs is what calls
    // populateDynamicChoices. See https://github.com/getodk/javarosa/issues/436
    List<FormEntryPrompt> questionsThatHaveNotChanged = new ArrayList<>();
    List<FormIndex> formIndexesToRemove = new ArrayList<>();
    for (ImmutableDisplayableQuestion questionBeforeSave : immutableQuestionsBeforeSave) {
        FormEntryPrompt questionAtSameFormIndex = questionsAfterSaveByIndex.get(questionBeforeSave.getFormIndex());
        // bypass SelectChoices stored in ImmutableDisplayableQuestion
        if (questionBeforeSave.sameAs(questionAtSameFormIndex) && !getFormController().usesDatabaseExternalDataFeature(questionBeforeSave.getFormIndex())) {
            questionsThatHaveNotChanged.add(questionAtSameFormIndex);
        } else if (!lastChangedIndex.equals(questionBeforeSave.getFormIndex())) {
            formIndexesToRemove.add(questionBeforeSave.getFormIndex());
        }
    }
    for (int i = immutableQuestionsBeforeSave.size() - 1; i >= 0; i--) {
        ImmutableDisplayableQuestion questionBeforeSave = immutableQuestionsBeforeSave.get(i);
        if (formIndexesToRemove.contains(questionBeforeSave.getFormIndex())) {
            odkView.removeWidgetAt(i);
        }
    }
    for (int i = 0; i < questionsAfterSave.length; i++) {
        if (!questionsThatHaveNotChanged.contains(questionsAfterSave[i]) && !questionsAfterSave[i].getIndex().equals(lastChangedIndex)) {
            // The values of widgets in intent groups are set by the view so widgetValueChanged
            // is never called. This means readOnlyOverride can always be set to false.
            odkView.addWidgetForQuestion(questionsAfterSave[i], i);
        }
    }
}
Also used : ImmutableDisplayableQuestion(org.odk.collect.android.logic.ImmutableDisplayableQuestion) FormEntryPrompt(org.javarosa.form.api.FormEntryPrompt) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) FormIndex(org.javarosa.core.model.FormIndex) FailedConstraint(org.odk.collect.android.javarosawrapper.FormController.FailedConstraint)

Aggregations

ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 FormIndex (org.javarosa.core.model.FormIndex)1 FormEntryPrompt (org.javarosa.form.api.FormEntryPrompt)1 FailedConstraint (org.odk.collect.android.javarosawrapper.FormController.FailedConstraint)1 ImmutableDisplayableQuestion (org.odk.collect.android.logic.ImmutableDisplayableQuestion)1