diff --git a/chrome/browser/autocomplete/autocomplete_edit_unittest.cc b/chrome/browser/autocomplete/autocomplete_edit_unittest.cc index 7dedb984f0f331..73c8ae9ff7c31b 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_unittest.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_unittest.cc @@ -55,6 +55,15 @@ class TestingAutocompleteEditView : public AutocompleteEditView { virtual gfx::NativeView GetNativeView() const { return 0; } virtual CommandUpdater* GetCommandUpdater() { return NULL; } +#if defined(TOOLKIT_VIEWS) + virtual views::View* AddToView(views::View* parent) { return NULL; } + virtual int TextWidth() const { return 0; } + virtual bool CommitInstantSuggestion( + const std::wstring& typed_text, + const std::wstring& suggested_text) { return false;} + virtual void SetInstantSuggestion(const string16& input) {} +#endif + private: DISALLOW_COPY_AND_ASSIGN(TestingAutocompleteEditView); }; diff --git a/chrome/browser/autocomplete/autocomplete_edit_view.h b/chrome/browser/autocomplete/autocomplete_edit_view.h index 439b2edce7b6cb..12c42a239ac2dc 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view.h @@ -24,6 +24,12 @@ class CommandUpdater; class GURL; class TabContents; +#if defined(TOOLKIT_VIEWS) +namespace views { +class View; +} // namespace views +#endif + class AutocompleteEditView { public: // Used by the automation system for getting at the model from the view. @@ -152,7 +158,23 @@ class AutocompleteEditView { // Returns the command updater for this view. virtual CommandUpdater* GetCommandUpdater() = 0; - protected: +#if defined(TOOLKIT_VIEWS) + // Adds the autocomplete edit view to view hierarchy and + // returns the views::View of the edit view. + virtual views::View* AddToView(views::View* parent) = 0; + + // Commits the suggested text. + virtual bool CommitInstantSuggestion(const std::wstring& typed_text, + const std::wstring& suggested_text) = 0; + + // Shows the instant suggestion text. + virtual void SetInstantSuggestion(const string16& input) = 0; + + // Returns the width in pixels needed to display the current text. The + // returned value includes margins. + virtual int TextWidth() const = 0; +#endif + virtual ~AutocompleteEditView() {} }; diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc index 3f435a326455fa..4de3d2ca03bd61 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc @@ -38,12 +38,14 @@ #include "ui/base/animation/multi_animation.h" #if defined(TOOLKIT_VIEWS) -#include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" -#include "chrome/browser/views/location_bar/location_bar_view.h" +#include "chrome/browser/gtk/accessible_widget_helper_gtk.h" +#include "chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_view.h" +#include "chrome/browser/ui/views/location_bar/location_bar_view.h" #else #include "chrome/browser/autocomplete/autocomplete_popup_view_gtk.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/location_bar_view_gtk.h" +#include "views/controls/native/native_view_host.h" #endif namespace { @@ -418,44 +420,6 @@ void AutocompleteEditViewGtk::SetFocus() { gtk_widget_grab_focus(text_view_); } -int AutocompleteEditViewGtk::TextWidth() { - int horizontal_border_size = - gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), - GTK_TEXT_WINDOW_LEFT) + - gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), - GTK_TEXT_WINDOW_RIGHT) + - gtk_text_view_get_left_margin(GTK_TEXT_VIEW(text_view_)) + - gtk_text_view_get_right_margin(GTK_TEXT_VIEW(text_view_)); - - GtkTextIter start, end; - GdkRectangle first_char_bounds, last_char_bounds; - gtk_text_buffer_get_start_iter(text_buffer_, &start); - - // Use the real end iterator here to take the width of instant suggestion - // text into account, so that location bar can layout its children correctly. - gtk_text_buffer_get_end_iter(text_buffer_, &end); - gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view_), - &start, &first_char_bounds); - gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view_), - &end, &last_char_bounds); - - gint first_char_start = first_char_bounds.x; - gint first_char_end = first_char_start + first_char_bounds.width; - gint last_char_start = last_char_bounds.x; - gint last_char_end = last_char_start + last_char_bounds.width; - - // bounds width could be negative for RTL text. - if (first_char_start > first_char_end) - std::swap(first_char_start, first_char_end); - if (last_char_start > last_char_end) - std::swap(last_char_start, last_char_end); - - gint text_width = first_char_start < last_char_start ? - last_char_end - first_char_start : first_char_end - last_char_start; - - return text_width + horizontal_border_size; -} - int AutocompleteEditViewGtk::WidthOfTextAfterCursor() { // Not used. return -1; @@ -790,6 +754,102 @@ CommandUpdater* AutocompleteEditViewGtk::GetCommandUpdater() { return command_updater_; } +#if defined(TOOLKIT_VIEWS) +views::View* AutocompleteEditViewGtk::AddToView(views::View* parent) { + views::NativeViewHost* host = new views::NativeViewHost; + parent->AddChildView(host); + host->set_focus_view(parent); + host->Attach(GetNativeView()); + return host; +} + +bool AutocompleteEditViewGtk::CommitInstantSuggestion( + const std::wstring& typed_text, + const std::wstring& suggestion) { + return CommitInstantSuggestion(); +} + +void AutocompleteEditViewGtk::EnableAccessibility() { + accessible_widget_helper_.reset( + new AccessibleWidgetHelper(text_view(), model_->profile())); + accessible_widget_helper_->SetWidgetName( + text_view(), l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION)); +} + +void AutocompleteEditViewGtk::SetInstantSuggestion(const string16& suggestion) { + SetInstantSuggestion(UTF16ToUTF8(suggestion)); +} +#endif + +int AutocompleteEditViewGtk::TextWidth() const { + int horizontal_border_size = + gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), + GTK_TEXT_WINDOW_LEFT) + + gtk_text_view_get_border_window_size(GTK_TEXT_VIEW(text_view_), + GTK_TEXT_WINDOW_RIGHT) + + gtk_text_view_get_left_margin(GTK_TEXT_VIEW(text_view_)) + + gtk_text_view_get_right_margin(GTK_TEXT_VIEW(text_view_)); + + GtkTextIter start, end; + GdkRectangle first_char_bounds, last_char_bounds; + gtk_text_buffer_get_start_iter(text_buffer_, &start); + + // Use the real end iterator here to take the width of instant suggestion + // text into account, so that location bar can layout its children correctly. + gtk_text_buffer_get_end_iter(text_buffer_, &end); + gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view_), + &start, &first_char_bounds); + gtk_text_view_get_iter_location(GTK_TEXT_VIEW(text_view_), + &end, &last_char_bounds); + + gint first_char_start = first_char_bounds.x; + gint first_char_end = first_char_start + first_char_bounds.width; + gint last_char_start = last_char_bounds.x; + gint last_char_end = last_char_start + last_char_bounds.width; + + // bounds width could be negative for RTL text. + if (first_char_start > first_char_end) + std::swap(first_char_start, first_char_end); + if (last_char_start > last_char_end) + std::swap(last_char_start, last_char_end); + + gint text_width = first_char_start < last_char_start ? + last_char_end - first_char_start : first_char_end - last_char_start; + + return text_width + horizontal_border_size; +} + +#if defined(TOOLKIT_VIEWS) +// static +AutocompleteEditView* AutocompleteEditViewGtk::Create( + AutocompleteEditController* controller, + ToolbarModel* toolbar_model, + Profile* profile, + CommandUpdater* command_updater, + bool popup_window_mode, + const views::View* location_bar) { + AutocompleteEditViewGtk* autocomplete = + new AutocompleteEditViewGtk(controller, + toolbar_model, + profile, + command_updater, + popup_window_mode, + location_bar); + autocomplete->Init(); + + // Make all the children of the widget visible. NOTE: this won't display + // anything, it just toggles the visible flag. + gtk_widget_show_all(autocomplete->GetNativeView()); + // Hide the widget. NativeViewHostGtk will make it visible again as + // necessary. + gtk_widget_hide(autocomplete->GetNativeView()); + + autocomplete->EnableAccessibility(); + + return autocomplete; +} +#endif + void AutocompleteEditViewGtk::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h index 9e45db641ba91b..2397d2617b265c 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h @@ -26,6 +26,7 @@ #include "ui/base/animation/animation_delegate.h" #include "webkit/glue/window_open_disposition.h" +class AccessibleWidgetHelper; class AutocompleteEditController; class AutocompleteEditModel; class AutocompletePopupView; @@ -74,19 +75,15 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, CommandUpdater* command_updater, bool popup_window_mode, #if defined(TOOLKIT_VIEWS) - const views::View* location_bar); + const views::View* location_bar #else - GtkWidget* location_bar); + GtkWidget* location_bar #endif - ~AutocompleteEditViewGtk(); + ); + virtual ~AutocompleteEditViewGtk(); // Initialize, create the underlying widgets, etc. void Init(); - - // Returns the width in pixels needed to display the current text. The - // returned value includes margins. - int TextWidth(); - // Returns the width in pixels needed to display the text from one character // before the caret to the end of the string. See comments in // LocationBarView::Layout as to why this uses -1. @@ -146,6 +143,27 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, virtual bool OnAfterPossibleChange(); virtual gfx::NativeView GetNativeView() const; virtual CommandUpdater* GetCommandUpdater(); +#if defined(TOOLKIT_VIEWS) + virtual views::View* AddToView(views::View* parent); + virtual bool CommitInstantSuggestion(const std::wstring& typed_text, + const std::wstring& suggested_text); + virtual void SetInstantSuggestion(const string16& suggestion); + + // Enables accessibility on AutocompleteEditView. + void EnableAccessibility(); + + // A factory method to create an AutocompleteEditView instance initialized for + // linux_views. This currently returns an instance of + // AutocompleteEditViewGtk only, but AutocompleteEditViewViews will + // be added as an option when TextfieldViews is enabled. + static AutocompleteEditView* Create(AutocompleteEditController* controller, + ToolbarModel* toolbar_model, + Profile* profile, + CommandUpdater* command_updater, + bool popup_window_mode, + const views::View* location_bar); +#endif + virtual int TextWidth() const; // Overridden from NotificationObserver: virtual void Observe(NotificationType type, @@ -517,6 +535,10 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, GtkSignalRegistrar signals_; +#if defined(TOOLKIT_VIEWS) + scoped_ptr accessible_widget_helper_; +#endif + DISALLOW_COPY_AND_ASSIGN(AutocompleteEditViewGtk); }; diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index cc2a486e323997..df2a8ba4eba28d 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -498,10 +498,6 @@ AutocompleteEditViewWin::~AutocompleteEditViewWin() { g_paint_patcher.Pointer()->DerefPatch(); } -int AutocompleteEditViewWin::TextWidth() { - return WidthNeededToDisplay(GetText()); -} - int AutocompleteEditViewWin::WidthOfTextAfterCursor() { CHARRANGE selection; GetSelection(selection); @@ -913,6 +909,30 @@ CommandUpdater* AutocompleteEditViewWin::GetCommandUpdater() { return command_updater_; } +views::View* AutocompleteEditViewWin::AddToView(views::View* parent) { + views::NativeViewHost* host = new views::NativeViewHost; + parent->AddChildView(host); + host->set_focus_view(parent); + host->Attach(GetNativeView()); + return host; +} + +bool AutocompleteEditViewWin::CommitInstantSuggestion( + const std::wstring& typed_text, + const std::wstring& suggested_text) { + model_->FinalizeInstantQuery(typed_text, suggested_text); + return true; +} + +void AutocompleteEditViewWin::SetInstantSuggestion(const string16& suggestion) { + // Win shows the suggestion in LocationBarView. + NOTREACHED(); +} + +int AutocompleteEditViewWin::TextWidth() const { + return WidthNeededToDisplay(GetText()); +} + void AutocompleteEditViewWin::PasteAndGo(const std::wstring& text) { if (CanPasteAndGo(text)) model_->PasteAndGo(); @@ -2570,7 +2590,7 @@ void AutocompleteEditViewWin::TrackMousePosition(MouseButton button, } } -int AutocompleteEditViewWin::GetHorizontalMargin() { +int AutocompleteEditViewWin::GetHorizontalMargin() const { RECT rect; GetRect(&rect); RECT client_rect; @@ -2578,7 +2598,8 @@ int AutocompleteEditViewWin::GetHorizontalMargin() { return (rect.left - client_rect.left) + (client_rect.right - rect.right); } -int AutocompleteEditViewWin::WidthNeededToDisplay(const std::wstring& text) { +int AutocompleteEditViewWin::WidthNeededToDisplay( + const std::wstring& text) const { // Use font_.GetStringWidth() instead of // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is // apparently buggy. In both LTR UI and RTL UI with left-to-right layout, diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h index 07738432eb1fb0..7fc56a9deccbe6 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h @@ -74,10 +74,6 @@ class AutocompleteEditViewWin views::View* parent_view() const { return parent_view_; } - // Returns the width in pixels needed to display the current text. The - // returned value includes margins. - int TextWidth(); - // Returns the width in pixels needed to display the text from one character // before the caret to the end of the string. See comments in // LocationBarView::Layout as to why this uses -1. @@ -137,6 +133,12 @@ class AutocompleteEditViewWin virtual bool OnAfterPossibleChange(); virtual gfx::NativeView GetNativeView() const; virtual CommandUpdater* GetCommandUpdater(); + virtual views::View* AddToView(views::View* parent); + virtual bool CommitInstantSuggestion(const std::wstring& typed_text, + const std::wstring& suggested_text); + virtual void SetInstantSuggestion(const string16& suggestion); + virtual int TextWidth() const; + int GetPopupMaxYCoordinate(); // Exposes custom IAccessible implementation to the overall MSAA hierarchy. @@ -401,10 +403,10 @@ class AutocompleteEditViewWin void TrackMousePosition(MouseButton button, const CPoint& point); // Returns the sum of the left and right margins. - int GetHorizontalMargin(); + int GetHorizontalMargin() const; // Returns the width in pixels needed to display |text|. - int WidthNeededToDisplay(const std::wstring& text); + int WidthNeededToDisplay(const std::wstring& text) const; scoped_ptr model_; diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.cc b/chrome/browser/ui/views/location_bar/location_bar_view.cc index 0067c66194883f..b5dad74241f545 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.cc +++ b/chrome/browser/ui/views/location_bar/location_bar_view.cc @@ -162,28 +162,14 @@ void LocationBarView::Init() { GetWidget()->GetNativeView(), profile_, command_updater_, mode_ == POPUP, this)); #else - location_entry_.reset(new AutocompleteEditViewGtk(this, model_, profile_, - command_updater_, mode_ == POPUP, this)); - location_entry_->Init(); - // Make all the children of the widget visible. NOTE: this won't display - // anything, it just toggles the visible flag. - gtk_widget_show_all(location_entry_->GetNativeView()); - // Hide the widget. NativeViewHostGtk will make it visible again as - // necessary. - gtk_widget_hide(location_entry_->GetNativeView()); - - // Associate an accessible name with the location entry. - accessible_widget_helper_.reset(new AccessibleWidgetHelper( - location_entry_->text_view(), profile_)); - accessible_widget_helper_->SetWidgetName( - location_entry_->text_view(), - l10n_util::GetStringUTF8(IDS_ACCNAME_LOCATION)); + location_entry_.reset( + AutocompleteEditViewGtk::Create( + this, model_, profile_, + command_updater_, mode_ == POPUP, this)); #endif - location_entry_view_ = new views::NativeViewHost; + + location_entry_view_ = location_entry_->AddToView(this); location_entry_view_->SetID(VIEW_ID_AUTOCOMPLETE); - AddChildView(location_entry_view_); - location_entry_view_->set_focus_view(this); - location_entry_view_->Attach(location_entry_->GetNativeView()); location_entry_view_->SetAccessibleName( UTF16ToWide(l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION))); @@ -785,17 +771,13 @@ bool LocationBarView::OnCommitSuggestedText(const std::wstring& typed_text) { InstantController* instant = delegate_->GetInstant(); if (!instant) return false; - + std::wstring suggestion; #if defined(OS_WIN) if (!HasValidSuggestText()) return false; - location_entry_->model()->FinalizeInstantQuery( - typed_text, - suggested_text_view_->GetText()); - return true; -#else - return location_entry_->CommitInstantSuggestion(); + suggestion = suggested_text_view_->GetText(); #endif + return location_entry_->CommitInstantSuggestion(typed_text, suggestion); } bool LocationBarView::AcceptCurrentInstantPreview() { @@ -847,9 +829,8 @@ void LocationBarView::OnAutocompleteAccept( } if (delegate_->GetInstant() && - !location_entry_->model()->popup_model()->IsOpen()) { + !location_entry_->model()->popup_model()->IsOpen()) delegate_->GetInstant()->DestroyPreviewContents(); - } update_instant_ = true; } @@ -1172,7 +1153,7 @@ void LocationBarView::SetSuggestedText(const string16& input) { Layout(); SchedulePaint(); #else - location_entry_->SetInstantSuggestion(UTF16ToUTF8(input)); + location_entry_->SetInstantSuggestion(input); #endif } diff --git a/chrome/browser/ui/views/location_bar/location_bar_view.h b/chrome/browser/ui/views/location_bar/location_bar_view.h index 317bd788dd3b00..1ffa5b19576e1e 100644 --- a/chrome/browser/ui/views/location_bar/location_bar_view.h +++ b/chrome/browser/ui/views/location_bar/location_bar_view.h @@ -25,9 +25,8 @@ #if defined(OS_WIN) #include "chrome/browser/autocomplete/autocomplete_edit_view_win.h" -#else +#elif defined(OS_LINUX) #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" -#include "chrome/browser/gtk/accessible_widget_helper_gtk.h" #endif class CommandUpdater; @@ -330,7 +329,7 @@ class LocationBarView : public LocationBar, #if defined(OS_WIN) scoped_ptr location_entry_; #else - scoped_ptr location_entry_; + scoped_ptr location_entry_; #endif // The CommandUpdater for the Browser object that corresponds to this View. @@ -364,8 +363,8 @@ class LocationBarView : public LocationBar, // A bubble displayed for EV HTTPS sites. EVBubbleView* ev_bubble_view_; - // Location_entry view wrapper - views::NativeViewHost* location_entry_view_; + // Location_entry view + views::View* location_entry_view_; // The following views are used to provide hints and remind the user as to // what is going in the edit. They are all added a children of the @@ -409,10 +408,6 @@ class LocationBarView : public LocationBar, // crash. TemplateURLModel* template_url_model_; -#if defined(OS_LINUX) - scoped_ptr accessible_widget_helper_; -#endif - // Should instant be updated? This is set to false in OnAutocompleteWillAccept // and true in OnAutocompleteAccept. This is needed as prior to accepting an // autocomplete suggestion the model is reverted which triggers resetting