OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 #include "chrome/browser/ui/views/autofill/autofill_dialog_views.h" | 5 #include "chrome/browser/ui/views/autofill/autofill_dialog_views.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "chrome/browser/ui/autofill/autofill_dialog_controller.h" | 10 #include "chrome/browser/ui/autofill/autofill_dialog_controller.h" |
11 #include "chrome/browser/ui/views/constrained_window_views.h" | 11 #include "chrome/browser/ui/views/constrained_window_views.h" |
12 #include "third_party/skia/include/core/SkColor.h" | 12 #include "third_party/skia/include/core/SkColor.h" |
13 #include "ui/views/border.h" | 13 #include "ui/views/border.h" |
14 #include "ui/views/controls/button/checkbox.h" | 14 #include "ui/views/controls/button/checkbox.h" |
| 15 #include "ui/views/controls/button/menu_button.h" |
15 #include "ui/views/controls/combobox/combobox.h" | 16 #include "ui/views/controls/combobox/combobox.h" |
16 #include "ui/views/controls/label.h" | 17 #include "ui/views/controls/label.h" |
| 18 #include "ui/views/controls/menu/menu_model_adapter.h" |
| 19 #include "ui/views/controls/menu/menu_runner.h" |
17 #include "ui/views/controls/separator.h" | 20 #include "ui/views/controls/separator.h" |
18 #include "ui/views/controls/textfield/textfield.h" | 21 #include "ui/views/controls/textfield/textfield.h" |
19 #include "ui/views/layout/box_layout.h" | 22 #include "ui/views/layout/box_layout.h" |
20 #include "ui/views/layout/grid_layout.h" | 23 #include "ui/views/layout/grid_layout.h" |
21 #include "ui/views/layout/layout_constants.h" | 24 #include "ui/views/layout/layout_constants.h" |
22 | 25 |
23 namespace autofill { | 26 namespace autofill { |
24 | 27 |
25 namespace { | 28 namespace { |
26 | 29 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
72 // static | 75 // static |
73 AutofillDialogView* AutofillDialogView::Create( | 76 AutofillDialogView* AutofillDialogView::Create( |
74 AutofillDialogController* controller) { | 77 AutofillDialogController* controller) { |
75 return new AutofillDialogViews(controller); | 78 return new AutofillDialogViews(controller); |
76 } | 79 } |
77 | 80 |
78 AutofillDialogViews::AutofillDialogViews(AutofillDialogController* controller) | 81 AutofillDialogViews::AutofillDialogViews(AutofillDialogController* controller) |
79 : controller_(controller), | 82 : controller_(controller), |
80 did_submit_(false), | 83 did_submit_(false), |
81 window_(NULL), | 84 window_(NULL), |
82 contents_(NULL) { | 85 contents_(NULL), |
| 86 email_(SECTION_EMAIL), |
| 87 cc_(SECTION_CC), |
| 88 billing_(SECTION_BILLING), |
| 89 shipping_(SECTION_SHIPPING) { |
83 DCHECK(controller); | 90 DCHECK(controller); |
84 } | 91 } |
85 | 92 |
86 AutofillDialogViews::~AutofillDialogViews() { | 93 AutofillDialogViews::~AutofillDialogViews() { |
87 DCHECK(!window_); | 94 DCHECK(!window_); |
88 } | 95 } |
89 | 96 |
90 void AutofillDialogViews::Show() { | 97 void AutofillDialogViews::Show() { |
91 InitChildViews(); | 98 InitChildViews(); |
92 | 99 |
(...skipping 10 matching lines...) Expand all Loading... |
103 DetailsGroup* group = GroupForSection(section); | 110 DetailsGroup* group = GroupForSection(section); |
104 | 111 |
105 for (DetailInputs::const_iterator iter = updated_inputs.begin(); | 112 for (DetailInputs::const_iterator iter = updated_inputs.begin(); |
106 iter != updated_inputs.end(); ++iter) { | 113 iter != updated_inputs.end(); ++iter) { |
107 TextfieldMap::iterator input = group->textfields.find(&(*iter)); | 114 TextfieldMap::iterator input = group->textfields.find(&(*iter)); |
108 if (input == group->textfields.end()) | 115 if (input == group->textfields.end()) |
109 continue; | 116 continue; |
110 | 117 |
111 input->second->SetText(iter->autofilled_value); | 118 input->second->SetText(iter->autofilled_value); |
112 } | 119 } |
113 } | |
114 | 120 |
115 int AutofillDialogViews::GetSuggestionSelection(DialogSection section) { | 121 UpdateDetailsGroupState(*group); |
116 return GroupForSection(section)->suggested_input->selected_index(); | |
117 } | 122 } |
118 | 123 |
119 void AutofillDialogViews::GetUserInput(DialogSection section, | 124 void AutofillDialogViews::GetUserInput(DialogSection section, |
120 DetailOutputMap* output) { | 125 DetailOutputMap* output) { |
121 DetailsGroup* group = GroupForSection(section); | 126 DetailsGroup* group = GroupForSection(section); |
122 for (TextfieldMap::iterator it = group->textfields.begin(); | 127 for (TextfieldMap::iterator it = group->textfields.begin(); |
123 it != group->textfields.end(); ++it) { | 128 it != group->textfields.end(); ++it) { |
124 output->insert(std::make_pair(it->first, it->second->text())); | 129 output->insert(std::make_pair(it->first, it->second->text())); |
125 } | 130 } |
126 for (ComboboxMap::iterator it = group->comboboxes.begin(); | |
127 it != group->comboboxes.end(); ++it) { | |
128 views::Combobox* combobox = it->second; | |
129 output->insert(std::make_pair( | |
130 it->first, | |
131 combobox->model()->GetItemAt(combobox->selected_index()))); | |
132 } | |
133 } | 131 } |
134 | 132 |
135 bool AutofillDialogViews::UseBillingForShipping() { | 133 bool AutofillDialogViews::UseBillingForShipping() { |
136 return use_billing_for_shipping_->checked(); | 134 return use_billing_for_shipping_->checked(); |
137 } | 135 } |
138 | 136 |
139 string16 AutofillDialogViews::GetWindowTitle() const { | 137 string16 AutofillDialogViews::GetWindowTitle() const { |
140 return controller_->DialogTitle(); | 138 return controller_->DialogTitle(); |
141 } | 139 } |
142 | 140 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 return true; | 180 return true; |
183 } | 181 } |
184 | 182 |
185 void AutofillDialogViews::ButtonPressed(views::Button* sender, | 183 void AutofillDialogViews::ButtonPressed(views::Button* sender, |
186 const ui::Event& event) { | 184 const ui::Event& event) { |
187 DCHECK_EQ(sender, use_billing_for_shipping_); | 185 DCHECK_EQ(sender, use_billing_for_shipping_); |
188 shipping_.container->SetVisible(!use_billing_for_shipping_->checked()); | 186 shipping_.container->SetVisible(!use_billing_for_shipping_->checked()); |
189 GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); | 187 GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); |
190 } | 188 } |
191 | 189 |
192 void AutofillDialogViews::OnSelectedIndexChanged(views::Combobox* combobox) { | 190 void AutofillDialogViews::OnMenuButtonClicked(views::View* source, |
| 191 const gfx::Point& point) { |
193 DetailsGroup* group = | 192 DetailsGroup* group = |
194 combobox == email_.suggested_input ? &email_ : | 193 source == email_.suggested_button ? &email_ : |
195 combobox == cc_.suggested_input ? &cc_ : | 194 source == cc_.suggested_button ? &cc_ : |
196 combobox == billing_.suggested_input ? &billing_ : | 195 source == billing_.suggested_button ? &billing_ : |
197 combobox == shipping_.suggested_input ? &shipping_ : NULL; | 196 source == shipping_.suggested_button ? &shipping_ : NULL; |
198 DCHECK(group); | 197 DCHECK(group); |
199 UpdateDetailsGroupState(*group); | 198 views::MenuModelAdapter adapter( |
200 GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); | 199 controller_->MenuModelForSection(group->section)); |
| 200 menu_runner_.reset(new views::MenuRunner(adapter.CreateMenu())); |
| 201 |
| 202 // Ignore the result since we don't need to handle a deleted menu specially. |
| 203 ignore_result( |
| 204 menu_runner_->RunMenuAt(source->GetWidget(), |
| 205 group->suggested_button, |
| 206 gfx::Rect(point, gfx::Size()), |
| 207 views::MenuItemView::TOPRIGHT, |
| 208 0)); |
201 } | 209 } |
202 | 210 |
203 void AutofillDialogViews::ContentsChanged(views::Textfield* sender, | 211 void AutofillDialogViews::ContentsChanged(views::Textfield* sender, |
204 const string16& new_contents) { | 212 const string16& new_contents) { |
205 // TODO(estade): work for not billing. | 213 // TODO(estade): work for not billing. |
206 for (TextfieldMap::iterator iter = billing_.textfields.begin(); | 214 for (TextfieldMap::iterator iter = billing_.textfields.begin(); |
207 iter != billing_.textfields.end(); | 215 iter != billing_.textfields.end(); |
208 ++iter) { | 216 ++iter) { |
209 if (iter->second == sender) { | 217 if (iter->second == sender) { |
210 controller_->UserEditedInput(iter->first, | 218 controller_->UserEditedInput(iter->first, |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 billing->AddChildView(use_billing_for_shipping_); | 363 billing->AddChildView(use_billing_for_shipping_); |
356 | 364 |
357 // Container (holds label + inputs). | 365 // Container (holds label + inputs). |
358 views::View* container = CreateSectionContainer( | 366 views::View* container = CreateSectionContainer( |
359 controller_->LabelForSection(SECTION_BILLING), billing); | 367 controller_->LabelForSection(SECTION_BILLING), billing); |
360 billing_.container = container; | 368 billing_.container = container; |
361 } | 369 } |
362 | 370 |
363 views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) { | 371 views::View* AutofillDialogViews::CreateInputsContainer(DialogSection section) { |
364 views::View* inputs_container = new views::View(); | 372 views::View* inputs_container = new views::View(); |
365 inputs_container->SetLayoutManager( | 373 views::GridLayout* layout = new views::GridLayout(inputs_container); |
| 374 inputs_container->SetLayoutManager(layout); |
| 375 |
| 376 int kColumnSetId = 0; |
| 377 views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId); |
| 378 column_set->AddColumn(views::GridLayout::FILL, |
| 379 views::GridLayout::LEADING, |
| 380 1, |
| 381 views::GridLayout::USE_PREF, |
| 382 0, |
| 383 0); |
| 384 column_set->AddColumn(views::GridLayout::CENTER, |
| 385 views::GridLayout::LEADING, |
| 386 0, |
| 387 views::GridLayout::USE_PREF, |
| 388 0, |
| 389 0); |
| 390 layout->StartRow(0, kColumnSetId); |
| 391 |
| 392 // The |info_view| holds |manual_inputs| and |suggested_info|, allowing the |
| 393 // dialog toggle which is shown. |
| 394 views::View* info_view = new views::View(); |
| 395 info_view->SetLayoutManager( |
366 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); | 396 new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0)); |
367 views::View* manual_inputs = InitInputsView(section); | 397 views::View* manual_inputs = InitInputsView(section); |
368 inputs_container->AddChildView(manual_inputs); | 398 info_view->AddChildView(manual_inputs); |
369 views::Combobox* combobox = | 399 views::Label* suggested_info = new views::Label(); |
370 new views::Combobox(controller_->ComboboxModelForSection(section)); | 400 suggested_info->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
371 combobox->set_listener(this); | 401 info_view->AddChildView(suggested_info); |
372 inputs_container->AddChildView(combobox); | 402 layout->AddView(info_view); |
| 403 |
| 404 // TODO(estade): Fix the appearance of this button. |
| 405 views::MenuButton* menu_button = |
| 406 new views::MenuButton(NULL, string16(), this, true); |
| 407 layout->AddView(menu_button); |
373 | 408 |
374 DetailsGroup* group = GroupForSection(section); | 409 DetailsGroup* group = GroupForSection(section); |
375 group->suggested_input = combobox; | 410 group->suggested_button = menu_button; |
376 group->manual_input = manual_inputs; | 411 group->manual_input = manual_inputs; |
| 412 group->suggested_info = suggested_info; |
377 UpdateDetailsGroupState(*group); | 413 UpdateDetailsGroupState(*group); |
378 return inputs_container; | 414 return inputs_container; |
379 } | 415 } |
380 | 416 |
381 // TODO(estade): we should be using Chrome-style constrained window padding | 417 // TODO(estade): we should be using Chrome-style constrained window padding |
382 // values. | 418 // values. |
383 views::View* AutofillDialogViews::InitInputsView(DialogSection section) { | 419 views::View* AutofillDialogViews::InitInputsView(DialogSection section) { |
384 const DetailInputs& inputs = controller_->RequestedFieldsForSection(section); | 420 const DetailInputs& inputs = controller_->RequestedFieldsForSection(section); |
385 TextfieldMap* textfields = &GroupForSection(section)->textfields; | 421 TextfieldMap* textfields = &GroupForSection(section)->textfields; |
386 ComboboxMap* comboboxes = &GroupForSection(section)->comboboxes; | 422 ComboboxMap* comboboxes = &GroupForSection(section)->comboboxes; |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 field->SetController(this); | 473 field->SetController(this); |
438 textfields->insert(std::make_pair(&input, field)); | 474 textfields->insert(std::make_pair(&input, field)); |
439 layout->AddView(field); | 475 layout->AddView(field); |
440 } | 476 } |
441 } | 477 } |
442 | 478 |
443 return view; | 479 return view; |
444 } | 480 } |
445 | 481 |
446 void AutofillDialogViews::UpdateDetailsGroupState(const DetailsGroup& group) { | 482 void AutofillDialogViews::UpdateDetailsGroupState(const DetailsGroup& group) { |
447 views::Combobox* combobox = group.suggested_input; | 483 string16 suggestion_text = |
448 int suggestion_count = combobox->model()->GetItemCount(); | 484 controller_->SuggestionTextForSection(group.section); |
449 bool show_combobox = suggestion_count > 1 && | 485 group.manual_input->SetVisible(suggestion_text.empty()); |
450 combobox->selected_index() != suggestion_count - 1; | 486 group.suggested_info->SetVisible(!suggestion_text.empty()); |
451 | 487 group.suggested_info->SetText(suggestion_text); |
452 combobox->SetVisible(show_combobox); | 488 if (GetWidget()) |
453 group.manual_input->SetVisible(!show_combobox); | 489 GetWidget()->SetSize(GetWidget()->non_client_view()->GetPreferredSize()); |
454 } | 490 } |
455 | 491 |
456 AutofillDialogViews::DetailsGroup* AutofillDialogViews:: | 492 AutofillDialogViews::DetailsGroup* AutofillDialogViews:: |
457 GroupForSection(DialogSection section) { | 493 GroupForSection(DialogSection section) { |
458 switch (section) { | 494 switch (section) { |
459 case SECTION_EMAIL: | 495 case SECTION_EMAIL: |
460 return &email_; | 496 return &email_; |
461 case SECTION_CC: | 497 case SECTION_CC: |
462 return &cc_; | 498 return &cc_; |
463 case SECTION_BILLING: | 499 case SECTION_BILLING: |
464 return &billing_; | 500 return &billing_; |
465 case SECTION_SHIPPING: | 501 case SECTION_SHIPPING: |
466 return &shipping_; | 502 return &shipping_; |
467 } | 503 } |
468 | 504 |
469 NOTREACHED(); | 505 NOTREACHED(); |
470 return NULL; | 506 return NULL; |
471 } | 507 } |
472 | 508 |
473 AutofillDialogViews::DetailsGroup::DetailsGroup() | 509 AutofillDialogViews::DetailsGroup::DetailsGroup(DialogSection section) |
474 : container(NULL), | 510 : section(section), |
475 suggested_input(NULL), | 511 container(NULL), |
476 manual_input(NULL) {} | 512 manual_input(NULL), |
| 513 suggested_info(NULL), |
| 514 suggested_button(NULL) {} |
477 | 515 |
478 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} | 516 AutofillDialogViews::DetailsGroup::~DetailsGroup() {} |
479 | 517 |
480 } // namespace autofill | 518 } // namespace autofill |
OLD | NEW |