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" |
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
130 ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf(); | 130 ui::ResourceBundle::RTL_ENABLED).ToGdkPixbuf(); |
131 gtk_box_pack_start(GTK_BOX(hbox), gtk_image_new_from_pixbuf(star), | 131 gtk_box_pack_start(GTK_BOX(hbox), gtk_image_new_from_pixbuf(star), |
132 FALSE, FALSE, 0); | 132 FALSE, FALSE, 0); |
133 } | 133 } |
134 | 134 |
135 return hbox; | 135 return hbox; |
136 } | 136 } |
137 | 137 |
138 } // namespace | 138 } // namespace |
139 | 139 |
| 140 // Create a new Widget for the "waiting for CWS" display. |
| 141 |
| 142 class WaitingDialog { |
| 143 public: |
| 144 explicit WaitingDialog(GtkThemeService* theme_service); |
| 145 ~WaitingDialog(); |
| 146 |
| 147 GtkWidget* widget() const { return widget_.get(); } |
| 148 private: |
| 149 // Initialize the widget. |
| 150 void Init(); |
| 151 |
| 152 // The actual GtkWidget |
| 153 ui::OwnedWidgetGtk widget_; |
| 154 |
| 155 // Waiting throbber. |
| 156 scoped_ptr<ThrobberGtk> throbber_; |
| 157 |
| 158 // Weak pointer to theme service. |
| 159 GtkThemeService* theme_service_; |
| 160 }; |
| 161 |
| 162 WaitingDialog::WaitingDialog(GtkThemeService* theme_service) |
| 163 : theme_service_(theme_service) { |
| 164 DCHECK(theme_service_); |
| 165 Init(); |
| 166 } |
| 167 |
| 168 WaitingDialog::~WaitingDialog() { |
| 169 widget_.Destroy(); |
| 170 } |
| 171 |
| 172 void WaitingDialog::Init() { |
| 173 const int kDialogSpacing = 30; |
| 174 |
| 175 widget_.Own(gtk_vbox_new(FALSE, 0)); |
| 176 GtkWidget* vbox = widget_.get(); |
| 177 |
| 178 // Create throbber |
| 179 ThrobberGtk* throbber = new ThrobberGtk(theme_service_); |
| 180 GtkWidget* throbber_alignment = gtk_alignment_new(0.5, 0.5, 0, 0); |
| 181 gtk_alignment_set_padding(GTK_ALIGNMENT(throbber_alignment), kDialogSpacing, |
| 182 kMainContentPixelSize, 0, 0); |
| 183 gtk_container_add(GTK_CONTAINER(throbber_alignment), throbber->widget()); |
| 184 gtk_box_pack_start(GTK_BOX(vbox), throbber_alignment, TRUE, TRUE, 0); |
| 185 |
| 186 // Add the message text. |
| 187 GtkWidget* message_label = theme_service_->BuildLabel( |
| 188 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_WAIT_FOR_CWS).c_str(), |
| 189 ui::kGdkBlack); |
| 190 |
| 191 GtkWidget* label_alignment = gtk_alignment_new(0.5, 0.5, 0, 0); |
| 192 gtk_alignment_set_padding(GTK_ALIGNMENT(label_alignment), |
| 193 kMainContentPixelSize, kDialogSpacing, 0, 0); |
| 194 gtk_container_add(GTK_CONTAINER(label_alignment), message_label); |
| 195 gtk_box_pack_start(GTK_BOX(vbox), label_alignment, TRUE, TRUE, 0); |
| 196 |
| 197 // TODO(groby): use IDR_SPEECH_INPUT_SPINNER. Pending fix for ThrobberGtk. |
| 198 // Animate throbber |
| 199 throbber->Start(); |
| 200 } |
140 // static | 201 // static |
141 WebIntentPicker* WebIntentPicker::Create(TabContents* tab_contents, | 202 WebIntentPicker* WebIntentPicker::Create(TabContents* tab_contents, |
142 WebIntentPickerDelegate* delegate, | 203 WebIntentPickerDelegate* delegate, |
143 WebIntentPickerModel* model) { | 204 WebIntentPickerModel* model) { |
144 return new WebIntentPickerGtk(tab_contents, delegate, model); | 205 return new WebIntentPickerGtk(tab_contents, delegate, model); |
145 } | 206 } |
146 | 207 |
147 WebIntentPickerGtk::WebIntentPickerGtk(TabContents* tab_contents, | 208 WebIntentPickerGtk::WebIntentPickerGtk(TabContents* tab_contents, |
148 WebIntentPickerDelegate* delegate, | 209 WebIntentPickerDelegate* delegate, |
149 WebIntentPickerModel* model) | 210 WebIntentPickerModel* model) |
(...skipping 26 matching lines...) Expand all Loading... |
176 } | 237 } |
177 | 238 |
178 void WebIntentPickerGtk::Close() { | 239 void WebIntentPickerGtk::Close() { |
179 window_->CloseConstrainedWindow(); | 240 window_->CloseConstrainedWindow(); |
180 if (inline_disposition_tab_contents_.get()) | 241 if (inline_disposition_tab_contents_.get()) |
181 inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); | 242 inline_disposition_tab_contents_->web_contents()->OnCloseStarted(); |
182 } | 243 } |
183 | 244 |
184 void WebIntentPickerGtk::SetActionString(const string16& action) { | 245 void WebIntentPickerGtk::SetActionString(const string16& action) { |
185 header_label_text_ = action; | 246 header_label_text_ = action; |
186 gtk_label_set_text(GTK_LABEL(header_label_), UTF16ToUTF8(action).c_str()); | 247 if (header_label_) |
| 248 gtk_label_set_text(GTK_LABEL(header_label_), UTF16ToUTF8(action).c_str()); |
187 } | 249 } |
188 | 250 |
189 void WebIntentPickerGtk::OnExtensionInstallSuccess(const std::string& id) { | 251 void WebIntentPickerGtk::OnExtensionInstallSuccess(const std::string& id) { |
190 RemoveThrobber(); | 252 RemoveThrobber(); |
191 } | 253 } |
192 | 254 |
193 void WebIntentPickerGtk::OnExtensionInstallFailure(const std::string& id) { | 255 void WebIntentPickerGtk::OnExtensionInstallFailure(const std::string& id) { |
194 // The throbber has an alignment as its parent, so it must be used instead of | 256 // The throbber has an alignment as its parent, so it must be used instead of |
195 // the throbber to find the extension row. | 257 // the throbber to find the extension row. |
196 size_t index = | 258 size_t index = |
197 GetExtensionWidgetRow(gtk_widget_get_parent(throbber_->widget())); | 259 GetExtensionWidgetRow(gtk_widget_get_parent(throbber_->widget())); |
198 GList* vbox_list = | 260 GList* vbox_list = |
199 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); | 261 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); |
200 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); | 262 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); |
201 | 263 |
202 RemoveThrobber(); | 264 RemoveThrobber(); |
203 gtk_widget_show_all(hbox); | 265 gtk_widget_show_all(hbox); |
204 g_list_free(vbox_list); | 266 g_list_free(vbox_list); |
205 SetWidgetsEnabled(true); | 267 SetWidgetsEnabled(true); |
206 } | 268 } |
207 | 269 |
208 void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) { | 270 void WebIntentPickerGtk::OnModelChanged(WebIntentPickerModel* model) { |
| 271 if (waiting_dialog_.get() && !model->IsWaitingForSuggestions()) { |
| 272 waiting_dialog_.reset(); |
| 273 InitMainContents(); |
| 274 } |
209 UpdateInstalledServices(); | 275 UpdateInstalledServices(); |
210 UpdateCWSLabel(); | 276 UpdateCWSLabel(); |
211 UpdateSuggestedExtensions(); | 277 UpdateSuggestedExtensions(); |
| 278 SetActionString(header_label_text_); |
212 } | 279 } |
213 | 280 |
214 void WebIntentPickerGtk::OnFaviconChanged(WebIntentPickerModel* model, | 281 void WebIntentPickerGtk::OnFaviconChanged(WebIntentPickerModel* model, |
215 size_t index) { | 282 size_t index) { |
216 UpdateInstalledServices(); | 283 UpdateInstalledServices(); |
217 } | 284 } |
218 | 285 |
219 void WebIntentPickerGtk::OnExtensionIconChanged(WebIntentPickerModel* model, | 286 void WebIntentPickerGtk::OnExtensionIconChanged(WebIntentPickerModel* model, |
220 const string16& extension_id) { | 287 const string16& extension_id) { |
221 UpdateSuggestedExtensions(); | 288 UpdateSuggestedExtensions(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
325 | 392 |
326 // Replace the picker contents with dialog box. | 393 // Replace the picker contents with dialog box. |
327 gtk_util::RemoveAllChildren(contents_); | 394 gtk_util::RemoveAllChildren(contents_); |
328 | 395 |
329 GtkWidget* sub_contents = CreateSubContents(contents_); | 396 GtkWidget* sub_contents = CreateSubContents(contents_); |
330 | 397 |
331 AddCloseButton(contents_); | 398 AddCloseButton(contents_); |
332 AddTitle(sub_contents); | 399 AddTitle(sub_contents); |
333 | 400 |
334 // Replace the dialog header. | 401 // Replace the dialog header. |
| 402 DCHECK(header_label_); |
335 gtk_label_set_text( | 403 gtk_label_set_text( |
336 GTK_LABEL(header_label_), | 404 GTK_LABEL(header_label_), |
337 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_NO_SERVICES_TITLE).c_str()); | 405 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_NO_SERVICES_TITLE).c_str()); |
338 | 406 |
339 // Add the message text. | 407 // Add the message text. |
340 GtkWidget* hbox = gtk_hbox_new(FALSE, 0); | 408 GtkWidget* hbox = gtk_hbox_new(FALSE, 0); |
341 gtk_box_pack_start(GTK_BOX(sub_contents), hbox, TRUE, TRUE, 0); | 409 gtk_box_pack_start(GTK_BOX(sub_contents), hbox, TRUE, TRUE, 0); |
342 GtkThemeService* theme_service = GetThemeService(tab_contents_); | 410 GtkThemeService* theme_service = GetThemeService(tab_contents_); |
343 GtkWidget* no_service_label = theme_service->BuildLabel( | 411 GtkWidget* no_service_label = theme_service->BuildLabel( |
344 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_NO_SERVICES).c_str(), | 412 l10n_util::GetStringUTF8(IDS_INTENT_PICKER_NO_SERVICES).c_str(), |
(...skipping 24 matching lines...) Expand all Loading... |
369 } | 437 } |
370 | 438 |
371 bool WebIntentPickerGtk::ShouldHaveBorderPadding() const { | 439 bool WebIntentPickerGtk::ShouldHaveBorderPadding() const { |
372 return false; | 440 return false; |
373 } | 441 } |
374 | 442 |
375 void WebIntentPickerGtk::Observe(int type, | 443 void WebIntentPickerGtk::Observe(int type, |
376 const content::NotificationSource& source, | 444 const content::NotificationSource& source, |
377 const content::NotificationDetails& details) { | 445 const content::NotificationDetails& details) { |
378 DCHECK_EQ(type, chrome::NOTIFICATION_BROWSER_THEME_CHANGED); | 446 DCHECK_EQ(type, chrome::NOTIFICATION_BROWSER_THEME_CHANGED); |
379 GtkThemeService* theme_service = GetThemeService(tab_contents_); | 447 if (header_label_) { |
380 if (theme_service->UsingNativeTheme()) | 448 GtkThemeService* theme_service = GetThemeService(tab_contents_); |
381 gtk_util::UndoForceFontSize(header_label_); | 449 if (theme_service->UsingNativeTheme()) |
382 else | 450 gtk_util::UndoForceFontSize(header_label_); |
383 gtk_util::ForceFontSizePixels(header_label_, kHeaderLabelPixelSize); | 451 else |
384 | 452 gtk_util::ForceFontSizePixels(header_label_, kHeaderLabelPixelSize); |
| 453 } |
385 UpdateInstalledServices(); | 454 UpdateInstalledServices(); |
386 UpdateSuggestedExtensions(); | 455 UpdateSuggestedExtensions(); |
387 } | 456 } |
388 | 457 |
389 void WebIntentPickerGtk::OnDestroy(GtkWidget* button) { | 458 void WebIntentPickerGtk::OnDestroy(GtkWidget* button) { |
390 // Destroy this object when the contents widget is destroyed. It can't be | 459 // Destroy this object when the contents widget is destroyed. It can't be |
391 // "delete this" because this function happens in a callback. | 460 // "delete this" because this function happens in a callback. |
392 MessageLoop::current()->DeleteSoon(FROM_HERE, this); | 461 MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
393 model_->set_observer(NULL); | 462 model_->set_observer(NULL); |
394 window_ = NULL; | 463 window_ = NULL; |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 GtkThemeService* theme_service = GetThemeService(tab_contents_); | 532 GtkThemeService* theme_service = GetThemeService(tab_contents_); |
464 | 533 |
465 // Main contents vbox. | 534 // Main contents vbox. |
466 if (!contents_) { | 535 if (!contents_) { |
467 contents_ = gtk_vbox_new(FALSE, 0); | 536 contents_ = gtk_vbox_new(FALSE, 0); |
468 g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this); | 537 g_signal_connect(contents_, "destroy", G_CALLBACK(&OnDestroyThunk), this); |
469 } | 538 } |
470 | 539 |
471 gtk_widget_set_size_request(contents_, kMainContentWidth, -1); | 540 gtk_widget_set_size_request(contents_, kMainContentWidth, -1); |
472 | 541 |
| 542 if (model_ && model_->IsWaitingForSuggestions()) { |
| 543 gtk_util::RemoveAllChildren(contents_); |
| 544 AddCloseButton(contents_); |
| 545 waiting_dialog_.reset(new WaitingDialog(theme_service)); |
| 546 gtk_box_pack_start(GTK_BOX(contents_), waiting_dialog_->widget(), |
| 547 TRUE, TRUE, 0); |
| 548 } else { |
| 549 InitMainContents(); |
| 550 } |
| 551 } |
| 552 |
| 553 void WebIntentPickerGtk::InitMainContents() { |
| 554 GtkThemeService* theme_service = GetThemeService(tab_contents_); |
| 555 |
| 556 gtk_util::RemoveAllChildren(contents_); |
| 557 |
473 AddCloseButton(contents_); | 558 AddCloseButton(contents_); |
474 GtkWidget* sub_contents = CreateSubContents(contents_); | 559 GtkWidget* sub_contents = CreateSubContents(contents_); |
| 560 |
475 AddTitle(sub_contents); | 561 AddTitle(sub_contents); |
476 | 562 |
477 // Add separation between the installed services list and the app suggestions. | 563 // Add separation between the installed services list and the app suggestions. |
478 GtkWidget* button_alignment = gtk_alignment_new(0.5, 0, 0, 0); | 564 GtkWidget* button_alignment = gtk_alignment_new(0.5, 0, 0, 0); |
479 gtk_alignment_set_padding(GTK_ALIGNMENT(button_alignment), 0, | 565 gtk_alignment_set_padding(GTK_ALIGNMENT(button_alignment), 0, |
480 kMainContentPixelSize * 2, 0, 0); | 566 kMainContentPixelSize * 2, 0, 0); |
481 | 567 |
482 // Vbox containing all service buttons. | 568 // Vbox containing all service buttons. |
483 button_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing); | 569 button_vbox_ = gtk_vbox_new(FALSE, ui::kControlSpacing); |
484 gtk_container_add(GTK_CONTAINER(button_alignment), button_vbox_); | 570 gtk_container_add(GTK_CONTAINER(button_alignment), button_vbox_); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 GTK_CHROME_LINK_BUTTON(more_suggestions_link)->label, | 605 GTK_CHROME_LINK_BUTTON(more_suggestions_link)->label, |
520 kMainContentPixelSize); | 606 kMainContentPixelSize); |
521 g_signal_connect(more_suggestions_link, "clicked", | 607 g_signal_connect(more_suggestions_link, "clicked", |
522 G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this); | 608 G_CALLBACK(OnMoreSuggestionsLinkClickThunk), this); |
523 | 609 |
524 GtkWidget* indent_link = gtk_util::IndentWidget(link_alignment); | 610 GtkWidget* indent_link = gtk_util::IndentWidget(link_alignment); |
525 gtk_box_pack_start(GTK_BOX(sub_contents), indent_link, TRUE, TRUE, 0); | 611 gtk_box_pack_start(GTK_BOX(sub_contents), indent_link, TRUE, TRUE, 0); |
526 | 612 |
527 // Throbber, which will be added to the hierarchy when necessary. | 613 // Throbber, which will be added to the hierarchy when necessary. |
528 throbber_.reset(new ThrobberGtk(theme_service)); | 614 throbber_.reset(new ThrobberGtk(theme_service)); |
| 615 |
| 616 gtk_widget_show_all(contents_); |
529 } | 617 } |
530 | 618 |
531 void WebIntentPickerGtk::ResetContents() { | 619 void WebIntentPickerGtk::ResetContents() { |
532 // Wipe out all currently displayed widgets. | 620 // Wipe out all currently displayed widgets. |
533 gtk_util::RemoveAllChildren(contents_); | 621 gtk_util::RemoveAllChildren(contents_); |
534 | 622 |
535 // Reset potential inline disposition data. | 623 // Reset potential inline disposition data. |
536 inline_disposition_delegate_.reset(NULL); | 624 inline_disposition_delegate_.reset(NULL); |
537 tab_contents_container_.reset(NULL); | 625 tab_contents_container_.reset(NULL); |
538 inline_disposition_tab_contents_.reset(NULL); | 626 inline_disposition_tab_contents_.reset(NULL); |
539 | 627 |
540 // Re-initialize picker widgets and data. | 628 // Re-initialize picker widgets and data. |
541 InitContents(); | 629 InitMainContents(); |
542 UpdateInstalledServices(); | 630 UpdateInstalledServices(); |
543 UpdateCWSLabel(); | 631 UpdateCWSLabel(); |
544 UpdateSuggestedExtensions(); | 632 UpdateSuggestedExtensions(); |
545 SetActionString(header_label_text_); | 633 SetActionString(header_label_text_); |
546 | 634 |
547 gtk_widget_show_all(contents_); | 635 gtk_widget_show_all(contents_); |
548 } | 636 } |
549 | 637 |
550 GtkWidget* WebIntentPickerGtk::CreateSubContents(GtkWidget* box) { | 638 GtkWidget* WebIntentPickerGtk::CreateSubContents(GtkWidget* box) { |
551 GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); | 639 GtkWidget* alignment = gtk_alignment_new(0.0, 0.0, 1.0, 1.0); |
(...skipping 29 matching lines...) Expand all Loading... |
581 | 669 |
582 // Label text will be set in the call to SetActionString(). | 670 // Label text will be set in the call to SetActionString(). |
583 header_label_ = GetThemeService(tab_contents_)->BuildLabel( | 671 header_label_ = GetThemeService(tab_contents_)->BuildLabel( |
584 std::string(), ui::kGdkBlack); | 672 std::string(), ui::kGdkBlack); |
585 gtk_util::ForceFontSizePixels(header_label_, kHeaderLabelPixelSize); | 673 gtk_util::ForceFontSizePixels(header_label_, kHeaderLabelPixelSize); |
586 gtk_box_pack_start(GTK_BOX(header_hbox), header_label_, TRUE, TRUE, 0); | 674 gtk_box_pack_start(GTK_BOX(header_hbox), header_label_, TRUE, TRUE, 0); |
587 gtk_misc_set_alignment(GTK_MISC(header_label_), 0, 0); | 675 gtk_misc_set_alignment(GTK_MISC(header_label_), 0, 0); |
588 } | 676 } |
589 | 677 |
590 void WebIntentPickerGtk::UpdateInstalledServices() { | 678 void WebIntentPickerGtk::UpdateInstalledServices() { |
| 679 if (!button_vbox_) |
| 680 return; |
| 681 |
591 gtk_util::RemoveAllChildren(button_vbox_); | 682 gtk_util::RemoveAllChildren(button_vbox_); |
592 | 683 |
593 if (model_->GetInstalledServiceCount() == 0) { | 684 if (model_->GetInstalledServiceCount() == 0) { |
594 gtk_widget_hide(gtk_widget_get_parent(button_vbox_)); | 685 gtk_widget_hide(gtk_widget_get_parent(button_vbox_)); |
595 return; | 686 return; |
596 } | 687 } |
597 | 688 |
598 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { | 689 for (size_t i = 0; i < model_->GetInstalledServiceCount(); ++i) { |
599 const WebIntentPickerModel::InstalledService& installed_service = | 690 const WebIntentPickerModel::InstalledService& installed_service = |
600 model_->GetInstalledServiceAt(i); | 691 model_->GetInstalledServiceAt(i); |
(...skipping 13 matching lines...) Expand all Loading... |
614 // Must be called after SetServiceButtonImage as the internal label widget | 705 // Must be called after SetServiceButtonImage as the internal label widget |
615 // is replaced in that call. | 706 // is replaced in that call. |
616 SetWidgetFontSize(button, kMainContentPixelSize); | 707 SetWidgetFontSize(button, kMainContentPixelSize); |
617 } | 708 } |
618 | 709 |
619 gtk_widget_show_all(button_vbox_); | 710 gtk_widget_show_all(button_vbox_); |
620 gtk_widget_show(gtk_widget_get_parent(button_vbox_)); | 711 gtk_widget_show(gtk_widget_get_parent(button_vbox_)); |
621 } | 712 } |
622 | 713 |
623 void WebIntentPickerGtk::UpdateCWSLabel() { | 714 void WebIntentPickerGtk::UpdateCWSLabel() { |
| 715 if (!button_vbox_) |
| 716 return; |
| 717 |
624 gtk_widget_set_visible(gtk_widget_get_parent(button_vbox_), | 718 gtk_widget_set_visible(gtk_widget_get_parent(button_vbox_), |
625 model_->GetInstalledServiceCount() != 0); | 719 model_->GetInstalledServiceCount() != 0); |
626 | 720 |
627 std::string label_text = UTF16ToUTF8(model_->GetSuggestionsLinkText()); | 721 std::string label_text = UTF16ToUTF8(model_->GetSuggestionsLinkText()); |
628 gtk_label_set_text(GTK_LABEL(cws_label_), label_text.c_str()); | 722 gtk_label_set_text(GTK_LABEL(cws_label_), label_text.c_str()); |
629 gtk_widget_set_visible(cws_label_, !label_text.empty()); | 723 gtk_widget_set_visible(cws_label_, !label_text.empty()); |
630 } | 724 } |
631 | 725 |
632 void WebIntentPickerGtk::UpdateSuggestedExtensions() { | 726 void WebIntentPickerGtk::UpdateSuggestedExtensions() { |
| 727 if (!extensions_vbox_) |
| 728 return; |
| 729 |
633 GtkThemeService* theme_service = GetThemeService(tab_contents_); | 730 GtkThemeService* theme_service = GetThemeService(tab_contents_); |
634 | 731 |
635 gtk_util::RemoveAllChildren(extensions_vbox_); | 732 gtk_util::RemoveAllChildren(extensions_vbox_); |
636 | 733 |
637 if (model_->GetSuggestedExtensionCount() == 0) { | 734 if (model_->GetSuggestedExtensionCount() == 0) { |
638 gtk_widget_hide(gtk_widget_get_parent(extensions_vbox_)); | 735 gtk_widget_hide(gtk_widget_get_parent(extensions_vbox_)); |
639 return; | 736 return; |
640 } | 737 } |
641 | 738 |
642 gtk_widget_show(gtk_widget_get_parent(extensions_vbox_)); | 739 gtk_widget_show(gtk_widget_get_parent(extensions_vbox_)); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
680 G_CALLBACK(OnExtensionInstallButtonClickThunk), this); | 777 G_CALLBACK(OnExtensionInstallButtonClickThunk), this); |
681 gtk_box_pack_end(GTK_BOX(hbox), install_button, FALSE, FALSE, 0); | 778 gtk_box_pack_end(GTK_BOX(hbox), install_button, FALSE, FALSE, 0); |
682 } | 779 } |
683 | 780 |
684 gtk_widget_show_all(extensions_vbox_); | 781 gtk_widget_show_all(extensions_vbox_); |
685 gtk_widget_show(gtk_widget_get_parent(extensions_vbox_)); | 782 gtk_widget_show(gtk_widget_get_parent(extensions_vbox_)); |
686 } | 783 } |
687 | 784 |
688 void WebIntentPickerGtk::SetWidgetsEnabled(bool enabled) { | 785 void WebIntentPickerGtk::SetWidgetsEnabled(bool enabled) { |
689 gboolean data = enabled; | 786 gboolean data = enabled; |
690 gtk_container_foreach(GTK_CONTAINER(button_vbox_), EnableWidgetCallback, | 787 if (button_vbox_) |
691 &data); | 788 gtk_container_foreach(GTK_CONTAINER(button_vbox_), EnableWidgetCallback, |
692 gtk_container_foreach(GTK_CONTAINER(extensions_vbox_), EnableWidgetCallback, | 789 &data); |
693 &data); | 790 if (extensions_vbox_) |
| 791 gtk_container_foreach(GTK_CONTAINER(extensions_vbox_), EnableWidgetCallback, |
| 792 &data); |
694 } | 793 } |
695 | 794 |
696 GtkWidget* WebIntentPickerGtk::AddThrobberToExtensionAt(size_t index) { | 795 GtkWidget* WebIntentPickerGtk::AddThrobberToExtensionAt(size_t index) { |
697 // The throbber should be unparented. | 796 // The throbber should be unparented. |
698 DCHECK(!gtk_widget_get_parent(throbber_->widget())); | 797 DCHECK(!gtk_widget_get_parent(throbber_->widget())); |
699 GList* vbox_list = | 798 GList* vbox_list = |
700 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); | 799 gtk_container_get_children(GTK_CONTAINER(extensions_vbox_)); |
701 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); | 800 GtkWidget* hbox = static_cast<GtkWidget*>(g_list_nth_data(vbox_list, index)); |
702 GtkWidget* alignment = gtk_alignment_new(0.5, 0.5, 0, 0); | 801 GtkWidget* alignment = gtk_alignment_new(0.5, 0.5, 0, 0); |
703 gtk_container_add(GTK_CONTAINER(alignment), throbber_->widget()); | 802 gtk_container_add(GTK_CONTAINER(alignment), throbber_->widget()); |
704 gtk_box_pack_end(GTK_BOX(hbox), alignment, FALSE, FALSE, 0); | 803 gtk_box_pack_end(GTK_BOX(hbox), alignment, FALSE, FALSE, 0); |
705 g_list_free(vbox_list); | 804 g_list_free(vbox_list); |
706 throbber_->Start(); | 805 throbber_->Start(); |
707 return alignment; | 806 return alignment; |
708 } | 807 } |
709 | 808 |
710 void WebIntentPickerGtk::RemoveThrobber() { | 809 void WebIntentPickerGtk::RemoveThrobber() { |
711 GtkWidget* alignment = gtk_widget_get_parent(throbber_->widget()); | 810 GtkWidget* alignment = gtk_widget_get_parent(throbber_->widget()); |
712 DCHECK(alignment); | 811 DCHECK(alignment); |
713 gtk_container_remove(GTK_CONTAINER(alignment), throbber_->widget()); | 812 gtk_container_remove(GTK_CONTAINER(alignment), throbber_->widget()); |
714 gtk_widget_destroy(alignment); | 813 gtk_widget_destroy(alignment); |
715 throbber_->Stop(); | 814 throbber_->Stop(); |
716 } | 815 } |
OLD | NEW |