| Index: chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
|
| index ce69ae098bcdd9bfb081506686314d6ed4f8658c..1e3e931647ff43c1e2be3723aa03524a405bde00 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java
|
| @@ -9,24 +9,26 @@ import android.os.Bundle;
|
| import android.text.Editable;
|
| import android.text.TextUtils;
|
| import android.text.TextWatcher;
|
| +import android.util.Pair;
|
| import android.view.LayoutInflater;
|
| import android.view.View;
|
| import android.view.ViewGroup;
|
| import android.widget.AdapterView;
|
| import android.widget.AdapterView.OnItemSelectedListener;
|
| +import android.widget.ArrayAdapter;
|
| import android.widget.Button;
|
| import android.widget.EditText;
|
| import android.widget.Spinner;
|
|
|
| -import com.android.i18n.addressinput.AddressData;
|
| -import com.android.i18n.addressinput.AddressField;
|
| -import com.android.i18n.addressinput.AddressWidget;
|
| -import com.android.i18n.addressinput.FormOptions;
|
| -import com.android.i18n.addressinput.SimpleClientCacheManager;
|
| -
|
| import org.chromium.chrome.R;
|
| import org.chromium.chrome.browser.autofill.PersonalDataManager;
|
| import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile;
|
| +import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.AddressField;
|
| +import org.chromium.chrome.browser.preferences.autofill.AutofillProfileBridge.Country;
|
| +import org.chromium.chrome.browser.widget.FloatLabelLayout;
|
| +
|
| +import java.util.ArrayList;
|
| +import java.util.List;
|
|
|
| /**
|
| * Provides the Java-ui for editing a Profile autofill entry.
|
| @@ -37,11 +39,18 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
|
| // May be the empty string if creating a new profile.
|
| private String mGUID;
|
|
|
| - private AddressWidget mAddressWidget;
|
| private boolean mNoCountryItemIsSelected;
|
| + private LayoutInflater mInflater;
|
| private EditText mPhoneText;
|
| + private FloatLabelLayout mPhoneLabel;
|
| private EditText mEmailText;
|
| + private FloatLabelLayout mEmailLabel;
|
| private String mLanguageCodeString;
|
| + private List<String> mCountryCodes;
|
| + private int mCurrentCountryPos;
|
| + private Spinner mCountriesSpinner;
|
| + private ViewGroup mWidgetRoot;
|
| + private FloatLabelLayout[] mAddressFields;
|
|
|
| @Override
|
| public void onCreate(Bundle savedState) {
|
| @@ -53,11 +62,6 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
|
| Bundle savedInstanceState) {
|
| super.onCreate(savedInstanceState);
|
|
|
| - View v = inflater.inflate(R.layout.autofill_profile_editor, container, false);
|
| -
|
| - mPhoneText = (EditText) v.findViewById(R.id.autofill_profile_editor_phone_number_edit);
|
| - mEmailText = (EditText) v.findViewById(R.id.autofill_profile_editor_email_address_edit);
|
| -
|
| // We know which profile to edit based on the GUID stuffed in
|
| // our extras by AutofillPreferences.
|
| Bundle extras = getArguments();
|
| @@ -71,8 +75,21 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
|
| getActivity().setTitle(R.string.autofill_edit_profile);
|
| }
|
|
|
| - addProfileDataToEditFields(v);
|
| + mInflater = inflater;
|
| + mAddressFields = new FloatLabelLayout[AddressField.NUM_FIELDS];
|
| + View v = mInflater.inflate(R.layout.autofill_profile_editor, container, false);
|
| +
|
| + mPhoneText = (EditText) v.findViewById(R.id.phone_number_edit);
|
| + mPhoneLabel = (FloatLabelLayout) v.findViewById(R.id.phone_number_label);
|
| + mEmailText = (EditText) v.findViewById(R.id.email_address_edit);
|
| + mEmailLabel = (FloatLabelLayout) v.findViewById(R.id.email_address_label);
|
| + mWidgetRoot = (ViewGroup) v.findViewById(R.id.autofill_profile_widget_root);
|
| + mCountriesSpinner = (Spinner) v.findViewById(R.id.countries);
|
| +
|
| + populateCountriesSpinner();
|
| + createAndPopulateEditFields();
|
| hookupSaveCancelDeleteButtons(v);
|
| +
|
| return v;
|
| }
|
|
|
| @@ -84,78 +101,196 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
|
|
|
| @Override
|
| public void onTextChanged(CharSequence s, int start, int before, int count) {
|
| - enableSaveButton();
|
| + boolean empty = mNoCountryItemIsSelected && TextUtils.isEmpty(s) && allFieldsEmpty();
|
| + setSaveButtonEnabled(!empty);
|
| + }
|
| +
|
| + private boolean allFieldsEmpty() {
|
| + if (!TextUtils.isEmpty(mPhoneText.getText())
|
| + || !TextUtils.isEmpty(mEmailText.getText())) {
|
| + return false;
|
| + }
|
| + for (FloatLabelLayout field : mAddressFields) {
|
| + if (field != null && !TextUtils.isEmpty(field.getEditText().getText())) {
|
| + return false;
|
| + }
|
| + }
|
| +
|
| + return true;
|
| }
|
|
|
| @Override
|
| public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
| - mAddressWidget.onItemSelected(parent, view, position, id);
|
| -
|
| - if (mNoCountryItemIsSelected) {
|
| + if (position != mCurrentCountryPos) {
|
| + mCurrentCountryPos = position;
|
| + // If all fields are empty (e.g. the user just entered the form and the first thing
|
| + // they did was select a country), focus on the first form element. Otherwise, don't.
|
| + resetFormFields(position, allFieldsEmpty());
|
| mNoCountryItemIsSelected = false;
|
| - return;
|
| + setSaveButtonEnabled(true);
|
| }
|
| -
|
| - enableSaveButton();
|
| }
|
|
|
| @Override
|
| public void onNothingSelected(AdapterView<?> parent) {}
|
|
|
| - private void addProfileDataToEditFields(View v) {
|
| - AddressData.Builder address = new AddressData.Builder();
|
| + private void populateCountriesSpinner() {
|
| + List<Country> countries = AutofillProfileBridge.getSupportedCountries();
|
| + mCountryCodes = new ArrayList<String>();
|
| +
|
| + for (Country country : countries) {
|
| + mCountryCodes.add(country.mCode);
|
| + }
|
| +
|
| + ArrayAdapter<Country> countriesAdapter = new ArrayAdapter<Country>(getActivity(),
|
| + android.R.layout.simple_spinner_item, countries);
|
| + countriesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
|
| + mCountriesSpinner.setAdapter(countriesAdapter);
|
| + }
|
| +
|
| + private void createAndPopulateEditFields() {
|
| AutofillProfile profile = PersonalDataManager.getInstance().getProfile(mGUID);
|
|
|
| if (profile != null) {
|
| - mPhoneText.setText(profile.getPhoneNumber());
|
| - mEmailText.setText(profile.getEmailAddress());
|
| + if (!TextUtils.isEmpty(profile.getPhoneNumber())) {
|
| + mPhoneLabel.setText(profile.getPhoneNumber());
|
| + }
|
| +
|
| + if (!TextUtils.isEmpty(profile.getEmailAddress())) {
|
| + mEmailLabel.setText(profile.getEmailAddress());
|
| + }
|
| +
|
| mLanguageCodeString = profile.getLanguageCode();
|
|
|
| - address.setAdminArea(profile.getRegion());
|
| - address.setLocality(profile.getLocality());
|
| - address.setRecipient(profile.getFullName());
|
| - address.setOrganization(profile.getCompanyName());
|
| - address.setDependentLocality(profile.getDependentLocality());
|
| - address.setPostalCode(profile.getPostalCode());
|
| - address.setSortingCode(profile.getSortingCode());
|
| - address.setAddress(profile.getStreetAddress());
|
| - address.setCountry(profile.getCountryCode());
|
| + mCurrentCountryPos = mCountryCodes.indexOf(profile.getCountryCode());
|
| + if (mCurrentCountryPos == -1) {
|
| + // Use the default country code if profile code is invalid.
|
| + mCurrentCountryPos = mCountryCodes.indexOf(
|
| + AutofillProfileBridge.getDefaultCountryCode());
|
| + if (mCurrentCountryPos == -1) {
|
| + // Use the first item in country spinner if the default country code is
|
| + // invalid.
|
| + mCurrentCountryPos = 0;
|
| + }
|
| + }
|
| +
|
| + resetFormFields(mCurrentCountryPos, false);
|
| +
|
| + setFieldText(AddressField.ADMIN_AREA, profile.getRegion());
|
| + setFieldText(AddressField.LOCALITY, profile.getLocality());
|
| + setFieldText(AddressField.DEPENDENT_LOCALITY, profile.getDependentLocality());
|
| + setFieldText(AddressField.SORTING_CODE, profile.getSortingCode());
|
| + setFieldText(AddressField.POSTAL_CODE, profile.getPostalCode());
|
| + setFieldText(AddressField.STREET_ADDRESS, profile.getStreetAddress());
|
| + setFieldText(AddressField.ORGANIZATION, profile.getCompanyName());
|
| + setFieldText(AddressField.RECIPIENT, profile.getFullName());
|
| + } else {
|
| + mCurrentCountryPos = mCountryCodes.indexOf(
|
| + AutofillProfileBridge.getDefaultCountryCode());
|
| + if (mCurrentCountryPos == -1) {
|
| + // Use the first item in country spinner if the default country code is
|
| + // invalid.
|
| + mCurrentCountryPos = 0;
|
| + }
|
| + resetFormFields(mCurrentCountryPos, true);
|
| + }
|
| +
|
| + mCountriesSpinner.setSelection(mCurrentCountryPos);
|
| + }
|
| +
|
| + private void resetFormFields(int countryCodeIndex, boolean autoFocusFirstField) {
|
| + // Save field text so we can restore it after updating the fields for the current country,
|
| + // and reset mAddressFields.
|
| + String[] fieldText = new String[mAddressFields.length];
|
| + for (int i = 0; i < mAddressFields.length; i++) {
|
| + if (mAddressFields[i] != null) {
|
| + fieldText[i] = mAddressFields[i].getEditText().getText().toString();
|
| + mAddressFields[i] = null;
|
| + }
|
| }
|
|
|
| - ViewGroup widgetRoot = (ViewGroup) v.findViewById(R.id.autofill_profile_widget_root);
|
| - mAddressWidget = new AddressWidget(getActivity(), widgetRoot,
|
| - (new FormOptions.Builder()).build(),
|
| - new SimpleClientCacheManager(),
|
| - address.build(),
|
| - new ChromeAddressWidgetUiComponentProvider(getActivity()));
|
| + // Remove all address form fields.
|
| + mWidgetRoot.removeAllViews();
|
| +
|
| + // Get address fields for the selected country.
|
| + List<Pair<Integer, String>> fields = AutofillProfileBridge.getAddressUiComponents(
|
| + mCountryCodes.get(countryCodeIndex));
|
|
|
| - if (profile == null) {
|
| - widgetRoot.requestFocus();
|
| + // Create form fields and focus the first field if autoFocusFirstField is true.
|
| + boolean firstField = true;
|
| + for (Pair<Integer, String> field : fields) {
|
| + int fieldId = field.first;
|
| + String fieldLabel = field.second;
|
| + FloatLabelLayout fieldFloatLabel = (FloatLabelLayout) mInflater.inflate(
|
| + R.layout.preference_address_float_label_layout, mWidgetRoot, false);
|
| + fieldFloatLabel.setHint(fieldLabel);
|
| +
|
| + EditText fieldEditText =
|
| + (EditText) fieldFloatLabel.findViewById(R.id.address_edit_text);
|
| + fieldEditText.setHint(fieldLabel);
|
| + fieldEditText.setContentDescription(fieldLabel);
|
| + fieldEditText.addTextChangedListener(this);
|
| + if (fieldId == AddressField.STREET_ADDRESS) {
|
| + fieldEditText.setSingleLine(false);
|
| + }
|
| +
|
| + mAddressFields[fieldId] = fieldFloatLabel;
|
| + mWidgetRoot.addView(fieldFloatLabel);
|
| +
|
| + if (firstField && autoFocusFirstField) {
|
| + // FloatLabelLayout animates showing the field label when the EditText is focused;
|
| + // to avoid this animation, manually set the label to be visible and the EditText
|
| + // hint to null and request focus on the EditText field.
|
| + fieldFloatLabel.getLabel().setVisibility(View.VISIBLE);
|
| + fieldEditText.setHint(null);
|
| + fieldEditText.requestFocus();
|
| + firstField = false;
|
| + }
|
| + }
|
| +
|
| + // Add back saved field text.
|
| + for (int i = 0; i < mAddressFields.length; i++) {
|
| + if (mAddressFields[i] != null && fieldText[i] != null
|
| + && !TextUtils.isEmpty(fieldText[i])) {
|
| + mAddressFields[i].setText(fieldText[i]);
|
| + }
|
| }
|
| }
|
|
|
| // Read edited data; save in the associated Chrome profile.
|
| // Ignore empty fields.
|
| private void saveProfile() {
|
| - AddressData input = mAddressWidget.getAddressData();
|
| AutofillProfile profile = new PersonalDataManager.AutofillProfile(
|
| mGUID,
|
| AutofillPreferences.SETTINGS_ORIGIN,
|
| - input.getRecipient(),
|
| - input.getOrganization(),
|
| - TextUtils.join("\n", input.getAddressLines()),
|
| - input.getAdministrativeArea(),
|
| - input.getLocality(),
|
| - input.getDependentLocality(),
|
| - input.getPostalCode(),
|
| - input.getSortingCode(),
|
| - input.getPostalCountry(),
|
| + getFieldText(AddressField.RECIPIENT),
|
| + getFieldText(AddressField.ORGANIZATION),
|
| + getFieldText(AddressField.STREET_ADDRESS),
|
| + getFieldText(AddressField.ADMIN_AREA),
|
| + getFieldText(AddressField.LOCALITY),
|
| + getFieldText(AddressField.DEPENDENT_LOCALITY),
|
| + getFieldText(AddressField.POSTAL_CODE),
|
| + getFieldText(AddressField.SORTING_CODE),
|
| + mCountryCodes.get(mCurrentCountryPos),
|
| mPhoneText.getText().toString(),
|
| mEmailText.getText().toString(),
|
| mLanguageCodeString);
|
| PersonalDataManager.getInstance().setProfile(profile);
|
| }
|
|
|
| + private String getFieldText(int fieldId) {
|
| + if (mAddressFields[fieldId] != null) {
|
| + return mAddressFields[fieldId].getEditText().getText().toString();
|
| + }
|
| + return null;
|
| + }
|
| +
|
| + private void setFieldText(int fieldId, String text) {
|
| + if (mAddressFields[fieldId] != null && !TextUtils.isEmpty(text)) {
|
| + mAddressFields[fieldId].setText(text);
|
| + }
|
| + }
|
| +
|
| private void deleteProfile() {
|
| if (AutofillProfileEditor.this.mGUID != null) {
|
| PersonalDataManager.getInstance().deleteProfile(mGUID);
|
| @@ -196,20 +331,14 @@ public class AutofillProfileEditor extends Fragment implements TextWatcher,
|
| // Listen for changes to inputs. Enable the save button after something has changed.
|
| mPhoneText.addTextChangedListener(this);
|
| mEmailText.addTextChangedListener(this);
|
| + mCountriesSpinner.setOnItemSelectedListener(this);
|
| mNoCountryItemIsSelected = true;
|
| -
|
| - for (AddressField field : AddressField.values()) {
|
| - View input = mAddressWidget.getViewForField(field);
|
| - if (input instanceof EditText) {
|
| - ((EditText) input).addTextChangedListener(this);
|
| - } else if (input instanceof Spinner) {
|
| - ((Spinner) input).setOnItemSelectedListener(this);
|
| - }
|
| - }
|
| }
|
|
|
| - private void enableSaveButton() {
|
| - Button button = (Button) getView().findViewById(R.id.autofill_profile_save);
|
| - button.setEnabled(true);
|
| + private void setSaveButtonEnabled(boolean enabled) {
|
| + if (getView() != null) {
|
| + Button button = (Button) getView().findViewById(R.id.autofill_profile_save);
|
| + button.setEnabled(enabled);
|
| + }
|
| }
|
| }
|
|
|