| Index: chrome/browser/ui/gtk/web_intent_picker_gtk.cc
|
| diff --git a/chrome/browser/ui/gtk/web_intent_picker_gtk.cc b/chrome/browser/ui/gtk/web_intent_picker_gtk.cc
|
| index a1e609bd4b9415fe03fbe153084964ff9c6cc90a..28838c65e9b7ec4575f28b78fedcb3469c5a9b8b 100644
|
| --- a/chrome/browser/ui/gtk/web_intent_picker_gtk.cc
|
| +++ b/chrome/browser/ui/gtk/web_intent_picker_gtk.cc
|
| @@ -20,6 +20,7 @@
|
| #include "chrome/browser/ui/gtk/location_bar_view_gtk.h"
|
| #include "chrome/browser/ui/gtk/tab_contents_container_gtk.h"
|
| #include "chrome/browser/ui/gtk/theme_service_gtk.h"
|
| +#include "chrome/browser/ui/gtk/throbber_gtk.h"
|
| #include "chrome/browser/ui/intents/web_intent_picker_controller.h"
|
| #include "chrome/browser/ui/intents/web_intent_picker_delegate.h"
|
| #include "chrome/browser/ui/intents/web_intent_picker_model.h"
|
| @@ -60,6 +61,14 @@ const int kHeaderLabelPixelSize = 15;
|
| // The maximum width in pixels of a suggested extension's title link.
|
| const int kTitleLinkMaxWidth = 130;
|
|
|
| +// Indices of the extension row widgets.
|
| +enum {
|
| + kIconIndex,
|
| + kTitleLinkIndex,
|
| + kStarsIndex,
|
| + kInstallButtonIndex,
|
| +};
|
| +
|
| ThemeServiceGtk *GetThemeService(TabContentsWrapper* wrapper) {
|
| return ThemeServiceGtk::GetFrom(wrapper->profile());
|
| }
|
| @@ -85,6 +94,11 @@ size_t GetExtensionWidgetRow(GtkWidget* widget) {
|
| return index;
|
| }
|
|
|
| +// A gtk_container_foreach callback to enable/disable a widget.
|
| +void EnableWidgetCallback(GtkWidget* widget, gpointer data) {
|
| + gtk_widget_set_sensitive(widget, *static_cast<gboolean*>(data));
|
| +}
|
| +
|
| } // namespace
|
|
|
| // static
|
| @@ -135,6 +149,24 @@ void WebIntentPickerGtk::Close() {
|
| inline_disposition_tab_contents_->web_contents()->OnCloseStarted();
|
| }
|
|
|
| +void WebIntentPickerGtk::OnExtensionInstallSuccess(const std::string& id) {
|
| + RemoveThrobber();
|
| +}
|
| +
|
| +void WebIntentPickerGtk::OnExtensionInstallFailure(const std::string& id) {
|
| + // The throbber has an alignment as its parent, so it must be used instead of
|
| + // the throbber to find the extension row.
|
| + size_t index =
|
| + GetExtensionWidgetRow(gtk_widget_get_parent(throbber_->widget()));
|
| + GList* vbox_list =
|
| + gtk_container_get_children(GTK_CONTAINER(extensions_vbox_));
|
| + GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index));
|
| +
|
| + RemoveThrobber();
|
| + gtk_widget_show_all(hbox);
|
| + SetWidgetsEnabled(true);
|
| +}
|
| +
|
| void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) {
|
| UpdateInstalledServices();
|
| UpdateCWSLabel();
|
| @@ -261,7 +293,31 @@ void WebIntentPickerGtk::OnExtensionLinkClick(GtkWidget* link) {
|
| }
|
|
|
| void WebIntentPickerGtk::OnExtensionInstallButtonClick(GtkWidget* button) {
|
| - // TODO(binji): Install the extension.
|
| + size_t index = GetExtensionWidgetRow(button);
|
| + const WebIntentPickerModel::SuggestedExtension& extension =
|
| + model_->GetSuggestedExtensionAt(index);
|
| +
|
| + delegate_->OnExtensionInstallRequested(UTF16ToUTF8(extension.id));
|
| + SetWidgetsEnabled(false);
|
| +
|
| + // Re-enable the clicked extension row.
|
| + GList* vbox_list =
|
| + gtk_container_get_children(GTK_CONTAINER(extensions_vbox_));
|
| + GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index));
|
| + gtk_widget_set_sensitive(hbox, TRUE);
|
| +
|
| + // Hide the install button.
|
| + GList* hbox_list = gtk_container_get_children(GTK_CONTAINER(hbox));
|
| + GtkWidget* install_button =
|
| + static_cast<GtkWidget*>(g_list_nth_data(hbox_list, kInstallButtonIndex));
|
| + GtkAllocation allocation;
|
| + gtk_widget_get_allocation(install_button, &allocation);
|
| + gtk_widget_hide(install_button);
|
| +
|
| + // Show the throbber with the same size as the install button.
|
| + GtkWidget* throbber = AddThrobberToExtensionAt(index);
|
| + gtk_widget_set_size_request(throbber, allocation.width, allocation.height);
|
| + gtk_widget_show_all(throbber);
|
| }
|
|
|
| void WebIntentPickerGtk::OnMoreSuggestionsLinkClick(GtkWidget* link) {
|
| @@ -318,7 +374,9 @@ void WebIntentPickerGtk::InitContents() {
|
| FALSE, FALSE, 0);
|
|
|
| // Alignment for service button vbox.
|
| - GtkWidget* button_alignment = gtk_alignment_new(0.5f, 0.5f, 0.3f, 0);
|
| + GtkWidget* button_alignment = gtk_alignment_new(0, 0.5f, 0.3f, 0);
|
| + gtk_alignment_set_padding(GTK_ALIGNMENT(button_alignment), 0, 0,
|
| + ui::kGroupIndent, 0);
|
| gtk_widget_set_no_show_all(button_alignment, TRUE);
|
|
|
| // Vbox containing all service buttons.
|
| @@ -335,17 +393,38 @@ void WebIntentPickerGtk::InitContents() {
|
| gtk_widget_set_no_show_all(cws_label_, TRUE);
|
| gtk_util::SetLabelWidth(cws_label_, kWebStoreLabelLength);
|
|
|
| - g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this);
|
| -
|
| // Suggested extensions vbox.
|
| - extensions_vbox_ = gtk_vbox_new(FALSE, ui::kContentAreaSpacing);
|
| - gtk_box_pack_start(GTK_BOX(contents_),
|
| - gtk_util::IndentWidget(extensions_vbox_), TRUE, TRUE, 0);
|
| + extensions_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing);
|
| + GtkWidget* indent_extensions = gtk_util::IndentWidget(extensions_vbox_);
|
| + gtk_widget_set_no_show_all(indent_extensions, TRUE);
|
| + gtk_box_pack_start(GTK_BOX(contents_), indent_extensions, TRUE, TRUE, 0);
|
| +
|
| + // Left-aligned link button.
|
| + GtkWidget* link_alignment = gtk_alignment_new(0, 0.5f, 0, 0);
|
| + GtkWidget* more_suggestions_link = theme_service->BuildChromeLinkButton(
|
| + l10n_util::GetStringUTF8(IDS_INTENT_PICKER_MORE_SUGGESTIONS).c_str());
|
| + gtk_container_add(GTK_CONTAINER(link_alignment), more_suggestions_link);
|
| + gtk_chrome_link_button_set_use_gtk_theme(
|
| + GTK_CHROME_LINK_BUTTON(more_suggestions_link),
|
| + theme_service->UsingNativeTheme());
|
| + g_signal_connect(more_suggestions_link, "clicked",
|
| + G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this);
|
| + gtk_box_pack_start(GTK_BOX(contents_), link_alignment, FALSE, FALSE, 0);
|
| +
|
| + // Throbber, which will be added to the hierarchy when necessary.
|
| + throbber_.reset(new ThrobberGtk(theme_service));
|
| +
|
| + g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this);
|
| }
|
|
|
| void WebIntentPickerGtk::UpdateInstalledServices() {
|
| gtk_util::RemoveAllChildren(button_vbox_);
|
|
|
| + if (model_->GetInstalledServiceCount() == 0) {
|
| + gtk_widget_hide(gtk_widget_get_parent(button_vbox_));
|
| + return;
|
| + }
|
| +
|
| for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) {
|
| const WebIntentPickerModel::InstalledService& installed_service =
|
| model_->GetInstalledServiceAt(i);
|
| @@ -367,6 +446,7 @@ void WebIntentPickerGtk::UpdateInstalledServices() {
|
| }
|
|
|
| gtk_widget_show_all(button_vbox_);
|
| + gtk_widget_show(gtk_widget_get_parent(button_vbox_));
|
| }
|
|
|
| void WebIntentPickerGtk::UpdateCWSLabel() {
|
| @@ -390,8 +470,13 @@ void WebIntentPickerGtk::UpdateSuggestedExtensions() {
|
| ThemeServiceGtk* theme_service = GetThemeService(wrapper_);
|
|
|
| gtk_util::RemoveAllChildren(extensions_vbox_);
|
| - if (model_->GetSuggestedExtensionCount() == 0)
|
| +
|
| + if (model_->GetSuggestedExtensionCount() == 0) {
|
| + gtk_widget_hide(gtk_widget_get_parent(extensions_vbox_));
|
| return;
|
| + }
|
| +
|
| + gtk_widget_show(gtk_widget_get_parent(extensions_vbox_));
|
|
|
| for (size_t i = 0; i < model_->GetSuggestedExtensionCount(); ++i) {
|
| const WebIntentPickerModel::SuggestedExtension& extension =
|
| @@ -431,31 +516,39 @@ void WebIntentPickerGtk::UpdateSuggestedExtensions() {
|
| gtk_box_pack_end(GTK_BOX(hbox), install_button, FALSE, FALSE, 0);
|
| }
|
|
|
| - ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
|
| -
|
| - GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
|
| -
|
| - // Chrome Web Store icon.
|
| - gtk_box_pack_start(
|
| - GTK_BOX(hbox),
|
| - gtk_image_new_from_pixbuf(
|
| - rb.GetRTLEnabledPixbufNamed(IDR_WEBSTORE_ICON_16)),
|
| - FALSE, FALSE, 0);
|
| + gtk_widget_show_all(extensions_vbox_);
|
| + gtk_widget_show(gtk_widget_get_parent(extensions_vbox_));
|
| +}
|
|
|
| - // Left-aligned link button.
|
| - GtkWidget* more_suggestions_link = theme_service->BuildChromeLinkButton(
|
| - l10n_util::GetStringUTF8(IDS_INTENT_PICKER_MORE_SUGGESTIONS).c_str());
|
| - gtk_chrome_link_button_set_use_gtk_theme(
|
| - GTK_CHROME_LINK_BUTTON(more_suggestions_link),
|
| - theme_service->UsingNativeTheme());
|
| - g_signal_connect(more_suggestions_link, "clicked",
|
| - G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this);
|
| - gtk_box_pack_start(GTK_BOX(hbox), more_suggestions_link,
|
| - FALSE, FALSE, 0);
|
| +void WebIntentPickerGtk::SetWidgetsEnabled(bool enabled) {
|
| + gboolean data = enabled;
|
| + gtk_container_foreach(GTK_CONTAINER(button_vbox_),
|
| + EnableWidgetCallback,
|
| + &data);
|
| + gtk_container_foreach(GTK_CONTAINER(extensions_vbox_),
|
| + EnableWidgetCallback,
|
| + &data);
|
| +}
|
|
|
| - gtk_box_pack_start(GTK_BOX(extensions_vbox_), hbox, FALSE, FALSE, 0);
|
| +GtkWidget* WebIntentPickerGtk::AddThrobberToExtensionAt(size_t index) {
|
| + // The throbber should be unparented.
|
| + DCHECK(!gtk_widget_get_parent(throbber_->widget()));
|
| + GList* vbox_list =
|
| + gtk_container_get_children(GTK_CONTAINER(extensions_vbox_));
|
| + GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index));
|
| + GtkWidget* alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
|
| + gtk_container_add(GTK_CONTAINER(alignment), throbber_->widget());
|
| + gtk_box_pack_end(GTK_BOX(hbox), alignment, FALSE, FALSE, 0);
|
| + throbber_->Start();
|
| + return alignment;
|
| +}
|
|
|
| - gtk_widget_show_all(extensions_vbox_);
|
| +void WebIntentPickerGtk::RemoveThrobber() {
|
| + GtkWidget* alignment = gtk_widget_get_parent(throbber_->widget());
|
| + DCHECK(alignment);
|
| + gtk_container_remove(GTK_CONTAINER(alignment), throbber_->widget());
|
| + gtk_widget_destroy(alignment);
|
| + throbber_->Stop();
|
| }
|
|
|
| GtkWidget* WebIntentPickerGtk::CreateStarsWidget(double rating) {
|
|
|