Index: chrome/browser/ui/views/first_run_search_engine_view.cc |
=================================================================== |
--- chrome/browser/ui/views/first_run_search_engine_view.cc (revision 104959) |
+++ chrome/browser/ui/views/first_run_search_engine_view.cc (working copy) |
@@ -19,6 +19,7 @@ |
#include "chrome/browser/search_engines/template_url.h" |
#include "chrome/browser/search_engines/template_url_service.h" |
#include "chrome/browser/search_engines/template_url_service_factory.h" |
+#include "chrome/browser/themes/theme_service.h" |
#include "grit/chromium_strings.h" |
#include "grit/generated_resources.h" |
#include "grit/google_chrome_strings.h" |
@@ -103,7 +104,8 @@ |
} else { |
// No logo -- we must show a text label. |
views::Label* logo_label = new views::Label(search_engine_->short_name()); |
- logo_label->SetColor(SK_ColorDKGRAY); |
+ logo_label->SetBackgroundColor(SK_ColorWHITE); |
+ logo_label->SetEnabledColor(SK_ColorDKGRAY); |
logo_label->SetFont(logo_label->font().DeriveFont(3, gfx::Font::BOLD)); |
logo_label->SetHorizontalAlignment(views::Label::ALIGN_CENTER); |
logo_label->SetTooltipText(WideToUTF16Hack(search_engine_->short_name())); |
@@ -140,30 +142,27 @@ |
choice_view_->SetBounds(x, y, width, height); |
} |
-FirstRunSearchEngineView::FirstRunSearchEngineView( |
- Profile* profile, bool randomize) |
+FirstRunSearchEngineView::FirstRunSearchEngineView(Profile* profile, |
+ bool randomize) |
: background_image_(NULL), |
- profile_(profile), |
+ template_url_service_(TemplateURLServiceFactory::GetForProfile(profile)), |
text_direction_is_rtl_(base::i18n::IsRTL()), |
+ template_url_service_loaded_(false), |
+ added_to_view_hierarchy_(false), |
randomize_(randomize) { |
// Don't show ourselves until all the search engines have loaded from |
// the profile -- otherwise we have nothing to show. |
SetVisible(false); |
// Start loading the search engines for the given profile. |
- search_engines_model_ = TemplateURLServiceFactory::GetForProfile(profile_); |
- if (search_engines_model_) { |
- DCHECK(!search_engines_model_->loaded()); |
- search_engines_model_->AddObserver(this); |
- search_engines_model_->Load(); |
- } else { |
- NOTREACHED(); |
- } |
- SetupControls(); |
+ DCHECK(template_url_service_); |
+ DCHECK(!template_url_service_->loaded()); |
+ template_url_service_->AddObserver(this); |
+ template_url_service_->Load(); |
} |
FirstRunSearchEngineView::~FirstRunSearchEngineView() { |
- search_engines_model_->RemoveObserver(this); |
+ template_url_service_->RemoveObserver(this); |
} |
string16 FirstRunSearchEngineView::GetWindowTitle() const { |
@@ -173,21 +172,19 @@ |
void FirstRunSearchEngineView::ButtonPressed(views::Button* sender, |
const views::Event& event) { |
SearchEngineChoice* choice = static_cast<SearchEngineChoice*>(sender); |
- TemplateURLService* template_url_service = |
- TemplateURLServiceFactory::GetForProfile(profile_); |
- DCHECK(template_url_service); |
- template_url_service->SetSearchEngineDialogSlot(choice->slot()); |
+ DCHECK(template_url_service_); |
+ template_url_service_->SetSearchEngineDialogSlot(choice->slot()); |
const TemplateURL* default_search = choice->GetSearchEngine(); |
if (default_search) |
- template_url_service->SetDefaultSearchProvider(default_search); |
+ template_url_service_->SetDefaultSearchProvider(default_search); |
MessageLoop::current()->Quit(); |
} |
void FirstRunSearchEngineView::OnPaint(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()); |
+ canvas->FillRectInt(GetThemeProvider()->GetColor(ThemeService::COLOR_TOOLBAR), |
+ 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(), |
@@ -195,108 +192,12 @@ |
} |
void FirstRunSearchEngineView::OnTemplateURLServiceChanged() { |
- using views::ImageView; |
- |
// We only watch the search engine model change once, on load. Remove |
// observer so we don't try to redraw if engines change under us. |
- search_engines_model_->RemoveObserver(this); |
+ template_url_service_->RemoveObserver(this); |
- // Add search engines in search_engines_model_ to buttons list. The |
- // first three will always be from prepopulated data. |
- std::vector<const TemplateURL*> template_urls = |
- search_engines_model_->GetTemplateURLs(); |
- |
- // If we have fewer than two search engines, end search engine dialog |
- // immediately, leaving imported default search engine setting intact. |
- if (template_urls.size() < 2) { |
- MessageLoop::current()->Quit(); |
- return; |
- } |
- |
- std::vector<const TemplateURL*>::iterator search_engine_iter; |
- |
- // Is user's default search engine included in first three prepopulated |
- // set? If not, we need to expand the dialog to include a fourth engine. |
- const TemplateURL* default_search_engine = |
- search_engines_model_->GetDefaultSearchProvider(); |
- // If the user's default choice is not in the first three search engines |
- // in template_urls, store it in |default_choice| and provide it as a |
- // fourth option. |
- SearchEngineChoice* default_choice = NULL; |
- |
- // First, see if we have 4 logos to show (in which case we use small logos). |
- // We show 4 logos when the default search engine the user has chosen is |
- // not one of the first three prepopulated engines. |
- if (template_urls.size() > 3) { |
- for (search_engine_iter = template_urls.begin() + 3; |
- search_engine_iter != template_urls.end(); |
- ++search_engine_iter) { |
- if (default_search_engine == *search_engine_iter) { |
- default_choice = new SearchEngineChoice(this, *search_engine_iter, |
- true); |
- } |
- } |
- } |
- |
- // Now that we know what size the logos should be, create new search engine |
- // choices for the view. If there are 2 search engines, only show 2 |
- // choices; for 3 or more, show 3 (unless the default is not one of the |
- // top 3, in which case show 4). |
- for (search_engine_iter = template_urls.begin(); |
- search_engine_iter < template_urls.begin() + |
- (template_urls.size() < 3 ? 2 : 3); |
- ++search_engine_iter) { |
- // Push first three engines into buttons: |
- SearchEngineChoice* choice = new SearchEngineChoice(this, |
- *search_engine_iter, default_choice != NULL); |
- search_engine_choices_.push_back(choice); |
- AddChildView(choice->GetView()); // The logo or text view. |
- AddChildView(choice); // The button associated with the choice. |
- } |
- // Push the default choice to the fourth position. |
- if (default_choice) { |
- search_engine_choices_.push_back(default_choice); |
- AddChildView(default_choice->GetView()); // The logo or text view. |
- AddChildView(default_choice); // The button associated with the choice. |
- } |
- |
- // Randomize order of logos if option has been set. |
- if (randomize_) { |
- std::random_shuffle(search_engine_choices_.begin(), |
- search_engine_choices_.end(), |
- base::RandGenerator); |
- // Assign to each choice the position in which it is shown on the screen. |
- std::vector<SearchEngineChoice*>::iterator it; |
- int slot = 0; |
- for (it = search_engine_choices_.begin(); |
- it != search_engine_choices_.end(); |
- it++) { |
- (*it)->set_slot(slot++); |
- } |
- } |
- |
- // Now that we know how many logos to show, lay out and become visible. |
- SetVisible(true); |
- Layout(); |
- SchedulePaint(); |
- |
- // If the widget has detected that a screenreader is running, change the |
- // button names from "Choose" to the name of the search engine. This works |
- // around a bug that JAWS ignores the accessible name of a native button. |
- if (GetWidget() && GetWidget()->IsAccessibleWidget()) { |
- std::vector<SearchEngineChoice*>::iterator it; |
- for (it = search_engine_choices_.begin(); |
- it != search_engine_choices_.end(); |
- it++) { |
- (*it)->SetText((*it)->GetSearchEngine()->short_name()); |
- } |
- } |
- |
- // This will tell screenreaders that they should read the full text |
- // of this dialog to the user now (rather than waiting for the user |
- // to explore it). |
- GetWidget()->NotifyAccessibilityEvent( |
- this, ui::AccessibilityTypes::EVENT_ALERT, true); |
+ template_url_service_loaded_ = true; |
+ AddSearchEnginesIfPossible(); |
} |
gfx::Size FirstRunSearchEngineView::GetPreferredSize() { |
@@ -305,46 +206,6 @@ |
IDS_FIRSTRUN_SEARCH_ENGINE_SELECTION_HEIGHT_LINES); |
} |
-void FirstRunSearchEngineView::SetupControls() { |
- using views::Background; |
- using views::ImageView; |
- using views::Label; |
- |
- ResourceBundle& rb = ResourceBundle::GetSharedInstance(); |
- background_image_ = new views::ImageView(); |
- background_image_->SetImage(rb.GetBitmapNamed(IDR_SEARCH_ENGINE_DIALOG_TOP)); |
- background_image_->EnableCanvasFlippingForRTLUI(true); |
- if (text_direction_is_rtl_) { |
- background_image_->SetHorizontalAlignment(ImageView::LEADING); |
- } else { |
- background_image_->SetHorizontalAlignment(ImageView::TRAILING); |
- } |
- |
- AddChildView(background_image_); |
- |
- int label_width = GetPreferredSize().width() - 2 * views::kPanelHorizMargin; |
- |
- // Add title and text asking the user to choose a search engine: |
- title_label_ = new Label(l10n_util::GetStringUTF16( |
- IDS_FR_SEARCH_MAIN_LABEL)); |
- title_label_->SetColor(SK_ColorBLACK); |
- title_label_->SetFont(title_label_->font().DeriveFont(3, gfx::Font::BOLD)); |
- title_label_->SetMultiLine(true); |
- title_label_->SetHorizontalAlignment(Label::ALIGN_LEFT); |
- title_label_->SizeToFit(label_width); |
- AddChildView(title_label_); |
- |
- text_label_ = new Label(l10n_util::GetStringFUTF16( |
- IDS_FR_SEARCH_TEXT, |
- l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); |
- text_label_->SetColor(SK_ColorBLACK); |
- text_label_->SetFont(text_label_->font().DeriveFont(1, gfx::Font::NORMAL)); |
- text_label_->SetMultiLine(true); |
- text_label_->SetHorizontalAlignment(Label::ALIGN_LEFT); |
- text_label_->SizeToFit(label_width); |
- AddChildView(text_label_); |
-} |
- |
void FirstRunSearchEngineView::Layout() { |
// Disable the close button. |
GetWidget()->EnableClose(false); |
@@ -457,7 +318,154 @@ |
} // if (search_engine_choices.size() > 0) |
} |
+void FirstRunSearchEngineView::ViewHierarchyChanged(bool is_add, |
+ View* parent, |
+ View* child) { |
+ View::ViewHierarchyChanged(is_add, parent, child); |
+ |
+ if (is_add && (child == this)) { |
+ background_image_ = new views::ImageView(); |
+ background_image_->SetImage( |
+ ResourceBundle::GetSharedInstance().GetBitmapNamed( |
+ IDR_SEARCH_ENGINE_DIALOG_TOP)); |
+ background_image_->EnableCanvasFlippingForRTLUI(true); |
+ background_image_->SetHorizontalAlignment(text_direction_is_rtl_ ? |
+ views::ImageView::LEADING : views::ImageView::TRAILING); |
+ |
+ AddChildView(background_image_); |
+ |
+ int label_width = GetPreferredSize().width() - 2 * views::kPanelHorizMargin; |
+ |
+ // Add title and text asking the user to choose a search engine: |
+ title_label_ = new views::Label(l10n_util::GetStringUTF16( |
+ IDS_FR_SEARCH_MAIN_LABEL)); |
+ title_label_->SetBackgroundColor( |
+ GetThemeProvider()->GetColor(ThemeService::COLOR_TOOLBAR)); |
+ title_label_->SetEnabledColor(SK_ColorBLACK); |
+ title_label_->SetFont(title_label_->font().DeriveFont(3, gfx::Font::BOLD)); |
+ title_label_->SetMultiLine(true); |
+ title_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
+ title_label_->SizeToFit(label_width); |
+ AddChildView(title_label_); |
+ |
+ text_label_ = new views::Label(l10n_util::GetStringFUTF16( |
+ IDS_FR_SEARCH_TEXT, l10n_util::GetStringUTF16(IDS_PRODUCT_NAME))); |
+ text_label_->SetBackgroundColor(SK_ColorWHITE); |
+ text_label_->SetEnabledColor(SK_ColorBLACK); |
+ text_label_->SetFont(text_label_->font().DeriveFont(1, gfx::Font::NORMAL)); |
+ text_label_->SetMultiLine(true); |
+ text_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); |
+ text_label_->SizeToFit(label_width); |
+ AddChildView(text_label_); |
+ |
+ added_to_view_hierarchy_ = true; |
+ AddSearchEnginesIfPossible(); |
+ } |
+} |
+ |
void FirstRunSearchEngineView::GetAccessibleState( |
ui::AccessibleViewState* state) { |
state->role = ui::AccessibilityTypes::ROLE_ALERT; |
} |
+ |
+void FirstRunSearchEngineView::AddSearchEnginesIfPossible() { |
+ if (!template_url_service_loaded_ || !added_to_view_hierarchy_) |
+ return; |
+ |
+ // Add search engines in template_url_service_ to buttons list. The |
+ // first three will always be from prepopulated data. |
+ std::vector<const TemplateURL*> template_urls = |
+ template_url_service_->GetTemplateURLs(); |
+ |
+ // If we have fewer than two search engines, end search engine dialog |
+ // immediately, leaving imported default search engine setting intact. |
+ if (template_urls.size() < 2) { |
+ MessageLoop::current()->Quit(); |
+ return; |
+ } |
+ |
+ std::vector<const TemplateURL*>::iterator search_engine_iter; |
+ |
+ // Is user's default search engine included in first three prepopulated |
+ // set? If not, we need to expand the dialog to include a fourth engine. |
+ const TemplateURL* default_search_engine = |
+ template_url_service_->GetDefaultSearchProvider(); |
+ // If the user's default choice is not in the first three search engines |
+ // in template_urls, store it in |default_choice| and provide it as a |
+ // fourth option. |
+ SearchEngineChoice* default_choice = NULL; |
+ |
+ // First, see if we have 4 logos to show (in which case we use small logos). |
+ // We show 4 logos when the default search engine the user has chosen is |
+ // not one of the first three prepopulated engines. |
+ if (template_urls.size() > 3) { |
+ for (search_engine_iter = template_urls.begin() + 3; |
+ search_engine_iter != template_urls.end(); |
+ ++search_engine_iter) { |
+ if (default_search_engine == *search_engine_iter) { |
+ default_choice = new SearchEngineChoice(this, *search_engine_iter, |
+ true); |
+ } |
+ } |
+ } |
+ |
+ // Now that we know what size the logos should be, create new search engine |
+ // choices for the view. If there are 2 search engines, only show 2 |
+ // choices; for 3 or more, show 3 (unless the default is not one of the |
+ // top 3, in which case show 4). |
+ for (search_engine_iter = template_urls.begin(); |
+ search_engine_iter < template_urls.begin() + |
+ (template_urls.size() < 3 ? 2 : 3); |
+ ++search_engine_iter) { |
+ // Push first three engines into buttons: |
+ SearchEngineChoice* choice = new SearchEngineChoice(this, |
+ *search_engine_iter, default_choice != NULL); |
+ search_engine_choices_.push_back(choice); |
+ AddChildView(choice->GetView()); // The logo or text view. |
+ AddChildView(choice); // The button associated with the choice. |
+ } |
+ // Push the default choice to the fourth position. |
+ if (default_choice) { |
+ search_engine_choices_.push_back(default_choice); |
+ AddChildView(default_choice->GetView()); // The logo or text view. |
+ AddChildView(default_choice); // The button associated with the choice. |
+ } |
+ |
+ // Randomize order of logos if option has been set. |
+ if (randomize_) { |
+ std::random_shuffle(search_engine_choices_.begin(), |
+ search_engine_choices_.end(), |
+ base::RandGenerator); |
+ // Assign to each choice the position in which it is shown on the screen. |
+ std::vector<SearchEngineChoice*>::iterator it; |
+ int slot = 0; |
+ for (it = search_engine_choices_.begin(); |
+ it != search_engine_choices_.end(); |
+ it++) { |
+ (*it)->set_slot(slot++); |
+ } |
+ } |
+ |
+ // Now that we know how many logos to show, lay out and become visible. |
+ SetVisible(true); |
+ Layout(); |
+ SchedulePaint(); |
+ |
+ // If the widget has detected that a screenreader is running, change the |
+ // button names from "Choose" to the name of the search engine. This works |
+ // around a bug that JAWS ignores the accessible name of a native button. |
+ if (GetWidget() && GetWidget()->IsAccessibleWidget()) { |
+ std::vector<SearchEngineChoice*>::iterator it; |
+ for (it = search_engine_choices_.begin(); |
+ it != search_engine_choices_.end(); |
+ it++) { |
+ (*it)->SetText((*it)->GetSearchEngine()->short_name()); |
+ } |
+ } |
+ |
+ // This will tell screenreaders that they should read the full text |
+ // of this dialog to the user now (rather than waiting for the user |
+ // to explore it). |
+ GetWidget()->NotifyAccessibilityEvent( |
+ this, ui::AccessibilityTypes::EVENT_ALERT, true); |
+} |