/*
* GeoSolutions - MapstoreMobile - GeoSpatial Framework on Android based devices
* Copyright (C) 2014 - 2016 GeoSolutions (www.geo-solutions.it)
*
* 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 it.geosolutions.geocollect.android.core.form.utils;
import it.geosolutions.android.map.control.CoordinateControl;
import it.geosolutions.android.map.control.LocationControl;
import it.geosolutions.android.map.control.MarkerControl;
import it.geosolutions.android.map.dto.MarkerDTO;
import it.geosolutions.android.map.model.Layer;
import it.geosolutions.android.map.model.MSMMap;
import it.geosolutions.android.map.overlay.MarkerOverlay;
import it.geosolutions.android.map.overlay.items.DescribedMarker;
import it.geosolutions.android.map.overlay.managers.MultiSourceOverlayManager;
import it.geosolutions.android.map.utils.MapFilesProvider;
import it.geosolutions.android.map.utils.SpatialDbUtils;
import it.geosolutions.android.map.view.AdvancedMapView;
import it.geosolutions.geocollect.android.app.BuildConfig;
import it.geosolutions.geocollect.android.app.R;
import it.geosolutions.geocollect.android.core.GeoCollectApplication;
import it.geosolutions.geocollect.android.core.form.FormEditActivity;
import it.geosolutions.geocollect.android.core.form.ViewPagerAwareMarkerControl;
import it.geosolutions.geocollect.android.core.mission.Mission;
import it.geosolutions.geocollect.android.core.mission.utils.MissionUtils;
import it.geosolutions.geocollect.android.core.widgets.DatePicker;
import it.geosolutions.geocollect.android.core.widgets.UILImageAdapter;
import it.geosolutions.geocollect.model.config.MissionTemplate;
import it.geosolutions.geocollect.model.viewmodel.Field;
import java.io.File;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import org.mapsforge.android.maps.MapView;
import org.mapsforge.android.maps.mapgenerator.mbtiles.MbTilesDatabaseRenderer;
import org.mapsforge.core.model.GeoPoint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.text.InputType;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.SimpleAdapter;
import android.widget.Spinner;
import android.widget.SpinnerAdapter;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.vividsolutions.jts.geom.Point;
/**
* @author Lorenzo Natali (lorenzo.natali@geo-solutions.it)
*
* Utility Class to build forms
*/
public class FormBuilder {
/**
* Tag for logging
*/
public static String TAG = "FormBuilder";
// set a static id
private static int sId = 0;
private static int id() {
return sId++;
}
/**
* Creates and add the form fields to the layout passed
*
* @param context
* the context
* @param mFormView
* the Layout
* @param mission
* @param t
* the <Page> of the form
*/
public static void buildForm(Context context, LinearLayout mFormView, List<Field> fields, Mission mission) {
if (fields == null) {
return;
}
ArrayList<String> addedFields = new ArrayList<String>();
for (Field f : fields) {
//the null field will be ignored
if(f == null || (f.fieldId != null && addedFields.contains(f.fieldId)) ){
continue;
}
if (f.xtype == null) {
//textfield as default
addTextField(f, mFormView, context,mission);
} else {
// switch witch widget create
switch (f.xtype) {
case textfield:
addTextField(f, mFormView, context,mission);
break;
case textarea:
addTextField(f, mFormView, context,mission);
break;
case datefield:
addDatePicker(f, mFormView, context,mission);
break;
case checkbox:
addCheckBox(f,mFormView,context,mission);
break;
case spinner:
addSpinner(f,mFormView,context,mission);
break;
case label:
addLabel(f,mFormView,context,mission);
break;
case separator:
addSeparator(f,mFormView,context,mission);
break;
case separatorWithIcon:
addSeparatorWithIcon(f,mFormView,context,mission);
break;
case mapViewPoint:
addMapViewPoint(f,mFormView,context,mission);
break;
case photo:
addPhotoGrid(f, mFormView, context, mission);
break;
default:
//textfield as default
addTextField(f, mFormView, context,mission);
}
}
addedFields.add(f.fieldId);
}
//mFormView.getParent().requestLayout();
}
/**
* Creates a map view
* @param f
* @param mFormView
* @param context
* @param mission
*/
private static void addMapViewPoint(Field field, LinearLayout mFormView,
final Context context, Mission mission) {
TextView tvLabel = getLabelForField(field, context);
AdvancedMapView mapView =null;
ImageButton buttonLocation = null;
//setup view
//ImageButton infoButton = new ImageButton(context);
//infoButton.setImageResource(R.drawable.ic_menu_info_details); //TODO move icon to main project
//infoButton.setVisibility(ImageButton.GONE);
//infoButton.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
//TODO find a mapview in layout to provide a better GUI
if(context instanceof FormEditActivity){
View formView = ((FormEditActivity)context).getLayoutInflater().inflate(R.layout.form_mapview, null);
mapView = (AdvancedMapView) formView.findViewById(R.id.advancedMapView);
buttonLocation = (ImageButton) formView.findViewById(R.id.ButtonLocation);
mFormView.addView(tvLabel);
mapView.setTag(field.fieldId);
mFormView.addView(formView);
}else{
if(mapView==null){
mapView = new AdvancedMapView(context);
mapView.setLayoutParams(getMapLayoutParams(field));//if not in layout
mFormView.addView(tvLabel);
//mFormView.addView(infoButton);
mapView.setMinimumHeight(100);//it doesn't work, try a different method
mapView.setMinimumWidth(100);
mapView.setTag(field.fieldId);
mFormView.addView(mapView);
}
}
//setup overlay Manager
MultiSourceOverlayManager o = new MultiSourceOverlayManager(mapView);
mapView.setOverlayManger(o);
MarkerOverlay m = new MarkerOverlay();
o.setMarkerOverlay(m);
m.setProjection(mapView.getProjection());
// only from tag is supported
List<String> tags = MissionUtils.getTags("${origin."+mission.getOrigin().geometry_name+"}");
GeoPoint geoPoint = null;
if(tags!=null && tags.size() ==1){
//Get geometry now geoPoint only supported)
//TODO support for different formats
Point geom = (Point) mission.getValueByTag(context, tags.get(0));
if(geom !=null){
if(!geom.isEmpty()){
double lat = geom.getY();
double lon = geom.getX();
geoPoint = new GeoPoint(lat, lon);
}
}
}
o.setMarkerOverlay(m);
//check editable
Boolean editable = (Boolean)getAttributeWithDefault(field,"editable",true);
//check disablePan
Boolean disablePan = (Boolean)getAttributeWithDefault(field,"disablePan",false);
//check zoom
Boolean disableZoom = (Boolean)getAttributeWithDefault(field,"disableZoom",false);
//add marker control
MarkerControl mc;
if(context instanceof FormEditActivity){
mc = new ViewPagerAwareMarkerControl(mapView,editable, ((FormEditActivity)context).mViewPager);
}else{
mc = new MarkerControl(mapView,editable);
}
//mc.setInfoButton(infoButton);
mapView.addControl(mc);
if(editable){
mc.setMode(MarkerControl.MODE_EDIT);
}
File mapFile = MapFilesProvider.getBackgroundMapFile();
String filePath = PreferenceManager.getDefaultSharedPreferences(context).getString(MapView.MAPSFORGE_BACKGROUND_FILEPATH, null);
int type = Integer.parseInt(PreferenceManager.getDefaultSharedPreferences(context).getString(MapView.MAPSFORGE_BACKGROUND_RENDERER_TYPE, "0"));
//if the map file was edited in the preferences
if(filePath != null && type == 0){
//use it
mapView.setMapFile(new File(filePath));
}else if(filePath != null && type == 1){
// Set a fake background, will not be rendered
// TODO: Change this workaround when the library will support setting MBTILES files as actual backgrounds
mapView.setMapFile((new File(MapFilesProvider.getBaseDirectoryFile(), "bg.map")));
// Set the MBTILES background renderer
mapView.setRenderer(new MbTilesDatabaseRenderer(context, filePath), true);
}else if (mapFile!=null) {
Log.i(TAG,"setting background file");
mapView.setMapFile(mapFile);
} else {
Log.i(TAG,"unable to set background file");
}
// Load map from mission
if(context instanceof SherlockFragmentActivity){
MissionTemplate t = ((GeoCollectApplication) ((SherlockFragmentActivity)context).getApplication()).getTemplate();
MSMMap missionmap = SpatialDbUtils.mapFromDb();
ArrayList<String> bg_layers = null;
try{
if(t != null && t.config != null && t.config.get(MissionTemplate.BG_LAYERS_KEY) != null){
if(t.config.get(MissionTemplate.BG_LAYERS_KEY) instanceof ArrayList<?>){
bg_layers = (ArrayList<String>) t.config.get(MissionTemplate.BG_LAYERS_KEY);
}
}
}catch (ClassCastException cce){
if(BuildConfig.DEBUG){
Log.w(TAG, "backgroundLayers tag is not an ArrayList, ignoring");
}
bg_layers = null;
}
// Use only the layers that are related to this Mission
ArrayList<Layer> layersList = new ArrayList<Layer>();
Layer layer = null;
if(t != null){
for (Iterator<Layer> it = missionmap.layers.iterator(); it.hasNext();) {
layer = it.next();
if (layer.getTitle().equals(t.schema_seg.localSourceStore)
|| layer.getTitle().equals(t.schema_sop.localFormStore)
|| layer.getTitle().equals(t.schema_seg.localSourceStore + MissionTemplate.NEW_NOTICE_SUFFIX)
) {
layersList.add(layer);
}else if (bg_layers != null && bg_layers.contains(layer.getTitle())){
// Adding in the head position, so the layer will
// be on the last in the LayerSwitcher order
layersList.add(0, layer);
}
}
// Set the correct layers
missionmap.layers = layersList;
o.loadMap(missionmap);
}
}
//pannable
mapView.setClickable(!disablePan);
//zoomable
mapView.setBuiltInZoomControls(!disableZoom);
//set center and zoom level limits
Integer b = 18;
Object zoomObj = getAttributeWithDefault(field,"zoom",18);
if(zoomObj instanceof Integer){
b = (Integer)zoomObj;
}
mapView.getMapViewPosition().setZoomLevel(b.byteValue());
mapView.getMapZoomControls().setZoomLevelMax((byte) 30);
mapView.getMapZoomControls().setZoomLevelMin((byte) 1);
//setup tile cache
mapView.getFileSystemTileCache().setPersistent(true);
if(geoPoint!=null){
o.setMarkerVisible();
DescribedMarker marker = new MarkerDTO(geoPoint.latitude, geoPoint.longitude,MarkerDTO.PIN_BLUE).createMarker(context);
marker.setDescription(mission.getValueAsString(context, field, (String)field.getAttribute("description")));
m.getOverlayItems().add(marker);
//mc.selectMarker(marker);
mapView.getMapViewPosition().setCenter(geoPoint);
}
if(context instanceof FormEditActivity){
//add coordinates control
mapView.addControl(new CoordinateControl(mapView, true));
//add "location" control connected to the button
LocationControl lc =new LocationControl(mapView);
lc.setActivationButton(buttonLocation);
mapView.addControl(lc);
}
}
/**
* Create an Header with separator
* @param f
* @param mFormView
* @param context
* @param mission
*/
private static void addSeparator(Field field, LinearLayout mFormView,
Context context, Mission mission) {
String label = mission.getValueAsString(context, field, field.label);
TextView tvLabel = new TextView(context,null,android.R.attr.listSeparatorTextViewStyle);
tvLabel.setLayoutParams(getTextDefaultParams(field, true));
tvLabel.setText(label);
mFormView.addView(tvLabel);
}
/**
* Create an Header with separator and icon
* @param f
* @param mFormView
* @param context
* @param mission
*/
private static void addSeparatorWithIcon(Field field, LinearLayout mFormView, Context context, Mission mission) {
String label = mission.getValueAsString(context, field, field.label);
LinearLayout linearLayout = new LinearLayout(context);
linearLayout.setLayoutParams(new LayoutParams(android.view.ViewGroup.LayoutParams.MATCH_PARENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT));
linearLayout.setOrientation(LinearLayout.HORIZONTAL);
TextView tvLabel = new TextView(context);
LayoutParams tvParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
tvLabel.setTextAppearance(context, android.R.style.TextAppearance_Medium);
tvLabel.setTypeface(Typeface.create("sans-serif", Typeface.BOLD));
tvLabel.setGravity(Gravity.CENTER_VERTICAL|Gravity.LEFT);
tvParams.topMargin = 20;
tvParams.leftMargin = 10;
tvParams.rightMargin =10;
tvParams.gravity = Gravity.LEFT;
tvParams.weight = 0.8f;
tvLabel.setLayoutParams(tvParams);
tvLabel.setText(label);
ImageView imageView = new ImageView(context);
LayoutParams ivParams = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT);
ivParams.topMargin = 10;
ivParams.leftMargin = 10;
ivParams.rightMargin = 10;
ivParams.gravity = Gravity.RIGHT;
tvParams.weight = 0.2f;
imageView.setLayoutParams(ivParams);
// Get the icon and tweak the color
Drawable d = context.getResources().getDrawable(R.drawable.ic_action_important_light);
HashMap <String,String> colors = mission.getTemplate().priorityValuesColors;
final String key = mission.getValueAsString(context, field);
final String color = colors.get(key);
if ( color != null ){
try{
d.mutate().setColorFilter(Color.parseColor(color), PorterDuff.Mode.SRC_ATOP);
}catch(IllegalArgumentException iae){
Log.e("FeatureAdapter", "A feature has an incorrect color value" );
}
}else{
d.mutate().clearColorFilter();
}
imageView.setImageDrawable(d);
linearLayout.addView(tvLabel);
linearLayout.addView(imageView);
mFormView.addView(linearLayout);
View separator = new View(context);
LayoutParams sepParams = new LayoutParams(LayoutParams.MATCH_PARENT,3);
separator.setBackgroundColor(0xffababab);
sepParams.bottomMargin = 5;
sepParams.topMargin = 2;
sepParams.leftMargin = 10;
sepParams.rightMargin =10;
separator.setLayoutParams(sepParams);
mFormView.addView(separator);
}
/**
* Create a not editable text field
* @param f
* @param mFormView
* @param context
* @param mission
*/
private static void addLabel(Field field, LinearLayout mFormView,
Context context, Mission mission) {
//set label
TextView tvLabel = getLabelForField(field, context);
//set text
TextView text = new TextView(context);
text.setLayoutParams(getTextDefaultParams(field, false));
if(field.lines!=null){
text.setSingleLine(false);
text.setLines(field.lines);
text.setMaxLines(field.lines);
}
// setting an unique id is important in order to save the state
// (content) of this view across screen configuration changes
//int type = getInputType(field);
text.setId(id());
text.setTag(field.fieldId);
//text.setInputType(type);
text.setText( mission.getValueAsString(context, field));//TODO make it parameterizable
mFormView.addView(tvLabel);
mFormView.addView(text);
}
/**
* Creates a <Spinner>
* @param field
* @param mFormView
* @param context
* @param mission
*/
private static void addSpinner(Field field, LinearLayout mFormView,
Context context, Mission mission) {
TextView tvLabel = getLabelForField(field, context);
List<HashMap<String, String>> l = getFieldAllowedData(field);
String[] from = getFieldAllowedFrom(field);
SpinnerAdapter adapter = new SimpleAdapter(
context,
l,
android.R.layout.simple_spinner_dropdown_item,
from,
new int[]{android.R.id.text1}
);
Spinner spinner = new Spinner(context);
spinner.setAdapter(adapter);
ArrayList<String> allowedList = new ArrayList<String>();
for( HashMap<String, String> hm : l){
for(String s : hm.values()){
allowedList.add(s);
}
}
String[] allowed = allowedList.isEmpty()? null : allowedList.toArray(new String[allowedList.size()]);
field.value="${origin."+field.fieldId+"}";
//set initial value
String value = mission.getValueAsString(context, field);
if(value!=null && allowed!=null){
int valueIndex=-1;
for(int i = 0;i<allowed.length;i++){
if(value.equals(allowed[i])){
valueIndex = i;
}
}
if(valueIndex>=0){
spinner.setSelection(valueIndex);
}
}
LayoutParams lp = getTextDefaultParams(field, false);
spinner.setLayoutParams(lp);
// setting an unique id is important in order to save the state
// (content) of this view across screen configuration changes
spinner.setId(id());
spinner.setTag(field.fieldId);
mFormView.addView(tvLabel);
mFormView.addView(spinner);
}
private static TextView getLabelForField(Field field, Context context) {
String label = field.label;
TextView tvLabel = new TextView(context);
tvLabel.setLayoutParams(getTextDefaultParams(field,true));
tvLabel.setText(label);
String labelStyle = (String)field.getAttribute("labelStyle");
if(labelStyle !=null){
//TODO use style attribute
}else{
//default style for field label
tvLabel.setTypeface(null, Typeface.BOLD|Typeface.ITALIC);
}
//if label is missing set none
if(label == null){
tvLabel.setVisibility(TextView.GONE);
}
return tvLabel;
}
/**
* Provides the attribute of the map to use in the spinner
* @param field
* @return
*/
private static String[] getFieldAllowedFrom(Field field) {
//TODO make it configurable
return new String[]{"f1"};
}
/**
* Provides the Data for the spinner
* @param field
* @return
*/
public static List<HashMap<String,String>> getFieldAllowedData(Field field){
ArrayList<HashMap<String,String>> data = new ArrayList<HashMap<String,String>>();
if(field.options!=null){
for(String value : field.options){
HashMap<String,String> v1 =new HashMap<String,String>();
v1.put("f1", value);
data.add(v1);
}
}
return data;
}
/**
* Creates a date picker
*
* @param f
* @param mFormView
* @param context
* @param mission
*/
private static void addDatePicker(Field field, LinearLayout mFormView,
Context context, Mission mission) {
int type = getInputType(field);
TextView tvLabel = getLabelForField(field, context);
DatePicker editView = new DatePicker(context,null);
LayoutParams lp = getTextDefaultParams(field, false);
editView.setLayoutParams(lp);
// setting an unique id is important in order to save the state
// (content) of this view across screen configuration changes
editView.setId(id());
editView.setTag(field.fieldId);
editView.setInputType(type);
mFormView.addView(tvLabel);
mFormView.addView(editView);
String value = mission.getValueAsString(context, field);
//get the value
if(value !=null){
DateFormat df = new SimpleDateFormat(field.format, Locale.getDefault());
try{
Calendar c = Calendar.getInstance();
c.setTime(df.parse(value));
editView.setDate(c.get(Calendar.YEAR), c.get(Calendar.MONTH), c.get(Calendar.DATE));
}catch(ParseException e){
Log.e("FORM_PARSER","unable to parse date:"+ value + "with format string" + field.format);
}
}
}
/**
* Add an <EditText> multiline
*
* @param field
* the field configuration
* @param mFormView
* the form view
* @param context
* the context
*/
public static void addTextArea(Field field, LinearLayout mFormView,
Context context) {
int type = getInputType(field);
TextView tvLabel = getLabelForField(field, context);
EditText editView = new EditText(context);
editView.setLayoutParams(getTextDefaultParams(field, false));
editView.setSingleLine(false);
editView.setLines(field.lines);
// setting an unique id is important in order to save the state
// (content) of this view across screen configuration changes
editView.setId(id());
editView.setInputType(type);
mFormView.addView(tvLabel);
mFormView.addView(editView);
}
/**
* Add a <EditText> single line
*
* @param label
* @param type
* @param context
* @param mission
*/
public static void addTextField(Field field, LinearLayout mFormView,
Context context, Mission mission) {
int type = getInputType(field);
TextView tvLabel = getLabelForField(field, context);
EditText editView = null;
//set autocomplete if options present
if(field.options!=null){
editView = addAutoCompleteField(field,mFormView,context);
}else{
editView = new EditText(context);
}
editView.setLayoutParams(getTextDefaultParams(field, false));
// setting an unique id is important in order to save the state
// (content) of this view across screen configuration changes
editView.setId(id());
editView.setTag(field.fieldId);
editView.setInputType(type);
final String mandatoryTag = field.mandatory ? " ("+mFormView.getContext().getString(R.string.mandatory)+")" : "";
tvLabel.setText(tvLabel.getText()+mandatoryTag);
editView.setText( mission.getValueAsString(context, field));//TODO make it parameterizable
mFormView.addView(tvLabel);
mFormView.addView(editView);
}
/**
* Add a <EditText> single line
*
* @param label
* @param type
* @param context
*/
public static AutoCompleteTextView addAutoCompleteField(Field field, LinearLayout mFormView,
Context context) {
AutoCompleteTextView editView = (AutoCompleteTextView) new AutoCompleteTextView(context);
// Get the string array
if(field.options !=null){
ArrayAdapter<String> adapter =
new ArrayAdapter<String>(context,
android.R.layout.simple_dropdown_item_1line, field.options);
editView.setAdapter(adapter);
editView.setLayoutParams(getTextDefaultParams(field, false));
}
return editView;
}
/**
* Add a <CheckBox> single line
*
* @param label
* @param type
* @param context
* @param mission
*/
public static void addCheckBox(Field field, LinearLayout mFormView,
Context context, Mission mission) {
// setting an unique id is important in order to save the state
// (content) of this view across screen configuration changes
CheckBox cb = new CheckBox(context);
cb.setText(field.label);
cb.setLayoutParams(getTextDefaultParams(field, false));
cb.setId(id());
cb.setTag(field.fieldId);
mFormView.addView(cb);
}
/**
* Create an Header with GridView
* @param f
* @param mFormView
* @param context
* @param mission
*/
private static void addPhotoGrid(Field field, LinearLayout mFormView,
Context context, Mission mission) {
// TODO: enable label?
//TextView tvLabel = getLabelForField(field, context);
// TODO: Null check on this line
GridView photoView = (GridView) ((LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.ac_image_grid, mFormView, false);;
photoView.setLayoutParams(getTextDefaultParams(field, true));
//photoView.setTag(field.fieldId); // TODO: useless, the photoView must be used to fetch from a folder derived from the mission id
// TODO: use a non-string tag
photoView.setTag("__photo__");
//String[] stringUrls = FormUtils.getPhotoUriStrings(mission.getOrigin().id);
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(it.geosolutions.geocollect.android.app.R.drawable.ic_launcher)
.showImageForEmptyUri(it.geosolutions.geocollect.android.app.R.drawable.ic_empty)
.showImageOnFail(it.geosolutions.geocollect.android.app.R.drawable.ic_error)
.resetViewBeforeLoading(false)
.cacheInMemory(false)
.cacheOnDisk(false)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.EXACTLY)
.build();
//***************************
photoView.setAdapter(new UILImageAdapter(context, MissionUtils.getMissionGCID(mission), options));
// enable ContexxtMenu on LongPress
((FormEditActivity) context).registerForContextMenu(photoView);
photoView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
//startImagePagerActivity(position);
Log.v("ItemListener", "Clicked position "+position+" , id "+id+ ", ViewID "+view.getId());
// TODO: start full image show activity
//view.showContextMenu();
}
});
/*
photoView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> parent, View view,
int position, long id) {
Log.v("ItemListener", "LONG Click on position "+position+" , id "+id+ ", ViewID "+view.getId());
// TODO: open contextual menu for deletion
return true;
}
});
*/
// TODO: enable label?
//mFormView.addView(tvLabel);
mFormView.addView(photoView);
}
/**
* Generates the Android input Type from the text field
*
* @param field
* @return
*/
private static int getInputType(Field field) {
if (field.type == null) {
return InputType.TYPE_CLASS_TEXT;
} else {
switch (field.type) {
case person:
//return InputType.TYPE_TEXT_VARIATION_PERSON_NAME; // TYPE_TEXT_VARIATION_PERSON_NAME seems to not be used by the framework
return InputType.TYPE_TEXT_FLAG_CAP_WORDS;
case phone:
return InputType.TYPE_CLASS_PHONE;
case decimal:
case integer:
return InputType.TYPE_CLASS_NUMBER;
case date:
return InputType.TYPE_CLASS_DATETIME
| InputType.TYPE_DATETIME_VARIATION_DATE;
case datetime:
return InputType.TYPE_CLASS_DATETIME
| InputType.TYPE_DATETIME_VARIATION_NORMAL;
case string:
return InputType.TYPE_CLASS_TEXT;
default:
break;
}
}
return InputType.TYPE_CLASS_TEXT;
}
/**
* Provides default Layout Parameters
*
* @param isLabel
* @return
*/
private static LayoutParams getTextDefaultParams(Field field,
boolean isLabel) {
LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
if (isLabel) {
params.bottomMargin = 5;
params.topMargin = 10;
}
params.leftMargin = 10;
params.rightMargin =10;
return params;
}
private static LayoutParams getMapLayoutParams (Field field){
Double h = (Double) field.getAttribute("height");
LayoutParams params = new LayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.MATCH_PARENT);
if(h!=null){
params = new LayoutParams(LayoutParams.MATCH_PARENT,
h.intValue());
}else{
params = new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT);
}
params.bottomMargin = 20;
params.topMargin = 20;
params.leftMargin = 10;
params.rightMargin =10;
return params;
}
/**
* get the attribute of a field if present, the default value instead
* @param f the field
* @param attributeName the name of the attribute
* @param defaultValue the default value
* @return
*/
public static Object getAttributeWithDefault(Field f, String attributeName,Object defaultValue){
Object o = f.getAttribute(attributeName);
if(o==null){
return defaultValue;
}
else{
return o;
}
}
}