Chromium Code Reviews| 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..43b09eefe7ad4cc70b85ab5b687118a229c6c0c2 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,24 @@ 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.widget.FloatLabelLayout; |
| + |
| +import java.util.ArrayList; |
| +import java.util.List; |
| /** |
| * Provides the Java-ui for editing a Profile autofill entry. |
| @@ -37,11 +37,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 +60,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 +73,23 @@ 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 = |
|
newt (away)
2015/01/29 20:00:37
don't need to wrap anymore. same below.
Theresa
2015/01/29 22:31:12
Done.
|
| + (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,190 @@ 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( |
|
newt (away)
2015/01/29 20:00:37
We need the same logic here in case the default co
Theresa
2015/01/29 22:31:12
We need the same logic here; I'll add it.
|
| + AutofillProfileBridge.getDefaultCountryCode()); |
| + resetFormFields(mCurrentCountryPos, true); |
| + } |
| + |
| + mCountriesSpinner.setSelection(mCurrentCountryPos); |
| + } |
| + |
| + private void resetFormFields(int countryCodeIndex, boolean autoFocusFirstField) { |
| + // Save field text and reset mAddressFields. |
|
newt (away)
2015/01/29 20:00:37
Maybe expand this comment a bit: "Save field text
Theresa
2015/01/29 22:31:12
Done.
|
| + 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)); |
| + |
| + // 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; |
| + } |
| + } |
| - if (profile == null) { |
| - widgetRoot.requestFocus(); |
| + // 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), |
|
Evan Stade
2015/01/29 22:29:57
just checking --- this is a string with embedded n
Theresa
2015/01/29 22:49:42
Yep :) There's a few lines of code above in resetF
|
| + 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 +325,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); |
| + } |
| } |
| } |