diff options
-rw-r--r-- | chrome/app/chromium_strings.grd | 3 | ||||
-rw-r--r-- | chrome/app/generated_resources.grd | 19 | ||||
-rw-r--r-- | chrome/app/google_chrome_strings.grd | 3 | ||||
-rw-r--r-- | chrome/app/resources/locale_settings.grd | 5 | ||||
-rw-r--r-- | chrome/browser/ui/views/default_search_view.cc | 282 | ||||
-rw-r--r-- | chrome/browser/ui/views/default_search_view.h | 59 |
6 files changed, 301 insertions, 70 deletions
diff --git a/chrome/app/chromium_strings.grd b/chrome/app/chromium_strings.grd index 001e26d..c622a61 100644 --- a/chrome/app/chromium_strings.grd +++ b/chrome/app/chromium_strings.grd @@ -418,9 +418,6 @@ be available for now. --> <message name="IDS_DEFAULT_BROWSER_INFOBAR_SHORT_TEXT" desc="More compact text to show in the default browser query infobar."> Chromium isn't your default browser. </message> - <message name="IDS_DEFAULT_SEARCH_PROMPT" desc="The message displayed when javascript has asked to change the default search engine. This appears in a message box."> - Would you like to make <ph name="HOST">$1<ex>www.bing.com</ex></ph> your search engine in Chromium? - </message> <!-- Try Chrome Toast Dialog --> <message name="IDS_TRY_TOAST_HEADING" desc="Top line of the try-chrome-again dialog"> There is a new version of Chromium available. diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 9be6fb7..ffb8948 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -1205,15 +1205,24 @@ each locale. --> <ph name="ENGINE_NAME">$1<ex>Google</ex></ph> (Default) </message> - <message name="IDS_DEFAULT_SEARCH_PROMPT_TITLE" desc="The title of the default search engine dialog. This dialog asks if the user would like a new default search engine."> + <message name="IDS_DEFAULT_SEARCH_TITLE" desc="The title of the default search engine dialog. This dialog asks if the user would like to set a new default search engine."> Change Default Search Engine </message> - <message name="IDS_DEFAULT_SEARCH_PROMPT_OK" desc="The button which accepts a new default search engine. Displayed in the default search engine message box."> - Change it + <message name="IDS_DEFAULT_SEARCH_SUMMARY" desc="Text at the top of the dialog to explain why the dialog is displayed. Displayed in the default search engine dialog."> + <ph name="ENGINE_HOST_NAME">$1<ex>google.com</ex></ph> wants to be your search engine. + </message> + <message name="IDS_DEFAULT_SEARCH_LABEL_CURRENT" desc="The text above the button which keeps the current search engine. Displayed in the default search engine dialog."> + Current search engine: </message> - <message name="IDS_DEFAULT_SEARCH_PROMPT_CANCEL" desc="The button which rejects a new default search engine. Displayed in the default search engine message box."> - No, thanks + <message name="IDS_DEFAULT_SEARCH_LABEL_PROPOSED" desc="The text above the button which accepts a new default search engine. Displayed in the default search engine dialog."> + New search engine: + </message> + <message name="IDS_DEFAULT_SEARCH_PROMPT_PROPOSED" desc="The text below the button which accepts a new default search engine. Displayed in the default search engine dialog."> + Change to <ph name="ENGINE_NAME">$1<ex>Google</ex></ph> + </message> + <message name="IDS_DEFAULT_SEARCH_PROMPT_CURRENT" desc="The text below the button which keeps the current search engine. Displayed in the default search engine dialog."> + Keep using <ph name="ENGINE_NAME">$1<ex>Google</ex></ph> </message> <message name="IDS_TIME_SECS_DEFAULT" diff --git a/chrome/app/google_chrome_strings.grd b/chrome/app/google_chrome_strings.grd index 4da3d44..21545cd4 100644 --- a/chrome/app/google_chrome_strings.grd +++ b/chrome/app/google_chrome_strings.grd @@ -468,9 +468,6 @@ Chrome supports. --> <message name="IDS_DEFAULT_BROWSER_INFOBAR_SHORT_TEXT" desc="More compact text to show in the default browser query infobar."> Google Chrome isn't your default browser. </message> - <message name="IDS_DEFAULT_SEARCH_PROMPT" desc="The message displayed when javascript has asked to change the default search engine. This appears in a message box."> - Would you like to make <ph name="HOST">$1<ex>www.bing.com</ex></ph> your search engine in Google Chrome? - </message> <!-- Try Chrome Toast Dialog --> <message name="IDS_TRY_TOAST_HEADING" desc="Top line of the try-chrome-again dialog"> There is a new version of Google Chrome available. diff --git a/chrome/app/resources/locale_settings.grd b/chrome/app/resources/locale_settings.grd index 3e5fa8a..c7853c5 100644 --- a/chrome/app/resources/locale_settings.grd +++ b/chrome/app/resources/locale_settings.grd @@ -710,6 +710,11 @@ 14 </message> </if> + + <!-- The width of the default search engine dialog in characters --> + <message name="IDS_DEFAULT_SEARCH_WIDTH_CHARS" use_name_for_id="true"> + 82 + </message> </messages> </release> </grit> diff --git a/chrome/browser/ui/views/default_search_view.cc b/chrome/browser/ui/views/default_search_view.cc index a90461f..d57ffc4 100644 --- a/chrome/browser/ui/views/default_search_view.cc +++ b/chrome/browser/ui/views/default_search_view.cc @@ -8,13 +8,104 @@ #include "app/l10n_util.h" #include "app/message_box_flags.h" +#include "app/resource_bundle.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" +#include "chrome/browser/search_engines/template_url_prepopulate_data.h" #include "chrome/browser/tab_contents/tab_contents.h" -#include "grit/chromium_strings.h" +#include "gfx/canvas.h" #include "grit/generated_resources.h" -#include "views/controls/message_box_view.h" +#include "grit/locale_settings.h" +#include "grit/theme_resources.h" +#include "views/controls/button/native_button.h" +#include "views/controls/image_view.h" +#include "views/controls/label.h" +#include "views/grid_layout.h" +#include "views/standard_layout.h" +#include "views/window/dialog_client_view.h" +#include "views/window/window.h" + +namespace { + +// Returns a short name and logo resource id for the given host. +void GetShortNameAndLogoId(PrefService* prefs, + const TemplateURL* turl, + std::wstring* short_name, + int* logo_id) { + DCHECK(prefs); + DCHECK(turl); + DCHECK(short_name); + DCHECK(logo_id); + + GURL url = TemplateURLModel::GenerateSearchURL(turl); + scoped_ptr<TemplateURL> built_in_data( + TemplateURLPrepopulateData::GetEngineForOrigin(prefs, url)); + + // Use the built-in information to generate the short name (to ensure + // that we don't use a name given by the search engine to itself which + // in the worst case could be misleading). + if (built_in_data.get()) { + *short_name = built_in_data->short_name(); + *logo_id = built_in_data->logo_id(); + } else { + *short_name = UTF8ToWide(url.host()).c_str(); + *logo_id = kNoSearchEngineLogo; + } +} + +views::Label* CreateProviderLabel(int message_id) { + views::Label* choice_label = + new views::Label(l10n_util::GetString(message_id)); + choice_label->SetColor(SK_ColorBLACK); + choice_label->SetFont( + choice_label->font().DeriveFont(1, gfx::Font::NORMAL)); + return choice_label; +} + +views::View* CreateProviderLogo( + int logo_id, + const std::wstring& short_name) { + views::View* logo_view = NULL; + + // The width for the "logo" element when text is displayed. + const int kTextLogoWidth = 132; + + bool use_images = false; +#if defined(GOOGLE_CHROME_BUILD) + use_images = true; +#endif + + if (use_images && logo_id != kNoSearchEngineLogo) { + views::ImageView* logo_image = new views::ImageView(); + SkBitmap* logo_bmp = + ResourceBundle::GetSharedInstance().GetBitmapNamed(logo_id); + logo_image->SetImage(logo_bmp); + logo_image->SetTooltipText(short_name); + logo_view = logo_image; + } else { + // No logo -- show a text label. + views::Label* logo_label = new views::Label(short_name); + logo_label->SetColor(SK_ColorDKGRAY); + logo_label->SetFont(logo_label->font().DeriveFont(3, gfx::Font::BOLD)); + logo_label->SetHorizontalAlignment(views::Label::ALIGN_CENTER); + // Tooltip text provides accessibility for low-vision users. + logo_label->SetTooltipText(short_name); + logo_view = logo_label; + } + + return logo_view; +} +views::NativeButton* CreateProviderChoiceButton( + views::ButtonListener* listener, + int message_id, + const std::wstring& short_name) { + return new views::NativeButton(listener, l10n_util::GetStringF( + message_id, short_name)); +} + +} // namespace // static void DefaultSearchView::Show(TabContents* tab_contents, @@ -30,74 +121,181 @@ void DefaultSearchView::Show(TabContents* tab_contents, template_url_model); } -std::wstring DefaultSearchView::GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const { - switch (button) { - case MessageBoxFlags::DIALOGBUTTON_OK: - return l10n_util::GetString(IDS_DEFAULT_SEARCH_PROMPT_OK); - - case MessageBoxFlags::DIALOGBUTTON_CANCEL: - return l10n_util::GetString(IDS_DEFAULT_SEARCH_PROMPT_CANCEL); +DefaultSearchView::~DefaultSearchView() { +} - case MessageBoxFlags::DIALOGBUTTON_NONE: - NOTREACHED(); - break; - } +void DefaultSearchView::Paint(gfx::Canvas* canvas) { + // Fill in behind the background image with the standard gray toolbar color. + canvas->FillRectInt(SkColorSetRGB(237, 238, 237), 0, 0, width(), + background_image_->height()); + // The rest of the dialog background should be white. + DCHECK(height() > background_image_->height()); + canvas->FillRectInt(SK_ColorWHITE, 0, background_image_->height(), width(), + height() - background_image_->height()); +} - NOTREACHED(); - return std::wstring(); +void DefaultSearchView::ButtonPressed(views::Button* sender, + const views::Event& event) { + views::DialogClientView* client = GetDialogClientView(); + if (sender == proposed_provider_button_) + client->AcceptWindow(); + else + client->CancelWindow(); } std::wstring DefaultSearchView::GetWindowTitle() const { - return l10n_util::GetString(IDS_DEFAULT_SEARCH_PROMPT_TITLE); + return l10n_util::GetString(IDS_DEFAULT_SEARCH_TITLE); } -void DefaultSearchView::DeleteDelegate() { - delete this; +views::View* DefaultSearchView::GetInitiallyFocusedView() { + return default_provider_button_; } views::View* DefaultSearchView::GetContentsView() { - return message_box_view_; + return this; } -int DefaultSearchView::GetDefaultDialogButton() const { - // To less the likelihood of an accidental default search engine change, make - // the cancel button the default dialog button. - return MessageBoxFlags::DIALOGBUTTON_CANCEL; +int DefaultSearchView::GetDialogButtons() const { + return MessageBoxFlags::DIALOGBUTTON_NONE; } bool DefaultSearchView::Accept() { // Check this again in case the default became managed while this dialog was // displayed. - if (!template_url_model_->CanMakeDefault(default_url_.get())) + TemplateURL* set_as_default = proposed_turl_.get(); + if (!template_url_model_->CanMakeDefault(set_as_default)) return true; - TemplateURL* set_as_default = default_url_.get(); - template_url_model_->Add(default_url_.release()); + template_url_model_->Add(proposed_turl_.release()); template_url_model_->SetDefaultSearchProvider(set_as_default); return true; } DefaultSearchView::DefaultSearchView(TabContents* tab_contents, - TemplateURL* default_url, + TemplateURL* proposed_default_turl, TemplateURLModel* template_url_model) - : default_url_(default_url), + : background_image_(NULL), + default_provider_button_(NULL), + proposed_provider_button_(NULL), + proposed_turl_(proposed_default_turl), template_url_model_(template_url_model) { - const int kDialogWidth = 420; - - // Also deleted when the window closes. - message_box_view_ = new MessageBoxView( - 0, - l10n_util::GetStringF(IDS_DEFAULT_SEARCH_PROMPT, - DefaultHostName()), - std::wstring(), - kDialogWidth); + PrefService* prefs = tab_contents->profile()->GetPrefs(); + SetupControls(prefs); + + // Show the dialog. tab_contents->CreateConstrainedDialog(this); } -DefaultSearchView::~DefaultSearchView() { -} +void DefaultSearchView::SetupControls(PrefService* prefs) { + using views::ColumnSet; + using views::GridLayout; + using views::ImageView; + using views::Label; + + // Column set id's. + const int kWholeDialogViewSetId = 0; + const int kPaddedWholeDialogViewSetId = 1; + const int kChoicesViewSetId = 2; + + // Set up the information for the proposed default. + std::wstring proposed_short_name; + int proposed_logo_id = kNoSearchEngineLogo; + GetShortNameAndLogoId(prefs, + proposed_turl_.get(), + &proposed_short_name, + &proposed_logo_id); + if (proposed_logo_id != kNoSearchEngineLogo) + proposed_turl_->set_logo_id(proposed_logo_id); + + + // Set up the information for the current default. + std::wstring default_short_name; + int default_logo_id = kNoSearchEngineLogo; + GetShortNameAndLogoId(prefs, + template_url_model_->GetDefaultSearchProvider(), + &default_short_name, + &default_logo_id); + + // Now set-up the dialog contents. + GridLayout* layout = new views::GridLayout(this); + layout->SetInsets(0, 0, kPanelVertMargin, 0); + SetLayoutManager(layout); + + // Add a column set that spans the whole dialog. + ColumnSet* whole_dialog_column_set = + layout->AddColumnSet(kWholeDialogViewSetId); + whole_dialog_column_set->AddColumn(GridLayout::LEADING, GridLayout::LEADING, + 1, GridLayout::FIXED, + views::Window::GetLocalizedContentsWidth( + IDS_DEFAULT_SEARCH_WIDTH_CHARS), + 0); + + // Add a column set that spans the whole dialog but obeying padding. + ColumnSet* padded_whole_dialog_column_set = + layout->AddColumnSet(kPaddedWholeDialogViewSetId); + padded_whole_dialog_column_set->AddPaddingColumn(1, kPanelVertMargin); + padded_whole_dialog_column_set->AddColumn( + GridLayout::LEADING, GridLayout::LEADING, + 1, GridLayout::USE_PREF, 0, 0); + padded_whole_dialog_column_set->AddPaddingColumn(1, kPanelVertMargin); + + // Add a column set for the search engine choices. + ColumnSet* choices_column_set = layout->AddColumnSet(kChoicesViewSetId); + choices_column_set->AddPaddingColumn(1, kPanelVertMargin); + choices_column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, + 1, GridLayout::USE_PREF, 0, 0); + choices_column_set->AddPaddingColumn(1, kRelatedControlHorizontalSpacing); + choices_column_set->AddColumn(GridLayout::CENTER, GridLayout::CENTER, + 1, GridLayout::USE_PREF, 0, 0); + choices_column_set->LinkColumnSizes(0, 2, -1); + choices_column_set->AddPaddingColumn(1, kPanelVertMargin); + + // Add the "search box" image. + layout->StartRow(0, kWholeDialogViewSetId); + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + background_image_ = new ImageView(); + background_image_->SetImage(rb.GetBitmapNamed(IDR_SEARCH_ENGINE_DIALOG_TOP)); + background_image_->EnableCanvasFlippingForRTLUI(true); + ImageView::Alignment horizontal_alignment = + base::i18n::IsRTL() ? ImageView::LEADING : ImageView::TRAILING; + background_image_->SetHorizontalAlignment(horizontal_alignment); + layout->AddView(background_image_); + + // Add text informing the user about the requested default change. + layout->StartRowWithPadding(0, kPaddedWholeDialogViewSetId, + 1, kLabelToControlVerticalSpacing); + Label* summary_label = new Label(l10n_util::GetStringF( + IDS_DEFAULT_SEARCH_SUMMARY, + proposed_short_name)); + summary_label->SetColor(SK_ColorBLACK); + summary_label->SetFont( + summary_label->font().DeriveFont(1, gfx::Font::NORMAL)); + summary_label->SetHorizontalAlignment(Label::ALIGN_LEFT); + layout->AddView(summary_label); + + // Add the labels for the tops of the choices. + layout->StartRowWithPadding(0, kChoicesViewSetId, + 0, kRelatedControlVerticalSpacing); + layout->AddView(CreateProviderLabel(IDS_DEFAULT_SEARCH_LABEL_CURRENT)); + layout->AddView(CreateProviderLabel(IDS_DEFAULT_SEARCH_LABEL_PROPOSED)); + + // Add the logos. + layout->StartRowWithPadding(0, kChoicesViewSetId, + 0, kRelatedControlVerticalSpacing); + layout->AddView(CreateProviderLogo(default_logo_id, default_short_name)); + layout->AddView(CreateProviderLogo(proposed_logo_id, proposed_short_name)); -string16 DefaultSearchView::DefaultHostName() const { - return UTF8ToUTF16(default_url_->url()->GetHost()); + // Add the buttons. + layout->StartRowWithPadding(0, kChoicesViewSetId, + 0, kRelatedControlVerticalSpacing); + default_provider_button_ = CreateProviderChoiceButton( + this, + IDS_DEFAULT_SEARCH_PROMPT_CURRENT, + default_short_name); + layout->AddView(default_provider_button_); + proposed_provider_button_ = CreateProviderChoiceButton( + this, + IDS_DEFAULT_SEARCH_PROMPT_PROPOSED, + proposed_short_name); + layout->AddView(proposed_provider_button_); } diff --git a/chrome/browser/ui/views/default_search_view.h b/chrome/browser/ui/views/default_search_view.h index c4ad70f..607bca69 100644 --- a/chrome/browser/ui/views/default_search_view.h +++ b/chrome/browser/ui/views/default_search_view.h @@ -16,48 +16,73 @@ #include "chrome/browser/gtk/constrained_window_gtk.h" #endif -class MessageBoxView; +class PrefService; class TabContents; class TemplateURL; class TemplateURLModel; +namespace gfx { +class Canvas; +} + namespace views { +class Button; +class ImageView; +class Label; class View; } -// This class is responsible for displaying the contents of the default search +// Responsible for displaying the contents of the default search // prompt for when InstallSearchProvider(url, true) is called. -class DefaultSearchView : public ConstrainedDialogDelegate { +class DefaultSearchView + : public views::View, + public views::ButtonListener, + public ConstrainedDialogDelegate { public: + // Takes ownership of |proposed_default_turl|. static void Show(TabContents* tab_contents, - TemplateURL* default_url, + TemplateURL* , TemplateURLModel* template_url_model); + virtual ~DefaultSearchView(); + protected: + // Overridden from views::View: + // Draws the gray background at the top of the dialog. + virtual void Paint(gfx::Canvas* canvas); + + // Overridden from views::ButtonListener: + virtual void ButtonPressed(views::Button* sender, const views::Event& event); + // ConstrainedDialogDelegate: - virtual std::wstring GetDialogButtonLabel( - MessageBoxFlags::DialogButton button) const; virtual std::wstring GetWindowTitle() const; - virtual void DeleteDelegate(); + virtual views::View* GetInitiallyFocusedView(); virtual views::View* GetContentsView(); - virtual int GetDefaultDialogButton() const; + virtual int GetDialogButtons() const; virtual bool Accept(); private: + // Takes ownership of |proposed_default_turl|. DefaultSearchView(TabContents* tab_contents, - TemplateURL* default_url, + TemplateURL* proposed_default_turl, TemplateURLModel* template_url_model); - ~DefaultSearchView(); - // The host name for the possible default search provider. - string16 DefaultHostName() const; + // Initializes the labels and controls in the view. + void SetupControls(PrefService* prefs); - // The possible new default url. - scoped_ptr<TemplateURL> default_url_; - TemplateURLModel* template_url_model_; + // Image of browser search box with grey background and bubble arrow. + views::ImageView* background_image_; + + // Button for the current default search engine. + views::View* default_provider_button_; + + // Button for the newly proposed search engine. + views::View* proposed_provider_button_; - // The message box view whose commands we handle. - MessageBoxView* message_box_view_; + // The proposed new default search engine. + scoped_ptr<TemplateURL> proposed_turl_; + + TemplateURLModel* template_url_model_; DISALLOW_COPY_AND_ASSIGN(DefaultSearchView); }; |