| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/ui/gtk/web_intent_picker_gtk.h" | 5 #include "chrome/browser/ui/gtk/web_intent_picker_gtk.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/i18n/rtl.h" | 9 #include "base/i18n/rtl.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 11 #include "chrome/browser/favicon/favicon_service.h" | 11 #include "chrome/browser/favicon/favicon_service.h" |
| 12 #include "chrome/browser/profiles/profile.h" | 12 #include "chrome/browser/profiles/profile.h" |
| 13 #include "chrome/browser/ui/browser.h" | 13 #include "chrome/browser/ui/browser.h" |
| 14 #include "chrome/browser/ui/browser_window.h" | 14 #include "chrome/browser/ui/browser_window.h" |
| 15 #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h" | 15 #include "chrome/browser/ui/gtk/browser_toolbar_gtk.h" |
| 16 #include "chrome/browser/ui/gtk/browser_window_gtk.h" | 16 #include "chrome/browser/ui/gtk/browser_window_gtk.h" |
| 17 #include "chrome/browser/ui/gtk/custom_button.h" | 17 #include "chrome/browser/ui/gtk/custom_button.h" |
| 18 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" | 18 #include "chrome/browser/ui/gtk/gtk_chrome_link_button.h" |
| 19 #include "chrome/browser/ui/gtk/gtk_util.h" | 19 #include "chrome/browser/ui/gtk/gtk_util.h" |
| 20 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" | 20 #include "chrome/browser/ui/gtk/location_bar_view_gtk.h" |
| 21 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" | 21 #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h" |
| 22 #include "chrome/browser/ui/gtk/theme_service_gtk.h" | 22 #include "chrome/browser/ui/gtk/theme_service_gtk.h" |
| 23 #include "chrome/browser/ui/gtk/throbber_gtk.h" |
| 23 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" | 24 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" |
| 24 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" | 25 #include "chrome/browser/ui/intents/web_intent_picker_delegate.h" |
| 25 #include "chrome/browser/ui/intents/web_intent_picker_model.h" | 26 #include "chrome/browser/ui/intents/web_intent_picker_model.h" |
| 26 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" | 27 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" |
| 27 #include "chrome/common/chrome_notification_types.h" | 28 #include "chrome/common/chrome_notification_types.h" |
| 28 #include "content/public/browser/notification_source.h" | 29 #include "content/public/browser/notification_source.h" |
| 29 #include "content/public/browser/notification_types.h" | 30 #include "content/public/browser/notification_types.h" |
| 30 #include "content/public/browser/render_view_host.h" | 31 #include "content/public/browser/render_view_host.h" |
| 31 #include "content/public/browser/render_widget_host_view.h" | 32 #include "content/public/browser/render_widget_host_view.h" |
| 32 #include "content/public/browser/web_contents.h" | 33 #include "content/public/browser/web_contents.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 53 // The length in pixels of the label at the bottom of the picker. Text longer | 54 // The length in pixels of the label at the bottom of the picker. Text longer |
| 54 // than this width will wrap. | 55 // than this width will wrap. |
| 55 const int kWebStoreLabelLength = 400; | 56 const int kWebStoreLabelLength = 400; |
| 56 | 57 |
| 57 // The pixel size of the header label when using a non-native theme. | 58 // The pixel size of the header label when using a non-native theme. |
| 58 const int kHeaderLabelPixelSize = 15; | 59 const int kHeaderLabelPixelSize = 15; |
| 59 | 60 |
| 60 // The maximum width in pixels of a suggested extension's title link. | 61 // The maximum width in pixels of a suggested extension's title link. |
| 61 const int kTitleLinkMaxWidth = 130; | 62 const int kTitleLinkMaxWidth = 130; |
| 62 | 63 |
| 64 // Indices of the extension row widgets. |
| 65 enum { |
| 66 kIconIndex, |
| 67 kTitleLinkIndex, |
| 68 kStarsIndex, |
| 69 kInstallButtonIndex, |
| 70 }; |
| 71 |
| 63 ThemeServiceGtk *GetThemeService(TabContentsWrapper* wrapper) { | 72 ThemeServiceGtk *GetThemeService(TabContentsWrapper* wrapper) { |
| 64 return ThemeServiceGtk::GetFrom(wrapper->profile()); | 73 return ThemeServiceGtk::GetFrom(wrapper->profile()); |
| 65 } | 74 } |
| 66 | 75 |
| 67 // Set the image of |button| to |pixbuf|. | 76 // Set the image of |button| to |pixbuf|. |
| 68 void SetServiceButtonImage(GtkWidget* button, GdkPixbuf* pixbuf) { | 77 void SetServiceButtonImage(GtkWidget* button, GdkPixbuf* pixbuf) { |
| 69 gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf)); | 78 gtk_button_set_image(GTK_BUTTON(button), gtk_image_new_from_pixbuf(pixbuf)); |
| 70 gtk_button_set_image_position(GTK_BUTTON(button), GTK_POS_LEFT); | 79 gtk_button_set_image_position(GTK_BUTTON(button), GTK_POS_LEFT); |
| 71 } | 80 } |
| 72 | 81 |
| 73 // Get the index of the row containing |widget|. Assume the widget is the child | 82 // Get the index of the row containing |widget|. Assume the widget is the child |
| 74 // of an hbox, which is a child of a vbox. The hbox represents a row, and the | 83 // of an hbox, which is a child of a vbox. The hbox represents a row, and the |
| 75 // vbox the full table. | 84 // vbox the full table. |
| 76 size_t GetExtensionWidgetRow(GtkWidget* widget) { | 85 size_t GetExtensionWidgetRow(GtkWidget* widget) { |
| 77 GtkWidget* hbox = gtk_widget_get_parent(widget); | 86 GtkWidget* hbox = gtk_widget_get_parent(widget); |
| 78 DCHECK(hbox); | 87 DCHECK(hbox); |
| 79 GtkWidget* vbox = gtk_widget_get_parent(hbox); | 88 GtkWidget* vbox = gtk_widget_get_parent(hbox); |
| 80 DCHECK(vbox); | 89 DCHECK(vbox); |
| 81 GList* hbox_list = gtk_container_get_children(GTK_CONTAINER(vbox)); | 90 GList* hbox_list = gtk_container_get_children(GTK_CONTAINER(vbox)); |
| 82 gint index = g_list_index(hbox_list, hbox); | 91 gint index = g_list_index(hbox_list, hbox); |
| 83 DCHECK(index != -1); | 92 DCHECK(index != -1); |
| 84 | 93 |
| 85 return index; | 94 return index; |
| 86 } | 95 } |
| 87 | 96 |
| 97 // A gtk_container_foreach callback to enable/disable a widget. |
| 98 void EnableWidgetCallback(GtkWidget* widget, gpointer data) { |
| 99 gtk_widget_set_sensitive(widget, *static_cast<gboolean*>(data)); |
| 100 } |
| 101 |
| 88 } // namespace | 102 } // namespace |
| 89 | 103 |
| 90 // static | 104 // static |
| 91 WebIntentPicker* WebIntentPicker::Create(Browser* browser, | 105 WebIntentPicker* WebIntentPicker::Create(Browser* browser, |
| 92 TabContentsWrapper* wrapper, | 106 TabContentsWrapper* wrapper, |
| 93 WebIntentPickerDelegate* delegate, | 107 WebIntentPickerDelegate* delegate, |
| 94 WebIntentPickerModel* model) { | 108 WebIntentPickerModel* model) { |
| 95 return new WebIntentPickerGtk(browser, wrapper, delegate, model); | 109 return new WebIntentPickerGtk(browser, wrapper, delegate, model); |
| 96 } | 110 } |
| 97 | 111 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 128 | 142 |
| 129 WebIntentPickerGtk::~WebIntentPickerGtk() { | 143 WebIntentPickerGtk::~WebIntentPickerGtk() { |
| 130 } | 144 } |
| 131 | 145 |
| 132 void WebIntentPickerGtk::Close() { | 146 void WebIntentPickerGtk::Close() { |
| 133 window_->CloseConstrainedWindow(); | 147 window_->CloseConstrainedWindow(); |
| 134 if (inline_disposition_tab_contents_.get()) | 148 if (inline_disposition_tab_contents_.get()) |
| 135 inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); | 149 inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); |
| 136 } | 150 } |
| 137 | 151 |
| 152 void WebIntentPickerGtk::OnExtensionInstallSuccess(const std::string& id) { |
| 153 RemoveThrobber(); |
| 154 } |
| 155 |
| 156 void WebIntentPickerGtk::OnExtensionInstallFailure(const std::string& id) { |
| 157 // The throbber has an alignment as its parent, so it must be used instead of |
| 158 // the throbber to find the extension row. |
| 159 size_t index = |
| 160 GetExtensionWidgetRow(gtk_widget_get_parent(throbber_->widget())); |
| 161 GList* vbox_list = |
| 162 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); |
| 163 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); |
| 164 |
| 165 RemoveThrobber(); |
| 166 gtk_widget_show_all(hbox); |
| 167 SetWidgetsEnabled(true); |
| 168 } |
| 169 |
| 138 void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) { | 170 void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) { |
| 139 UpdateInstalledServices(); | 171 UpdateInstalledServices(); |
| 140 UpdateCWSLabel(); | 172 UpdateCWSLabel(); |
| 141 UpdateSuggestedExtensions(); | 173 UpdateSuggestedExtensions(); |
| 142 } | 174 } |
| 143 | 175 |
| 144 void WebIntentPickerGtk::OnFaviconChanged(WebIntentPickerModel* model, | 176 void WebIntentPickerGtk::OnFaviconChanged(WebIntentPickerModel* model, |
| 145 size_t index) { | 177 size_t index) { |
| 146 UpdateInstalledServices(); | 178 UpdateInstalledServices(); |
| 147 } | 179 } |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 GURL extension_url(extension_urls::GetWebstoreItemDetailURLPrefix() + | 286 GURL extension_url(extension_urls::GetWebstoreItemDetailURLPrefix() + |
| 255 UTF16ToUTF8(extension.id)); | 287 UTF16ToUTF8(extension.id)); |
| 256 browser::NavigateParams params(browser_, | 288 browser::NavigateParams params(browser_, |
| 257 extension_url, | 289 extension_url, |
| 258 content::PAGE_TRANSITION_AUTO_BOOKMARK); | 290 content::PAGE_TRANSITION_AUTO_BOOKMARK); |
| 259 params.disposition = NEW_FOREGROUND_TAB; | 291 params.disposition = NEW_FOREGROUND_TAB; |
| 260 browser::Navigate(¶ms); | 292 browser::Navigate(¶ms); |
| 261 } | 293 } |
| 262 | 294 |
| 263 void WebIntentPickerGtk::OnExtensionInstallButtonClick(GtkWidget* button) { | 295 void WebIntentPickerGtk::OnExtensionInstallButtonClick(GtkWidget* button) { |
| 264 // TODO(binji): Install the extension. | 296 size_t index = GetExtensionWidgetRow(button); |
| 297 const WebIntentPickerModel::SuggestedExtension& extension = |
| 298 model_->GetSuggestedExtensionAt(index); |
| 299 |
| 300 delegate_->OnExtensionInstallRequested(UTF16ToUTF8(extension.id)); |
| 301 SetWidgetsEnabled(false); |
| 302 |
| 303 // Re-enable the clicked extension row. |
| 304 GList* vbox_list = |
| 305 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); |
| 306 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); |
| 307 gtk_widget_set_sensitive(hbox, TRUE); |
| 308 |
| 309 // Hide the install button. |
| 310 GList* hbox_list = gtk_container_get_children(GTK_CONTAINER(hbox)); |
| 311 GtkWidget* install_button = |
| 312 static_cast<GtkWidget*>(g_list_nth_data(hbox_list, kInstallButtonIndex)); |
| 313 GtkAllocation allocation; |
| 314 gtk_widget_get_allocation(install_button, &allocation); |
| 315 gtk_widget_hide(install_button); |
| 316 |
| 317 // Show the throbber with the same size as the install button. |
| 318 GtkWidget* throbber = AddThrobberToExtensionAt(index); |
| 319 gtk_widget_set_size_request(throbber, allocation.width, allocation.height); |
| 320 gtk_widget_show_all(throbber); |
| 265 } | 321 } |
| 266 | 322 |
| 267 void WebIntentPickerGtk::OnMoreSuggestionsLinkClick(GtkWidget* link) { | 323 void WebIntentPickerGtk::OnMoreSuggestionsLinkClick(GtkWidget* link) { |
| 268 // TODO(binji): This should link to a CWS search, based on the current | 324 // TODO(binji): This should link to a CWS search, based on the current |
| 269 // action/type pair. | 325 // action/type pair. |
| 270 browser::NavigateParams params( | 326 browser::NavigateParams params( |
| 271 browser_, | 327 browser_, |
| 272 GURL(extension_urls::GetWebstoreLaunchURL()), | 328 GURL(extension_urls::GetWebstoreLaunchURL()), |
| 273 content::PAGE_TRANSITION_AUTO_BOOKMARK); | 329 content::PAGE_TRANSITION_AUTO_BOOKMARK); |
| 274 params.disposition = NEW_FOREGROUND_TAB; | 330 params.disposition = NEW_FOREGROUND_TAB; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 311 CustomDrawButton::CloseButton(GetThemeService(wrapper_))); | 367 CustomDrawButton::CloseButton(GetThemeService(wrapper_))); |
| 312 g_signal_connect(close_button_->widget(), | 368 g_signal_connect(close_button_->widget(), |
| 313 "clicked", | 369 "clicked", |
| 314 G_CALLBACK(OnCloseButtonClickThunk), | 370 G_CALLBACK(OnCloseButtonClickThunk), |
| 315 this); | 371 this); |
| 316 gtk_widget_set_can_focus(close_button_->widget(), FALSE); | 372 gtk_widget_set_can_focus(close_button_->widget(), FALSE); |
| 317 gtk_box_pack_end(GTK_BOX(header_hbox), close_button_->widget(), | 373 gtk_box_pack_end(GTK_BOX(header_hbox), close_button_->widget(), |
| 318 FALSE, FALSE, 0); | 374 FALSE, FALSE, 0); |
| 319 | 375 |
| 320 // Alignment for service button vbox. | 376 // Alignment for service button vbox. |
| 321 GtkWidget* button_alignment = gtk_alignment_new(0.5f, 0.5f, 0.3f, 0); | 377 GtkWidget* button_alignment = gtk_alignment_new(0, 0.5f, 0.3f, 0); |
| 378 gtk_alignment_set_padding(GTK_ALIGNMENT(button_alignment), 0, 0, |
| 379 ui::kGroupIndent, 0); |
| 322 gtk_widget_set_no_show_all(button_alignment, TRUE); | 380 gtk_widget_set_no_show_all(button_alignment, TRUE); |
| 323 | 381 |
| 324 // Vbox containing all service buttons. | 382 // Vbox containing all service buttons. |
| 325 button_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing); | 383 button_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing); |
| 326 gtk_container_add(GTK_CONTAINER(button_alignment), button_vbox_); | 384 gtk_container_add(GTK_CONTAINER(button_alignment), button_vbox_); |
| 327 gtk_box_pack_start(GTK_BOX(contents_), button_alignment, TRUE, TRUE, 0); | 385 gtk_box_pack_start(GTK_BOX(contents_), button_alignment, TRUE, TRUE, 0); |
| 328 | 386 |
| 329 // Chrome Web Store label. | 387 // Chrome Web Store label. |
| 330 cws_label_ = theme_service->BuildLabel( | 388 cws_label_ = theme_service->BuildLabel( |
| 331 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_GET_MORE_SERVICES).c_str(), | 389 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_GET_MORE_SERVICES).c_str(), |
| 332 ui::kGdkBlack); | 390 ui::kGdkBlack); |
| 333 gtk_box_pack_start(GTK_BOX(contents_), cws_label_, TRUE, TRUE, 0); | 391 gtk_box_pack_start(GTK_BOX(contents_), cws_label_, TRUE, TRUE, 0); |
| 334 gtk_misc_set_alignment(GTK_MISC(cws_label_), 0, 0); | 392 gtk_misc_set_alignment(GTK_MISC(cws_label_), 0, 0); |
| 335 gtk_widget_set_no_show_all(cws_label_, TRUE); | 393 gtk_widget_set_no_show_all(cws_label_, TRUE); |
| 336 gtk_util::SetLabelWidth(cws_label_, kWebStoreLabelLength); | 394 gtk_util::SetLabelWidth(cws_label_, kWebStoreLabelLength); |
| 337 | 395 |
| 396 // Suggested extensions vbox. |
| 397 extensions_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing); |
| 398 GtkWidget* indent_extensions = gtk_util::IndentWidget(extensions_vbox_); |
| 399 gtk_widget_set_no_show_all(indent_extensions, TRUE); |
| 400 gtk_box_pack_start(GTK_BOX(contents_), indent_extensions, TRUE, TRUE, 0); |
| 401 |
| 402 // Left-aligned link button. |
| 403 GtkWidget* link_alignment = gtk_alignment_new(0, 0.5f, 0, 0); |
| 404 GtkWidget* more_suggestions_link = theme_service->BuildChromeLinkButton( |
| 405 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_MORE_SUGGESTIONS).c_str()); |
| 406 gtk_container_add(GTK_CONTAINER(link_alignment), more_suggestions_link); |
| 407 gtk_chrome_link_button_set_use_gtk_theme( |
| 408 GTK_CHROME_LINK_BUTTON(more_suggestions_link), |
| 409 theme_service->UsingNativeTheme()); |
| 410 g_signal_connect(more_suggestions_link, "clicked", |
| 411 G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this); |
| 412 gtk_box_pack_start(GTK_BOX(contents_), link_alignment, FALSE, FALSE, 0); |
| 413 |
| 414 // Throbber, which will be added to the hierarchy when necessary. |
| 415 throbber_.reset(new ThrobberGtk(theme_service)); |
| 416 |
| 338 g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this); | 417 g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this); |
| 339 | |
| 340 // Suggested extensions vbox. | |
| 341 extensions_vbox_ = gtk_vbox_new(FALSE, ui::kContentAreaSpacing); | |
| 342 gtk_box_pack_start(GTK_BOX(contents_), | |
| 343 gtk_util::IndentWidget(extensions_vbox_), TRUE, TRUE, 0); | |
| 344 } | 418 } |
| 345 | 419 |
| 346 void WebIntentPickerGtk::UpdateInstalledServices() { | 420 void WebIntentPickerGtk::UpdateInstalledServices() { |
| 347 gtk_util::RemoveAllChildren(button_vbox_); | 421 gtk_util::RemoveAllChildren(button_vbox_); |
| 348 | 422 |
| 423 if (model_->GetInstalledServiceCount() == 0) { |
| 424 gtk_widget_hide(gtk_widget_get_parent(button_vbox_)); |
| 425 return; |
| 426 } |
| 427 |
| 349 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { | 428 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { |
| 350 const WebIntentPickerModel::InstalledService& installed_service = | 429 const WebIntentPickerModel::InstalledService& installed_service = |
| 351 model_->GetInstalledServiceAt(i); | 430 model_->GetInstalledServiceAt(i); |
| 352 | 431 |
| 353 GtkWidget* button = gtk_button_new(); | 432 GtkWidget* button = gtk_button_new(); |
| 354 | 433 |
| 355 gtk_widget_set_tooltip_text(button, installed_service.url.spec().c_str()); | 434 gtk_widget_set_tooltip_text(button, installed_service.url.spec().c_str()); |
| 356 gtk_button_set_label(GTK_BUTTON(button), | 435 gtk_button_set_label(GTK_BUTTON(button), |
| 357 UTF16ToUTF8(installed_service.title).c_str()); | 436 UTF16ToUTF8(installed_service.title).c_str()); |
| 358 gtk_button_set_alignment(GTK_BUTTON(button), 0, 0); | 437 gtk_button_set_alignment(GTK_BUTTON(button), 0, 0); |
| 359 | 438 |
| 360 gtk_box_pack_start(GTK_BOX(button_vbox_), button, FALSE, FALSE, 0); | 439 gtk_box_pack_start(GTK_BOX(button_vbox_), button, FALSE, FALSE, 0); |
| 361 g_signal_connect(button, | 440 g_signal_connect(button, |
| 362 "clicked", | 441 "clicked", |
| 363 G_CALLBACK(OnServiceButtonClickThunk), | 442 G_CALLBACK(OnServiceButtonClickThunk), |
| 364 this); | 443 this); |
| 365 | 444 |
| 366 SetServiceButtonImage(button, installed_service.favicon.ToGdkPixbuf()); | 445 SetServiceButtonImage(button, installed_service.favicon.ToGdkPixbuf()); |
| 367 } | 446 } |
| 368 | 447 |
| 369 gtk_widget_show_all(button_vbox_); | 448 gtk_widget_show_all(button_vbox_); |
| 449 gtk_widget_show(gtk_widget_get_parent(button_vbox_)); |
| 370 } | 450 } |
| 371 | 451 |
| 372 void WebIntentPickerGtk::UpdateCWSLabel() { | 452 void WebIntentPickerGtk::UpdateCWSLabel() { |
| 373 if (model_->GetInstalledServiceCount() == 0) { | 453 if (model_->GetInstalledServiceCount() == 0) { |
| 374 gtk_widget_hide(gtk_widget_get_parent(button_vbox_)); | 454 gtk_widget_hide(gtk_widget_get_parent(button_vbox_)); |
| 375 gtk_label_set_text(GTK_LABEL(cws_label_), l10n_util::GetStringUTF8( | 455 gtk_label_set_text(GTK_LABEL(cws_label_), l10n_util::GetStringUTF8( |
| 376 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED).c_str()); | 456 IDS_INTENT_PICKER_GET_MORE_SERVICES_NONE_INSTALLED).c_str()); |
| 377 } else { | 457 } else { |
| 378 gtk_label_set_text(GTK_LABEL(cws_label_), | 458 gtk_label_set_text(GTK_LABEL(cws_label_), |
| 379 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_GET_MORE_SERVICES).c_str()); | 459 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_GET_MORE_SERVICES).c_str()); |
| 380 gtk_widget_show(gtk_widget_get_parent(button_vbox_)); | 460 gtk_widget_show(gtk_widget_get_parent(button_vbox_)); |
| 381 } | 461 } |
| 382 | 462 |
| 383 if (model_->GetSuggestedExtensionCount() == 0) | 463 if (model_->GetSuggestedExtensionCount() == 0) |
| 384 gtk_widget_hide(cws_label_); | 464 gtk_widget_hide(cws_label_); |
| 385 else | 465 else |
| 386 gtk_widget_show(cws_label_); | 466 gtk_widget_show(cws_label_); |
| 387 } | 467 } |
| 388 | 468 |
| 389 void WebIntentPickerGtk::UpdateSuggestedExtensions() { | 469 void WebIntentPickerGtk::UpdateSuggestedExtensions() { |
| 390 ThemeServiceGtk* theme_service = GetThemeService(wrapper_); | 470 ThemeServiceGtk* theme_service = GetThemeService(wrapper_); |
| 391 | 471 |
| 392 gtk_util::RemoveAllChildren(extensions_vbox_); | 472 gtk_util::RemoveAllChildren(extensions_vbox_); |
| 393 if (model_->GetSuggestedExtensionCount() == 0) | 473 |
| 474 if (model_->GetSuggestedExtensionCount() == 0) { |
| 475 gtk_widget_hide(gtk_widget_get_parent(extensions_vbox_)); |
| 394 return; | 476 return; |
| 477 } |
| 478 |
| 479 gtk_widget_show(gtk_widget_get_parent(extensions_vbox_)); |
| 395 | 480 |
| 396 for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) { | 481 for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) { |
| 397 const WebIntentPickerModel::SuggestedExtension& extension = | 482 const WebIntentPickerModel::SuggestedExtension& extension = |
| 398 model_->GetSuggestedExtensionAt(i); | 483 model_->GetSuggestedExtensionAt(i); |
| 399 | 484 |
| 400 GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); | 485 GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); |
| 401 gtk_box_pack_start(GTK_BOX(extensions_vbox_), hbox, FALSE, FALSE, 0); | 486 gtk_box_pack_start(GTK_BOX(extensions_vbox_), hbox, FALSE, FALSE, 0); |
| 402 | 487 |
| 403 // Icon. | 488 // Icon. |
| 404 GtkWidget* icon = gtk_image_new_from_pixbuf(extension.icon.ToGdkPixbuf()); | 489 GtkWidget* icon = gtk_image_new_from_pixbuf(extension.icon.ToGdkPixbuf()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 424 // Install button. | 509 // Install button. |
| 425 GtkWidget* install_button = gtk_button_new(); | 510 GtkWidget* install_button = gtk_button_new(); |
| 426 gtk_button_set_label( | 511 gtk_button_set_label( |
| 427 GTK_BUTTON(install_button), | 512 GTK_BUTTON(install_button), |
| 428 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_INSTALL_EXTENSION).c_str()); | 513 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_INSTALL_EXTENSION).c_str()); |
| 429 g_signal_connect(install_button, "clicked", | 514 g_signal_connect(install_button, "clicked", |
| 430 G_CALLBACK(OnExtensionInstallButtonClickThunk), this); | 515 G_CALLBACK(OnExtensionInstallButtonClickThunk), this); |
| 431 gtk_box_pack_end(GTK_BOX(hbox), install_button, FALSE, FALSE, 0); | 516 gtk_box_pack_end(GTK_BOX(hbox), install_button, FALSE, FALSE, 0); |
| 432 } | 517 } |
| 433 | 518 |
| 434 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 519 gtk_widget_show_all(extensions_vbox_); |
| 520 gtk_widget_show(gtk_widget_get_parent(extensions_vbox_)); |
| 521 } |
| 435 | 522 |
| 436 GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing); | 523 void WebIntentPickerGtk::SetWidgetsEnabled(bool enabled) { |
| 524 gboolean data = enabled; |
| 525 gtk_container_foreach(GTK_CONTAINER(button_vbox_), |
| 526 EnableWidgetCallback, |
| 527 &data); |
| 528 gtk_container_foreach(GTK_CONTAINER(extensions_vbox_), |
| 529 EnableWidgetCallback, |
| 530 &data); |
| 531 } |
| 437 | 532 |
| 438 // Chrome Web Store icon. | 533 GtkWidget* WebIntentPickerGtk::AddThrobberToExtensionAt(size_t index) { |
| 439 gtk_box_pack_start( | 534 // The throbber should be unparented. |
| 440 GTK_BOX(hbox), | 535 DCHECK(!gtk_widget_get_parent(throbber_->widget())); |
| 441 gtk_image_new_from_pixbuf( | 536 GList* vbox_list = |
| 442 rb.GetRTLEnabledPixbufNamed(IDR_WEBSTORE_ICON_16)), | 537 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); |
| 443 FALSE, FALSE, 0); | 538 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); |
| 539 GtkWidget* alignment = gtk_alignment_new(0.5, 0.5, 0, 0); |
| 540 gtk_container_add(GTK_CONTAINER(alignment), throbber_->widget()); |
| 541 gtk_box_pack_end(GTK_BOX(hbox), alignment, FALSE, FALSE, 0); |
| 542 throbber_->Start(); |
| 543 return alignment; |
| 544 } |
| 444 | 545 |
| 445 // Left-aligned link button. | 546 void WebIntentPickerGtk::RemoveThrobber() { |
| 446 GtkWidget* more_suggestions_link = theme_service->BuildChromeLinkButton( | 547 GtkWidget* alignment = gtk_widget_get_parent(throbber_->widget()); |
| 447 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_MORE_SUGGESTIONS).c_str()); | 548 DCHECK(alignment); |
| 448 gtk_chrome_link_button_set_use_gtk_theme( | 549 gtk_container_remove(GTK_CONTAINER(alignment), throbber_->widget()); |
| 449 GTK_CHROME_LINK_BUTTON(more_suggestions_link), | 550 gtk_widget_destroy(alignment); |
| 450 theme_service->UsingNativeTheme()); | 551 throbber_->Stop(); |
| 451 g_signal_connect(more_suggestions_link, "clicked", | |
| 452 G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this); | |
| 453 gtk_box_pack_start(GTK_BOX(hbox), more_suggestions_link, | |
| 454 FALSE, FALSE, 0); | |
| 455 | |
| 456 gtk_box_pack_start(GTK_BOX(extensions_vbox_), hbox, FALSE, FALSE, 0); | |
| 457 | |
| 458 gtk_widget_show_all(extensions_vbox_); | |
| 459 } | 552 } |
| 460 | 553 |
| 461 GtkWidget* WebIntentPickerGtk::CreateStarsWidget(double rating) { | 554 GtkWidget* WebIntentPickerGtk::CreateStarsWidget(double rating) { |
| 462 const int kStarSpacing = 1; // Spacing between stars in pixels. | 555 const int kStarSpacing = 1; // Spacing between stars in pixels. |
| 463 GtkWidget* hbox = gtk_hbox_new(FALSE, kStarSpacing); | 556 GtkWidget* hbox = gtk_hbox_new(FALSE, kStarSpacing); |
| 464 | 557 |
| 465 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 558 ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); |
| 466 for (int i = 0; i < 5; ++i) { | 559 for (int i = 0; i < 5; ++i) { |
| 467 gtk_box_pack_start( | 560 gtk_box_pack_start( |
| 468 GTK_BOX(hbox), | 561 GTK_BOX(hbox), |
| 469 gtk_image_new_from_pixbuf(rb.GetRTLEnabledPixbufNamed( | 562 gtk_image_new_from_pixbuf(rb.GetRTLEnabledPixbufNamed( |
| 470 WebIntentPicker::GetNthStarImageIdFromCWSRating(rating, i))), | 563 WebIntentPicker::GetNthStarImageIdFromCWSRating(rating, i))), |
| 471 FALSE, FALSE, 0); | 564 FALSE, FALSE, 0); |
| 472 } | 565 } |
| 473 | 566 |
| 474 return hbox; | 567 return hbox; |
| 475 } | 568 } |
| OLD | NEW |