[Payments] Refactor the autofill preferences
* Pulls out code common to both editors into a new AutofillEditorBase.
* AutofillEditorBase supports an ActionBar with a delete button and
a pair of CANCEL/SAVE buttons that are permanently at the bottom
of the screen.
* Add a delete icon instead of the delete button for deleting entries.
- Does not yet properly style the editor fields.
See bug for screenshots:
https://bugs.chromium.org/p/chromium/issues/detail?id=603635#c177
BUG=603635
Review-Url: https://codereview.chromium.org/2100483002
Cr-Commit-Position: refs/heads/master@{#401995}
diff --git a/chrome/android/java/res/drawable-hdpi/ic_delete_white_24dp.png b/chrome/android/java/res/drawable-hdpi/ic_delete_white_24dp.png
new file mode 100644
index 0000000..0d0e518
--- /dev/null
+++ b/chrome/android/java/res/drawable-hdpi/ic_delete_white_24dp.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-mdpi/ic_delete_white_24dp.png b/chrome/android/java/res/drawable-mdpi/ic_delete_white_24dp.png
new file mode 100644
index 0000000..6b44a07
--- /dev/null
+++ b/chrome/android/java/res/drawable-mdpi/ic_delete_white_24dp.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xhdpi/ic_delete_white_24dp.png b/chrome/android/java/res/drawable-xhdpi/ic_delete_white_24dp.png
new file mode 100644
index 0000000..a05955e
--- /dev/null
+++ b/chrome/android/java/res/drawable-xhdpi/ic_delete_white_24dp.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxhdpi/ic_delete_white_24dp.png b/chrome/android/java/res/drawable-xxhdpi/ic_delete_white_24dp.png
new file mode 100644
index 0000000..5834edc
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxhdpi/ic_delete_white_24dp.png
Binary files differ
diff --git a/chrome/android/java/res/drawable-xxxhdpi/ic_delete_white_24dp.png b/chrome/android/java/res/drawable-xxxhdpi/ic_delete_white_24dp.png
new file mode 100644
index 0000000..8acaa86d
--- /dev/null
+++ b/chrome/android/java/res/drawable-xxxhdpi/ic_delete_white_24dp.png
Binary files differ
diff --git a/chrome/android/java/res/layout/autofill_credit_card_editor.xml b/chrome/android/java/res/layout/autofill_credit_card_editor.xml
index 7fef65a..f05fd94 100644
--- a/chrome/android/java/res/layout/autofill_credit_card_editor.xml
+++ b/chrome/android/java/res/layout/autofill_credit_card_editor.xml
@@ -3,137 +3,99 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fillViewport="true"
- android:scrollbarStyle="outsideOverlay" >
+<!-- EditText views in FloatLabelLayout require both hint and contentDescription to be set
+ to work correctly for accessibility because FloatLabelLayout sometimes clear hint. -->
+<!--suppress ContentDescription -->
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto" >
+
+ <org.chromium.chrome.browser.widget.FloatLabelLayout
+ android:id="@+id/credit_card_name_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ <EditText
+ android:id="@+id/credit_card_name_edit"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:imeOptions="flagNoExtractUi"
+ android:inputType="textCapWords"
+ android:hint="@string/autofill_credit_card_editor_name" />
+ </org.chromium.chrome.browser.widget.FloatLabelLayout>
+
+ <org.chromium.chrome.browser.widget.FloatLabelLayout
+ android:id="@+id/credit_card_number_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ <EditText
+ android:id="@+id/credit_card_number_edit"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:imeOptions="flagNoExtractUi"
+ android:inputType="phone"
+ android:digits="0123456789- "
+ android:hint="@string/autofill_credit_card_editor_number" />
+ </org.chromium.chrome.browser.widget.FloatLabelLayout>
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:focusable="true"
+ android:paddingTop="@dimen/pref_autofill_field_top_padding"
+ android:textAppearance="@style/PreferenceFloatLabelTextAppearance"
+ android:text="@string/autofill_credit_card_editor_expiration_date"
+ android:paddingStart="@dimen/pref_autofill_field_horizontal_padding"
+ android:paddingEnd="@dimen/pref_autofill_field_horizontal_padding" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical" >
+ android:orientation="horizontal"
+ android:paddingTop="8dp"
+ android:baselineAligned="false"
+ android:layout_marginStart="@dimen/pref_autofill_field_horizontal_padding"
+ android:layout_marginEnd="@dimen/pref_autofill_field_horizontal_padding" >
- <!-- EditText views in FloatLabelLayout require both hint and contentDescription to be set
- to work correctly for accessibility because FloatLabelLayout sometimes clear hint. -->
- <!--suppress ContentDescription -->
<LinearLayout
- style="@style/PreferenceScreenLayout"
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:layout_height="wrap_content"
+ android:layout_weight="1"
android:orientation="vertical"
- android:focusableInTouchMode="true"
- android:paddingTop="6dp" >
-
- <org.chromium.chrome.browser.widget.FloatLabelLayout
- android:id="@+id/credit_card_name_label"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" >
- <EditText
- android:id="@+id/credit_card_name_edit"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="flagNoExtractUi"
- android:inputType="textCapWords"
- android:hint="@string/autofill_credit_card_editor_name" />
- </org.chromium.chrome.browser.widget.FloatLabelLayout>
-
- <org.chromium.chrome.browser.widget.FloatLabelLayout
- android:id="@+id/credit_card_number_label"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" >
- <EditText
- android:id="@+id/credit_card_number_edit"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="flagNoExtractUi"
- android:inputType="phone"
- android:digits="0123456789- "
- android:hint="@string/autofill_credit_card_editor_number" />
- </org.chromium.chrome.browser.widget.FloatLabelLayout>
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:focusable="true"
- android:paddingTop="@dimen/pref_autofill_field_top_padding"
- android:textAppearance="@style/PreferenceFloatLabelTextAppearance"
- android:text="@string/autofill_credit_card_editor_expiration_date"
- android:paddingStart="@dimen/pref_autofill_field_horizontal_padding"
- android:paddingEnd="@dimen/pref_autofill_field_horizontal_padding" />
-
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="horizontal"
- android:paddingTop="8dp"
- android:baselineAligned="false"
- android:layout_marginStart="@dimen/pref_autofill_field_horizontal_padding"
- android:layout_marginEnd="@dimen/pref_autofill_field_horizontal_padding" >
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:orientation="vertical"
- android:paddingEnd="10dp" >
- <Spinner
- android:id="@+id/autofill_credit_card_editor_month_spinner"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- <View style="@style/PreferenceSpinnerUnderlineView" />
- </LinearLayout>
-
- <LinearLayout
- android:layout_width="0dp"
- android:layout_height="wrap_content"
- android:layout_weight="1"
- android:orientation="vertical" >
- <Spinner
- android:id="@+id/autofill_credit_card_editor_year_spinner"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- <View style="@style/PreferenceSpinnerUnderlineView" />
- </LinearLayout>
- </LinearLayout>
-
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:focusable="true"
- android:paddingTop="@dimen/pref_autofill_field_top_padding"
- android:textAppearance="@style/PreferenceFloatLabelTextAppearance"
- android:text="@string/autofill_credit_card_editor_billing_address"
- android:paddingStart="@dimen/pref_autofill_field_horizontal_padding"
- android:paddingEnd="@dimen/pref_autofill_field_horizontal_padding" />
-
+ android:paddingEnd="10dp" >
<Spinner
- android:id="@+id/autofill_credit_card_editor_billing_address_spinner"
+ android:id="@+id/autofill_credit_card_editor_month_spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
- <View style="@style/PreferenceSpinnerUnderlineView" />
+ <View style="@style/PreferenceSpinnerUnderlineView" />
</LinearLayout>
- <Space style="@style/ButtonBarTopSpacer" />
- <View style="@style/ButtonBarTopDivider" />
-
- <LinearLayout style="@style/ButtonBar" >
- <Button
- android:id="@+id/autofill_credit_card_delete"
- style="@style/ButtonBarButton"
- android:text="@string/delete" />
-
- <Button
- android:id="@+id/autofill_credit_card_cancel"
- style="@style/ButtonBarButton"
- android:text="@string/cancel" />
-
- <Button
- android:id="@+id/autofill_credit_card_save"
- style="@style/ButtonBarButton"
- android:text="@string/save" />
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical" >
+ <Spinner
+ android:id="@+id/autofill_credit_card_editor_year_spinner"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ <View style="@style/PreferenceSpinnerUnderlineView" />
</LinearLayout>
</LinearLayout>
-</ScrollView>
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:focusable="true"
+ android:paddingTop="@dimen/pref_autofill_field_top_padding"
+ android:textAppearance="@style/PreferenceFloatLabelTextAppearance"
+ android:text="@string/autofill_credit_card_editor_billing_address"
+ android:paddingStart="@dimen/pref_autofill_field_horizontal_padding"
+ android:paddingEnd="@dimen/pref_autofill_field_horizontal_padding" />
+
+ <Spinner
+ android:id="@+id/autofill_credit_card_editor_billing_address_spinner"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ <View style="@style/PreferenceSpinnerUnderlineView" />
+
+</merge>
diff --git a/chrome/android/java/res/layout/autofill_editor_base.xml b/chrome/android/java/res/layout/autofill_editor_base.xml
new file mode 100644
index 0000000..707612c
--- /dev/null
+++ b/chrome/android/java/res/layout/autofill_editor_base.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright 2016 The Chromium Authors. All rights reserved.
+ Use of this source code is governed by a BSD-style license that can be
+ found in the LICENSE file. -->
+
+<!-- Base layout for Autofill editors.
+ Editor fields are expected to be added to the LinearLayout inside of the ScrollLayout.
+-->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+
+ <org.chromium.chrome.browser.payments.ui.FadingEdgeScrollView
+ android:id="@+id/scroll_view"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:fillViewport="true" >
+
+ <!-- All fields go into this LinearLayout. -->
+ <LinearLayout
+ style="@style/PreferenceScreenLayout"
+ android:id="@+id/content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+
+ </org.chromium.chrome.browser.payments.ui.FadingEdgeScrollView>
+
+ <!-- CANCEL and SAVE buttons. -->
+ <org.chromium.chrome.browser.widget.DualControlLayout
+ android:id="@+id/button_bar"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:padding="@dimen/payments_section_large_spacing"
+ android:background="@android:color/white"
+ app:stackedMargin="@dimen/infobar_margin_between_stacked_buttons"
+ app:primaryButtonText="@string/save"
+ app:secondaryButtonText="@string/cancel" />
+
+</LinearLayout>
diff --git a/chrome/android/java/res/layout/autofill_profile_editor.xml b/chrome/android/java/res/layout/autofill_profile_editor.xml
index 255c198b..0996cfe 100644
--- a/chrome/android/java/res/layout/autofill_profile_editor.xml
+++ b/chrome/android/java/res/layout/autofill_profile_editor.xml
@@ -3,105 +3,68 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
-<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:fillViewport="true" >
+<!-- EditText views in FloatLabelLayout require both hint and contentDescription to be set
+ to work correctly for accessibility because FloatLabelLayout sometimes clear hint. -->
+<!--suppress ContentDescription -->
+<merge
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto" >
+ <!-- Editable fields for the profile -->
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="match_parent"
android:orientation="vertical"
- android:focusableInTouchMode="true" >
-
- <!-- EditText views in FloatLabelLayout require both hint and contentDescription to be set
- to work correctly for accessibility because FloatLabelLayout sometimes clear hint. -->
- <!--suppress ContentDescription -->
- <LinearLayout
- style="@style/PreferenceScreenLayout"
+ android:layout_marginStart="@dimen/pref_autofill_field_horizontal_padding"
+ android:layout_marginEnd="@dimen/pref_autofill_field_horizontal_padding"
+ android:paddingBottom="5dp" >
+ <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:orientation="vertical" >
-
- <!-- Editable fields for the profile -->
- <LinearLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical"
- android:layout_marginStart="@dimen/pref_autofill_field_horizontal_padding"
- android:layout_marginEnd="@dimen/pref_autofill_field_horizontal_padding"
- android:paddingBottom="5dp" >
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:focusable="true"
- android:textAppearance="@style/PreferenceFloatLabelTextAppearance"
- android:text="@string/autofill_profile_editor_country"
- android:paddingBottom="8dp" />
- <Spinner
- android:id="@+id/countries"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content" />
- <View style="@style/PreferenceSpinnerUnderlineView" />
- </LinearLayout>
-
- <LinearLayout
- android:id="@+id/autofill_profile_widget_root"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:orientation="vertical" >
- </LinearLayout>
-
- <org.chromium.chrome.browser.widget.FloatLabelLayout
- android:id="@+id/phone_number_label"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" >
- <EditText
- android:id="@+id/phone_number_edit"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="flagNoExtractUi"
- android:inputType="phone"
- android:singleLine="true"
- android:hint="@string/autofill_profile_editor_phone_number" />
- </org.chromium.chrome.browser.widget.FloatLabelLayout>
-
- <org.chromium.chrome.browser.widget.FloatLabelLayout
- android:id="@+id/email_address_label"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" >
- <EditText
- android:id="@+id/email_address_edit"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:imeOptions="flagNoExtractUi"
- android:inputType="textEmailAddress"
- android:singleLine="true"
- android:hint="@string/autofill_profile_editor_email_address" />
- </org.chromium.chrome.browser.widget.FloatLabelLayout>
-
- </LinearLayout>
-
- <Space style="@style/ButtonBarTopSpacer" />
- <View style="@style/ButtonBarTopDivider" />
-
- <LinearLayout style="@style/ButtonBar" >
- <Button
- android:id="@+id/autofill_profile_delete"
- style="@style/ButtonBarButton"
- android:text="@string/delete" />
-
- <Button
- android:id="@+id/autofill_profile_cancel"
- style="@style/ButtonBarButton"
- android:text="@string/cancel" />
-
- <Button
- android:id="@+id/autofill_profile_save"
- style="@style/ButtonBarButton"
- android:text="@string/save" />
- </LinearLayout>
+ android:focusable="true"
+ android:textAppearance="@style/PreferenceFloatLabelTextAppearance"
+ android:text="@string/autofill_profile_editor_country"
+ android:paddingBottom="8dp" />
+ <Spinner
+ android:id="@+id/countries"
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content" />
+ <View style="@style/PreferenceSpinnerUnderlineView" />
</LinearLayout>
-</ScrollView>
+ <LinearLayout
+ android:id="@+id/autofill_profile_widget_root"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+ </LinearLayout>
+
+ <org.chromium.chrome.browser.widget.FloatLabelLayout
+ android:id="@+id/phone_number_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ <EditText
+ android:id="@+id/phone_number_edit"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:imeOptions="flagNoExtractUi"
+ android:inputType="phone"
+ android:singleLine="true"
+ android:hint="@string/autofill_profile_editor_phone_number" />
+ </org.chromium.chrome.browser.widget.FloatLabelLayout>
+
+ <org.chromium.chrome.browser.widget.FloatLabelLayout
+ android:id="@+id/email_address_label"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" >
+ <EditText
+ android:id="@+id/email_address_edit"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:imeOptions="flagNoExtractUi"
+ android:inputType="textEmailAddress"
+ android:singleLine="true"
+ android:hint="@string/autofill_profile_editor_email_address" />
+ </org.chromium.chrome.browser.widget.FloatLabelLayout>
+
+</merge>
diff --git a/chrome/android/java/res/menu/payments_editor_menu.xml b/chrome/android/java/res/menu/payments_editor_menu.xml
index f3da8e2..1b81ca0 100644
--- a/chrome/android/java/res/menu/payments_editor_menu.xml
+++ b/chrome/android/java/res/menu/payments_editor_menu.xml
@@ -7,9 +7,15 @@
xmlns:chrome="http://schemas.android.com/apk/res-auto" >
<item
+ android:id="@+id/delete_menu_id"
+ android:icon="@drawable/ic_delete_white_24dp"
+ android:title="@string/delete"
+ chrome:showAsAction="ifRoom" />
+
+ <item
android:id="@+id/help_menu_id"
android:icon="@drawable/ic_help_white_24dp"
android:title="@string/help"
- chrome:showAsAction="ifRoom"/>
+ chrome:showAsAction="ifRoom" />
</menu>
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDialogToolbar.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDialogToolbar.java
index dabf2e7..12b1ef6 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDialogToolbar.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorDialogToolbar.java
@@ -7,16 +7,34 @@
import android.content.Context;
import android.support.v7.widget.Toolbar;
import android.util.AttributeSet;
+import android.view.Menu;
+import android.view.MenuItem;
import org.chromium.chrome.R;
/** Simple class for displaying a toolbar in the editor dialog. */
public class EditorDialogToolbar extends Toolbar {
+ private boolean mShowDeleteMenuItem = true;
+
/** Constructor for when the toolbar is inflated from XML. */
public EditorDialogToolbar(Context context, AttributeSet attrs) {
super(context, attrs);
inflateMenu(R.menu.payments_editor_menu);
+ updateMenu();
}
+ /** Sets whether or not the the delete menu item will be shown. */
+ public void setShowDeleteMenuItem(boolean state) {
+ mShowDeleteMenuItem = state;
+ updateMenu();
+ }
+
+ /** Updates what is displayed in the menu. */
+ public void updateMenu() {
+ Menu menu = getMenu();
+
+ MenuItem deleteMenuItem = menu.findItem(R.id.delete_menu_id);
+ if (deleteMenuItem != null) deleteMenuItem.setVisible(mShowDeleteMenuItem);
+ }
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java
index cad624c..c673af7 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/payments/ui/EditorView.java
@@ -11,7 +11,6 @@
import android.os.AsyncTask;
import android.os.Handler;
import android.support.design.widget.TextInputLayout;
-import android.support.v7.widget.Toolbar;
import android.support.v7.widget.Toolbar.OnMenuItemClickListener;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.text.Editable;
@@ -196,6 +195,12 @@
};
}
+ /** Launches the Autofill help page on top of the current Context. */
+ public static void launchAutofillHelpPage(Context context) {
+ EmbedContentViewActivity.show(
+ context, context.getString(R.string.help), HELP_URL);
+ }
+
/**
* Prepares the toolbar for use.
*
@@ -203,16 +208,16 @@
* programmatically. This is likely due to how we compile the support libraries.
*/
private void prepareToolbar() {
- Toolbar toolbar = (Toolbar) mLayout.findViewById(R.id.action_bar);
+ EditorDialogToolbar toolbar = (EditorDialogToolbar) mLayout.findViewById(R.id.action_bar);
toolbar.setTitle(mEditorModel.getTitle());
toolbar.setTitleTextColor(Color.WHITE);
+ toolbar.setShowDeleteMenuItem(false);
// Show the help article when the user asks.
toolbar.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
- EmbedContentViewActivity.show(
- mContext, mContext.getString(R.string.help), HELP_URL);
+ launchAutofillHelpPage(mContext);
return true;
}
});
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java
index 8b7e2976..97a7938 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java
@@ -4,7 +4,6 @@
package org.chromium.chrome.browser.preferences.autofill;
-import android.app.Fragment;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextUtils;
@@ -13,7 +12,6 @@
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;
@@ -33,12 +31,7 @@
/**
* Provides the Java-ui for editing a Credit Card autofill entry.
*/
-public class AutofillCreditCardEditor extends Fragment implements OnItemSelectedListener,
- TextWatcher {
- // GUID of the card profile we are editing.
- // May be the empty string if creating a new card.
- private String mGUID;
-
+public class AutofillCreditCardEditor extends AutofillEditorBase {
private FloatLabelLayout mNameLabel;
private EditText mNameText;
private FloatLabelLayout mNumberLabel;
@@ -51,16 +44,10 @@
private int mInitialExpirationYearPos;
@Override
- public void onCreate(Bundle savedState) {
- super.onCreate(savedState);
- }
-
- @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
+ View v = super.onCreateView(inflater, container, savedInstanceState);
- View v = inflater.inflate(R.layout.autofill_credit_card_editor, container, false);
mNameLabel = (FloatLabelLayout) v.findViewById(R.id.credit_card_name_label);
mNameText = (EditText) v.findViewById(R.id.credit_card_name_edit);
mNumberLabel = (FloatLabelLayout) v.findViewById(R.id.credit_card_number_label);
@@ -74,26 +61,24 @@
mBillingAddress =
(Spinner) v.findViewById(R.id.autofill_credit_card_editor_billing_address_spinner);
- // We know which profile to edit based on the GUID stuffed in
- // our extras by AutofillPreferences.
- Bundle extras = getArguments();
- if (extras != null) {
- mGUID = extras.getString(AutofillPreferences.AUTOFILL_GUID);
- }
- if (mGUID == null) {
- mGUID = "";
- getActivity().setTitle(R.string.autofill_create_credit_card);
- } else {
- getActivity().setTitle(R.string.autofill_edit_credit_card);
- }
-
addSpinnerAdapters();
addCardDataToEditFields();
- initializeSaveCancelDeleteButtons(v);
+ initializeButtons(v);
return v;
}
@Override
+ protected int getLayoutId() {
+ return R.layout.autofill_credit_card_editor;
+ }
+
+ @Override
+ protected int getTitleResourceId(boolean isNewEntry) {
+ return isNewEntry
+ ? R.string.autofill_create_credit_card : R.string.autofill_edit_credit_card;
+ }
+
+ @Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
if ((parent == mExpirationYear && position != mInitialExpirationYearPos)
|| (parent == mExpirationMonth && position != mInitialExpirationMonthPos)) {
@@ -102,15 +87,6 @@
}
@Override
- public void onNothingSelected(AdapterView<?> parent) {}
-
- @Override
- public void afterTextChanged(Editable s) {}
-
- @Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
-
- @Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
updateSaveButtonEnabled();
}
@@ -209,7 +185,8 @@
// Read edited data; save in the associated Chrome profile.
// Ignore empty fields.
- private void saveCreditCard() {
+ @Override
+ protected void saveEntry() {
// Remove all spaces in editText.
String cardNumber = mNumberText.getText().toString().replaceAll("\\s+", "");
CreditCard card = new CreditCard(mGUID, AutofillPreferences.SETTINGS_ORIGIN,
@@ -223,43 +200,16 @@
PersonalDataManager.getInstance().setCreditCard(card);
}
- private void deleteCreditCard() {
+ @Override
+ protected void deleteEntry() {
if (mGUID != null) {
PersonalDataManager.getInstance().deleteCreditCard(mGUID);
}
}
- private void initializeSaveCancelDeleteButtons(View v) {
- Button button = (Button) v.findViewById(R.id.autofill_credit_card_delete);
- if ((mGUID == null) || (mGUID.compareTo("") == 0)) {
- // If this is a create, disable the delete button.
- button.setEnabled(false);
- } else {
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- AutofillCreditCardEditor.this.deleteCreditCard();
- getActivity().finish();
- }
- });
- }
- button = (Button) v.findViewById(R.id.autofill_credit_card_cancel);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().finish();
- }
- });
- button = (Button) v.findViewById(R.id.autofill_credit_card_save);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- AutofillCreditCardEditor.this.saveCreditCard();
- getActivity().finish();
- }
- });
-
- button.setEnabled(false);
+ @Override
+ protected void initializeButtons(View v) {
+ super.initializeButtons(v);
// Listen for changes to inputs. Enable the save button after something has changed.
mNameText.addTextChangedListener(this);
@@ -271,7 +221,7 @@
private void updateSaveButtonEnabled() {
boolean enabled = !TextUtils.isEmpty(mNameText.getText())
|| !TextUtils.isEmpty(mNumberText.getText());
- Button button = (Button) getView().findViewById(R.id.autofill_credit_card_save);
+ Button button = (Button) getView().findViewById(R.id.button_primary);
button.setEnabled(enabled);
}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillEditorBase.java b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillEditorBase.java
new file mode 100644
index 0000000..15c683d
--- /dev/null
+++ b/chrome/android/java/src/org/chromium/chrome/browser/preferences/autofill/AutofillEditorBase.java
@@ -0,0 +1,139 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package org.chromium.chrome.browser.preferences.autofill;
+
+import android.app.Fragment;
+import android.os.Bundle;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.Button;
+import android.widget.LinearLayout;
+
+import org.chromium.chrome.R;
+import org.chromium.chrome.browser.payments.ui.EditorView;
+import org.chromium.chrome.browser.payments.ui.FadingEdgeScrollView;
+import org.chromium.chrome.browser.widget.DualControlLayout;
+
+/** Base class for Autofill editors (e.g. credit cards and profiles). */
+public abstract class AutofillEditorBase
+ extends Fragment implements OnItemSelectedListener, TextWatcher {
+
+ /** GUID of the profile we are editing. Empty if creating a new profile. */
+ protected String mGUID;
+
+ /** Whether or not the editor is creating a new entry. */
+ protected boolean mIsNewEntry;
+
+ @Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ super.onCreateView(inflater, container, savedInstanceState);
+ setHasOptionsMenu(true);
+
+ // We know which profile to edit based on the GUID stuffed in
+ // our extras by AutofillPreferences.
+ Bundle extras = getArguments();
+ if (extras != null) {
+ mGUID = extras.getString(AutofillPreferences.AUTOFILL_GUID);
+ }
+ if (mGUID == null) {
+ mGUID = "";
+ mIsNewEntry = true;
+ } else {
+ mIsNewEntry = false;
+ }
+ getActivity().setTitle(getTitleResourceId(mIsNewEntry));
+
+ LinearLayout editorView =
+ (LinearLayout) inflater.inflate(R.layout.autofill_editor_base, container, false);
+
+ // Hide the top shadow on the ScrollView because the toolbar draws one.
+ FadingEdgeScrollView scrollView =
+ (FadingEdgeScrollView) editorView.findViewById(R.id.scroll_view);
+ scrollView.setShadowVisibility(false, true);
+
+ // Inflate the editor into the content LinearLayout.
+ LinearLayout contentLayout = (LinearLayout) editorView.findViewById(R.id.content);
+ inflater.inflate(getLayoutId(), contentLayout, true);
+
+ return editorView;
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ if (item.getItemId() == R.id.delete_menu_id) {
+ deleteEntry();
+ getActivity().finish();
+ return true;
+ } else if (item.getItemId() == R.id.help_menu_id) {
+ EditorView.launchAutofillHelpPage(getContext());
+ return true;
+ }
+
+ return super.onOptionsItemSelected(item);
+ }
+
+ @Override
+ public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+ menu.clear();
+ inflater.inflate(R.menu.payments_editor_menu, menu);
+
+ MenuItem deleteItem = menu.findItem(R.id.delete_menu_id);
+ if (deleteItem != null) deleteItem.setVisible(!mIsNewEntry);
+ }
+
+ /** Initializes the buttons within the layout. */
+ protected void initializeButtons(View layout) {
+ DualControlLayout buttonBar = (DualControlLayout) layout.findViewById(R.id.button_bar);
+ buttonBar.setAlignment(DualControlLayout.ALIGN_END);
+
+ Button button = (Button) layout.findViewById(R.id.button_secondary);
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ getActivity().finish();
+ }
+ });
+
+ button = (Button) layout.findViewById(R.id.button_primary);
+ button.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ saveEntry();
+ getActivity().finish();
+ }
+ });
+ button.setEnabled(false);
+ }
+
+ /** Returns the ID of the layout to inflate. */
+ protected abstract int getLayoutId();
+
+ /** Called when the entry should be saved. */
+ protected abstract void saveEntry();
+
+ /** Called when the entry being edited should be deleted. */
+ protected abstract void deleteEntry();
+
+ /** @return ID of the String to use as the title in the ActionBar. */
+ protected abstract int getTitleResourceId(boolean isNewEntry);
+
+ @Override
+ public void onNothingSelected(AdapterView<?> parent) {}
+
+ @Override
+ public void afterTextChanged(Editable s) {}
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+}
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 74555b7b..e22b1f1 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
@@ -4,17 +4,13 @@
package org.chromium.chrome.browser.preferences.autofill;
-import android.app.Fragment;
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;
@@ -33,12 +29,7 @@
/**
* Provides the Java-ui for editing a Profile autofill entry.
*/
-public class AutofillProfileEditor extends Fragment implements TextWatcher,
- OnItemSelectedListener {
- // GUID of the profile we are editing.
- // May be the empty string if creating a new profile.
- private String mGUID;
-
+public class AutofillProfileEditor extends AutofillEditorBase {
private boolean mNoCountryItemIsSelected;
private LayoutInflater mInflater;
private EditText mPhoneText;
@@ -55,31 +46,12 @@
private boolean mUseSavedProfileLanguage;
@Override
- public void onCreate(Bundle savedState) {
- super.onCreate(savedState);
- }
-
- @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // We know which profile to edit based on the GUID stuffed in
- // our extras by AutofillPreferences.
- Bundle extras = getArguments();
- if (extras != null) {
- mGUID = extras.getString(AutofillPreferences.AUTOFILL_GUID);
- }
- if (mGUID == null) {
- mGUID = "";
- getActivity().setTitle(R.string.autofill_create_profile);
- } else {
- getActivity().setTitle(R.string.autofill_edit_profile);
- }
+ View v = super.onCreateView(inflater, container, savedInstanceState);
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);
@@ -92,16 +64,20 @@
populateCountriesSpinner();
createAndPopulateEditFields();
- initializeSaveCancelDeleteButtons(v);
+ initializeButtons(v);
return v;
}
@Override
- public void afterTextChanged(Editable s) {}
+ protected int getLayoutId() {
+ return R.layout.autofill_profile_editor;
+ }
@Override
- public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
+ protected int getTitleResourceId(boolean isNewEntry) {
+ return isNewEntry ? R.string.autofill_create_profile : R.string.autofill_edit_profile;
+ }
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
@@ -136,9 +112,6 @@
}
}
- @Override
- public void onNothingSelected(AdapterView<?> parent) {}
-
private void populateCountriesSpinner() {
List<Country> countries = AutofillProfileBridge.getSupportedCountries();
mCountryCodes = new ArrayList<String>();
@@ -264,7 +237,8 @@
// Read edited data; save in the associated Chrome profile.
// Ignore empty fields.
- private void saveProfile() {
+ @Override
+ protected void saveEntry() {
AutofillProfile profile = new PersonalDataManager.AutofillProfile(mGUID,
AutofillPreferences.SETTINGS_ORIGIN, true /* isLocal */,
getFieldText(AddressField.RECIPIENT), getFieldText(AddressField.ORGANIZATION),
@@ -289,42 +263,16 @@
}
}
- private void deleteProfile() {
- if (AutofillProfileEditor.this.mGUID != null) {
+ @Override
+ protected void deleteEntry() {
+ if (mGUID != null) {
PersonalDataManager.getInstance().deleteProfile(mGUID);
}
}
- private void initializeSaveCancelDeleteButtons(View v) {
- Button button = (Button) v.findViewById(R.id.autofill_profile_delete);
- if ((mGUID == null) || (mGUID.compareTo("") == 0)) {
- // If this is a create, disable the delete button.
- button.setEnabled(false);
- } else {
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- AutofillProfileEditor.this.deleteProfile();
- getActivity().finish();
- }
- });
- }
- button = (Button) v.findViewById(R.id.autofill_profile_cancel);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- getActivity().finish();
- }
- });
- button = (Button) v.findViewById(R.id.autofill_profile_save);
- button.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- AutofillProfileEditor.this.saveProfile();
- getActivity().finish();
- }
- });
- button.setEnabled(false);
+ @Override
+ protected void initializeButtons(View v) {
+ super.initializeButtons(v);
// Listen for changes to inputs. Enable the save button after something has changed.
mPhoneText.addTextChangedListener(this);
@@ -335,7 +283,7 @@
private void setSaveButtonEnabled(boolean enabled) {
if (getView() != null) {
- Button button = (Button) getView().findViewById(R.id.autofill_profile_save);
+ Button button = (Button) getView().findViewById(R.id.button_primary);
button.setEnabled(enabled);
}
}
diff --git a/chrome/android/java_sources.gni b/chrome/android/java_sources.gni
index db20958..fdb78c5 100644
--- a/chrome/android/java_sources.gni
+++ b/chrome/android/java_sources.gni
@@ -661,6 +661,7 @@
"java/src/org/chromium/chrome/browser/preferences/TextMessageWithLinkAndIconPreference.java",
"java/src/org/chromium/chrome/browser/preferences/TextScalePreference.java",
"java/src/org/chromium/chrome/browser/preferences/autofill/AutofillCreditCardEditor.java",
+ "java/src/org/chromium/chrome/browser/preferences/autofill/AutofillEditorBase.java",
"java/src/org/chromium/chrome/browser/preferences/autofill/AutofillPreferences.java",
"java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileBridge.java",
"java/src/org/chromium/chrome/browser/preferences/autofill/AutofillProfileEditor.java",