Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(355)

Side by Side Diff: chrome/browser/autocomplete/autocomplete_edit_view_views.cc

Issue 6685082: Refactor Textfield and AutocompleteEditViewViews. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address review feedbacks. Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/autocomplete/autocomplete_edit_view_views.h" 5 #include "chrome/browser/autocomplete/autocomplete_edit_view_views.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "chrome/app/chrome_command_ids.h" 10 #include "chrome/app/chrome_command_ids.h"
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
114 CommandUpdater* command_updater, 114 CommandUpdater* command_updater,
115 bool popup_window_mode, 115 bool popup_window_mode,
116 const views::View* location_bar) 116 const views::View* location_bar)
117 : model_(new AutocompleteEditModel(this, controller, profile)), 117 : model_(new AutocompleteEditModel(this, controller, profile)),
118 popup_view_(CreatePopupView(profile, location_bar)), 118 popup_view_(CreatePopupView(profile, location_bar)),
119 controller_(controller), 119 controller_(controller),
120 toolbar_model_(toolbar_model), 120 toolbar_model_(toolbar_model),
121 command_updater_(command_updater), 121 command_updater_(command_updater),
122 popup_window_mode_(popup_window_mode), 122 popup_window_mode_(popup_window_mode),
123 security_level_(ToolbarModel::NONE), 123 security_level_(ToolbarModel::NONE),
124 delete_was_pressed_(false), 124 ime_composing_before_change_(false),
125 delete_at_end_pressed_(false) { 125 delete_at_end_pressed_(false) {
126 set_border(views::Border::CreateEmptyBorder(kAutocompleteVerticalMargin, 0, 126 set_border(views::Border::CreateEmptyBorder(kAutocompleteVerticalMargin, 0,
127 kAutocompleteVerticalMargin, 0)); 127 kAutocompleteVerticalMargin, 0));
128 } 128 }
129 129
130 AutocompleteEditViewViews::~AutocompleteEditViewViews() { 130 AutocompleteEditViewViews::~AutocompleteEditViewViews() {
131 NotificationService::current()->Notify( 131 NotificationService::current()->Notify(
132 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED, 132 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED,
133 Source<AutocompleteEditViewViews>(this), 133 Source<AutocompleteEditViewViews>(this),
134 NotificationService::NoDetails()); 134 NotificationService::NoDetails());
(...skipping 22 matching lines...) Expand all
157 } 157 }
158 158
159 void AutocompleteEditViewViews::SetBaseColor() { 159 void AutocompleteEditViewViews::SetBaseColor() {
160 // TODO(oshima): Implment style change. 160 // TODO(oshima): Implment style change.
161 NOTIMPLEMENTED(); 161 NOTIMPLEMENTED();
162 } 162 }
163 163
164 bool AutocompleteEditViewViews::HandleAfterKeyEvent( 164 bool AutocompleteEditViewViews::HandleAfterKeyEvent(
165 const views::KeyEvent& event, 165 const views::KeyEvent& event,
166 bool handled) { 166 bool handled) {
167 handling_key_press_ = false;
168 if (content_maybe_changed_by_key_press_)
169 OnAfterPossibleChange();
170
171 if (event.key_code() == ui::VKEY_RETURN) { 167 if (event.key_code() == ui::VKEY_RETURN) {
172 bool alt_held = event.IsAltDown(); 168 bool alt_held = event.IsAltDown();
173 model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); 169 model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
174 handled = true; 170 handled = true;
175 } else if (!handled && event.key_code() == ui::VKEY_ESCAPE) { 171 } else if (!handled && event.key_code() == ui::VKEY_ESCAPE) {
176 // We can handle the Escape key if textfield did not handle it. 172 // We can handle the Escape key if textfield did not handle it.
177 // If it's not handled by us, then we need to propagate it up to the parent 173 // If it's not handled by us, then we need to propagate it up to the parent
178 // widgets, so that Escape accelerator can still work. 174 // widgets, so that Escape accelerator can still work.
179 handled = model_->OnEscapeKeyPressed(); 175 handled = model_->OnEscapeKeyPressed();
180 } else if (event.key_code() == ui::VKEY_CONTROL) { 176 } else if (event.key_code() == ui::VKEY_CONTROL) {
181 // Omnibox2 can switch its contents while pressing a control key. To switch 177 // Omnibox2 can switch its contents while pressing a control key. To switch
182 // the contents of omnibox2, we notify the AutocompleteEditModel class when 178 // the contents of omnibox2, we notify the AutocompleteEditModel class when
183 // the control-key state is changed. 179 // the control-key state is changed.
184 model_->OnControlKeyChanged(true); 180 model_->OnControlKeyChanged(true);
185 } else if (!text_changed_ && event.key_code() == ui::VKEY_DELETE && 181 } else if (!handled && event.key_code() == ui::VKEY_DELETE &&
186 event.IsShiftDown()) { 182 event.IsShiftDown()) {
187 // If shift+del didn't change the text, we let this delete an entry from 183 // If shift+del didn't change the text, we let this delete an entry from
188 // the popup. We can't check to see if the IME handled it because even if 184 // the popup. We can't check to see if the IME handled it because even if
189 // nothing is selected, the IME or the TextView still report handling it. 185 // nothing is selected, the IME or the TextView still report handling it.
190 if (model_->popup_model()->IsOpen()) 186 if (model_->popup_model()->IsOpen())
191 model_->popup_model()->TryDeletingCurrentItem(); 187 model_->popup_model()->TryDeletingCurrentItem();
192 } else if (!handled && event.key_code() == ui::VKEY_UP) { 188 } else if (!handled && event.key_code() == ui::VKEY_UP) {
193 model_->OnUpOrDownKeyPressed(-1); 189 model_->OnUpOrDownKeyPressed(-1);
194 handled = true; 190 handled = true;
195 } else if (!handled && event.key_code() == ui::VKEY_DOWN) { 191 } else if (!handled && event.key_code() == ui::VKEY_DOWN) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 model_->OnWillKillFocus(NULL); 244 model_->OnWillKillFocus(NULL);
249 // Close the popup. 245 // Close the popup.
250 ClosePopup(); 246 ClosePopup();
251 // Tell the model to reset itself. 247 // Tell the model to reset itself.
252 model_->OnKillFocus(); 248 model_->OnKillFocus();
253 controller_->OnKillFocus(); 249 controller_->OnKillFocus();
254 } 250 }
255 251
256 //////////////////////////////////////////////////////////////////////////////// 252 ////////////////////////////////////////////////////////////////////////////////
257 // AutocompleteEditViewViews, views::View implementation: 253 // AutocompleteEditViewViews, views::View implementation:
258
259 bool AutocompleteEditViewViews::OnMousePressed(
260 const views::MouseEvent& event) {
261 if (event.IsLeftMouseButton()) {
262 // Button press event may change the selection, we need to record the change
263 // and report it to |model_| later when button is released.
264 OnBeforePossibleChange();
265 }
266 // Pass the event through to TextfieldViews.
267 return false;
268 }
269
270 void AutocompleteEditViewViews::Layout() { 254 void AutocompleteEditViewViews::Layout() {
271 gfx::Insets insets = GetInsets(); 255 gfx::Insets insets = GetInsets();
272 textfield_->SetBounds(insets.left(), insets.top(), 256 textfield_->SetBounds(insets.left(), insets.top(),
273 width() - insets.width(), 257 width() - insets.width(),
274 height() - insets.height()); 258 height() - insets.height());
275 } 259 }
276 260
277 void AutocompleteEditViewViews::GetAccessibleState( 261 void AutocompleteEditViewViews::GetAccessibleState(
278 ui::AccessibleViewState* state) { 262 ui::AccessibleViewState* state) {
279 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION); 263 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION);
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 455
472 void AutocompleteEditViewViews::OnRevertTemporaryText() { 456 void AutocompleteEditViewViews::OnRevertTemporaryText() {
473 textfield_->SelectRange(saved_temporary_selection_); 457 textfield_->SelectRange(saved_temporary_selection_);
474 TextChanged(); 458 TextChanged();
475 } 459 }
476 460
477 void AutocompleteEditViewViews::OnBeforePossibleChange() { 461 void AutocompleteEditViewViews::OnBeforePossibleChange() {
478 // Record our state. 462 // Record our state.
479 text_before_change_ = GetText(); 463 text_before_change_ = GetText();
480 textfield_->GetSelectedRange(&sel_before_change_); 464 textfield_->GetSelectedRange(&sel_before_change_);
465 ime_composing_before_change_ = textfield_->IsIMEComposing();
481 } 466 }
482 467
483 bool AutocompleteEditViewViews::OnAfterPossibleChange() { 468 bool AutocompleteEditViewViews::OnAfterPossibleChange() {
484 // OnAfterPossibleChange should be called once per modification,
485 // and we should ignore if this is called while a key event is being handled
486 // because OnAfterPossibleChagne will be called after the key event is
487 // actually handled.
488 if (handling_key_press_) {
489 content_maybe_changed_by_key_press_ = true;
490 return false;
491 }
492 ui::Range new_sel; 469 ui::Range new_sel;
493 textfield_->GetSelectedRange(&new_sel); 470 textfield_->GetSelectedRange(&new_sel);
494 471
495 size_t length = GetTextLength(); 472 size_t length = GetTextLength();
496 bool at_end_of_edit = (new_sel.start() == length && new_sel.end() == length); 473 bool at_end_of_edit = (new_sel.start() == length && new_sel.end() == length);
497 474
498 // See if the text or selection have changed since OnBeforePossibleChange(). 475 // See if the text or selection have changed since OnBeforePossibleChange().
499 string16 new_text = GetText(); 476 string16 new_text = GetText();
500 text_changed_ = (new_text != text_before_change_); 477 bool text_changed = (new_text != text_before_change_) ||
478 (ime_composing_before_change_ != textfield_->IsIMEComposing());
501 bool selection_differs = 479 bool selection_differs =
502 !((sel_before_change_.is_empty() && new_sel.is_empty()) || 480 !((sel_before_change_.is_empty() && new_sel.is_empty()) ||
503 sel_before_change_.EqualsIgnoringDirection(new_sel)); 481 sel_before_change_.EqualsIgnoringDirection(new_sel));
504 482
505 // When the user has deleted text, we don't allow inline autocomplete. Make 483 // When the user has deleted text, we don't allow inline autocomplete. Make
506 // sure to not flag cases like selecting part of the text and then pasting 484 // sure to not flag cases like selecting part of the text and then pasting
507 // (or typing) the prefix of that selection. (We detect these by making 485 // (or typing) the prefix of that selection. (We detect these by making
508 // sure the caret, which should be after any insertion, hasn't moved 486 // sure the caret, which should be after any insertion, hasn't moved
509 // forward of the old selection start.) 487 // forward of the old selection start.)
510 bool just_deleted_text = 488 bool just_deleted_text =
511 (text_before_change_.length() > new_text.length()) && 489 (text_before_change_.length() > new_text.length()) &&
512 (new_sel.start() <= sel_before_change_.GetMin()); 490 (new_sel.start() <= sel_before_change_.GetMin());
513 491
514 delete_at_end_pressed_ = false;
515
516 bool something_changed = model_->OnAfterPossibleChange(new_text, 492 bool something_changed = model_->OnAfterPossibleChange(new_text,
517 selection_differs, text_changed_, just_deleted_text, at_end_of_edit); 493 selection_differs, text_changed, just_deleted_text, at_end_of_edit);
518 494
519 // If only selection was changed, we don't need to call |model_|'s 495 // If only selection was changed, we don't need to call |model_|'s
520 // OnChanged() method, which is called in TextChanged(). 496 // OnChanged() method, which is called in TextChanged().
521 // But we still need to call EmphasizeURLComponents() to make sure the text 497 // But we still need to call EmphasizeURLComponents() to make sure the text
522 // attributes are updated correctly. 498 // attributes are updated correctly.
523 if (something_changed && text_changed_) { 499 if (something_changed && text_changed)
524 TextChanged(); 500 TextChanged();
525 } else if (selection_differs) { 501 else if (selection_differs)
526 EmphasizeURLComponents(); 502 EmphasizeURLComponents();
527 } else if (delete_was_pressed_ && at_end_of_edit) { 503 else if (delete_at_end_pressed_)
528 delete_at_end_pressed_ = true;
529 model_->OnChanged(); 504 model_->OnChanged();
530 }
531 delete_was_pressed_ = false;
532 505
533 return something_changed; 506 return something_changed;
534 } 507 }
535 508
536 gfx::NativeView AutocompleteEditViewViews::GetNativeView() const { 509 gfx::NativeView AutocompleteEditViewViews::GetNativeView() const {
537 return GetWidget()->GetNativeView(); 510 return GetWidget()->GetNativeView();
538 } 511 }
539 512
540 CommandUpdater* AutocompleteEditViewViews::GetCommandUpdater() { 513 CommandUpdater* AutocompleteEditViewViews::GetCommandUpdater() {
541 return command_updater_; 514 return command_updater_;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 const NotificationDetails& details) { 553 const NotificationDetails& details) {
581 DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); 554 DCHECK(type == NotificationType::BROWSER_THEME_CHANGED);
582 SetBaseColor(); 555 SetBaseColor();
583 } 556 }
584 557
585 //////////////////////////////////////////////////////////////////////////////// 558 ////////////////////////////////////////////////////////////////////////////////
586 // AutocompleteEditViewViews, views::TextfieldController implementation: 559 // AutocompleteEditViewViews, views::TextfieldController implementation:
587 560
588 void AutocompleteEditViewViews::ContentsChanged(views::Textfield* sender, 561 void AutocompleteEditViewViews::ContentsChanged(views::Textfield* sender,
589 const string16& new_contents) { 562 const string16& new_contents) {
590 if (handling_key_press_)
591 content_maybe_changed_by_key_press_ = true;
592 } 563 }
593 564
594 bool AutocompleteEditViewViews::HandleKeyEvent( 565 bool AutocompleteEditViewViews::HandleKeyEvent(
595 views::Textfield* textfield, 566 views::Textfield* textfield,
596 const views::KeyEvent& event) { 567 const views::KeyEvent& event) {
597 delete_was_pressed_ = event.key_code() == ui::VKEY_DELETE; 568 delete_at_end_pressed_ = false;
598
599 // Reset |text_changed_| before passing the key event on to the text view.
600 text_changed_ = false;
601 OnBeforePossibleChange();
602 handling_key_press_ = true;
603 content_maybe_changed_by_key_press_ = false;
604 569
605 if (event.key_code() == ui::VKEY_BACK) { 570 if (event.key_code() == ui::VKEY_BACK) {
606 // Checks if it's currently in keyword search mode. 571 // Checks if it's currently in keyword search mode.
607 if (model_->is_keyword_hint() || model_->keyword().empty()) 572 if (model_->is_keyword_hint() || model_->keyword().empty())
608 return false; 573 return false;
609 // If there is selection, let textfield handle the backspace. 574 // If there is selection, let textfield handle the backspace.
610 if (!textfield_->GetSelectedText().empty()) 575 if (textfield_->HasSelection())
611 return false; 576 return false;
612 // If not at the begining of the text, let textfield handle the backspace. 577 // If not at the begining of the text, let textfield handle the backspace.
613 if (textfield_->GetCursorPosition()) 578 if (textfield_->GetCursorPosition())
614 return false; 579 return false;
615 model_->ClearKeyword(GetText()); 580 model_->ClearKeyword(GetText());
616 return true; 581 return true;
617 } 582 }
618 583
584 if (event.key_code() == ui::VKEY_DELETE && !event.IsAltDown()) {
585 delete_at_end_pressed_ =
586 (!textfield_->HasSelection() &&
587 textfield_->GetCursorPosition() == textfield_->text().length());
588 }
589
619 return false; 590 return false;
620 } 591 }
621 592
593 void AutocompleteEditViewViews::OnBeforeUserAction(views::Textfield* sender) {
594 OnBeforePossibleChange();
595 }
596
597 void AutocompleteEditViewViews::OnAfterUserAction(views::Textfield* sender) {
598 OnAfterPossibleChange();
599 }
600
622 //////////////////////////////////////////////////////////////////////////////// 601 ////////////////////////////////////////////////////////////////////////////////
623 // AutocompleteEditViewViews, private: 602 // AutocompleteEditViewViews, private:
624 603
625 size_t AutocompleteEditViewViews::GetTextLength() const { 604 size_t AutocompleteEditViewViews::GetTextLength() const {
626 // TODO(oshima): Support instant, IME. 605 // TODO(oshima): Support instant, IME.
627 return textfield_->text().length(); 606 return textfield_->text().length();
628 } 607 }
629 608
630 void AutocompleteEditViewViews::EmphasizeURLComponents() { 609 void AutocompleteEditViewViews::EmphasizeURLComponents() {
631 // TODO(oshima): Update URL visual style 610 // TODO(oshima): Update URL visual style
(...skipping 26 matching lines...) Expand all
658 AutocompletePopupView* AutocompleteEditViewViews::CreatePopupView( 637 AutocompletePopupView* AutocompleteEditViewViews::CreatePopupView(
659 Profile* profile, 638 Profile* profile,
660 const View* location_bar) { 639 const View* location_bar) {
661 #if defined(TOUCH_UI) 640 #if defined(TOUCH_UI)
662 return new TouchAutocompletePopupContentsView( 641 return new TouchAutocompletePopupContentsView(
663 #else 642 #else
664 return new AutocompletePopupContentsView( 643 return new AutocompletePopupContentsView(
665 #endif 644 #endif
666 gfx::Font(), this, model_.get(), profile, location_bar); 645 gfx::Font(), this, model_.get(), profile, location_bar);
667 } 646 }
OLDNEW
« no previous file with comments | « chrome/browser/autocomplete/autocomplete_edit_view_views.h ('k') | views/controls/textfield/native_textfield_views.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698