Search in sources :

Example 6 with IFormElement

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

the class FormEntryModel method decrementHelper.

private void decrementHelper(List<Integer> indexes, List<Integer> multiplicities, List<IFormElement> elements) {
    int i = indexes.size() - 1;
    if (i != -1) {
        int curIndex = indexes.get(i);
        int curMult = multiplicities.get(i);
        if (repeatStructure == REPEAT_STRUCTURE_NON_LINEAR && elements.get(elements.size() - 1) instanceof GroupDef && ((GroupDef) elements.get(elements.size() - 1)).getRepeat() && multiplicities.get(multiplicities.size() - 1) != TreeReference.INDEX_REPEAT_JUNCTURE) {
            multiplicities.set(i, TreeReference.INDEX_REPEAT_JUNCTURE);
            return;
        } else if (repeatStructure != REPEAT_STRUCTURE_NON_LINEAR && curMult > 0) {
            multiplicities.set(i, curMult - 1);
        } else if (curIndex > 0) {
            // set node to previous element
            indexes.set(i, curIndex - 1);
            multiplicities.set(i, 0);
            elements.set(i, (i == 0 ? form : elements.get(i - 1)).getChild(curIndex - 1));
            if (setRepeatNextMultiplicity(elements, multiplicities))
                return;
        } else {
            // at absolute beginning of current level; index to parent
            indexes.remove(i);
            multiplicities.remove(i);
            elements.remove(i);
            return;
        }
    }
    IFormElement element = (i < 0 ? form : elements.get(i));
    while (!(element instanceof QuestionDef)) {
        if (element.getChildren() == null || element.getChildren().size() == 0) {
            // if there are no children we just return the current index (the group itself)
            return;
        }
        int subIndex = element.getChildren().size() - 1;
        element = element.getChild(subIndex);
        indexes.add(subIndex);
        multiplicities.add(0);
        elements.add(element);
        if (setRepeatNextMultiplicity(elements, multiplicities))
            return;
    }
}
Also used : IFormElement(org.javarosa.core.model.IFormElement) QuestionDef(org.javarosa.core.model.QuestionDef) GroupDef(org.javarosa.core.model.GroupDef)

Example 7 with IFormElement

use of org.javarosa.core.model.IFormElement in project collect by opendatakit.

the class FormHierarchyActivity method isGroupSizeLocked.

/**
 * Returns true if the current index is a group that's designated as `noAddRemove`
 * (e.g. if `jr:count` is explicitly set).
 */
private boolean isGroupSizeLocked(FormIndex index) {
    FormController formController = Collect.getInstance().getFormController();
    IFormElement element = formController.getCaptionPrompt(index).getFormElement();
    return element instanceof GroupDef && ((GroupDef) element).noAddRemove;
}
Also used : FormController(org.odk.collect.android.javarosawrapper.FormController) IFormElement(org.javarosa.core.model.IFormElement) GroupDef(org.javarosa.core.model.GroupDef)

Example 8 with IFormElement

use of org.javarosa.core.model.IFormElement in project collect by opendatakit.

the class ODKView method addIntentLaunchButton.

/**
 * Adds a button to launch an intent if the group displayed by this view is an intent group.
 * An intent group launches an intent and receives multiple values from the launched app.
 */
private void addIntentLaunchButton(Context context, FormEntryPrompt[] questionPrompts, FormEntryCaption c, String intentString) {
    final String buttonText;
    final String errorString;
    String v = c.getSpecialFormQuestionText("buttonText");
    buttonText = (v != null) ? v : context.getString(R.string.launch_app);
    v = c.getSpecialFormQuestionText("noAppErrorString");
    errorString = (v != null) ? v : context.getString(R.string.no_app);
    // set button formatting
    MaterialButton launchIntentButton = findViewById(R.id.launchIntentButton);
    launchIntentButton.setText(buttonText);
    launchIntentButton.setTextSize(TypedValue.COMPLEX_UNIT_DIP, QuestionFontSizeUtils.getQuestionFontSize() + 2);
    launchIntentButton.setVisibility(VISIBLE);
    launchIntentButton.setOnClickListener(view -> {
        String intentName = ExternalAppsUtils.extractIntentName(intentString);
        Map<String, String> parameters = ExternalAppsUtils.extractParameters(intentString);
        Intent i = new Intent(intentName);
        if (i.resolveActivity(Collect.getInstance().getPackageManager()) == null) {
            Intent launchIntent = Collect.getInstance().getPackageManager().getLaunchIntentForPackage(intentName);
            if (launchIntent != null) {
                // Make sure FLAG_ACTIVITY_NEW_TASK is not set because it doesn't work with startActivityForResult
                launchIntent.setFlags(0);
                i = launchIntent;
            }
        }
        try {
            ExternalAppsUtils.populateParameters(i, parameters, c.getIndex().getReference());
            for (FormEntryPrompt p : questionPrompts) {
                IFormElement formElement = p.getFormElement();
                if (formElement instanceof QuestionDef) {
                    TreeReference reference = (TreeReference) formElement.getBind().getReference();
                    IAnswerData answerValue = p.getAnswerValue();
                    Object value = answerValue == null ? null : answerValue.getValue();
                    switch(p.getDataType()) {
                        case Constants.DATATYPE_TEXT:
                        case Constants.DATATYPE_INTEGER:
                        case Constants.DATATYPE_DECIMAL:
                        case Constants.DATATYPE_BINARY:
                            i.putExtra(reference.getNameLast(), (Serializable) value);
                            break;
                    }
                }
            }
            ((Activity) getContext()).startActivityForResult(i, RequestCodes.EX_GROUP_CAPTURE);
        } catch (ExternalParamsException e) {
            Timber.e(e, "ExternalParamsException");
            ToastUtils.showShortToast(getContext(), e.getMessage());
        } catch (ActivityNotFoundException e) {
            Timber.d(e, "ActivityNotFoundExcept");
            ToastUtils.showShortToast(getContext(), errorString);
        }
    });
}
Also used : IAnswerData(org.javarosa.core.model.data.IAnswerData) FormEntryPrompt(org.javarosa.form.api.FormEntryPrompt) ComponentActivity(androidx.activity.ComponentActivity) Activity(android.app.Activity) Intent(android.content.Intent) MaterialButton(com.google.android.material.button.MaterialButton) IFormElement(org.javarosa.core.model.IFormElement) ExternalParamsException(org.odk.collect.android.exception.ExternalParamsException) ActivityNotFoundException(android.content.ActivityNotFoundException) TreeReference(org.javarosa.core.model.instance.TreeReference) QuestionDef(org.javarosa.core.model.QuestionDef)

Example 9 with IFormElement

use of org.javarosa.core.model.IFormElement in project collect by opendatakit.

the class FormController method getQuestionPrompts.

/**
 * Returns an array of question prompts corresponding to the current {@link FormIndex}. These
 * are the prompts that should be displayed to the user and don't include any non-relevant
 * questions.
 * <p>
 * The array has a single element if there is a question at this {@link FormIndex} or multiple
 * elements if there is a group.
 *
 * @throws RepeatsInFieldListException if there is a group at this {@link FormIndex} and it contains
 *                          elements that are not questions or regular (non-repeat) groups.
 */
public FormEntryPrompt[] getQuestionPrompts() throws RepeatsInFieldListException {
    // For questions, there is only one.
    // For groups, there could be many, but we set that below
    FormEntryPrompt[] questions = new FormEntryPrompt[0];
    IFormElement element = formEntryController.getModel().getForm().getChild(getFormIndex());
    if (element instanceof GroupDef) {
        GroupDef gd = (GroupDef) element;
        // we only display relevant questions
        List<FormEntryPrompt> questionList = new ArrayList<>();
        for (FormIndex index : getIndicesForGroup(gd)) {
            if (getEvent(index) != FormEntryController.EVENT_QUESTION) {
                throw new RepeatsInFieldListException("Repeats in 'field-list' groups " + "are not supported. Please update the form design to remove the " + "following repeat from a field list: " + index.getReference().toString(false));
            }
            // we only display relevant questions
            if (formEntryController.getModel().isIndexRelevant(index)) {
                questionList.add(getQuestionPrompt(index));
            }
            questions = new FormEntryPrompt[questionList.size()];
            questionList.toArray(questions);
        }
    } else {
        // We have a question, so just get the one prompt
        questions = new FormEntryPrompt[1];
        questions[0] = getQuestionPrompt();
    }
    return questions;
}
Also used : IFormElement(org.javarosa.core.model.IFormElement) FormEntryPrompt(org.javarosa.form.api.FormEntryPrompt) ArrayList(java.util.ArrayList) FormIndex(org.javarosa.core.model.FormIndex) GroupDef(org.javarosa.core.model.GroupDef)

Example 10 with IFormElement

use of org.javarosa.core.model.IFormElement in project collect by opendatakit.

the class FormController method getIndicesForGroup.

private List<FormIndex> getIndicesForGroup(GroupDef gd, FormIndex currentChildIndex, boolean jumpIntoRepeatGroups) {
    List<FormIndex> indices = new ArrayList<>();
    for (int i = 0; i < gd.getChildren().size(); i++) {
        final FormEntryModel formEntryModel = formEntryController.getModel();
        if (getEvent(currentChildIndex) == FormEntryController.EVENT_GROUP || (jumpIntoRepeatGroups && getEvent(currentChildIndex) == FormEntryController.EVENT_REPEAT)) {
            IFormElement nestedElement = formEntryModel.getForm().getChild(currentChildIndex);
            if (nestedElement instanceof GroupDef) {
                indices.addAll(getIndicesForGroup((GroupDef) nestedElement, formEntryModel.incrementIndex(currentChildIndex, true), jumpIntoRepeatGroups));
                currentChildIndex = formEntryModel.incrementIndex(currentChildIndex, false);
            }
        } else if (!jumpIntoRepeatGroups || getEvent(currentChildIndex) != FormEntryController.EVENT_PROMPT_NEW_REPEAT) {
            indices.add(currentChildIndex);
            currentChildIndex = formEntryModel.incrementIndex(currentChildIndex, false);
        }
    }
    return indices;
}
Also used : IFormElement(org.javarosa.core.model.IFormElement) FormEntryModel(org.javarosa.form.api.FormEntryModel) ArrayList(java.util.ArrayList) FormIndex(org.javarosa.core.model.FormIndex) GroupDef(org.javarosa.core.model.GroupDef)

Aggregations

IFormElement (org.javarosa.core.model.IFormElement)26 GroupDef (org.javarosa.core.model.GroupDef)19 QuestionDef (org.javarosa.core.model.QuestionDef)10 ArrayList (java.util.ArrayList)9 TreeReference (org.javarosa.core.model.instance.TreeReference)8 FormIndex (org.javarosa.core.model.FormIndex)6 TreeElement (org.javarosa.core.model.instance.TreeElement)6 FormEntryPrompt (org.javarosa.form.api.FormEntryPrompt)5 IDataReference (org.javarosa.core.model.IDataReference)4 AbstractTreeElement (org.javarosa.core.model.instance.AbstractTreeElement)3 XPathReference (org.javarosa.model.xform.XPathReference)3 Element (org.kxml2.kdom.Element)3 DataBinding (org.javarosa.core.model.DataBinding)2 Constraint (org.javarosa.core.model.condition.Constraint)2 IAnswerData (org.javarosa.core.model.data.IAnswerData)2 FormEntryModel (org.javarosa.form.api.FormEntryModel)2 Test (org.junit.Test)2 QuestionDetails (org.odk.collect.android.formentry.questions.QuestionDetails)2 MockFormEntryPromptBuilder (org.odk.collect.android.support.MockFormEntryPromptBuilder)2 Activity (android.app.Activity)1