use of org.javarosa.core.model.FormIndex 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;
}
use of org.javarosa.core.model.FormIndex in project collect by opendatakit.
the class FormController method stepOverGroup.
/**
* If using a view like HierarchyView that doesn't support multi-question per screen, step over
* the group represented by the FormIndex.
*/
public int stepOverGroup() {
GroupDef gd = (GroupDef) formEntryController.getModel().getForm().getChild(getFormIndex());
List<FormIndex> indices = getIndicesForGroup(gd);
// jump to the end of the group
formEntryController.jumpToIndex(indices.get(indices.size() - 1));
return stepToNextEvent(STEP_OVER_GROUP);
}
use of org.javarosa.core.model.FormIndex in project collect by opendatakit.
the class FormController method getIndexFromXPath.
@Nullable
public FormIndex getIndexFromXPath(String xpath) {
switch(xpath) {
case "beginningOfForm":
return FormIndex.createBeginningOfFormIndex();
case "endOfForm":
return FormIndex.createEndOfFormIndex();
case "unexpected":
Timber.e("Unexpected string from XPath");
return null;
default:
FormIndex returned = null;
FormIndex saved = getFormIndex();
// until the XPath of a form entry matches that of the supplied XPath
try {
jumpToIndex(FormIndex.createBeginningOfFormIndex());
int event = stepToNextEvent(true);
while (event != FormEntryController.EVENT_END_OF_FORM) {
String candidateXPath = getXPath(getFormIndex());
if (candidateXPath.equals(xpath)) {
returned = getFormIndex();
break;
}
event = stepToNextEvent(true);
}
} finally {
jumpToIndex(saved);
}
return returned;
}
}
use of org.javarosa.core.model.FormIndex in project collect by opendatakit.
the class FormLoaderTask method doInBackground.
/**
* Initialize {@link FormEntryController} with {@link FormDef} from binary or
* from XML. If given an instance, it will be used to fill the {@link FormDef}.
*/
@Override
protected FECWrapper doInBackground(String... path) {
errorMsg = null;
final String formPath = path[0];
if (formPath == null) {
Timber.e("formPath is null");
errorMsg = "formPath is null, please email support@getodk.org with a description of what you were doing when this happened.";
return null;
}
final File formXml = new File(formPath);
final File formMediaDir = FileUtils.getFormMediaDir(formXml);
setupReferenceManagerForForm(ReferenceManager.instance(), formMediaDir);
FormDef formDef = null;
try {
formDef = createFormDefFromCacheOrXml(formPath, formXml);
} catch (StackOverflowError e) {
Timber.e(e);
errorMsg = getLocalizedString(Collect.getInstance(), R.string.too_complex_form);
} catch (Exception | Error e) {
Timber.w(e);
errorMsg = "An unknown error has occurred. Please ask your project leadership to email support@getodk.org with information about this form.";
errorMsg += "\n\n" + e.getMessage();
}
if (errorMsg != null || formDef == null) {
Timber.w("No exception loading form but errorMsg set");
return null;
}
externalDataManager = new ExternalDataManagerImpl(formMediaDir);
// add external data function handlers
ExternalDataHandler externalDataHandlerPull = new ExternalDataHandlerPull(externalDataManager);
formDef.getEvaluationContext().addFunctionHandler(externalDataHandlerPull);
try {
loadExternalData(formMediaDir);
} catch (Exception e) {
Timber.e(e, "Exception thrown while loading external data");
errorMsg = e.getMessage();
return null;
}
if (isCancelled()) {
// that means that the user has cancelled, so no need to go further
return null;
}
// create FormEntryController from formdef
final FormEntryModel fem = new FormEntryModel(formDef);
final FormEntryController fec = new FormEntryController(fem);
boolean usedSavepoint = false;
try {
Timber.i("Initializing form.");
final long start = System.currentTimeMillis();
usedSavepoint = initializeForm(formDef, fec);
Timber.i("Form initialized in %.3f seconds.", (System.currentTimeMillis() - start) / 1000F);
} catch (IOException | RuntimeException e) {
Timber.e(e);
if (e.getCause() instanceof XPathTypeMismatchException) {
// this is a case of
// https://bitbucket.org/m
// .sundt/javarosa/commits/e5d344783e7968877402bcee11828fa55fac69de
// the data are imported, the survey will be unusable
// but we should give the option to the user to edit the form
// otherwise the survey will be TOTALLY inaccessible.
Timber.w("We have a syntactically correct instance, but the data threw an exception inside JR. We should allow editing.");
} else {
errorMsg = e.getMessage();
return null;
}
}
processItemSets(formMediaDir);
final FormController fc = new FormController(formMediaDir, fec, instancePath == null ? null : new File(instancePath));
if (xpath != null) {
// we are resuming after having terminated -- set index to this
// position...
FormIndex idx = fc.getIndexFromXPath(xpath);
if (idx != null) {
fc.jumpToIndex(idx);
}
}
if (waitingXPath != null) {
FormIndex idx = fc.getIndexFromXPath(waitingXPath);
if (idx != null) {
fc.setIndexWaitingForData(idx);
}
}
data = new FECWrapper(fc, usedSavepoint);
return data;
}
use of org.javarosa.core.model.FormIndex in project collect by opendatakit.
the class SelectOneWidget method clearFollowingItemsetWidgets.
/**
* If there are "fast external itemset" selects right after this select, assume that they are linked to the current question and clear them.
*/
private void clearFollowingItemsetWidgets() {
FormController formController = Collect.getInstance().getFormController();
if (formController == null) {
return;
}
if (formController.currentCaptionPromptIsQuestion()) {
try {
FormIndex startFormIndex = formController.getQuestionPrompt().getIndex();
formController.stepToNextScreenEvent();
while (formController.currentCaptionPromptIsQuestion() && formController.getQuestionPrompt().getFormElement().getAdditionalAttribute(null, "query") != null) {
formController.saveAnswer(formController.getQuestionPrompt().getIndex(), null);
formController.stepToNextScreenEvent();
}
formController.jumpToIndex(startFormIndex);
} catch (JavaRosaException e) {
Timber.d(e);
}
}
}
Aggregations