use of org.odk.collect.forms.Form in project collect by opendatakit.
the class InMemFormsRepository method save.
@Override
public Form save(@NotNull Form form) {
Form.Builder builder = new Form.Builder(form);
if (form.getFormMediaPath() == null) {
builder.formMediaPath(TempFiles.getPathInTempDir());
}
if (form.getDbId() != null) {
String formFilePath = form.getFormFilePath();
String hash = Md5.getMd5Hash(new File(formFilePath));
builder.md5Hash(hash);
forms.removeIf(f -> f.getDbId().equals(form.getDbId()));
forms.add(builder.build());
return form;
} else {
builder.dbId(idCounter++).date(clock.get());
// Allows tests to override hash
String hash;
if (form.getMD5Hash() == null) {
String formFilePath = form.getFormFilePath();
hash = Md5.getMd5Hash(new File(formFilePath));
builder.md5Hash(hash);
} else {
hash = form.getMD5Hash();
}
if (form.getJrCacheFilePath() == null) {
builder.jrCacheFilePath(TempFiles.getPathInTempDir(hash, ".formdef"));
}
Form formToSave = builder.build();
forms.add(formToSave);
return formToSave;
}
}
use of org.odk.collect.forms.Form in project collect by opendatakit.
the class FormEntryActivity method loadFromIntent.
private void loadFromIntent(Intent intent) {
Uri uri = intent.getData();
String uriMimeType = null;
if (uri != null) {
uriMimeType = getContentResolver().getType(uri);
}
if (uriMimeType != null && uriMimeType.equals(InstancesContract.CONTENT_ITEM_TYPE)) {
Instance instance = new InstancesRepositoryProvider(Collect.getInstance()).get().get(ContentUriHelper.getIdFromUri(uri));
if (instance == null) {
createErrorDialog(getString(R.string.bad_uri, uri), true);
return;
}
instancePath = instance.getInstanceFilePath();
if (!new File(instancePath).exists()) {
analytics.logEvent(AnalyticsEvents.OPEN_DELETED_INSTANCE);
new InstanceDeleter(new InstancesRepositoryProvider(Collect.getInstance()).get(), formsRepository).delete(instance.getDbId());
createErrorDialog(getString(R.string.instance_deleted_message), true);
return;
}
List<Form> candidateForms = formsRepository.getAllByFormIdAndVersion(instance.getFormId(), instance.getFormVersion());
if (candidateForms.isEmpty()) {
createErrorDialog(getString(R.string.parent_form_not_present, instance.getFormId()) + ((instance.getFormVersion() == null) ? "" : "\n" + getString(R.string.version) + " " + instance.getFormVersion()), true);
return;
} else if (candidateForms.stream().filter(f -> !f.isDeleted()).count() > 1) {
createErrorDialog(getString(R.string.survey_multiple_forms_error), true);
return;
}
formPath = candidateForms.get(0).getFormFilePath();
} else if (uriMimeType != null && uriMimeType.equals(FormsContract.CONTENT_ITEM_TYPE)) {
Form form = formsRepositoryProvider.get().get(ContentUriHelper.getIdFromUri(uri));
if (form != null) {
formPath = form.getFormFilePath();
}
if (formPath == null) {
createErrorDialog(getString(R.string.bad_uri, uri), true);
return;
} else {
/**
* This is the fill-blank-form code path.See if there is a savepoint for this form
* that has never been explicitly saved by the user. If there is, open this savepoint(resume this filled-in form).
* Savepoints for forms that were explicitly saved will be recovered when that
* explicitly saved instance is edited via edit-saved-form.
*/
instancePath = loadSavePoint();
}
} else {
Timber.i("Unrecognized URI: %s", uri);
createErrorDialog(getString(R.string.unrecognized_uri, uri), true);
return;
}
formLoaderTask = new FormLoaderTask(instancePath, null, null);
showIfNotShowing(FormLoadingDialogFragment.class, getSupportFragmentManager());
formLoaderTask.execute(formPath);
}
use of org.odk.collect.forms.Form in project collect by opendatakit.
the class FormEntryActivity method loadingComplete.
/**
* Given a {@link FormLoaderTask} which has created a {@link FormController} for either a new or
* existing instance, shows that instance to the user. Either launches {@link FormHierarchyActivity}
* if an existing instance is being edited or builds the view for the current question(s) if a
* new instance is being created.
* <p>
* May do some or all of these depending on current state:
* - Ensures phone state permissions are given if this form needs them
* - Cleans up {@link #formLoaderTask}
* - Sets the global form controller and database manager for search()/pulldata()
* - Restores the last-used language
* - Handles activity results that may have come in while the form was loading
* - Alerts the user of a recovery from savepoint
* - Verifies whether an instance folder exists and creates one if not
* - Initializes background location capture (only if the instance being loaded is a new one)
*/
@Override
public void loadingComplete(FormLoaderTask task, FormDef formDef, String warningMsg) {
DialogFragmentUtils.dismissDialog(FormLoadingDialogFragment.class, getSupportFragmentManager());
final FormController formController = task.getFormController();
if (formController != null) {
if (readPhoneStatePermissionRequestNeeded) {
permissionsProvider.requestReadPhoneStatePermission(this, true, new PermissionListener() {
@Override
public void granted() {
readPhoneStatePermissionRequestNeeded = false;
loadForm();
}
@Override
public void denied() {
finish();
}
});
} else {
formLoaderTask.setFormLoaderListener(null);
FormLoaderTask t = formLoaderTask;
formLoaderTask = null;
t.cancel(true);
t.destroy();
Collect.getInstance().setFormController(formController);
backgroundLocationViewModel.formFinishedLoading();
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();
Form form = formsRepository.getOneByPath(formPath);
if (form != null) {
String newLanguage = form.getLanguage();
try {
formController.setLanguage(newLanguage);
} catch (Exception e) {
// if somehow we end up with a bad language, set it to the default
Timber.i("Ended up with a bad language. %s", newLanguage);
formController.setLanguage(defaultLanguage);
}
}
}
boolean pendingActivityResult = task.hasPendingActivityResult();
if (pendingActivityResult) {
Timber.w("Calling onActivityResult from loadingComplete");
formControllerAvailable(formController);
onScreenRefresh();
onActivityResult(task.getRequestCode(), task.getResultCode(), task.getIntent());
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(() -> showLongToast(this, R.string.savepoint_used));
}
if (formController.getInstanceFile() == null) {
FormInstanceFileCreator formInstanceFileCreator = new FormInstanceFileCreator(storagePathProvider, System::currentTimeMillis);
File instanceFile = formInstanceFileCreator.createInstanceFile(formPath);
if (instanceFile != null) {
formController.setInstanceFile(instanceFile);
} else {
showFormLoadErrorAndExit(getString(R.string.loading_form_failed));
}
formControllerAvailable(formController);
identityPromptViewModel.requiresIdentityToContinue().observe(this, requiresIdentity -> {
if (!requiresIdentity) {
formController.getAuditEventLogger().logEvent(AuditEvent.AuditEventType.FORM_START, true, System.currentTimeMillis());
startFormEntry(formController, warningMsg);
}
});
} else {
Intent reqIntent = getIntent();
boolean showFirst = reqIntent.getBooleanExtra("start", false);
if (!showFirst) {
// we've just loaded a saved form, so start in the hierarchy view
String formMode = reqIntent.getStringExtra(ApplicationConstants.BundleKeys.FORM_MODE);
if (formMode == null || ApplicationConstants.FormModes.EDIT_SAVED.equalsIgnoreCase(formMode)) {
formControllerAvailable(formController);
identityPromptViewModel.requiresIdentityToContinue().observe(this, requiresIdentity -> {
if (!requiresIdentity) {
if (!allowMovingBackwards) {
// we aren't allowed to jump around the form so attempt to
// go directly to the question we were on last time the
// form was saved.
// TODO: revisit the fallback. If for some reason the index
// wasn't saved, we can now jump around which doesn't seem right.
FormIndex formIndex = SaveFormIndexTask.loadFormIndexFromFile();
if (formIndex != null) {
formController.jumpToIndex(formIndex);
onScreenRefresh();
return;
}
}
formController.getAuditEventLogger().logEvent(AuditEvent.AuditEventType.FORM_RESUME, true, System.currentTimeMillis());
formController.getAuditEventLogger().logEvent(AuditEvent.AuditEventType.HIERARCHY, true, System.currentTimeMillis());
startActivityForResult(new Intent(this, FormHierarchyActivity.class), RequestCodes.HIERARCHY_ACTIVITY);
}
});
formSaveViewModel.editingForm();
} else {
if (ApplicationConstants.FormModes.VIEW_SENT.equalsIgnoreCase(formMode)) {
startActivity(new Intent(this, ViewOnlyFormHierarchyActivity.class));
}
finish();
}
} else {
formControllerAvailable(formController);
identityPromptViewModel.requiresIdentityToContinue().observe(this, requiresIdentity -> {
if (!requiresIdentity) {
formController.getAuditEventLogger().logEvent(AuditEvent.AuditEventType.FORM_RESUME, true, System.currentTimeMillis());
startFormEntry(formController, warningMsg);
}
});
}
}
}
} else {
Timber.e("FormController is null");
showLongToast(this, R.string.loading_form_failed);
finish();
}
}
use of org.odk.collect.forms.Form in project collect by opendatakit.
the class FormMapActivity method onCreate.
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
DaggerUtils.getComponent(this).inject(this);
setContentView(R.layout.form_map_activity);
Form form = loadForm();
selectionMapViewModel = new ViewModelProvider(this).get(SelectionMapViewModel.class);
selectionMapViewModel.setMapTitle(form.getDisplayName());
FormNavigator formNavigator = new FormNavigator(currentProjectProvider, settingsProvider, instancesRepositoryProvider::get);
getSupportFragmentManager().setFragmentResultListener(SelectionMapFragment.REQUEST_SELECT_ITEM, this, (requestKey, result) -> {
if (result.containsKey(SelectionMapFragment.RESULT_SELECTED_ITEM)) {
long instanceId = result.getLong(SelectionMapFragment.RESULT_SELECTED_ITEM);
formNavigator.editInstance(this, instanceId);
} else if (result.containsKey(SelectionMapFragment.RESULT_CREATE_NEW_ITEM)) {
formNavigator.newInstance(this, form.getDbId());
}
});
}
use of org.odk.collect.forms.Form in project collect by opendatakit.
the class FormMapActivity method loadForm.
@Nullable
private Form loadForm() {
Form form = formsRepositoryProvider.get().get(getIntent().getLongExtra(EXTRA_FORM_ID, -1));
FormMapViewModelFactory viewModelFactory = new FormMapViewModelFactory(form, instancesRepositoryProvider.get());
formMapViewModel = new ViewModelProvider(this, viewModelFactory).get(FormMapViewModel.class);
return form;
}
Aggregations