OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.autofill; | 5 package org.chromium.chrome.browser.autofill; |
6 | 6 |
7 import java.util.ArrayList; | |
8 import java.util.List; | |
9 | |
10 import android.app.AlertDialog; | 7 import android.app.AlertDialog; |
11 import android.content.Context; | 8 import android.content.Context; |
12 import android.content.DialogInterface; | 9 import android.content.DialogInterface; |
13 | 10 |
14 import android.content.DialogInterface.OnClickListener; | 11 import android.content.DialogInterface.OnClickListener; |
| 12 import android.content.res.Resources; |
15 import android.text.TextUtils; | 13 import android.text.TextUtils; |
16 import android.view.View; | 14 import android.view.View; |
17 import android.widget.AdapterView; | 15 import android.widget.AdapterView; |
18 import android.widget.AdapterView.OnItemSelectedListener; | 16 import android.widget.AdapterView.OnItemSelectedListener; |
19 import android.widget.EditText; | 17 import android.widget.EditText; |
20 import android.widget.ScrollView; | 18 import android.widget.ScrollView; |
21 | 19 |
22 import org.chromium.chrome.R; | 20 import org.chromium.chrome.R; |
23 | 21 |
| 22 import java.util.ArrayList; |
| 23 import java.util.Arrays; |
| 24 import java.util.List; |
| 25 |
24 /** | 26 /** |
25 * This is the dialog that will act as the java side controller between the | 27 * This is the dialog that will act as the java side controller between the |
26 * AutofillDialogGlue object and the UI elements on the page. It contains the | 28 * AutofillDialogGlue object and the UI elements on the page. It contains the |
27 * title and the content views and relays messages from the backend to them. | 29 * title and the content views and relays messages from the backend to them. |
28 */ | 30 */ |
29 public class AutofillDialog extends AlertDialog | 31 public class AutofillDialog extends AlertDialog |
30 implements OnClickListener, OnItemSelectedListener { | 32 implements OnClickListener, OnItemSelectedListener { |
| 33 private static final int ADD_MENU_ITEM_INDEX = -1; |
| 34 private static final int EDIT_MENU_ITEM_INDEX = -2; |
| 35 |
31 private AutofillDialogContentView mContentView; | 36 private AutofillDialogContentView mContentView; |
32 private AutofillDialogTitleView mTitleView; | 37 private AutofillDialogTitleView mTitleView; |
33 private AutofillDialogField[][] mAutofillSectionFieldData = | 38 private AutofillDialogField[][] mAutofillSectionFieldData = |
34 new AutofillDialogField[AutofillDialogConstants.NUM_SECTIONS][]; | 39 new AutofillDialogField[AutofillDialogConstants.NUM_SECTIONS][]; |
35 private AutofillDialogMenuItem[][] mAutofillSectionMenuData = | 40 private AutofillDialogMenuItem[][] mAutofillSectionMenuData = |
36 new AutofillDialogMenuItem[AutofillDialogConstants.NUM_SECTIONS][]; | 41 new AutofillDialogMenuItem[AutofillDialogConstants.NUM_SECTIONS][]; |
| 42 private final List<String> mDefaultAccountItems = new ArrayList<String>(); |
| 43 private final AutofillDialogMenuItem[][] mDefaultMenuItems = |
| 44 new AutofillDialogMenuItem[AutofillDialogConstants.NUM_SECTIONS][]; |
| 45 private AutofillDialogDelegate mDelegate; |
37 private boolean mWillDismiss = false; | 46 private boolean mWillDismiss = false; |
38 | 47 |
39 /** | 48 /** |
40 * An interface to handle the interaction with an AutofillDialog object. | 49 * An interface to handle the interaction with an AutofillDialog object. |
41 */ | 50 */ |
42 public interface AutofillDialogDelegate { | 51 public interface AutofillDialogDelegate { |
43 | 52 |
44 /** | 53 /** |
45 * Informs AutofillDialog controller that a menu item was selected. | 54 * Informs AutofillDialog controller that a menu item was selected. |
46 * @param section Section in which a menu item was selected. Should matc
h one of the values | 55 * @param section Section in which a menu item was selected. Should matc
h one of the values |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 * Informs AutofillDialog controller that the user clicked on the submit
button. | 89 * Informs AutofillDialog controller that the user clicked on the submit
button. |
81 */ | 90 */ |
82 public void dialogSubmit(); | 91 public void dialogSubmit(); |
83 | 92 |
84 /** | 93 /** |
85 * Informs AutofillDialog controller that the user clicked on the cancel
button. | 94 * Informs AutofillDialog controller that the user clicked on the cancel
button. |
86 */ | 95 */ |
87 public void dialogCancel(); | 96 public void dialogCancel(); |
88 } | 97 } |
89 | 98 |
90 protected AutofillDialog(Context context) { | 99 protected AutofillDialog(Context context, AutofillDialogDelegate delegate) { |
91 super(context); | 100 super(context); |
| 101 mDelegate = delegate; |
92 | 102 |
93 addTitleWithPlaceholders(); | 103 addTitleWithPlaceholders(); |
94 | 104 |
95 ScrollView scroll = new ScrollView(context); | 105 ScrollView scroll = new ScrollView(context); |
96 mContentView = (AutofillDialogContentView) getLayoutInflater(). | 106 mContentView = (AutofillDialogContentView) getLayoutInflater(). |
97 inflate(R.layout.autofill_dialog_content, null); | 107 inflate(R.layout.autofill_dialog_content, null); |
98 scroll.addView(mContentView); | 108 scroll.addView(mContentView); |
99 setView(scroll); | 109 setView(scroll); |
| 110 Resources resources = context.getResources(); |
100 | 111 |
101 setButton(AlertDialog.BUTTON_NEGATIVE, | 112 setButton(AlertDialog.BUTTON_NEGATIVE, |
102 getContext().getResources().getString(R.string.autofill_negative
_button), this); | 113 resources.getString(R.string.autofill_negative_button), this); |
103 setButton(AlertDialog.BUTTON_POSITIVE, | 114 setButton(AlertDialog.BUTTON_POSITIVE, |
104 getContext().getResources().getString(R.string.autofill_positive
_button), this); | 115 getContext().getResources().getString(R.string.autofill_positive
_button), this); |
105 | 116 |
106 mContentView.setOnItemSelectedListener(this); | 117 mContentView.setOnItemSelectedListener(this); |
| 118 |
| 119 AutofillDialogMenuItem[] billingItems = { |
| 120 new AutofillDialogMenuItem(ADD_MENU_ITEM_INDEX, |
| 121 resources.getString(R.string.autofill_new_billing)), |
| 122 new AutofillDialogMenuItem(EDIT_MENU_ITEM_INDEX, |
| 123 resources.getString(R.string.autofill_edit_billing)) |
| 124 }; |
| 125 AutofillDialogMenuItem[] shippingItems = { |
| 126 new AutofillDialogMenuItem(ADD_MENU_ITEM_INDEX, |
| 127 resources.getString(R.string.autofill_new_shipping)), |
| 128 new AutofillDialogMenuItem(EDIT_MENU_ITEM_INDEX, |
| 129 resources.getString(R.string.autofill_edit_shipping)) |
| 130 }; |
| 131 |
| 132 mDefaultMenuItems[AutofillDialogConstants.SECTION_CC_BILLING] = billingI
tems; |
| 133 mDefaultMenuItems[AutofillDialogConstants.SECTION_SHIPPING] = shippingIt
ems; |
| 134 |
| 135 mDefaultAccountItems.add(resources.getString(R.string.autofill_new_accou
nt)); |
| 136 mDefaultAccountItems.add(resources.getString(R.string.autofill_use_local
)); |
107 } | 137 } |
108 | 138 |
109 @Override | 139 @Override |
110 public void dismiss() { | 140 public void dismiss() { |
111 if (mWillDismiss) super.dismiss(); | 141 if (mWillDismiss) super.dismiss(); |
112 } | 142 } |
113 | 143 |
114 @Override | 144 @Override |
115 public void onClick(DialogInterface dialog, int which) { | 145 public void onClick(DialogInterface dialog, int which) { |
116 if (mContentView.getCurrentLayout() == AutofillDialogContentView.LAYOUT_
STEADY) { | 146 if (!mContentView.isInEditingMode()) { |
117 mWillDismiss = true; | 147 mWillDismiss = true; |
| 148 if (which == AlertDialog.BUTTON_POSITIVE) mDelegate.dialogSubmit(); |
| 149 else mDelegate.dialogCancel(); |
118 return; | 150 return; |
119 } | 151 } |
120 | 152 |
| 153 int section = mContentView.getCurrentSection(); |
| 154 assert(section != AutofillDialogUtils.INVALID_SECTION); |
| 155 |
| 156 if (which == AlertDialog.BUTTON_POSITIVE) mDelegate.editingComplete(sect
ion); |
| 157 else mDelegate.editingCancel(section); |
| 158 |
121 mContentView.changeLayoutTo(AutofillDialogContentView.LAYOUT_STEADY); | 159 mContentView.changeLayoutTo(AutofillDialogContentView.LAYOUT_STEADY); |
122 getButton(BUTTON_POSITIVE).setText(R.string.autofill_positive_button); | 160 getButton(BUTTON_POSITIVE).setText(R.string.autofill_positive_button); |
123 mWillDismiss = false; | 161 mWillDismiss = false; |
124 } | 162 } |
125 | 163 |
126 @Override | 164 @Override |
127 public void onItemSelected(AdapterView<?> spinner, View view, int position, | 165 public void onItemSelected(AdapterView<?> spinner, View view, int position,
long id) { |
128 long id) { | 166 if (spinner.getId() == R.id.accounts_spinner) return; |
129 if (spinner.getId() == R.id.accounts_spinner) { | 167 |
130 if (spinner.getItemAtPosition(position).toString().equals( | 168 int section = AutofillDialogUtils.getSectionForSpinnerID(spinner.getId()
); |
131 getContext().getResources().getString(R.string.autofill_use_
local))) { | 169 |
132 mContentView.changeLayoutTo(AutofillDialogContentView.LAYOUT_STE
ADY); | 170 if (!selectionShouldChangeLayout(spinner, section, position)) { |
133 } else { | 171 mDelegate.itemSelected(section, position); |
134 mContentView.changeLayoutTo(AutofillDialogContentView.LAYOUT_FET
CHING); | |
135 } | |
136 return; | 172 return; |
137 } | 173 } |
138 | 174 |
139 int section = AutofillDialogUtils.getSectionForSpinnerID(spinner.getId()
); | 175 mDelegate.editingStart(section); |
140 | 176 AutofillDialogMenuItem currentItem = |
141 if (!mContentView.selectionShouldChangeLayout(spinner, section, position
)) return; | 177 (AutofillDialogMenuItem) spinner.getItemAtPosition(position); |
142 | 178 if (currentItem.mIndex == ADD_MENU_ITEM_INDEX) clearAutofillSectionField
Values(section); |
143 mContentView.changeLayoutTo(AutofillDialogContentView.getLayoutModeForSe
ction(section)); | 179 mContentView.changeLayoutTo(AutofillDialogContentView.getLayoutModeForSe
ction(section)); |
144 spinner.setSelection(0); | |
145 getButton(BUTTON_POSITIVE).setText(R.string.autofill_positive_button_edi
ting); | 180 getButton(BUTTON_POSITIVE).setText(R.string.autofill_positive_button_edi
ting); |
146 } | 181 } |
147 | 182 |
148 @Override | 183 @Override |
149 public void onNothingSelected(AdapterView<?> spinner) { | 184 public void onNothingSelected(AdapterView<?> spinner) { |
150 } | 185 } |
151 | 186 |
| 187 /** |
| 188 * @param spinner The dropdown that was selected by the user. |
| 189 * @param section The section that the dropdown corresponds to. |
| 190 * @param position The position for the selected item in the dropdown. |
| 191 * @return Whether the selection should cause a layout state change. |
| 192 */ |
| 193 private boolean selectionShouldChangeLayout(AdapterView<?> spinner, int sect
ion, int position) { |
| 194 int numDefaultItems = mDefaultMenuItems[section] != null ? |
| 195 mDefaultMenuItems[section].length : 0; |
| 196 return position >= spinner.getCount() - numDefaultItems; |
| 197 } |
| 198 |
152 //TODO(yusufo): Remove this. updateAccountChooserAndAddTitle will get initia
ted from glue. | 199 //TODO(yusufo): Remove this. updateAccountChooserAndAddTitle will get initia
ted from glue. |
153 private void addTitleWithPlaceholders() { | 200 private void addTitleWithPlaceholders() { |
154 List<String> accounts = new ArrayList<String>(); | 201 String[] accounts = { |
155 accounts.add("placeholder@gmail.com"); | 202 "placeholder@gmail.com", |
156 accounts.add("placeholder@google.com"); | 203 "placeholder@google.com" |
157 updateAccountChooserAndAddTitle(accounts); | 204 }; |
| 205 updateAccountChooserAndAddTitle(accounts, 0); |
158 } | 206 } |
159 | 207 |
160 /** | 208 /** |
161 * Update account chooser dropdown with given accounts and create the title
view if needed. | 209 * Update account chooser dropdown with given accounts and create the title
view if needed. |
162 * @param accounts The accounts to be used for the dropdown. | 210 * @param accounts The accounts to be used for the dropdown. |
| 211 * @param selectedAccountIndex The index of a currently selected account or
-1 |
| 212 * if the local payments should be used. |
163 */ | 213 */ |
164 public void updateAccountChooserAndAddTitle(List<String> accounts) { | 214 public void updateAccountChooserAndAddTitle(String[] accounts, int selectedA
ccountIndex) { |
| 215 ArrayList<String> combinedItems = |
| 216 new ArrayList<String>(accounts.length + mDefaultAccountItems.siz
e()); |
| 217 combinedItems.addAll(Arrays.asList(accounts)); |
| 218 combinedItems.addAll(mDefaultAccountItems); |
165 if (mTitleView == null) { | 219 if (mTitleView == null) { |
166 mTitleView = new AutofillDialogTitleView(getContext(), accounts); | 220 mTitleView = new AutofillDialogTitleView(getContext(), combinedItems
); |
167 mTitleView.setOnItemSelectedListener(this); | 221 mTitleView.setOnItemSelectedListener(this); |
168 setCustomTitle(mTitleView); | 222 setCustomTitle(mTitleView); |
169 return; | 223 return; |
170 } | 224 } |
171 // TODO(yusufo): Add code to update accounts after title is created. | 225 mTitleView.updateAccountsAndSelect(combinedItems, selectedAccountIndex); |
172 } | 226 } |
173 | 227 |
174 /** | 228 /** |
| 229 * Notifies the dialog that the underlying model is changed and all sections
will be updated. |
| 230 * Any editing should be invalidated. |
| 231 * The dialog should either go to the FETCHING or to the STEADY mode. |
| 232 * @param fetchingIsActive If true, the data is being fetched and is not yet
available. |
| 233 */ |
| 234 public void modelChanged(boolean fetchingIsActive) { |
| 235 if (fetchingIsActive) { |
| 236 mContentView.changeLayoutTo(AutofillDialogContentView.LAYOUT_FETCHIN
G); |
| 237 } else { |
| 238 mContentView.changeLayoutTo(AutofillDialogContentView.LAYOUT_STEADY)
; |
| 239 } |
| 240 } |
| 241 |
| 242 /** |
175 * Update given section with the data provided. This fills out the related {
@link EditText} | 243 * Update given section with the data provided. This fills out the related {
@link EditText} |
176 * fields in the layout corresponding to the section. | 244 * fields in the layout corresponding to the section. |
177 * @param section The section to update with the given data. | 245 * @param section The section to update with the given data. |
178 * @param visible Whether the section should be visible. | 246 * @param visible Whether the section should be visible. |
179 * @param dialogInputs The array that contains the data for each field in th
e section. | 247 * @param dialogInputs The array that contains the data for each field in th
e section. |
180 * @param menuItems The array that contains the dropdown items to be shown f
or the section. | 248 * @param menuItems The array that contains the dropdown items to be shown f
or the section. |
181 * @param selectedMenuItem The menu item that is currently selected or -1 ot
herwise. | 249 * @param selectedMenuItem The menu item that is currently selected or -1 ot
herwise. |
182 */ | 250 */ |
183 public void updateSection(int section, boolean visible, AutofillDialogField[
] dialogInputs, | 251 public void updateSection(int section, boolean visible, AutofillDialogField[
] dialogInputs, |
184 AutofillDialogMenuItem[] menuItems, int selectedMenuItem) { | 252 AutofillDialogMenuItem[] menuItems, int selectedMenuItem) { |
185 EditText currentField; | 253 EditText currentField; |
186 String inputValue; | 254 String inputValue; |
187 for (int i = 0; i < dialogInputs.length; i++) { | 255 for (int i = 0; i < dialogInputs.length; i++) { |
188 currentField = (EditText) findViewById(AutofillDialogUtils.getEditTe
xtIDForField( | 256 currentField = (EditText) findViewById(AutofillDialogUtils.getEditTe
xtIDForField( |
189 section, dialogInputs[i].mFieldType)); | 257 section, dialogInputs[i].mFieldType)); |
190 if (currentField == null) continue; | 258 if (currentField == null) continue; |
191 currentField.setHint(dialogInputs[i].mPlaceholder); | 259 currentField.setHint(dialogInputs[i].mPlaceholder); |
192 inputValue = dialogInputs[i].getValue(); | 260 inputValue = dialogInputs[i].getValue(); |
193 if (TextUtils.isEmpty(inputValue)) currentField.setText(""); | 261 if (TextUtils.isEmpty(inputValue)) currentField.setText(""); |
194 else currentField.setText(inputValue); | 262 else currentField.setText(inputValue); |
195 } | 263 } |
196 mAutofillSectionFieldData[section] = dialogInputs; | 264 mAutofillSectionFieldData[section] = dialogInputs; |
197 mContentView.setVisibilityForSection(section, visible); | 265 mContentView.setVisibilityForSection(section, visible); |
198 mContentView.updateMenuItemsForSection(section, menuItems); | 266 List<AutofillDialogMenuItem> combinedItems; |
| 267 if (mDefaultMenuItems[section] == null) { |
| 268 combinedItems = Arrays.asList(menuItems); |
| 269 } else { |
| 270 combinedItems = new ArrayList<AutofillDialogMenuItem>( |
| 271 menuItems.length + mDefaultMenuItems[section].length); |
| 272 combinedItems.addAll(Arrays.asList(menuItems)); |
| 273 combinedItems.addAll(Arrays.asList(mDefaultMenuItems[section])); |
| 274 } |
| 275 mContentView.updateMenuItemsForSection(section, combinedItems); |
199 mAutofillSectionMenuData[section] = menuItems; | 276 mAutofillSectionMenuData[section] = menuItems; |
200 } | 277 } |
201 | 278 |
202 /** | 279 /** |
203 * Clears the field values for the given section. | 280 * Clears the field values for the given section. |
204 * @param section The section to clear the field values for. | 281 * @param section The section to clear the field values for. |
205 */ | 282 */ |
206 public void clearAutofillSectionFieldValues(int section) { | 283 public void clearAutofillSectionFieldData(int section) { |
207 AutofillDialogField[] fieldData = mAutofillSectionFieldData[section]; | 284 AutofillDialogField[] fieldData = mAutofillSectionFieldData[section]; |
208 if (fieldData == null) return; | 285 if (fieldData == null) return; |
209 | 286 |
210 for (int i = 0; i < fieldData.length; i++) fieldData[i].setValue(""); | 287 for (int i = 0; i < fieldData.length; i++) fieldData[i].setValue(""); |
211 } | 288 } |
212 | 289 |
| 290 private void clearAutofillSectionFieldValues(int section) { |
| 291 AutofillDialogField[] fieldData = mAutofillSectionFieldData[section]; |
| 292 if (fieldData == null) return; |
| 293 |
| 294 EditText currentField; |
| 295 for (int i = 0; i < fieldData.length; i++) { |
| 296 currentField = (EditText) findViewById(AutofillDialogUtils.getEditTe
xtIDForField( |
| 297 section, fieldData[i].mFieldType)); |
| 298 if (currentField == null) continue; |
| 299 |
| 300 currentField.setText(""); |
| 301 } |
| 302 } |
| 303 |
213 /** | 304 /** |
214 * Return the array that holds all the data about the fields in the given se
ction. | 305 * Return the array that holds all the data about the fields in the given se
ction. |
215 * @param section The section to return the data for. | 306 * @param section The section to return the data for. |
216 * @return An array containing the data for each field in the given section. | 307 * @return An array containing the data for each field in the given section. |
217 */ | 308 */ |
218 public AutofillDialogField[] getSection(int section) { | 309 public AutofillDialogField[] getSection(int section) { |
219 AutofillDialogField[] fieldData = mAutofillSectionFieldData[section]; | 310 AutofillDialogField[] fieldData = mAutofillSectionFieldData[section]; |
220 if (fieldData == null) return null; | 311 if (fieldData == null) return null; |
221 | 312 |
222 EditText currentField; | 313 EditText currentField; |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 return false; | 354 return false; |
264 } | 355 } |
265 | 356 |
266 /** | 357 /** |
267 * Updates the progress for the final transaction with the given value. | 358 * Updates the progress for the final transaction with the given value. |
268 * @param value The current progress percentage value. | 359 * @param value The current progress percentage value. |
269 */ | 360 */ |
270 public void updateProgressBar(double value) { | 361 public void updateProgressBar(double value) { |
271 } | 362 } |
272 } | 363 } |
OLD | NEW |