# HG changeset patch
# User tomsmyth
# Date 1373557321 14400
#      Thu Jul 11 11:42:01 2013 -0400
# Node ID 0eac588a515bfcca74a5ce959d425e0d736c49a9
# Parent  f8ad402a87c8f5332921e5efb2311cdf6ce6d09d
constraint behavior patch

diff -r f8ad402a87c8 -r 0eac588a515b res/values-fr/strings.xml
--- a/res/values-fr/strings.xml	Wed Jul 10 12:14:52 2013 -0700
+++ b/res/values-fr/strings.xml	Thu Jul 11 11:42:01 2013 -0400
@@ -243,4 +243,7 @@
   <string name="change_url_default">URL</string>
   <string name="launch_printer">Lancer l\'impression</string>
   <string name="no_printer">L\'imprimante demandée n\'est pas installée. Merci d\'installer l\'imprimante.</string>
+  <string name="constraint_behavior">Comportement pour traitement des contraintes</string>
+  <string name="constraint_behavior_on_swipe">Valider avec défilement en avant</string>
+  <string name="constraint_behavior_on_finalize">Valider avec finalisation</string>
 </resources>
diff -r f8ad402a87c8 -r 0eac588a515b res/values/arrays.xml
--- a/res/values/arrays.xml	Wed Jul 10 12:14:52 2013 -0700
+++ b/res/values/arrays.xml	Thu Jul 11 11:42:01 2013 -0400
@@ -50,4 +50,14 @@
 		<item>@string/buttons_navigation</item>
 		<item>@string/swipe_buttons_navigation</item>
 	</string-array>
+	<string-array
+		name="constraint_behavior_entry_values">
+		<item>on_swipe</item>
+		<item>on_finalize</item>
+	</string-array>
+	<string-array
+		name="constraint_behavior_entries">
+		<item>@string/constraint_behavior_on_swipe</item>
+		<item>@string/constraint_behavior_on_finalize</item>
+	</string-array>
 </resources>
\ No newline at end of file
diff -r f8ad402a87c8 -r 0eac588a515b res/values/strings.xml
--- a/res/values/strings.xml	Wed Jul 10 12:14:52 2013 -0700
+++ b/res/values/strings.xml	Thu Jul 11 11:42:01 2013 -0400
@@ -249,4 +249,7 @@
 <string name="change_url_default">URL</string>
 <string name="launch_printer">Initiate Printing</string>
 <string name="no_printer">The requested printer is not installed. Please install the printer.</string>
+<string name="constraint_behavior">Constraint processing behavior</string>
+<string name="constraint_behavior_on_swipe">Validate upon forward swipe</string>
+<string name="constraint_behavior_on_finalize">Defer validation until finalized</string>
 </resources>
\ No newline at end of file
diff -r f8ad402a87c8 -r 0eac588a515b res/xml/admin_preferences.xml
--- a/res/xml/admin_preferences.xml	Wed Jul 10 12:14:52 2013 -0700
+++ b/res/xml/admin_preferences.xml	Thu Jul 11 11:42:01 2013 -0400
@@ -97,6 +97,12 @@
             android:summary="@string/found_in_settings"
             android:title="@string/navigation" />
         <CheckBoxPreference
+            android:id="@+id/constraint_behavior"
+            android:defaultValue="true"
+            android:key="constraint_behavior"
+            android:summary="@string/found_in_settings"
+            android:title="@string/constraint_behavior" />
+        <CheckBoxPreference
             android:id="@+id/change_font_size"
             android:defaultValue="true"
             android:key="change_font_size"
diff -r f8ad402a87c8 -r 0eac588a515b res/xml/preferences.xml
--- a/res/xml/preferences.xml	Wed Jul 10 12:14:52 2013 -0700
+++ b/res/xml/preferences.xml	Thu Jul 11 11:42:01 2013 -0400
@@ -101,6 +101,14 @@
             android:key="navigation"
             android:title="@string/navigation" />
         <ListPreference
+            android:id="@+id/constraint_behavior"
+            android:defaultValue="on_swipe"
+            android:dialogTitle="@string/constraint_behavior"
+            android:entries="@array/constraint_behavior_entries"
+            android:entryValues="@array/constraint_behavior_entry_values"
+            android:key="constraint_behavior"
+            android:title="@string/constraint_behavior" />
+        <ListPreference
             android:id="@+id/font_size"
             android:defaultValue="21"
             android:dialogTitle="@string/change_font_size"
diff -r f8ad402a87c8 -r 0eac588a515b src/org/odk/collect/android/activities/FormEntryActivity.java
--- a/src/org/odk/collect/android/activities/FormEntryActivity.java	Wed Jul 10 12:14:52 2013 -0700
+++ b/src/org/odk/collect/android/activities/FormEntryActivity.java	Thu Jul 11 11:42:01 2013 -0400
@@ -1224,12 +1224,25 @@
 	private void showNextView() {
 		FormController formController = Collect.getInstance()
 				.getFormController();
+			
+		// get constraint behavior preference value with appropriate default
+		String constraint_behavior = PreferenceManager.getDefaultSharedPreferences(this)
+			.getString(PreferencesActivity.KEY_CONSTRAINT_BEHAVIOR, 
+				PreferencesActivity.CONSTRAINT_BEHAVIOR_DEFAULT);
+		
 		if (formController.currentPromptIsQuestion()) {
-			if (!saveAnswersForCurrentScreen(EVALUATE_CONSTRAINTS)) {
-				// A constraint was violated so a dialog should be showing.
-				mBeenSwiped = false;
-				return;
-			}
+
+			// if constraint behavior says we should validate on swipe, do so
+			if (constraint_behavior.equals(PreferencesActivity.CONSTRAINT_BEHAVIOR_ON_SWIPE)) {
+				if (!saveAnswersForCurrentScreen(EVALUATE_CONSTRAINTS)) {
+					// A constraint was violated so a dialog should be showing.
+					mBeenSwiped = false;
+					return;
+				}
+				
+			// otherwise, just save without validating (constraints will be validated on finalize)
+			} else
+				saveAnswersForCurrentScreen(DO_NOT_EVALUATE_CONSTRAINTS);
 		}
 
 		View next;
@@ -2349,9 +2362,20 @@
 		case FormEntryController.ANSWER_CONSTRAINT_VIOLATED:
 		case FormEntryController.ANSWER_REQUIRED_BUT_EMPTY:
 			refreshCurrentView();
-			// an answer constraint was violated, so do a 'swipe' to the next
-			// question to display the proper toast(s)
-			next();
+			
+			// get constraint behavior preference value with appropriate default
+			String constraint_behavior = PreferenceManager.getDefaultSharedPreferences(this)
+				.getString(PreferencesActivity.KEY_CONSTRAINT_BEHAVIOR, 
+					PreferencesActivity.CONSTRAINT_BEHAVIOR_DEFAULT);
+			
+			// an answer constraint was violated, so we need to display the proper toast(s)
+			// if constraint behavior is on_swipe, this will happen if we do a 'swipe' to the next question
+			if (constraint_behavior.equals(PreferencesActivity.CONSTRAINT_BEHAVIOR_ON_SWIPE))
+				next();
+			// otherwise, we can get the proper toast(s) by saving with constraint check
+			else
+				saveAnswersForCurrentScreen(EVALUATE_CONSTRAINTS);
+				
 			break;
 		}
 	}
diff -r f8ad402a87c8 -r 0eac588a515b src/org/odk/collect/android/preferences/AdminPreferencesActivity.java
--- a/src/org/odk/collect/android/preferences/AdminPreferencesActivity.java	Wed Jul 10 12:14:52 2013 -0700
+++ b/src/org/odk/collect/android/preferences/AdminPreferencesActivity.java	Thu Jul 11 11:42:01 2013 -0400
@@ -69,6 +69,7 @@
     public static String KEY_AUTOSEND_NETWORK = "autosend_network";
 
     public static String KEY_NAVIGATION = "navigation";
+    public static String KEY_CONSTRAINT_BEHAVIOR = "constraint_behavior";
 
     private static final int SAVE_PREFS_MENU = Menu.FIRST;
 
diff -r f8ad402a87c8 -r 0eac588a515b src/org/odk/collect/android/preferences/PreferencesActivity.java
--- a/src/org/odk/collect/android/preferences/PreferencesActivity.java	Wed Jul 10 12:14:52 2013 -0700
+++ b/src/org/odk/collect/android/preferences/PreferencesActivity.java	Thu Jul 11 11:42:01 2013 -0400
@@ -73,6 +73,10 @@
 	public static final String NAVIGATION_BUTTONS = "buttons";
 	public static final String NAVIGATION_SWIPE_BUTTONS = "swipe_buttons";
 
+	public static final String CONSTRAINT_BEHAVIOR_ON_SWIPE = "on_swipe";
+	public static final String CONSTRAINT_BEHAVIOR_ON_FINALIZE = "on_finalize";
+	public static final String CONSTRAINT_BEHAVIOR_DEFAULT = "on_swipe";
+
 	public static final String KEY_FORMLIST_URL = "formlist_url";
 	public static final String KEY_SUBMISSION_URL = "submission_url";
 
@@ -84,6 +88,7 @@
 	public static final String KEY_AUTOSEND_NETWORK = "autosend_network";
 
 	public static final String KEY_NAVIGATION = "navigation";
+	public static final String KEY_CONSTRAINT_BEHAVIOR = "constraint_behavior";
 
 	private PreferenceScreen mSplashPathPreference;
 	private EditTextPreference mSubmissionUrlPreference;
@@ -94,6 +99,7 @@
 	private ListPreference mSelectedGoogleAccountPreference;
 	private ListPreference mFontSizePreference;
 	private ListPreference mNavigationPreference;
+	private ListPreference mConstraintBehaviorPreference;
 
 	private CheckBoxPreference mAutosendWifiPreference;
 	private CheckBoxPreference mAutosendNetworkPreference;
@@ -352,6 +358,28 @@
 			clientCategory.removePreference(mNavigationPreference);
 		}
 		
+		boolean constraintBehaviorAvailable = adminPreferences.getBoolean(
+				AdminPreferencesActivity.KEY_CONSTRAINT_BEHAVIOR, true);
+		mConstraintBehaviorPreference = (ListPreference) findPreference(KEY_CONSTRAINT_BEHAVIOR);
+		mConstraintBehaviorPreference.setSummary(mConstraintBehaviorPreference.getEntry());
+		mConstraintBehaviorPreference
+				.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
+
+					@Override
+					public boolean onPreferenceChange(Preference preference,
+							Object newValue) {
+						int index = ((ListPreference) preference)
+								.findIndexOfValue(newValue.toString());
+						String entry = (String) ((ListPreference) preference)
+								.getEntries()[index];
+						((ListPreference) preference).setSummary(entry);
+						return true;
+					}
+				});
+		if (!(constraintBehaviorAvailable || adminMode)) {
+			clientCategory.removePreference(mConstraintBehaviorPreference);
+		}
+		
 		boolean fontAvailable = adminPreferences.getBoolean(
 				AdminPreferencesActivity.KEY_CHANGE_FONT_SIZE, true);
 		mFontSizePreference = (ListPreference) findPreference(KEY_FONT_SIZE);
