/* * Geopaparazzi - Digital field mapping on Android based devices * Copyright (C) 2016 HydroloGIS (www.hydrologis.com) * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package eu.geopaparazzi.library.forms; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentTransaction; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; import org.json.JSONArray; import org.json.JSONObject; import java.io.File; import java.io.Serializable; import java.util.ArrayList; import java.util.List; import eu.geopaparazzi.library.R; import eu.geopaparazzi.library.core.ResourcesManager; import eu.geopaparazzi.library.database.DefaultHelperClasses; import eu.geopaparazzi.library.database.GPLog; import eu.geopaparazzi.library.database.IImagesDbHelper; import eu.geopaparazzi.library.database.Image; import eu.geopaparazzi.library.forms.FormListFragment.IFragmentListSupporter; import eu.geopaparazzi.library.forms.constraints.Constraints; import eu.geopaparazzi.library.images.ImageUtilities; import eu.geopaparazzi.library.share.ShareUtilities; import eu.geopaparazzi.library.util.GPDialogs; import eu.geopaparazzi.library.util.LibraryConstants; import eu.geopaparazzi.library.util.UrlUtilities; import eu.geopaparazzi.library.util.Utilities; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_IS_RENDER_LABEL; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_KEY; import static eu.geopaparazzi.library.forms.FormUtilities.TAG_VALUE; /** * The form activity. * <p/> * <p>This returns an array of {@link String} data that can be retrieved * through: {@link LibraryConstants#PREFS_KEY_FORM} and contain:</p> * <ul> * <li>longitude</li> * <li>latitude</li> * <li>elevation (or -1.0)</li> * <li>timestamp</li> * <li>a name for the form</li> * <li>the filled form data json</li> * </ul> * * @author Andrea Antonello (www.hydrologis.com) */ @SuppressWarnings("nls") public class FormActivity extends AppCompatActivity implements IFragmentListSupporter { // private final int RETURNCODE_DETAILACTIVITY = 665; private double latitude = -9999.0; private double longitude = -9999.0; private double elevation = -9999.0; private String mSectionName; private String mFormName; private JSONObject sectionObject; private List<String> formNames4Section = new ArrayList<String>(); private long noteId = -1; private boolean noteIsNew = false; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_form); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar); try { Bundle extras = getIntent().getExtras(); if (savedInstanceState != null) { // state has been restored readBundle(savedInstanceState); FormInfoHolder formInfoHolder = new FormInfoHolder(); formInfoHolder.sectionName = mSectionName; formInfoHolder.formName = mFormName; if (formInfoHolder.formName == null) formInfoHolder.formName = formNames4Section.get(0); formInfoHolder.noteId = noteId; formInfoHolder.longitude = longitude; formInfoHolder.latitude = latitude; formInfoHolder.sectionObjectString = sectionObject.toString(); Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.detailFragment); if (currentFragment instanceof FormDetailFragment) { FormDetailFragment formDetailFragment = (FormDetailFragment) currentFragment; formDetailFragment.refreshView(formInfoHolder); } } else if (extras != null) { readBundle(extras); if (formNames4Section.size() > 0) { FormInfoHolder formInfoHolder = new FormInfoHolder(); if (formInfoHolder.formName == null) formInfoHolder.formName = formNames4Section.get(0); formInfoHolder.noteId = noteId; formInfoHolder.longitude = longitude; formInfoHolder.latitude = latitude; formInfoHolder.sectionObjectString = sectionObject.toString(); Fragment currentFragment = getSupportFragmentManager().findFragmentById(R.id.detailFragment); if (currentFragment instanceof FormDetailFragment) { FormDetailFragment formDetailFragment = (FormDetailFragment) currentFragment; formDetailFragment.refreshView(formInfoHolder); } } } } catch (Exception e) { GPLog.error(this, null, e); } } private void readBundle(Bundle bundle) { if (bundle != null) { Serializable formInfoHolder = bundle.getSerializable(FormInfoHolder.BUNDLE_KEY_INFOHOLDER); if (formInfoHolder instanceof FormInfoHolder) { FormInfoHolder formInfo = (FormInfoHolder) formInfoHolder; extractVariablesFromForminfo(formInfo); } } } private void extractVariablesFromForminfo(FormInfoHolder formInfo) { mSectionName = formInfo.sectionName; mFormName = formInfo.formName; latitude = formInfo.latitude; longitude = formInfo.longitude; elevation = formInfo.elevation; noteId = formInfo.noteId; noteIsNew = !formInfo.objectExists; try { if (formInfo.sectionObjectString == null) { sectionObject = TagsManager.getInstance(this).getSectionByName(mSectionName); // copy the section object, which will be kept around along the activity formInfo.sectionObjectString = sectionObject.toString(); } sectionObject = new JSONObject(formInfo.sectionObjectString); formNames4Section = TagsManager.getFormNames4Section(sectionObject); } catch (Exception e) { GPLog.error(this, null, e); } } @Override protected void onSaveInstanceState(Bundle outState) { try { Fragment detailFragment = getSupportFragmentManager().findFragmentById(R.id.detailFragment); if (detailFragment instanceof FormDetailFragment) { FormDetailFragment fdFragment = (FormDetailFragment) detailFragment; fdFragment.storeFormItems(false); FormInfoHolder formInfo = fdFragment.getFormInfoHolder(); sectionObject = new JSONObject(formInfo.sectionObjectString); FormInfoHolder formInfoHolder = new FormInfoHolder(); formInfoHolder.sectionName = mSectionName; formInfoHolder.formName = mFormName; formInfoHolder.sectionObjectString = sectionObject.toString(); formInfoHolder.noteId = noteId; formInfoHolder.longitude = longitude; formInfoHolder.latitude = latitude; formInfoHolder.elevation = elevation; formInfoHolder.objectExists = !noteIsNew; outState.putSerializable(FormInfoHolder.BUNDLE_KEY_INFOHOLDER, formInfoHolder); } } catch (Exception e) { GPLog.error(this, null, e); } super.onSaveInstanceState(outState); } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_form, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_share) { try { shareAction(); } catch (Exception e) { GPLog.error(this, null, e); GPDialogs.warningDialog(this, e.getLocalizedMessage(), null); } } else if (id == R.id.action_save) { try { saveAction(); } catch (Exception e) { GPLog.error(this, null, e); GPDialogs.warningDialog(this, e.getLocalizedMessage(), null); } } return super.onOptionsItemSelected(item); } @Override public void onBackPressed() { if (noteIsNew) { Intent intent = getIntent(); intent.putExtra(LibraryConstants.DATABASE_ID, noteId); setResult(Activity.RESULT_CANCELED, intent); } super.onBackPressed(); } private void shareAction() throws Exception { String form = sectionObject.toString(); float lat = (float) latitude; float lon = (float) longitude; String osmUrl = UrlUtilities.osmUrlFromLatLong(lat, lon, true, false); IImagesDbHelper imageHelper = DefaultHelperClasses.getDefaulfImageHelper(); File tempDir = ResourcesManager.getInstance(this).getTempDir(); // for now only one image is shared List<String> imageIds = FormUtilities.getImageIds(form); File imageFile = null; if (imageIds.size() > 0) { String imageId = imageIds.get(0); Image image = imageHelper.getImage(Long.parseLong(imageId)); String name = image.getName(); imageFile = new File(tempDir, name); byte[] imageData = imageHelper.getImageDataById(image.getImageDataId(), null); ImageUtilities.writeImageDataToFile(imageData, imageFile.getAbsolutePath()); } String formText = FormUtilities.formToPlainText(form, false); formText = formText + "\n" + osmUrl; String shareNoteMsg = getResources().getString(R.string.share_note_with); if (imageFile != null) { ShareUtilities.shareTextAndImage(this, shareNoteMsg, formText, imageFile); } else { ShareUtilities.shareText(this, shareNoteMsg, formText); } } private void saveAction() throws Exception { // if in landscape mode store last inserted info, since that fragment has not been stored Fragment detailFragment = getSupportFragmentManager().findFragmentById(R.id.detailFragment); if (detailFragment instanceof FormDetailFragment) { FormDetailFragment fdFragment = (FormDetailFragment) detailFragment; fdFragment.storeFormItems(false); FormInfoHolder formInfo = fdFragment.getFormInfoHolder(); sectionObject = new JSONObject(formInfo.sectionObjectString); } // extract and check constraints List<String> availableFormNames = TagsManager.getFormNames4Section(sectionObject); String renderingLabel = null; for (String formName : availableFormNames) { JSONObject formObject = TagsManager.getForm4Name(formName, sectionObject); JSONArray formItemsArray = TagsManager.getFormItems(formObject); int length = formItemsArray.length(); String value = null; for (int i = 0; i < length; i++) { JSONObject jsonObject = formItemsArray.getJSONObject(i); String key = "-"; if (jsonObject.has(TAG_KEY)) key = jsonObject.getString(TAG_KEY).trim(); if (jsonObject.has(TAG_VALUE)) { value = jsonObject.getString(TAG_VALUE).trim(); } if (jsonObject.has(TAG_IS_RENDER_LABEL)) { String isRenderingLabelStr = jsonObject.getString(TAG_IS_RENDER_LABEL).trim(); boolean isRenderingLabel = Boolean.parseBoolean(isRenderingLabelStr); if (isRenderingLabel) renderingLabel = value; } // inject latitude if (key.equals(LibraryConstants.LATITUDE)) { String latitudeString = String.valueOf(latitude); value = latitudeString; jsonObject.put(TAG_VALUE, latitudeString); } // inject longitude if (key.equals(LibraryConstants.LONGITUDE)) { String longitudeString = String.valueOf(longitude); value = longitudeString; jsonObject.put(TAG_VALUE, longitudeString); } Constraints constraints = FormUtilities.handleConstraints(jsonObject, null); if (value == null || !constraints.isValid(value)) { String constraintDescription = constraints.getDescription(); String validfieldMsg = getString(R.string.form_field_check); String msg = Utilities.format(validfieldMsg, key, formName, constraintDescription); GPDialogs.infoDialog(this, msg, null); return; } } } // finally store data String sectionObjectString = sectionObject.toString(); long timestamp = System.currentTimeMillis(); if (renderingLabel == null) { renderingLabel = mSectionName; } FormInfoHolder formInfoHolder = new FormInfoHolder(); formInfoHolder.sectionName = mSectionName; formInfoHolder.formName = mFormName; formInfoHolder.noteId = noteId; formInfoHolder.longitude = longitude; formInfoHolder.latitude = latitude; formInfoHolder.elevation = elevation; formInfoHolder.sectionObjectString = sectionObjectString; formInfoHolder.lastTimestamp = timestamp; formInfoHolder.renderingLabel = renderingLabel; Intent intent = getIntent(); intent.putExtra(FormInfoHolder.BUNDLE_KEY_INFOHOLDER, formInfoHolder); setResult(Activity.RESULT_OK, intent); finish(); } @Override public void onListItemSelected(String selectedItemName) { // depending on the mode, set the detail fragment or launch the detail activity FormDetailFragment currentFragment = (FormDetailFragment) getSupportFragmentManager().findFragmentById(R.id.detailFragment); FormInfoHolder formInfoHolder = new FormInfoHolder(); formInfoHolder.sectionName = mSectionName; mFormName = selectedItemName; formInfoHolder.formName = mFormName; formInfoHolder.noteId = noteId; formInfoHolder.longitude = longitude; formInfoHolder.latitude = latitude; try { currentFragment.storeFormItems(false); FormInfoHolder formInfo = currentFragment.getFormInfoHolder(); formInfoHolder.sectionObjectString = formInfo.sectionObjectString; sectionObject = new JSONObject(formInfo.sectionObjectString); currentFragment.refreshView(formInfoHolder); } catch (Exception e) { GPLog.error(this, null, e); } } @Override public List<String> getListTitles() { return formNames4Section; } public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // result = new Result(); // result.requestCode = requestCode; // result.resultCode = resultCode; // result.data = data; // // FormDetailFragment currentFragment = (FormDetailFragment) getSupportFragmentManager().findFragmentById(R.id.detailFragmentContainer); // if (currentFragment != null) // currentFragment.onActivityResult(requestCode, resultCode, data); // switch (requestCode) { // case (RETURNCODE_DETAILACTIVITY): { // if (resultCode == AppCompatActivity.RESULT_OK) { // FormInfoHolder formInfoHolder = (FormInfoHolder) data.getSerializableExtra(FormInfoHolder.BUNDLE_KEY_INFOHOLDER); // extractVariablesFromForminfo(formInfoHolder); // } // break; // } // } } }