aboutsummaryrefslogtreecommitdiff
path: root/java/src/com/android/i18n/addressinput/AddressWidget.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/src/com/android/i18n/addressinput/AddressWidget.java')
-rw-r--r--java/src/com/android/i18n/addressinput/AddressWidget.java1315
1 files changed, 656 insertions, 659 deletions
diff --git a/java/src/com/android/i18n/addressinput/AddressWidget.java b/java/src/com/android/i18n/addressinput/AddressWidget.java
index 8a598ff..3a7267b 100644
--- a/java/src/com/android/i18n/addressinput/AddressWidget.java
+++ b/java/src/com/android/i18n/addressinput/AddressWidget.java
@@ -51,731 +51,728 @@ import java.util.Map;
* customs.
*/
public class AddressWidget implements AdapterView.OnItemSelectedListener {
- private Context mContext;
+ private Context context;
- private ViewGroup mRootView;
+ private ViewGroup rootView;
- private LayoutInflater mInflater;
+ private LayoutInflater inflater;
- private CacheData mCacheData;
+ private CacheData cacheData;
- // A map for all address fields.
- private final EnumMap<AddressField, AddressUiComponent> mInputWidgets =
- new EnumMap<AddressField, AddressUiComponent>(AddressField.class);
+ // A map for all address fields.
+ private final EnumMap<AddressField, AddressUiComponent> inputWidgets =
+ new EnumMap<AddressField, AddressUiComponent>(AddressField.class);
- private FormController mFormController;
+ private FormController formController;
- private FormatInterpreter mFormatInterpreter;
+ private FormatInterpreter formatInterpreter;
- private FormOptions mFormOptions;
+ private FormOptions formOptions;
- private StandardAddressVerifier mVerifier;
+ private StandardAddressVerifier verifier;
- private ProgressDialog mProgressDialog;
+ private ProgressDialog progressDialog;
- private String mCurrentRegion;
+ private String currentRegion;
- // The current language the widget uses in BCP47 format. It differs from the default locale of
- // the phone in that it contains information on the script to use.
- private String mWidgetLocale;
+ // The current language the widget uses in BCP47 format. It differs from the default locale of
+ // the phone in that it contains information on the script to use.
+ private String widgetLocale;
- private ScriptType mScript;
+ private ScriptType script;
- // Possible labels that could be applied to the admin area field of the current country.
- // Examples include "state", "province", "emirate", etc.
- private static final Map<String, Integer> ADMIN_LABELS;
- // Possible labels that could be applied to the locality (city) field of the current country.
- // Examples include "city" or "district".
- private static final Map<String, Integer> LOCALITY_LABELS;
- // Possible labels that could be applied to the sublocality field of the current country.
- // Examples include "suburb" or "neighborhood".
- private static final Map<String, Integer> SUBLOCALITY_LABELS;
+ // Possible labels that could be applied to the admin area field of the current country.
+ // Examples include "state", "province", "emirate", etc.
+ private static final Map<String, Integer> ADMIN_LABELS;
+ // Possible labels that could be applied to the locality (city) field of the current country.
+ // Examples include "city" or "district".
+ private static final Map<String, Integer> LOCALITY_LABELS;
+ // Possible labels that could be applied to the sublocality field of the current country.
+ // Examples include "suburb" or "neighborhood".
+ private static final Map<String, Integer> SUBLOCALITY_LABELS;
- private static final FormOptions SHOW_ALL_FIELDS = new FormOptions.Builder().build();
+ private static final FormOptions SHOW_ALL_FIELDS = new FormOptions.Builder().build();
- // The appropriate label that should be applied to the zip code field of the current country.
- private enum ZipLabel {
- ZIP,
- POSTAL
- }
-
- private ZipLabel mZipLabel;
-
- static {
- Map<String, Integer> adminLabelMap = new HashMap<String, Integer>(15);
- adminLabelMap.put("area", R.string.i18n_area);
- adminLabelMap.put("county", R.string.i18n_county);
- adminLabelMap.put("department", R.string.i18n_department);
- adminLabelMap.put("district", R.string.i18n_district);
- adminLabelMap.put("do_si", R.string.i18n_do_si);
- adminLabelMap.put("emirate", R.string.i18n_emirate);
- adminLabelMap.put("island", R.string.i18n_island);
- adminLabelMap.put("oblast", R.string.i18n_oblast);
- adminLabelMap.put("parish", R.string.i18n_parish);
- adminLabelMap.put("prefecture", R.string.i18n_prefecture);
- adminLabelMap.put("province", R.string.i18n_province);
- adminLabelMap.put("state", R.string.i18n_state);
- ADMIN_LABELS = Collections.unmodifiableMap(adminLabelMap);
+ // The appropriate label that should be applied to the zip code field of the current country.
+ private enum ZipLabel {
+ ZIP,
+ POSTAL
+ }
- Map<String, Integer> localityLabelMap = new HashMap<String, Integer>(2);
- localityLabelMap.put("city", R.string.i18n_locality_label);
- localityLabelMap.put("district", R.string.i18n_district);
- localityLabelMap.put("post_town", R.string.i18n_post_town);
- LOCALITY_LABELS = Collections.unmodifiableMap(localityLabelMap);
+ private ZipLabel zipLabel;
- Map<String, Integer> sublocalityLabelMap = new HashMap<String, Integer>(2);
- sublocalityLabelMap.put("suburb", R.string.i18n_suburb);
- sublocalityLabelMap.put("district", R.string.i18n_district);
- sublocalityLabelMap.put("neighborhood", R.string.i18n_neighborhood);
- sublocalityLabelMap.put("village_township", R.string.i18n_village_township);
- SUBLOCALITY_LABELS = Collections.unmodifiableMap(sublocalityLabelMap);
- }
+ static {
+ Map<String, Integer> adminLabelMap = new HashMap<String, Integer>(15);
+ adminLabelMap.put("area", R.string.i18n_area);
+ adminLabelMap.put("county", R.string.i18n_county);
+ adminLabelMap.put("department", R.string.i18n_department);
+ adminLabelMap.put("district", R.string.i18n_district);
+ adminLabelMap.put("do_si", R.string.i18n_do_si);
+ adminLabelMap.put("emirate", R.string.i18n_emirate);
+ adminLabelMap.put("island", R.string.i18n_island);
+ adminLabelMap.put("oblast", R.string.i18n_oblast);
+ adminLabelMap.put("parish", R.string.i18n_parish);
+ adminLabelMap.put("prefecture", R.string.i18n_prefecture);
+ adminLabelMap.put("province", R.string.i18n_province);
+ adminLabelMap.put("state", R.string.i18n_state);
+ ADMIN_LABELS = Collections.unmodifiableMap(adminLabelMap);
- // Need handler for callbacks to the UI thread
- final Handler mHandler = new Handler();
+ Map<String, Integer> localityLabelMap = new HashMap<String, Integer>(2);
+ localityLabelMap.put("city", R.string.i18n_locality_label);
+ localityLabelMap.put("district", R.string.i18n_district);
+ localityLabelMap.put("post_town", R.string.i18n_post_town);
+ LOCALITY_LABELS = Collections.unmodifiableMap(localityLabelMap);
- final Runnable mUpdateMultipleFields = new Runnable() {
- @Override
- public void run() {
- updateFields();
- }
- };
+ Map<String, Integer> sublocalityLabelMap = new HashMap<String, Integer>(2);
+ sublocalityLabelMap.put("suburb", R.string.i18n_suburb);
+ sublocalityLabelMap.put("district", R.string.i18n_district);
+ sublocalityLabelMap.put("neighborhood", R.string.i18n_neighborhood);
+ sublocalityLabelMap.put("village_township", R.string.i18n_village_township);
+ SUBLOCALITY_LABELS = Collections.unmodifiableMap(sublocalityLabelMap);
+ }
- private class UpdateRunnable implements Runnable {
- private AddressField myId;
+ // Need handler for callbacks to the UI thread
+ final Handler handler = new Handler();
- public UpdateRunnable(AddressField id) {
- myId = id;
- }
-
- @Override
- public void run() {
- updateInputWidget(myId);
- }
+ final Runnable updateMultipleFields = new Runnable() {
+ @Override
+ public void run() {
+ updateFields();
}
+ };
- private static class AddressSpinnerInfo {
- private Spinner mView;
+ private class UpdateRunnable implements Runnable {
+ private AddressField myId;
- private AddressField mId;
+ public UpdateRunnable(AddressField id) {
+ myId = id;
+ }
- private AddressField mParentId;
+ @Override
+ public void run() {
+ updateInputWidget(myId);
+ }
+ }
- private ArrayAdapter<String> mAdapter;
+ private static class AddressSpinnerInfo {
+ private Spinner view;
- private List<RegionData> mCurrentRegions;
+ private AddressField id;
- @SuppressWarnings("unchecked")
- public AddressSpinnerInfo(Spinner view, AddressField id, AddressField parentId) {
- mView = view;
- mId = id;
- mParentId = parentId;
- mAdapter = (ArrayAdapter<String>) view.getAdapter();
- }
+ private AddressField parentId;
- public void setSpinnerList(List<RegionData> list, String defaultKey) {
- mCurrentRegions = list;
- mAdapter.clear();
- for (RegionData item : list) {
- mAdapter.add(item.getDisplayName());
- }
- mAdapter.sort(Collator.getInstance(Locale.getDefault()));
- if (defaultKey.length() == 0) {
- mView.setSelection(0);
- } else {
- int position = mAdapter.getPosition(defaultKey);
- mView.setSelection(position);
- }
- }
+ private ArrayAdapter<String> adapter;
- // Returns the region key of the currently selected region in the Spinner.
- public String getRegionCode(int position) {
- if (mAdapter.getCount() <= position) {
- return "";
- }
- String value = mAdapter.getItem(position);
- return getRegionDataKeyForValue(value);
- }
+ private List<RegionData> currentRegions;
- // Returns the region key for the region value.
- public String getRegionDataKeyForValue(String value) {
- for (RegionData data : mCurrentRegions) {
- if (data.getDisplayName().endsWith(value)) {
- return data.getKey();
- }
- }
- return "";
- }
+ @SuppressWarnings("unchecked")
+ public AddressSpinnerInfo(Spinner view, AddressField id, AddressField parentId) {
+ this.view = view;
+ this.id = id;
+ this.parentId = parentId;
+ this.adapter = (ArrayAdapter<String>) view.getAdapter();
}
- private final ArrayList<AddressSpinnerInfo> mSpinners = new ArrayList<AddressSpinnerInfo>();
-
- private AddressWidgetUiComponentProvider mComponentProvider;
-
- /** TODO: Add region-dependent width types for address fields. */
- private WidthType getFieldWidthType(AddressUiComponent field) {
- return field.getId().getDefaulWidthType();
+ public void setSpinnerList(List<RegionData> list, String defaultKey) {
+ currentRegions = list;
+ adapter.clear();
+ for (RegionData item : list) {
+ adapter.add(item.getDisplayName());
+ }
+ adapter.sort(Collator.getInstance(Locale.getDefault()));
+ if (defaultKey.length() == 0) {
+ view.setSelection(0);
+ } else {
+ int position = adapter.getPosition(defaultKey);
+ view.setSelection(position);
+ }
}
- private void createView(ViewGroup rootView, AddressUiComponent field, String defaultKey,
- boolean readOnly) {
- @SuppressWarnings("deprecation") // FILL_PARENT renamed MATCH_PARENT in API Level 8.
- LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
- LayoutParams.WRAP_CONTENT);
- String fieldText = field.getFieldName();
- WidthType widthType = getFieldWidthType(field);
-
- if (fieldText.length() > 0) {
- TextView textView = mComponentProvider.createUiLabel(fieldText, widthType);
- rootView.addView(textView, lp);
- }
- if (field.getUiType().equals(UiComponent.EDIT)) {
- EditText editText = mComponentProvider.createUiTextField(widthType);
- field.setView(editText);
- editText.setEnabled(!readOnly);
- rootView.addView(editText, lp);
- } else if (field.getUiType().equals(UiComponent.SPINNER)) {
- ArrayAdapter<String> adapter = mComponentProvider.createUiPickerAdapter(widthType);
- Spinner spinner = mComponentProvider.createUiPickerSpinner(widthType);
-
- field.setView(spinner);
- rootView.addView(spinner, lp);
- spinner.setAdapter(adapter);
- AddressSpinnerInfo spinnerInfo =
- new AddressSpinnerInfo(spinner, field.getId(), field.getParentId());
- spinnerInfo.setSpinnerList(field.getCandidatesList(), defaultKey);
-
- if (fieldText.length() > 0) {
- spinner.setPrompt(fieldText);
- }
- spinner.setOnItemSelectedListener(this);
- mSpinners.add(spinnerInfo);
- }
+ // Returns the region key of the currently selected region in the Spinner.
+ public String getRegionCode(int position) {
+ if (adapter.getCount() <= position) {
+ return "";
+ }
+ String value = adapter.getItem(position);
+ return getRegionDataKeyForValue(value);
}
- /**
- * Associates each field with its corresponding AddressUiComponent.
- */
- private void buildFieldWidgets() {
- AddressData data = new AddressData.Builder().setCountry(mCurrentRegion).build();
- LookupKey key = new LookupKey.Builder(LookupKey.KeyType.DATA).setAddressData(data).build();
- AddressVerificationNodeData countryNode =
- (new ClientData(mCacheData)).getDefaultData(key.toString());
-
- // Set up AddressField.ADMIN_AREA
- AddressUiComponent adminAreaUi = new AddressUiComponent(AddressField.ADMIN_AREA);
- adminAreaUi.setFieldName(getAdminAreaFieldName(countryNode));
- mInputWidgets.put(AddressField.ADMIN_AREA, adminAreaUi);
-
- // Set up AddressField.LOCALITY
- AddressUiComponent localityUi = new AddressUiComponent(AddressField.LOCALITY);
- localityUi.setFieldName(getLocalityFieldName(countryNode));
- mInputWidgets.put(AddressField.LOCALITY, localityUi);
-
- // Set up AddressField.DEPENDENT_LOCALITY
- AddressUiComponent subLocalityUi = new AddressUiComponent(AddressField.DEPENDENT_LOCALITY);
- subLocalityUi.setFieldName(getSublocalityFieldName(countryNode));
- mInputWidgets.put(AddressField.DEPENDENT_LOCALITY, subLocalityUi);
-
- // Set up AddressField.ADDRESS_LINE_1
- AddressUiComponent addressLine1Ui = new AddressUiComponent(AddressField.ADDRESS_LINE_1);
- addressLine1Ui.setFieldName(mContext.getString(R.string.i18n_address_line1_label));
- mInputWidgets.put(AddressField.ADDRESS_LINE_1, addressLine1Ui);
-
- // Set up AddressField.ADDRESS_LINE_2
- AddressUiComponent addressLine2Ui = new AddressUiComponent(AddressField.ADDRESS_LINE_2);
- addressLine2Ui.setFieldName("");
- mInputWidgets.put(AddressField.ADDRESS_LINE_2, addressLine2Ui);
-
- // Set up AddressField.ORGANIZATION
- AddressUiComponent organizationUi = new AddressUiComponent(AddressField.ORGANIZATION);
- organizationUi.setFieldName(mContext.getString(R.string.i18n_organization_label));
- mInputWidgets.put(AddressField.ORGANIZATION, organizationUi);
-
- // Set up AddressField.RECIPIENT
- AddressUiComponent recipientUi = new AddressUiComponent(AddressField.RECIPIENT);
- recipientUi.setFieldName(mContext.getString(R.string.i18n_recipient_label));
- mInputWidgets.put(AddressField.RECIPIENT, recipientUi);
-
- // Set up AddressField.POSTAL_CODE
- AddressUiComponent postalCodeUi = new AddressUiComponent(AddressField.POSTAL_CODE);
- postalCodeUi.setFieldName(getZipFieldName(countryNode));
- mInputWidgets.put(AddressField.POSTAL_CODE, postalCodeUi);
-
- // Set up AddressField.SORTING_CODE
- AddressUiComponent sortingCodeUi = new AddressUiComponent(AddressField.SORTING_CODE);
- sortingCodeUi.setFieldName("CEDEX");
- mInputWidgets.put(AddressField.SORTING_CODE, sortingCodeUi);
- }
-
- private void initializeDropDowns() {
- AddressUiComponent adminAreaUi = mInputWidgets.get(AddressField.ADMIN_AREA);
- List<RegionData> adminAreaList = getRegionData(AddressField.COUNTRY);
- adminAreaUi.initializeCandidatesList(adminAreaList);
-
- AddressUiComponent localityUi = mInputWidgets.get(AddressField.LOCALITY);
- List<RegionData> localityList = getRegionData(AddressField.ADMIN_AREA);
- localityUi.initializeCandidatesList(localityList);
- }
-
- // ZIP code is called postal code in some countries. This method returns the appropriate name
- // for the given countryNode.
- private String getZipFieldName(AddressVerificationNodeData countryNode) {
- String zipName;
- String zipType = countryNode.get(AddressDataKey.ZIP_NAME_TYPE);
- if (zipType == null) {
- mZipLabel = ZipLabel.POSTAL;
- zipName = mContext.getString(R.string.i18n_postal_code_label);
- } else {
- mZipLabel = ZipLabel.ZIP;
- zipName = mContext.getString(R.string.i18n_zip_code_label);
+ // Returns the region key for the region value.
+ public String getRegionDataKeyForValue(String value) {
+ for (RegionData data : currentRegions) {
+ if (data.getDisplayName().endsWith(value)) {
+ return data.getKey();
}
- return zipName;
+ }
+ return "";
}
+ }
- private String getLocalityFieldName(AddressVerificationNodeData countryNode) {
- String localityLabelType = countryNode.get(AddressDataKey.LOCALITY_NAME_TYPE);
- Integer result = LOCALITY_LABELS.get(localityLabelType);
- if (result == null) {
- // Fallback to city.
- result = R.string.i18n_locality_label;
- }
- return mContext.getString(result);
- }
+ private final ArrayList<AddressSpinnerInfo> spinners = new ArrayList<AddressSpinnerInfo>();
- private String getSublocalityFieldName(AddressVerificationNodeData countryNode) {
- String sublocalityLabelType = countryNode.get(AddressDataKey.SUBLOCALITY_NAME_TYPE);
- Integer result = SUBLOCALITY_LABELS.get(sublocalityLabelType);
- if (result == null) {
- // Fallback to suburb.
- result = R.string.i18n_suburb;
- }
- return mContext.getString(result);
- }
+ private AddressWidgetUiComponentProvider componentProvider;
- private String getAdminAreaFieldName(AddressVerificationNodeData countryNode) {
- String adminLabelType = countryNode.get(AddressDataKey.STATE_NAME_TYPE);
- Integer result = ADMIN_LABELS.get(adminLabelType);
- if (result == null) {
- // Fallback to province.
- result = R.string.i18n_province;
- }
- return mContext.getString(result);
- }
-
- private void buildCountryListBox() {
- // Set up AddressField.COUNTRY
- AddressUiComponent countryUi = new AddressUiComponent(AddressField.COUNTRY);
- countryUi.setFieldName(mContext.getString(R.string.i18n_country_or_region_label));
- ArrayList<RegionData> countries = new ArrayList<RegionData>();
- for (RegionData regionData : mFormController.getRegionData(new LookupKey.Builder(
- KeyType.DATA).build())) {
- String regionKey = regionData.getKey();
- // ZZ represents an unknown region code.
- if (!regionKey.equals("ZZ")) {
- String localCountryName = getLocalCountryName(regionKey);
- RegionData country = new RegionData.Builder().setKey(regionKey).setName(
- localCountryName).build();
- countries.add(country);
- }
- }
- countryUi.initializeCandidatesList(countries);
- mInputWidgets.put(AddressField.COUNTRY, countryUi);
- }
+ /** TODO: Add region-dependent width types for address fields. */
+ private WidthType getFieldWidthType(AddressUiComponent field) {
+ return field.getId().getDefaulWidthType();
+ }
- private String getLocalCountryName(String regionCode) {
- return (new Locale("", regionCode)).getDisplayCountry(Locale.getDefault());
+ private void createView(ViewGroup rootView, AddressUiComponent field, String defaultKey,
+ boolean readOnly) {
+ @SuppressWarnings("deprecation") // FILL_PARENT renamed MATCH_PARENT in API Level 8.
+ LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT,
+ LayoutParams.WRAP_CONTENT);
+ String fieldText = field.getFieldName();
+ WidthType widthType = getFieldWidthType(field);
+
+ if (fieldText.length() > 0) {
+ TextView textView = componentProvider.createUiLabel(fieldText, widthType);
+ rootView.addView(textView, lp);
+ }
+ if (field.getUiType().equals(UiComponent.EDIT)) {
+ EditText editText = componentProvider.createUiTextField(widthType);
+ field.setView(editText);
+ editText.setEnabled(!readOnly);
+ rootView.addView(editText, lp);
+ } else if (field.getUiType().equals(UiComponent.SPINNER)) {
+ ArrayAdapter<String> adapter = componentProvider.createUiPickerAdapter(widthType);
+ Spinner spinner = componentProvider.createUiPickerSpinner(widthType);
+
+ field.setView(spinner);
+ rootView.addView(spinner, lp);
+ spinner.setAdapter(adapter);
+ AddressSpinnerInfo spinnerInfo =
+ new AddressSpinnerInfo(spinner, field.getId(), field.getParentId());
+ spinnerInfo.setSpinnerList(field.getCandidatesList(), defaultKey);
+
+ if (fieldText.length() > 0) {
+ spinner.setPrompt(fieldText);
+ }
+ spinner.setOnItemSelectedListener(this);
+ spinners.add(spinnerInfo);
+ }
+ }
+
+ /**
+ * Associates each field with its corresponding AddressUiComponent.
+ */
+ private void buildFieldWidgets() {
+ AddressData data = new AddressData.Builder().setCountry(currentRegion).build();
+ LookupKey key = new LookupKey.Builder(LookupKey.KeyType.DATA).setAddressData(data).build();
+ AddressVerificationNodeData countryNode =
+ (new ClientData(cacheData)).getDefaultData(key.toString());
+
+ // Set up AddressField.ADMIN_AREA
+ AddressUiComponent adminAreaUi = new AddressUiComponent(AddressField.ADMIN_AREA);
+ adminAreaUi.setFieldName(getAdminAreaFieldName(countryNode));
+ inputWidgets.put(AddressField.ADMIN_AREA, adminAreaUi);
+
+ // Set up AddressField.LOCALITY
+ AddressUiComponent localityUi = new AddressUiComponent(AddressField.LOCALITY);
+ localityUi.setFieldName(getLocalityFieldName(countryNode));
+ inputWidgets.put(AddressField.LOCALITY, localityUi);
+
+ // Set up AddressField.DEPENDENT_LOCALITY
+ AddressUiComponent subLocalityUi = new AddressUiComponent(AddressField.DEPENDENT_LOCALITY);
+ subLocalityUi.setFieldName(getSublocalityFieldName(countryNode));
+ inputWidgets.put(AddressField.DEPENDENT_LOCALITY, subLocalityUi);
+
+ // Set up AddressField.ADDRESS_LINE_1
+ AddressUiComponent addressLine1Ui = new AddressUiComponent(AddressField.ADDRESS_LINE_1);
+ addressLine1Ui.setFieldName(context.getString(R.string.i18n_address_line1_label));
+ inputWidgets.put(AddressField.ADDRESS_LINE_1, addressLine1Ui);
+
+ // Set up AddressField.ADDRESS_LINE_2
+ AddressUiComponent addressLine2Ui = new AddressUiComponent(AddressField.ADDRESS_LINE_2);
+ addressLine2Ui.setFieldName("");
+ inputWidgets.put(AddressField.ADDRESS_LINE_2, addressLine2Ui);
+
+ // Set up AddressField.ORGANIZATION
+ AddressUiComponent organizationUi = new AddressUiComponent(AddressField.ORGANIZATION);
+ organizationUi.setFieldName(context.getString(R.string.i18n_organization_label));
+ inputWidgets.put(AddressField.ORGANIZATION, organizationUi);
+
+ // Set up AddressField.RECIPIENT
+ AddressUiComponent recipientUi = new AddressUiComponent(AddressField.RECIPIENT);
+ recipientUi.setFieldName(context.getString(R.string.i18n_recipient_label));
+ inputWidgets.put(AddressField.RECIPIENT, recipientUi);
+
+ // Set up AddressField.POSTAL_CODE
+ AddressUiComponent postalCodeUi = new AddressUiComponent(AddressField.POSTAL_CODE);
+ postalCodeUi.setFieldName(getZipFieldName(countryNode));
+ inputWidgets.put(AddressField.POSTAL_CODE, postalCodeUi);
+
+ // Set up AddressField.SORTING_CODE
+ AddressUiComponent sortingCodeUi = new AddressUiComponent(AddressField.SORTING_CODE);
+ sortingCodeUi.setFieldName("CEDEX");
+ inputWidgets.put(AddressField.SORTING_CODE, sortingCodeUi);
+ }
+
+ private void initializeDropDowns() {
+ AddressUiComponent adminAreaUi = inputWidgets.get(AddressField.ADMIN_AREA);
+ List<RegionData> adminAreaList = getRegionData(AddressField.COUNTRY);
+ adminAreaUi.initializeCandidatesList(adminAreaList);
+
+ AddressUiComponent localityUi = inputWidgets.get(AddressField.LOCALITY);
+ List<RegionData> localityList = getRegionData(AddressField.ADMIN_AREA);
+ localityUi.initializeCandidatesList(localityList);
+ }
+
+ // ZIP code is called postal code in some countries. This method returns the appropriate name
+ // for the given countryNode.
+ private String getZipFieldName(AddressVerificationNodeData countryNode) {
+ String zipName;
+ String zipType = countryNode.get(AddressDataKey.ZIP_NAME_TYPE);
+ if (zipType == null) {
+ zipLabel = ZipLabel.POSTAL;
+ zipName = context.getString(R.string.i18n_postal_code_label);
+ } else {
+ zipLabel = ZipLabel.ZIP;
+ zipName = context.getString(R.string.i18n_zip_code_label);
+ }
+ return zipName;
+ }
+
+ private String getLocalityFieldName(AddressVerificationNodeData countryNode) {
+ String localityLabelType = countryNode.get(AddressDataKey.LOCALITY_NAME_TYPE);
+ Integer result = LOCALITY_LABELS.get(localityLabelType);
+ if (result == null) {
+ // Fallback to city.
+ result = R.string.i18n_locality_label;
+ }
+ return context.getString(result);
+ }
+
+ private String getSublocalityFieldName(AddressVerificationNodeData countryNode) {
+ String sublocalityLabelType = countryNode.get(AddressDataKey.SUBLOCALITY_NAME_TYPE);
+ Integer result = SUBLOCALITY_LABELS.get(sublocalityLabelType);
+ if (result == null) {
+ // Fallback to suburb.
+ result = R.string.i18n_suburb;
+ }
+ return context.getString(result);
+ }
+
+ private String getAdminAreaFieldName(AddressVerificationNodeData countryNode) {
+ String adminLabelType = countryNode.get(AddressDataKey.STATE_NAME_TYPE);
+ Integer result = ADMIN_LABELS.get(adminLabelType);
+ if (result == null) {
+ // Fallback to province.
+ result = R.string.i18n_province;
+ }
+ return context.getString(result);
+ }
+
+ private void buildCountryListBox() {
+ // Set up AddressField.COUNTRY
+ AddressUiComponent countryUi = new AddressUiComponent(AddressField.COUNTRY);
+ countryUi.setFieldName(context.getString(R.string.i18n_country_or_region_label));
+ ArrayList<RegionData> countries = new ArrayList<RegionData>();
+ for (RegionData regionData : formController.getRegionData(new LookupKey.Builder(
+ KeyType.DATA).build())) {
+ String regionKey = regionData.getKey();
+ // ZZ represents an unknown region code.
+ if (!regionKey.equals("ZZ")) {
+ String localCountryName = getLocalCountryName(regionKey);
+ RegionData country = new RegionData.Builder().setKey(regionKey).setName(
+ localCountryName).build();
+ countries.add(country);
+ }
}
+ countryUi.initializeCandidatesList(countries);
+ inputWidgets.put(AddressField.COUNTRY, countryUi);
+ }
- private AddressSpinnerInfo findSpinnerByView(View view) {
- for (AddressSpinnerInfo spinnerInfo : mSpinners) {
- if (spinnerInfo.mView == view) {
- return spinnerInfo;
- }
- }
- return null;
- }
+ private String getLocalCountryName(String regionCode) {
+ return (new Locale("", regionCode)).getDisplayCountry(Locale.getDefault());
+ }
- private void updateFields() {
- removePreviousViews();
- buildFieldWidgets();
- initializeDropDowns();
- layoutAddressFields();
+ private AddressSpinnerInfo findSpinnerByView(View view) {
+ for (AddressSpinnerInfo spinnerInfo : spinners) {
+ if (spinnerInfo.view == view) {
+ return spinnerInfo;
+ }
}
+ return null;
+ }
- private void removePreviousViews() {
- if (mRootView == null) {
- return;
- }
- int childCount = mRootView.getChildCount();
- if (mFormOptions.isHidden(AddressField.COUNTRY)) {
- if (childCount > 0) {
- mRootView.removeAllViews();
- }
- } else if (childCount > 2) {
- // Keep the TextView and Spinner for Country and remove everything else.
- mRootView.removeViews(2, mRootView.getChildCount() - 2);
- }
- }
+ private void updateFields() {
+ removePreviousViews();
+ buildFieldWidgets();
+ initializeDropDowns();
+ layoutAddressFields();
+ }
- private void layoutAddressFields() {
- for (AddressField field : mFormatInterpreter.getAddressFieldOrder(mScript,
- mCurrentRegion)) {
- if (!mFormOptions.isHidden(field)) {
- createView(mRootView, mInputWidgets.get(field), "", mFormOptions.isReadonly(field));
- }
- }
+ private void removePreviousViews() {
+ if (rootView == null) {
+ return;
}
+ int childCount = rootView.getChildCount();
+ if (formOptions.isHidden(AddressField.COUNTRY)) {
+ if (childCount > 0) {
+ rootView.removeAllViews();
+ }
+ } else if (childCount > 2) {
+ // Keep the TextView and Spinner for Country and remove everything else.
+ rootView.removeViews(2, rootView.getChildCount() - 2);
+ }
+ }
- private void updateChildNodes(AdapterView<?> parent, int position) {
- AddressSpinnerInfo spinnerInfo = findSpinnerByView(parent);
- if (spinnerInfo == null) {
- return;
- }
-
- // Find all the child spinners, if any, that depend on this one.
- final AddressField myId = spinnerInfo.mId;
- if (myId != AddressField.COUNTRY && myId != AddressField.ADMIN_AREA
- && myId != AddressField.LOCALITY) {
- // Only a change in the three AddressFields above will trigger a change in other
- // AddressFields. Therefore, for all other AddressFields, we return immediately.
- return;
- }
-
- String regionCode = spinnerInfo.getRegionCode(position);
- if (myId == AddressField.COUNTRY) {
- updateWidgetOnCountryChange(regionCode);
- return;
- }
-
- mFormController.requestDataForAddress(getAddressData(), new DataLoadListener() {
- @Override
- public void dataLoadingBegin(){
- }
+ private void layoutAddressFields() {
+ for (AddressField field : formatInterpreter.getAddressFieldOrder(script,
+ currentRegion)) {
+ if (!formOptions.isHidden(field)) {
+ createView(rootView, inputWidgets.get(field), "", formOptions.isReadonly(field));
+ }
+ }
+ }
- @Override
- public void dataLoadingEnd() {
- Runnable updateChild = new UpdateRunnable(myId);
- mHandler.post(updateChild);
- }
- });
+ private void updateChildNodes(AdapterView<?> parent, int position) {
+ AddressSpinnerInfo spinnerInfo = findSpinnerByView(parent);
+ if (spinnerInfo == null) {
+ return;
}
- public void updateWidgetOnCountryChange(String regionCode) {
- if (mCurrentRegion.equalsIgnoreCase(regionCode)) {
- return;
- }
- mCurrentRegion = regionCode;
- mFormController.setCurrentCountry(mCurrentRegion);
- renderForm();
+ // Find all the child spinners, if any, that depend on this one.
+ final AddressField myId = spinnerInfo.id;
+ if (myId != AddressField.COUNTRY && myId != AddressField.ADMIN_AREA
+ && myId != AddressField.LOCALITY) {
+ // Only a change in the three AddressFields above will trigger a change in other
+ // AddressFields. Therefore, for all other AddressFields, we return immediately.
+ return;
}
- private void updateInputWidget(AddressField myId) {
- for (AddressSpinnerInfo child : mSpinners) {
- if (child.mParentId == myId) {
- List<RegionData> candidates = getRegionData(child.mParentId);
- child.setSpinnerList(candidates, "");
- }
- }
+ String regionCode = spinnerInfo.getRegionCode(position);
+ if (myId == AddressField.COUNTRY) {
+ updateWidgetOnCountryChange(regionCode);
+ return;
}
- public void renderForm() {
- setWidgetLocaleAndScript();
- AddressData data = new AddressData.Builder().setCountry(mCurrentRegion)
- .setLanguageCode(mWidgetLocale).build();
- mFormController.requestDataForAddress(data, new DataLoadListener() {
- @Override
- public void dataLoadingBegin() {
- mProgressDialog = mComponentProvider.getUiActivityIndicatorView();
- mProgressDialog.setMessage(mContext.getString(R.string.address_data_loading));
- Log.d(this.toString(), "Progress dialog started.");
- }
- @Override
- public void dataLoadingEnd() {
- Log.d(this.toString(), "Data loading completed.");
- mProgressDialog.dismiss();
- Log.d(this.toString(), "Progress dialog stopped.");
- mHandler.post(mUpdateMultipleFields);
- }
- });
- }
-
- private void setWidgetLocaleAndScript() {
- mWidgetLocale = Util.getWidgetCompatibleLanguageCode(Locale.getDefault(), mCurrentRegion);
- mFormController.setLanguageCode(mWidgetLocale);
- mScript = Util.isExplicitLatinScript(mWidgetLocale)
- ? ScriptType.LATIN
- : ScriptType.LOCAL;
- }
-
- private List<RegionData> getRegionData(AddressField parentField) {
- AddressData address = getAddressData();
-
- // Removes language code from address if it is default. This address is used to build
- // lookup key, which neglects default language. For example, instead of "data/US--en/CA",
- // the right lookup key is "data/US/CA".
- if (mFormController.isDefaultLanguage(address.getLanguageCode())) {
- address = new AddressData.Builder(address).setLanguageCode(null).build();
- }
+ formController.requestDataForAddress(getAddressData(), new DataLoadListener() {
+ @Override
+ public void dataLoadingBegin(){
+ }
- LookupKey parentKey = mFormController.getDataKeyFor(address).getKeyForUpperLevelField(
- parentField);
- List<RegionData> candidates;
- // Can't build a key with parent field, quit.
- if (parentKey == null) {
- Log.w(this.toString(), "Can't build key with parent field " + parentField + ". One of"
- + " the ancestor fields might be empty");
-
- // Removes candidates that exist from previous settings. For example, data/US has a
- // list of candidates AB, BC, CA, etc, that list should be cleaned up when user updates
- // the address by changing country to Channel Islands.
- candidates = new ArrayList<RegionData>(1);
- } else {
- candidates = mFormController.getRegionData(parentKey);
- }
- return candidates;
- }
-
- /**
- * Creates an AddressWidget to be attached to rootView for the specific context using the
- * default UI component provider.
- */
- public AddressWidget(Context context, ViewGroup rootView, FormOptions formOptions,
- ClientCacheManager cacheManager) {
- this(context, rootView, formOptions, cacheManager,
- new AddressWidgetUiComponentProvider(context));
- }
-
- /**
- * Creates an AddressWidget to be attached to rootView for the specific context using UI
- * component provided by the provider.
- */
- public AddressWidget(Context context, ViewGroup rootView, FormOptions formOptions,
- ClientCacheManager cacheManager, AddressWidgetUiComponentProvider provider) {
- mComponentProvider = provider;
- mCurrentRegion =
- ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE))
- .getSimCountryIso().toUpperCase(Locale.US);
- if (mCurrentRegion.length() == 0) {
- mCurrentRegion = "US";
- }
- init(context, rootView, formOptions, cacheManager);
- renderForm();
- }
-
- /**
- * Creates an AddressWidget to be attached to rootView for the specific context using the
- * default UI component provider, and fill out the address form with savedAddress.
- */
- public AddressWidget(Context context, ViewGroup rootView, FormOptions formOptions,
- ClientCacheManager cacheManager, AddressData savedAddress) {
- this(context, rootView, formOptions, cacheManager, savedAddress,
- new AddressWidgetUiComponentProvider(context));
- }
-
- /**
- * Creates an AddressWidget to be attached to rootView for the specific context using UI
- * component provided by the provider, and fill out the address form with savedAddress.
- */
- public AddressWidget(Context context, ViewGroup rootView, FormOptions formOptions,
- ClientCacheManager cacheManager, AddressData savedAddress,
- AddressWidgetUiComponentProvider provider) {
- mComponentProvider = provider;
- mCurrentRegion = savedAddress.getPostalCountry();
- // Postal country must be 2 letter country code. Otherwise default to US.
- if (mCurrentRegion == null || mCurrentRegion.length() != 2) {
- mCurrentRegion = "US";
- }
- init(context, rootView, formOptions, cacheManager);
- renderFormWithSavedAddress(savedAddress);
- }
-
- public void renderFormWithSavedAddress(AddressData savedAddress) {
- setWidgetLocaleAndScript();
- removePreviousViews();
- buildFieldWidgets();
- layoutAddressFields();
- initializeFieldsWithAddress(savedAddress);
- }
-
- private void initializeFieldsWithAddress(AddressData savedAddress) {
- for (AddressField field : mFormatInterpreter.getAddressFieldOrder(mScript,
- mCurrentRegion)) {
- String value = savedAddress.getFieldValue(field);
- if (value == null) {
- value = "";
- }
- AddressUiComponent uiComponent = mInputWidgets.get(field);
- EditText view = (EditText) uiComponent.getView();
- if (view != null) {
- view.setText(value);
- }
- }
+ @Override
+ public void dataLoadingEnd() {
+ Runnable updateChild = new UpdateRunnable(myId);
+ handler.post(updateChild);
+ }
+ });
+ }
+
+ public void updateWidgetOnCountryChange(String regionCode) {
+ if (currentRegion.equalsIgnoreCase(regionCode)) {
+ return;
+ }
+ currentRegion = regionCode;
+ formController.setCurrentCountry(currentRegion);
+ renderForm();
+ }
+
+ private void updateInputWidget(AddressField myId) {
+ for (AddressSpinnerInfo child : spinners) {
+ if (child.parentId == myId) {
+ List<RegionData> candidates = getRegionData(child.parentId);
+ child.setSpinnerList(candidates, "");
+ }
}
-
- private void init(Context context, ViewGroup rootView, FormOptions formOptions,
- ClientCacheManager cacheManager) {
- mContext = context;
- mRootView = rootView;
- mFormOptions = formOptions;
- mCacheData = new CacheData(cacheManager);
- mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- mFormController =
- new FormController(new ClientData(mCacheData),
- mWidgetLocale, mCurrentRegion);
- mFormatInterpreter = new FormatInterpreter(mFormOptions);
- mVerifier = new StandardAddressVerifier(
- new FieldVerifier(new ClientData(mCacheData)));
- if (!formOptions.isHidden(AddressField.COUNTRY)) {
- buildCountryListBox();
- createView(mRootView, mInputWidgets.get(AddressField.COUNTRY),
- getLocalCountryName(mCurrentRegion),
- formOptions.isReadonly(AddressField.COUNTRY));
- }
+ }
+
+ public void renderForm() {
+ setWidgetLocaleAndScript();
+ AddressData data = new AddressData.Builder().setCountry(currentRegion)
+ .setLanguageCode(widgetLocale).build();
+ formController.requestDataForAddress(data, new DataLoadListener() {
+ @Override
+ public void dataLoadingBegin() {
+ progressDialog = componentProvider.getUiActivityIndicatorView();
+ progressDialog.setMessage(context.getString(R.string.address_data_loading));
+ Log.d(this.toString(), "Progress dialog started.");
+ }
+ @Override
+ public void dataLoadingEnd() {
+ Log.d(this.toString(), "Data loading completed.");
+ progressDialog.dismiss();
+ Log.d(this.toString(), "Progress dialog stopped.");
+ handler.post(updateMultipleFields);
+ }
+ });
+ }
+
+ private void setWidgetLocaleAndScript() {
+ widgetLocale = Util.getWidgetCompatibleLanguageCode(Locale.getDefault(), currentRegion);
+ formController.setLanguageCode(widgetLocale);
+ script = Util.isExplicitLatinScript(widgetLocale)
+ ? ScriptType.LATIN
+ : ScriptType.LOCAL;
+ }
+
+ private List<RegionData> getRegionData(AddressField parentField) {
+ AddressData address = getAddressData();
+
+ // Removes language code from address if it is default. This address is used to build
+ // lookup key, which neglects default language. For example, instead of "data/US--en/CA",
+ // the right lookup key is "data/US/CA".
+ if (formController.isDefaultLanguage(address.getLanguageCode())) {
+ address = new AddressData.Builder(address).setLanguageCode(null).build();
+ }
+
+ LookupKey parentKey = formController.getDataKeyFor(address).getKeyForUpperLevelField(
+ parentField);
+ List<RegionData> candidates;
+ // Can't build a key with parent field, quit.
+ if (parentKey == null) {
+ Log.w(this.toString(), "Can't build key with parent field " + parentField + ". One of"
+ + " the ancestor fields might be empty");
+
+ // Removes candidates that exist from previous settings. For example, data/US has a
+ // list of candidates AB, BC, CA, etc, that list should be cleaned up when user updates
+ // the address by changing country to Channel Islands.
+ candidates = new ArrayList<RegionData>(1);
+ } else {
+ candidates = formController.getRegionData(parentKey);
+ }
+ return candidates;
+ }
+
+ /**
+ * Creates an AddressWidget to be attached to rootView for the specific context using the
+ * default UI component provider.
+ */
+ public AddressWidget(Context context, ViewGroup rootView, FormOptions formOptions,
+ ClientCacheManager cacheManager) {
+ this(context, rootView, formOptions, cacheManager,
+ new AddressWidgetUiComponentProvider(context));
+ }
+
+ /**
+ * Creates an AddressWidget to be attached to rootView for the specific context using UI
+ * component provided by the provider.
+ */
+ public AddressWidget(Context context, ViewGroup rootView, FormOptions formOptions,
+ ClientCacheManager cacheManager, AddressWidgetUiComponentProvider provider) {
+ componentProvider = provider;
+ currentRegion =
+ ((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE))
+ .getSimCountryIso().toUpperCase(Locale.US);
+ if (currentRegion.length() == 0) {
+ currentRegion = "US";
+ }
+ init(context, rootView, formOptions, cacheManager);
+ renderForm();
+ }
+
+ /**
+ * Creates an AddressWidget to be attached to rootView for the specific context using the
+ * default UI component provider, and fill out the address form with savedAddress.
+ */
+ public AddressWidget(Context context, ViewGroup rootView, FormOptions formOptions,
+ ClientCacheManager cacheManager, AddressData savedAddress) {
+ this(context, rootView, formOptions, cacheManager, savedAddress,
+ new AddressWidgetUiComponentProvider(context));
+ }
+
+ /**
+ * Creates an AddressWidget to be attached to rootView for the specific context using UI
+ * component provided by the provider, and fill out the address form with savedAddress.
+ */
+ public AddressWidget(Context context, ViewGroup rootView, FormOptions formOptions,
+ ClientCacheManager cacheManager, AddressData savedAddress,
+ AddressWidgetUiComponentProvider provider) {
+ componentProvider = provider;
+ currentRegion = savedAddress.getPostalCountry();
+ // Postal country must be 2 letter country code. Otherwise default to US.
+ if (currentRegion == null || currentRegion.length() != 2) {
+ currentRegion = "US";
+ }
+ init(context, rootView, formOptions, cacheManager);
+ renderFormWithSavedAddress(savedAddress);
+ }
+
+ public void renderFormWithSavedAddress(AddressData savedAddress) {
+ setWidgetLocaleAndScript();
+ removePreviousViews();
+ buildFieldWidgets();
+ layoutAddressFields();
+ initializeFieldsWithAddress(savedAddress);
+ }
+
+ private void initializeFieldsWithAddress(AddressData savedAddress) {
+ for (AddressField field : formatInterpreter.getAddressFieldOrder(script, currentRegion)) {
+ String value = savedAddress.getFieldValue(field);
+ if (value == null) {
+ value = "";
+ }
+ AddressUiComponent uiComponent = inputWidgets.get(field);
+ EditText view = (EditText) uiComponent.getView();
+ if (view != null) {
+ view.setText(value);
+ }
}
-
- /**
- * Sets address data server URL. Input URL cannot be null.
- *
- * @param url The service URL.
- */
- public void setUrl(String url) {
- mCacheData.setUrl(url);
- }
-
- /**
- * Gets user input address in AddressData format.
- */
- public AddressData getAddressData() {
- AddressData.Builder builder = new AddressData.Builder();
- builder.setCountry(mCurrentRegion);
- for (AddressField field : mFormatInterpreter.getAddressFieldOrder(mScript,
- mCurrentRegion)) {
- AddressUiComponent addressUiComponent = mInputWidgets.get(field);
- if (addressUiComponent != null) {
- String value = addressUiComponent.getValue();
- if (addressUiComponent.getUiType() == UiComponent.SPINNER) {
- // For drop-downs, return the key of the region selected instead of the value.
- View view = getViewForField(field);
- AddressSpinnerInfo spinnerInfo = findSpinnerByView(view);
- if (spinnerInfo != null) {
- value = spinnerInfo.getRegionDataKeyForValue(value);
- }
- }
- builder.set(field, value);
- }
- }
- builder.setLanguageCode(mWidgetLocale);
- return builder.build();
- }
-
- /**
- * Gets the formatted address.
- *
- * This method does not validate addresses. Also, it will "normalize" the result strings by
- * removing redundant spaces and empty lines.
- *
- * @return the formatted address
- */
- public List<String> getEnvelopeAddress() {
- return mFormatInterpreter.getEnvelopeAddress(getAddressData());
- }
-
- /**
- * Gets the formatted address based on the AddressData passed in.
- */
- public List<String> getEnvelopeAddress(AddressData address) {
- return mFormatInterpreter.getEnvelopeAddress(address);
- }
-
- /**
- * Gets the formatted address based on the AddressData passed in with none of the relevant
- * fields hidden.
- */
- public static List<String> getFullEnvelopeAddress(AddressData address) {
- return new FormatInterpreter(SHOW_ALL_FIELDS).getEnvelopeAddress(address);
- }
-
- /**
- * Get problems found in the address data entered by the user.
- */
- public AddressProblems getAddressProblems() {
- AddressProblems problems = new AddressProblems();
- AddressData addressData = getAddressData();
- mVerifier.verify(addressData, problems);
- return problems;
- }
-
- /**
- * Displays an appropriate error message for an AddressField with a problem.
- *
- * @return the View object representing the AddressField.
- */
- public View displayErrorMessageForField(AddressData address,
- AddressField field, AddressProblemType problem) {
- Log.d(this.toString(), "Display error message for the field: " + field.toString());
- AddressUiComponent addressUiComponent = mInputWidgets.get(field);
- if (addressUiComponent != null && addressUiComponent.getUiType() == UiComponent.EDIT) {
- EditText view = (EditText) addressUiComponent.getView();
- view.setError(getErrorMessageForInvalidEntry(address, field, problem));
- return view;
- }
- return null;
- }
-
- private String getErrorMessageForInvalidEntry(AddressData address, AddressField field,
- AddressProblemType problem) {
- switch (problem) {
- case MISSING_REQUIRED_FIELD:
- return mContext.getString(R.string.i18n_missing_required_field);
- case UNKNOWN_VALUE:
- String currentValue = address.getFieldValue(field);
- return String.format(mContext.getString(R.string.unknown_entry), currentValue);
- case UNRECOGNIZED_FORMAT:
- // We only support this error type for the Postal Code field.
- return (mZipLabel == ZipLabel.POSTAL
- ? mContext.getString(R.string.unrecognized_format_postal_code)
- : mContext.getString(R.string.unrecognized_format_zip_code));
- case MISMATCHING_VALUE:
- // We only support this error type for the Postal Code field.
- return (mZipLabel == ZipLabel.POSTAL
- ? mContext.getString(R.string.mismatching_value_postal_code)
- : mContext.getString(R.string.mismatching_value_zip_code));
- }
- return "";
+ }
+
+ private void init(Context context, ViewGroup rootView, FormOptions formOptions,
+ ClientCacheManager cacheManager) {
+ this.context = context;
+ this.rootView = rootView;
+ this.formOptions = formOptions;
+ this.cacheData = new CacheData(cacheManager);
+ this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ this.formController =
+ new FormController(new ClientData(cacheData), widgetLocale, currentRegion);
+ this.formatInterpreter = new FormatInterpreter(formOptions);
+ this.verifier = new StandardAddressVerifier(new FieldVerifier(new ClientData(cacheData)));
+ if (!formOptions.isHidden(AddressField.COUNTRY)) {
+ buildCountryListBox();
+ createView(rootView, inputWidgets.get(AddressField.COUNTRY),
+ getLocalCountryName(currentRegion),
+ formOptions.isReadonly(AddressField.COUNTRY));
+ }
+ }
+
+ /**
+ * Sets address data server URL. Input URL cannot be null.
+ *
+ * @param url The service URL.
+ */
+ public void setUrl(String url) {
+ cacheData.setUrl(url);
+ }
+
+ /**
+ * Gets user input address in AddressData format.
+ */
+ public AddressData getAddressData() {
+ AddressData.Builder builder = new AddressData.Builder();
+ builder.setCountry(currentRegion);
+ for (AddressField field : formatInterpreter.getAddressFieldOrder(script,
+ currentRegion)) {
+ AddressUiComponent addressUiComponent = inputWidgets.get(field);
+ if (addressUiComponent != null) {
+ String value = addressUiComponent.getValue();
+ if (addressUiComponent.getUiType() == UiComponent.SPINNER) {
+ // For drop-downs, return the key of the region selected instead of the value.
+ View view = getViewForField(field);
+ AddressSpinnerInfo spinnerInfo = findSpinnerByView(view);
+ if (spinnerInfo != null) {
+ value = spinnerInfo.getRegionDataKeyForValue(value);
+ }
+ }
+ builder.set(field, value);
+ }
}
-
- /**
- * Clears all error messages in the UI.
- */
- public void clearErrorMessage() {
- for (AddressField field : mFormatInterpreter.getAddressFieldOrder(mScript,
- mCurrentRegion)) {
- AddressUiComponent addressUiComponent = mInputWidgets.get(field);
-
- if (addressUiComponent != null && addressUiComponent.getUiType() == UiComponent.EDIT) {
- EditText view = (EditText) addressUiComponent.getView();
- if (view != null) {
- view.setError(null);
- }
- }
+ builder.setLanguageCode(widgetLocale);
+ return builder.build();
+ }
+
+ /**
+ * Gets the formatted address.
+ *
+ * This method does not validate addresses. Also, it will "normalize" the result strings by
+ * removing redundant spaces and empty lines.
+ *
+ * @return the formatted address
+ */
+ public List<String> getEnvelopeAddress() {
+ return formatInterpreter.getEnvelopeAddress(getAddressData());
+ }
+
+ /**
+ * Gets the formatted address based on the AddressData passed in.
+ */
+ public List<String> getEnvelopeAddress(AddressData address) {
+ return formatInterpreter.getEnvelopeAddress(address);
+ }
+
+ /**
+ * Gets the formatted address based on the AddressData passed in with none of the relevant
+ * fields hidden.
+ */
+ public static List<String> getFullEnvelopeAddress(AddressData address) {
+ return new FormatInterpreter(SHOW_ALL_FIELDS).getEnvelopeAddress(address);
+ }
+
+ /**
+ * Get problems found in the address data entered by the user.
+ */
+ public AddressProblems getAddressProblems() {
+ AddressProblems problems = new AddressProblems();
+ AddressData addressData = getAddressData();
+ verifier.verify(addressData, problems);
+ return problems;
+ }
+
+ /**
+ * Displays an appropriate error message for an AddressField with a problem.
+ *
+ * @return the View object representing the AddressField.
+ */
+ public View displayErrorMessageForField(AddressData address,
+ AddressField field, AddressProblemType problem) {
+ Log.d(this.toString(), "Display error message for the field: " + field.toString());
+ AddressUiComponent addressUiComponent = inputWidgets.get(field);
+ if (addressUiComponent != null && addressUiComponent.getUiType() == UiComponent.EDIT) {
+ EditText view = (EditText) addressUiComponent.getView();
+ view.setError(getErrorMessageForInvalidEntry(address, field, problem));
+ return view;
+ }
+ return null;
+ }
+
+ private String getErrorMessageForInvalidEntry(AddressData address, AddressField field,
+ AddressProblemType problem) {
+ switch (problem) {
+ case MISSING_REQUIRED_FIELD:
+ return context.getString(R.string.i18n_missing_required_field);
+ case UNKNOWN_VALUE:
+ String currentValue = address.getFieldValue(field);
+ return String.format(context.getString(R.string.unknown_entry), currentValue);
+ case UNRECOGNIZED_FORMAT:
+ // We only support this error type for the Postal Code field.
+ return (zipLabel == ZipLabel.POSTAL
+ ? context.getString(R.string.unrecognized_format_postal_code)
+ : context.getString(R.string.unrecognized_format_zip_code));
+ case MISMATCHING_VALUE:
+ // We only support this error type for the Postal Code field.
+ return (zipLabel == ZipLabel.POSTAL
+ ? context.getString(R.string.mismatching_value_postal_code)
+ : context.getString(R.string.mismatching_value_zip_code));
+ }
+ return "";
+ }
+
+ /**
+ * Clears all error messages in the UI.
+ */
+ public void clearErrorMessage() {
+ for (AddressField field : formatInterpreter.getAddressFieldOrder(script,
+ currentRegion)) {
+ AddressUiComponent addressUiComponent = inputWidgets.get(field);
+
+ if (addressUiComponent != null && addressUiComponent.getUiType() == UiComponent.EDIT) {
+ EditText view = (EditText) addressUiComponent.getView();
+ if (view != null) {
+ view.setError(null);
}
- }
-
- public View getViewForField(AddressField field) {
- AddressUiComponent component = mInputWidgets.get(field);
- if (component == null) {
- return null;
}
- return component.getView();
}
+ }
- @Override
- public void onNothingSelected(AdapterView<?> arg0) {
+ public View getViewForField(AddressField field) {
+ AddressUiComponent component = inputWidgets.get(field);
+ if (component == null) {
+ return null;
}
+ return component.getView();
+ }
- @Override
- public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
- updateChildNodes(parent, position);
- }
+ @Override
+ public void onNothingSelected(AdapterView<?> arg0) {
+ }
+
+ @Override
+ public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+ updateChildNodes(parent, position);
+ }
}