diff options
Diffstat (limited to 'chrome/browser/views/autofill_profiles_view_win.cc')
-rw-r--r-- | chrome/browser/views/autofill_profiles_view_win.cc | 171 |
1 files changed, 152 insertions, 19 deletions
diff --git a/chrome/browser/views/autofill_profiles_view_win.cc b/chrome/browser/views/autofill_profiles_view_win.cc index 1721208..bb56477 100644 --- a/chrome/browser/views/autofill_profiles_view_win.cc +++ b/chrome/browser/views/autofill_profiles_view_win.cc @@ -69,7 +69,7 @@ class ListBackground : public views::Background { ///////////////////////////////////////////////////////////////////////////// // AutoFillProfilesView, static data: -AutoFillProfilesView *AutoFillProfilesView::instance_ = NULL; +AutoFillProfilesView* AutoFillProfilesView::instance_ = NULL; ///////////////////////////////////////////////////////////////////////////// // AutoFillProfilesView::ScrollViewContents, static data: @@ -83,7 +83,8 @@ AutoFillProfilesView::AutoFillProfilesView( : personal_data_manager_(personal_data_manager), observer_(observer), scroll_view_(NULL), - save_changes_(NULL) { + save_changes_(NULL), + focus_manager_(NULL) { } AutoFillProfilesView::~AutoFillProfilesView() { @@ -111,20 +112,26 @@ int AutoFillProfilesView::Show(gfx::NativeWindow parent, ///////////////////////////////////////////////////////////////////////////// // AutoFillProfilesView, protected: void AutoFillProfilesView::AddClicked(EditableSetType item_type) { + int group_id = 0; if (item_type == EDITABLE_SET_ADDRESS) { AutoFillProfile address(std::wstring(), 0); profiles_set_.push_back(EditableSetInfo(&address, true)); + group_id = profiles_set_.size() - 1; } else if (item_type == EDITABLE_SET_CREDIT_CARD) { CreditCard credit_card(std::wstring(), 0); credit_card_set_.push_back(EditableSetInfo(&credit_card, true)); + group_id = profiles_set_.size() + credit_card_set_.size() - 1; } else { NOTREACHED(); } - scroll_view_->RebuildView(); + scroll_view_->RebuildView(FocusedItem(group_id, + EditableSetViewContents::kLabelText)); + scroll_view_->EnsureGroupOnScreen(group_id); } void AutoFillProfilesView::DeleteEditableSet( std::vector<EditableSetInfo>::iterator field_set_iterator) { + FocusedItem focused_item_index; if (field_set_iterator->is_address) { string16 label = field_set_iterator->address.Label(); profiles_set_.erase(field_set_iterator); @@ -136,15 +143,17 @@ void AutoFillProfilesView::DeleteEditableSet( if (it->credit_card.billing_address() == label) it->credit_card.set_billing_address(string16()); } + focused_item_index = FocusedItem(ScrollViewContents::kAddAddressButton, 0); } else { credit_card_set_.erase(field_set_iterator); + focused_item_index = FocusedItem(ScrollViewContents::kAddCcButton, 0); } - scroll_view_->RebuildView(); + scroll_view_->RebuildView(focused_item_index); } void AutoFillProfilesView::CollapseStateChanged( std::vector<EditableSetInfo>::iterator field_set_iterator) { - scroll_view_->RebuildView(); + scroll_view_->RebuildView(FocusedItem()); } void AutoFillProfilesView::ValidateAndFixLabel() { @@ -224,6 +233,8 @@ std::wstring AutoFillProfilesView::GetWindowTitle() const { } void AutoFillProfilesView::WindowClosing() { + DCHECK(focus_manager_); + focus_manager_->RemoveFocusChangeListener(this); instance_ = NULL; } @@ -257,11 +268,27 @@ void AutoFillProfilesView::ButtonPressed(views::Button* sender, } ///////////////////////////////////////////////////////////////////////////// +// AutoFillProfilesView, views::FocusChangeListener implementations: +void AutoFillProfilesView::FocusWillChange(views::View* focused_before, + views::View* focused_now) { + if (focused_now) { + focused_now->ScrollRectToVisible(gfx::Rect(focused_now->width(), + focused_now->height())); + } +} + + +///////////////////////////////////////////////////////////////////////////// // AutoFillProfilesView, PersonalDataManager::Observer implementation. void AutoFillProfilesView::OnPersonalDataLoaded() { personal_data_manager_->RemoveObserver(this); GetData(); - scroll_view_->RebuildView(); + FocusedItem focused_item_index(ScrollViewContents::kAddAddressButton, 0); + if (profiles_set_.size() + credit_card_set_.size() > 0) { + focused_item_index = FocusedItem(0, EditableSetViewContents::kLabelText); + } + + scroll_view_->RebuildView(focused_item_index); } ///////////////////////////////////////////////////////////////////////////// @@ -283,6 +310,9 @@ void AutoFillProfilesView::Init() { layout->StartRow(1, single_column_view_set_id); layout->AddView(scroll_view_); ValidateAndFixLabel(); + focus_manager_ = GetFocusManager(); + DCHECK(focus_manager_); + focus_manager_->AddFocusChangeListener(this); } void AutoFillProfilesView::GetData() { @@ -290,19 +320,22 @@ void AutoFillProfilesView::GetData() { personal_data_manager_->SetObserver(this); return; } + bool first_item = true; // first item must be opened. profiles_set_.reserve(personal_data_manager_->profiles().size()); for (std::vector<AutoFillProfile*>::const_iterator address_it = personal_data_manager_->profiles().begin(); address_it != personal_data_manager_->profiles().end(); ++address_it) { - profiles_set_.push_back(EditableSetInfo(*address_it, false)); + profiles_set_.push_back(EditableSetInfo(*address_it, first_item)); + first_item = false; } credit_card_set_.reserve(personal_data_manager_->credit_cards().size()); for (std::vector<CreditCard*>::const_iterator cc_it = personal_data_manager_->credit_cards().begin(); cc_it != personal_data_manager_->credit_cards().end(); ++cc_it) { - credit_card_set_.push_back(EditableSetInfo(*cc_it, false)); + credit_card_set_.push_back(EditableSetInfo(*cc_it, first_item)); + first_item = false; } } @@ -442,6 +475,44 @@ AutoFillProfilesView::EditableSetViewContents::EditableSetViewContents( ZeroMemory(text_fields_, sizeof(text_fields_)); } +// Two helpers to set focus correctly during rebuild of list view. +int AutoFillProfilesView::EditableSetViewContents::GetFocusedControlIndex( + const views::View* focus) const { + DCHECK(focus); + if (static_cast<const views::View*>(expand_item_button_) == focus) + return 0; + if (static_cast<const views::View*>(combo_box_billing_) == focus) + return 1; + if (static_cast<const views::View*>(combo_box_shipping_) == focus) + return 2; + if (static_cast<const views::View*>(delete_button_) == focus) + return 3; + for (int i = 0; i < MAX_TEXT_FIELD; ++i) { + if (static_cast<const views::View*>(text_fields_[i]) == focus) + return i + 4; + } + return AutoFillProfilesView::kNoItemFocused; +} + +views::View* AutoFillProfilesView::EditableSetViewContents::GetFocusedControl( + int index) { + if (index == 0 || index == AutoFillProfilesView::kNoItemFocused || + !editable_fields_set_->is_opened) { + return expand_item_button_; + } + switch (index) { + case 1: + return combo_box_billing_; + case 2: + return combo_box_shipping_; + case 3: + return delete_button_; + default: + DCHECK(index - 4 < MAX_TEXT_FIELD); + return text_fields_[index - 4]; + } +} + ///////////////////////////////////////////////////////////////////////////// // AutoFillProfilesView::EditableSetViewContents, protected: ///////////////////////////////////////////////////////////////////////////// @@ -591,7 +662,7 @@ void AutoFillProfilesView::EditableSetViewContents::InitTitle( } expand_item_button_ = new views::ImageButton(this); ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - SkBitmap *image = NULL; + SkBitmap* image = NULL; if (editable_fields_set_->is_opened) { image = rb.GetBitmapNamed(ThemeResourcesUtil::GetId("expand_arrow_down_icon")); @@ -603,6 +674,7 @@ void AutoFillProfilesView::EditableSetViewContents::InitTitle( expand_item_button_->SetImage(views::CustomButton::BS_NORMAL, image); expand_item_button_->SetImageAlignment(views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE); + expand_item_button_->SetFocusable(true); title_label_ = new views::Label(title); gfx::Font title_font = rb.GetFont(ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD); @@ -708,13 +780,13 @@ void AutoFillProfilesView::EditableSetViewContents::InitAddressFields( layout->AddView(text_fields_[TEXT_ADDRESS_ZIP]); layout->AddView(text_fields_[TEXT_ADDRESS_COUNTRY]); - PhoneSubView *phone = new PhoneSubView( + PhoneSubView* phone = new PhoneSubView( CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_PHONE), text_fields_[TEXT_PHONE_COUNTRY], text_fields_[TEXT_PHONE_AREA], text_fields_[TEXT_PHONE_PHONE]); - PhoneSubView *fax = new PhoneSubView( + PhoneSubView* fax = new PhoneSubView( CreateLeftAlignedLabel(IDS_AUTOFILL_DIALOG_FAX), text_fields_[TEXT_FAX_COUNTRY], text_fields_[TEXT_FAX_AREA], @@ -912,14 +984,14 @@ void AutoFillProfilesView::AddressComboBoxModel::set_address_labels( } void AutoFillProfilesView::AddressComboBoxModel::UsedWithComboBox( - views::Combobox *combo_box) { + views::Combobox* combo_box) { DCHECK(address_labels_); combo_boxes_.push_back(combo_box); } void AutoFillProfilesView::AddressComboBoxModel::LabelChanged() { DCHECK(address_labels_); - for (std::list<views::Combobox *>::iterator it = combo_boxes_.begin(); + for (std::list<views::Combobox*>::iterator it = combo_boxes_.begin(); it != combo_boxes_.end(); ++it) (*it)->ModelChanged(); @@ -972,6 +1044,44 @@ AutoFillProfilesView::ScrollViewContents::ScrollViewContents( shipping_model_(false) { } +AutoFillProfilesView::FocusedItem +AutoFillProfilesView::ScrollViewContents::GetFocusedControlIndex( + const views::View* focus) const { + if (static_cast<const views::View*>(add_address_) == focus) + return FocusedItem(kAddAddressButton, 0); + if (static_cast<const views::View*>(add_credit_card_) == focus) + return FocusedItem(kAddCcButton, 0); + for (size_t i = 0; i < editable_contents_.size(); ++i) { + int index = editable_contents_[i]->GetFocusedControlIndex(focus); + if (index != AutoFillProfilesView::kNoItemFocused) + return FocusedItem(i, index); + } + return FocusedItem(); +} + +views::View* AutoFillProfilesView::ScrollViewContents::GetFocusedControl( + const AutoFillProfilesView::FocusedItem& index) { + if (index.group == AutoFillProfilesView::kNoItemFocused) + return add_address_; + switch (index.group) { + case kAddAddressButton: + return add_address_; + case kAddCcButton: + return add_credit_card_; + default: + DCHECK(index.group < static_cast<int>(editable_contents_.size())); + DCHECK(index.group >= 0); + return editable_contents_[index.group]->GetFocusedControl( + index.item); + } +} + +views::View* AutoFillProfilesView::ScrollViewContents::GetGroup( + int group_index) { + DCHECK(static_cast<size_t>(group_index) < editable_contents_.size()); + return static_cast<views::View*>(editable_contents_[group_index]); +} + ///////////////////////////////////////////////////////////////////////////// // AutoFillProfilesView::ScrollViewContents, protected: ///////////////////////////////////////////////////////////////////////////// @@ -1053,7 +1163,7 @@ void AutoFillProfilesView::ScrollViewContents::Init() { layout->AddColumnSet(single_column_filled_view_set_id_full_width); column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1, views::GridLayout::USE_PREF, 0, 0); - views::Label *title_label = new views::Label( + views::Label* title_label = new views::Label( l10n_util::GetString(IDS_AUTOFILL_ADDRESSES_GROUP_NAME)); ResourceBundle& rb = ResourceBundle::GetSharedInstance(); gfx::Font title_font = @@ -1066,15 +1176,16 @@ void AutoFillProfilesView::ScrollViewContents::Init() { layout->AddView(new views::Separator); layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); - + editable_contents_.reserve(profiles_->size() + credit_cards_->size()); std::vector<EditableSetInfo>::iterator it; for (it = profiles_->begin(); it != profiles_->end(); ++it) { - EditableSetViewContents *address_view = + EditableSetViewContents* address_view = new EditableSetViewContents(observer_, &billing_model_, &shipping_model_, it); layout->StartRow(0, single_column_filled_view_set_id); layout->AddView(address_view); layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + editable_contents_.push_back(address_view); } billing_model_.set_address_labels(profiles_); @@ -1097,12 +1208,13 @@ void AutoFillProfilesView::ScrollViewContents::Init() { layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); for (it = credit_cards_->begin(); it != credit_cards_->end(); ++it) { - EditableSetViewContents *address_view = + EditableSetViewContents* cc_view = new EditableSetViewContents(observer_, &billing_model_, &shipping_model_, it); layout->StartRow(0, single_column_filled_view_set_id); - layout->AddView(address_view); + layout->AddView(cc_view); layout->AddPaddingRow(0, kRelatedControlVerticalSpacing); + editable_contents_.push_back(cc_view); } add_credit_card_ = new views::NativeButton(this, @@ -1131,17 +1243,38 @@ AutoFillProfilesView::AutoFillScrollView::AutoFillScrollView( set_background(new ListBackground()); } -void AutoFillProfilesView::AutoFillScrollView::RebuildView() { +void AutoFillProfilesView::AutoFillScrollView::RebuildView( + const AutoFillProfilesView::FocusedItem& new_focus_index) { + AutoFillProfilesView::FocusedItem focus_index(new_focus_index); gfx::Rect visible_rectangle = scroll_view_->GetVisibleRect(); + if (focus_index.group == AutoFillProfilesView::kNoItemFocused && + GetFocusManager()) { + // Save focus and restore it later. + focus_index = scroll_contents_view_->GetFocusedControlIndex( + GetFocusManager()->GetFocusedView()); + } + scroll_contents_view_ = new ScrollViewContents(observer_, profiles_, credit_cards_); // Deletes the old contents view and takes ownership of // |scroll_contents_view_|. scroll_view_->SetContents(scroll_contents_view_); + if (focus_index.group != AutoFillProfilesView::kNoItemFocused) { + views::View* view = scroll_contents_view_->GetFocusedControl(focus_index); + if (view && GetFocusManager()) { + GetFocusManager()->SetFocusedView(view); + } + } scroll_contents_view_->ScrollRectToVisible(visible_rectangle); } +void AutoFillProfilesView::AutoFillScrollView::EnsureGroupOnScreen( + int group_index) { + views::View* group = scroll_contents_view_->GetGroup(group_index); + + group->ScrollRectToVisible(gfx::Rect(group->width(), group->height())); +} ///////////////////////////////////////////////////////////////////////////// // AutoFillProfilesView::AutoFillScrollView, views::View implementations |