use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class FormEntryActivity method nonblockingCreateSavePointData.
/**
* Create save-points asynchronously in order to not affect swiping performance
* on larger forms.
*/
private void nonblockingCreateSavePointData() {
try {
SavePointTask savePointTask = new SavePointTask(this);
savePointTask.execute();
if (!allowMovingBackwards) {
FormController formController = getFormController();
if (formController != null) {
new SaveFormIndexTask(this, formController.getFormIndex()).execute();
}
}
} catch (Exception e) {
Timber.e("Could not schedule SavePointTask. Perhaps a lot of swiping is taking place?");
}
}
use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class FormEntryActivity method loadingComplete.
/**
* loadingComplete() is called by FormLoaderTask once it has finished
* loading a form.
*/
@Override
public void loadingComplete(FormLoaderTask task, FormDef formDef) {
dismissDialog(PROGRESS_DIALOG);
final FormController formController = task.getFormController();
// these are bogus if
int requestCode = task.getRequestCode();
// pendingActivityResult is
// false
int resultCode = task.getResultCode();
Intent intent = task.getIntent();
formLoaderTask.setFormLoaderListener(null);
FormLoaderTask t = formLoaderTask;
formLoaderTask = null;
t.cancel(true);
t.destroy();
Collect.getInstance().setFormController(formController);
supportInvalidateOptionsMenu();
Collect.getInstance().setExternalDataManager(task.getExternalDataManager());
// Set the language if one has already been set in the past
String[] languageTest = formController.getLanguages();
if (languageTest != null) {
String defaultLanguage = formController.getLanguage();
String newLanguage = FormsDaoHelper.getFormLanguage(formPath);
long start = System.currentTimeMillis();
Timber.i("calling formController.setLanguage");
try {
formController.setLanguage(newLanguage);
} catch (Exception e) {
// if somehow we end up with a bad language, set it to the default
Timber.e("Ended up with a bad language. %s", newLanguage);
formController.setLanguage(defaultLanguage);
}
Timber.i("Done in %.3f seconds.", (System.currentTimeMillis() - start) / 1000F);
}
boolean pendingActivityResult = task.hasPendingActivityResult();
if (pendingActivityResult) {
// set the current view to whatever group we were at...
refreshCurrentView();
// process the pending activity request...
onActivityResult(requestCode, resultCode, intent);
return;
}
// it can be a normal flow for a pending activity result to restore from
// a savepoint
// (the call flow handled by the above if statement). For all other use
// cases, the
// user should be notified, as it means they wandered off doing other
// things then
// returned to ODK Collect and chose Edit Saved Form, but that the
// savepoint for that
// form is newer than the last saved version of their form data.
boolean hasUsedSavepoint = task.hasUsedSavepoint();
if (hasUsedSavepoint) {
runOnUiThread(() -> ToastUtils.showLongToast(R.string.savepoint_used));
}
// Set saved answer path
if (formController.getInstanceFile() == null) {
// Create new answer folder.
String time = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss", Locale.ENGLISH).format(Calendar.getInstance().getTime());
String file = formPath.substring(formPath.lastIndexOf('/') + 1, formPath.lastIndexOf('.'));
String path = Collect.INSTANCES_PATH + File.separator + file + "_" + time;
if (FileUtils.createFolder(path)) {
File instanceFile = new File(path + File.separator + file + "_" + time + ".xml");
formController.setInstanceFile(instanceFile);
}
formController.getTimerLogger().logTimerEvent(TimerLogger.EventTypes.FORM_START, 0, null, false, true);
} else {
Intent reqIntent = getIntent();
boolean showFirst = reqIntent.getBooleanExtra("start", false);
formController.getTimerLogger().logTimerEvent(TimerLogger.EventTypes.FORM_RESUME, 0, null, false, true);
if (!showFirst) {
if (!allowMovingBackwards) {
FormIndex formIndex = SaveFormIndexTask.loadFormIndexFromFile();
if (formIndex != null) {
formController.jumpToIndex(formIndex);
refreshCurrentView();
return;
}
}
String formMode = reqIntent.getStringExtra(ApplicationConstants.BundleKeys.FORM_MODE);
if (formMode == null || ApplicationConstants.FormModes.EDIT_SAVED.equalsIgnoreCase(formMode)) {
startActivity(new Intent(this, EditFormHierarchyActivity.class));
// so we don't show the intro screen before jumping to the hierarchy
return;
} else {
if (ApplicationConstants.FormModes.VIEW_SENT.equalsIgnoreCase(formMode)) {
startActivity(new Intent(this, ViewFormHierarchyActivity.class));
}
finish();
}
}
}
refreshCurrentView();
if (formDef != null) {
final File cachedFormDefFile = FormDefCache.getCacheFile(new File(formPath));
if (cachedFormDefFile.exists()) {
Timber.i("FormDef %s is already in the cache", cachedFormDefFile.toString());
} else {
Disposable formDefCacheDisposable = writeCacheAsync(formDef, cachedFormDefFile).subscribe(() -> {
}, Timber::e);
formDefCacheCompositeDisposable.add(formDefCacheDisposable);
}
}
}
use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class FormEntryActivity method createConstraintToast.
// Hopefully someday we can use managed dialogs when the bugs are fixed
/*
* Ideally, we'd like to use Android to manage dialogs with onCreateDialog()
* and onPrepareDialog(), but dialogs with dynamic content are broken in 1.5
* (cupcake). We do use managed dialogs for our static loading
* ProgressDialog. The main issue we noticed and are waiting to see fixed
* is: onPrepareDialog() is not called after a screen orientation change.
* http://code.google.com/p/android/issues/detail?id=1639
*/
//
/**
* Creates and displays a dialog displaying the violated constraint.
*/
private void createConstraintToast(FormIndex index, int saveStatus) {
FormController formController = getFormController();
String constraintText;
switch(saveStatus) {
case FormEntryController.ANSWER_CONSTRAINT_VIOLATED:
Collect.getInstance().getActivityLogger().logInstanceAction(this, "createConstraintToast.ANSWER_CONSTRAINT_VIOLATED", "show", index);
constraintText = formController.getQuestionPromptConstraintText(index);
if (constraintText == null) {
constraintText = formController.getQuestionPrompt(index).getSpecialFormQuestionText("constraintMsg");
if (constraintText == null) {
constraintText = getString(R.string.invalid_answer_error);
}
}
break;
case FormEntryController.ANSWER_REQUIRED_BUT_EMPTY:
Collect.getInstance().getActivityLogger().logInstanceAction(this, "createConstraintToast.ANSWER_REQUIRED_BUT_EMPTY", "show", index);
constraintText = formController.getQuestionPromptRequiredText(index);
if (constraintText == null) {
constraintText = formController.getQuestionPrompt(index).getSpecialFormQuestionText("requiredMsg");
if (constraintText == null) {
constraintText = getString(R.string.required_answer_error);
}
}
break;
default:
return;
}
showCustomToast(constraintText, Toast.LENGTH_SHORT);
}
use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class FormEntryActivity method createRepeatDialog.
/**
* Creates and displays a dialog asking the user if they'd like to create a
* repeat of the current group.
*/
private void createRepeatDialog() {
Collect.getInstance().getActivityLogger().logInstanceAction(this, "createRepeatDialog", "show");
// alertDialog is being used for all alert dialogs in this activity.
if (alertDialog != null && alertDialog.isShowing() && shownAlertDialogIsGroupRepeat) {
return;
}
alertDialog = new AlertDialog.Builder(this).create();
DialogInterface.OnClickListener repeatListener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int i) {
shownAlertDialogIsGroupRepeat = false;
FormController formController = getFormController();
switch(i) {
case // yes, repeat
BUTTON_POSITIVE:
Collect.getInstance().getActivityLogger().logInstanceAction(this, "createRepeatDialog", "addRepeat");
try {
formController.newRepeat();
} catch (Exception e) {
FormEntryActivity.this.createErrorDialog(e.getMessage(), DO_NOT_EXIT);
return;
}
if (!formController.indexIsInFieldList()) {
// we are at a REPEAT event that does not have a
// field-list appearance
// step to the next visible field...
// which could be the start of a new repeat group...
showNextView();
} else {
// we are at a REPEAT event that has a field-list
// appearance
// just display this REPEAT event's group.
refreshCurrentView();
}
break;
case // no, no repeat
BUTTON_NEGATIVE:
Collect.getInstance().getActivityLogger().logInstanceAction(this, "createRepeatDialog", "showNext");
//
// Make sure the error dialog will not disappear.
//
// When showNextView() popups an error dialog (because of a
// JavaRosaException)
// the issue is that the "add new repeat dialog" is referenced by
// alertDialog
// like the error dialog. When the "no repeat" is clicked, the error dialog
// is shown. Android by default dismisses the dialogs when a button is
// clicked,
// so instead of closing the first dialog, it closes the second.
new Thread() {
@Override
public void run() {
FormEntryActivity.this.runOnUiThread(() -> {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// This is rare
Timber.e(e);
}
showNextView();
});
}
}.start();
break;
}
}
};
FormController formController = getFormController();
if (formController.getLastRepeatCount() > 0) {
alertDialog.setTitle(getString(R.string.leaving_repeat_ask));
alertDialog.setMessage(getString(R.string.add_another_repeat, formController.getLastGroupText()));
alertDialog.setButton(BUTTON_POSITIVE, getString(R.string.add_another), repeatListener);
alertDialog.setButton(BUTTON_NEGATIVE, getString(R.string.leave_repeat_yes), repeatListener);
} else {
alertDialog.setTitle(getString(R.string.entering_repeat_ask));
alertDialog.setMessage(getString(R.string.add_repeat, formController.getLastGroupText()));
alertDialog.setButton(BUTTON_POSITIVE, getString(R.string.entering_repeat), repeatListener);
alertDialog.setButton(BUTTON_NEGATIVE, getString(R.string.add_repeat_no), repeatListener);
}
alertDialog.setCancelable(false);
beenSwiped = false;
shownAlertDialogIsGroupRepeat = true;
alertDialog.show();
}
use of org.odk.collect.android.logic.FormController in project collect by opendatakit.
the class FormEntryActivity method onCreateContextMenu.
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
Collect.getInstance().getActivityLogger().logInstanceAction(this, "onCreateContextMenu", "show");
FormController formController = getFormController();
menu.add(0, v.getId(), 0, getString(R.string.clear_answer));
if (formController.indexContainsRepeatableGroup()) {
menu.add(0, DELETE_REPEAT, 0, getString(R.string.delete_repeat));
}
menu.setHeaderTitle(getString(R.string.edit_prompt));
}
Aggregations