diff options
Diffstat (limited to 'java/src/com/android/i18n/addressinput/AddressWidget.java')
-rw-r--r-- | java/src/com/android/i18n/addressinput/AddressWidget.java | 1315 |
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); + } } |