| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/ui/gtk/extensions/media_galleries_dialog_gtk.h" | |
| 6 | |
| 7 #include "base/auto_reset.h" | |
| 8 #include "base/strings/utf_string_conversions.h" | |
| 9 #include "chrome/browser/media_galleries/media_galleries_preferences.h" | |
| 10 #include "chrome/browser/ui/gtk/gtk_util.h" | |
| 11 #include "components/web_modal/web_contents_modal_dialog_manager.h" | |
| 12 #include "grit/generated_resources.h" | |
| 13 #include "ui/base/gtk/gtk_hig_constants.h" | |
| 14 #include "ui/base/l10n/l10n_util.h" | |
| 15 | |
| 16 using web_modal::WebContentsModalDialogManager; | |
| 17 | |
| 18 namespace { | |
| 19 | |
| 20 // Color used for additional attachment detail text for galleries. | |
| 21 const GdkColor kDeemphasizedTextColor = GDK_COLOR_RGB(0x96, 0x96, 0x96); | |
| 22 | |
| 23 // Width and height of the scrollable area in which galleries are shown. | |
| 24 const int kGalleryControlScrollableWidth = 280; | |
| 25 const int kGalleryControlScrollableHeight = 192; | |
| 26 | |
| 27 } // namespace | |
| 28 | |
| 29 typedef MediaGalleriesDialogController::GalleryPermissionsVector | |
| 30 GalleryPermissionsVector; | |
| 31 | |
| 32 MediaGalleriesDialogGtk::MediaGalleriesDialogGtk( | |
| 33 MediaGalleriesDialogController* controller) | |
| 34 : controller_(controller), | |
| 35 window_(NULL), | |
| 36 confirm_(NULL), | |
| 37 accepted_(false) { | |
| 38 contents_.reset(gtk_vbox_new(FALSE, ui::kContentAreaSpacing)); | |
| 39 g_object_ref_sink(contents_.get()); | |
| 40 g_signal_connect(contents_.get(), | |
| 41 "destroy", | |
| 42 G_CALLBACK(OnDestroyThunk), | |
| 43 this); | |
| 44 InitWidgets(); | |
| 45 | |
| 46 // May be NULL during tests. | |
| 47 if (controller->web_contents()) { | |
| 48 window_ = CreateWebContentsModalDialogGtk(contents_.get(), confirm_); | |
| 49 | |
| 50 WebContentsModalDialogManager* web_contents_modal_dialog_manager = | |
| 51 WebContentsModalDialogManager::FromWebContents( | |
| 52 controller->web_contents()); | |
| 53 web_contents_modal_dialog_manager->ShowDialog(window_); | |
| 54 } | |
| 55 } | |
| 56 | |
| 57 MediaGalleriesDialogGtk::~MediaGalleriesDialogGtk() { | |
| 58 } | |
| 59 | |
| 60 void MediaGalleriesDialogGtk::InitWidgets() { | |
| 61 gtk_util::RemoveAllChildren(contents_.get()); | |
| 62 checkbox_map_.clear(); | |
| 63 new_checkbox_map_.clear(); | |
| 64 confirm_ = NULL; | |
| 65 | |
| 66 GtkWidget* header = gtk_util::LeftAlignMisc(gtk_label_new( | |
| 67 base::UTF16ToUTF8(controller_->GetHeader()).c_str())); | |
| 68 gtk_box_pack_start(GTK_BOX(contents_.get()), header, FALSE, FALSE, 0); | |
| 69 | |
| 70 GtkWidget* subtext = | |
| 71 gtk_label_new(base::UTF16ToUTF8(controller_->GetSubtext()).c_str()); | |
| 72 gtk_label_set_line_wrap(GTK_LABEL(subtext), TRUE); | |
| 73 gtk_widget_set_size_request(subtext, 500, -1); | |
| 74 gtk_box_pack_start(GTK_BOX(contents_.get()), subtext, FALSE, FALSE, 0); | |
| 75 | |
| 76 // The checkboxes are added inside a scrollable area. | |
| 77 GtkWidget* scroll_window = | |
| 78 gtk_scrolled_window_new(NULL, NULL); | |
| 79 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll_window), | |
| 80 GTK_POLICY_NEVER, | |
| 81 GTK_POLICY_AUTOMATIC); | |
| 82 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll_window), | |
| 83 GTK_SHADOW_ETCHED_IN); | |
| 84 | |
| 85 GtkWidget* checkbox_container = gtk_vbox_new(FALSE, ui::kControlSpacing); | |
| 86 gtk_widget_set_size_request(scroll_window, | |
| 87 kGalleryControlScrollableWidth, | |
| 88 kGalleryControlScrollableHeight); | |
| 89 gtk_container_set_border_width(GTK_CONTAINER(checkbox_container), | |
| 90 ui::kGroupIndent); | |
| 91 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll_window), | |
| 92 checkbox_container); | |
| 93 gtk_widget_show(checkbox_container); | |
| 94 gtk_box_pack_start(GTK_BOX(contents_.get()), scroll_window, | |
| 95 FALSE, FALSE, 0); | |
| 96 gtk_widget_show(scroll_window); | |
| 97 | |
| 98 // Attached galleries checkboxes | |
| 99 GalleryPermissionsVector permissions = controller_->AttachedPermissions(); | |
| 100 for (GalleryPermissionsVector::const_iterator iter = permissions.begin(); | |
| 101 iter != permissions.end(); ++iter) { | |
| 102 UpdateGalleryInContainer(iter->pref_info, iter->allowed, | |
| 103 checkbox_container); | |
| 104 } | |
| 105 | |
| 106 const GalleryPermissionsVector unattached_permissions = | |
| 107 controller_->UnattachedPermissions(); | |
| 108 if (!unattached_permissions.empty()) { | |
| 109 // Separator line and unattached volumes header text. | |
| 110 GtkWidget* separator = gtk_hseparator_new(); | |
| 111 gtk_box_pack_start(GTK_BOX(checkbox_container), separator, FALSE, FALSE, 0); | |
| 112 | |
| 113 GtkWidget* unattached_hbox = gtk_hbox_new(FALSE, ui::kLabelSpacing); | |
| 114 GtkWidget* unattached_text = gtk_label_new(base::UTF16ToUTF8( | |
| 115 controller_->GetUnattachedLocationsHeader()).c_str()); | |
| 116 gtk_label_set_line_wrap(GTK_LABEL(unattached_text), FALSE); | |
| 117 gtk_box_pack_start(GTK_BOX(unattached_hbox), unattached_text, | |
| 118 FALSE, FALSE, 0); | |
| 119 gtk_box_pack_start(GTK_BOX(checkbox_container), unattached_hbox, | |
| 120 FALSE, FALSE, 0); | |
| 121 | |
| 122 // Unattached galleries checkboxes | |
| 123 for (GalleryPermissionsVector::const_iterator iter = | |
| 124 unattached_permissions.begin(); | |
| 125 iter != unattached_permissions.end(); ++iter) { | |
| 126 UpdateGalleryInContainer(iter->pref_info, iter->allowed, | |
| 127 checkbox_container); | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 GtkWidget* bottom_area = gtk_hbox_new(FALSE, ui::kControlSpacing); | |
| 132 | |
| 133 // Add gallery button. | |
| 134 GtkWidget* add_folder = gtk_button_new_with_label( | |
| 135 l10n_util::GetStringUTF8(IDS_MEDIA_GALLERIES_DIALOG_ADD_GALLERY).c_str()); | |
| 136 g_signal_connect(add_folder, "clicked", G_CALLBACK(OnAddFolderThunk), this); | |
| 137 gtk_box_pack_start(GTK_BOX(bottom_area), add_folder, FALSE, FALSE, 0); | |
| 138 | |
| 139 // Confirm/cancel button. | |
| 140 confirm_ = gtk_button_new_with_label(l10n_util::GetStringUTF8( | |
| 141 IDS_MEDIA_GALLERIES_DIALOG_CONFIRM).c_str()); | |
| 142 gtk_button_set_image( | |
| 143 GTK_BUTTON(confirm_), | |
| 144 gtk_image_new_from_stock(GTK_STOCK_APPLY, GTK_ICON_SIZE_BUTTON)); | |
| 145 g_signal_connect(confirm_, "clicked", G_CALLBACK(OnConfirmThunk), this); | |
| 146 gtk_box_pack_end(GTK_BOX(bottom_area), confirm_, FALSE, FALSE, 0); | |
| 147 | |
| 148 GtkWidget* cancel = gtk_button_new_with_label(l10n_util::GetStringUTF8( | |
| 149 IDS_MEDIA_GALLERIES_DIALOG_CANCEL).c_str()); | |
| 150 gtk_button_set_image( | |
| 151 GTK_BUTTON(cancel), | |
| 152 gtk_image_new_from_stock(GTK_STOCK_CANCEL, GTK_ICON_SIZE_BUTTON)); | |
| 153 g_signal_connect(cancel, "clicked", G_CALLBACK(OnCancelThunk), this); | |
| 154 gtk_box_pack_end(GTK_BOX(bottom_area), cancel, FALSE, FALSE, 0); | |
| 155 gtk_box_pack_start(GTK_BOX(contents_.get()), bottom_area, FALSE, FALSE, 0); | |
| 156 | |
| 157 // As a safeguard against the user skipping reading over the dialog and just | |
| 158 // confirming, the button will be unavailable for dialogs without any checks | |
| 159 // until the user toggles something. | |
| 160 gtk_widget_set_sensitive(confirm_, controller_->HasPermittedGalleries()); | |
| 161 | |
| 162 gtk_widget_show_all(contents_.get()); | |
| 163 } | |
| 164 | |
| 165 void MediaGalleriesDialogGtk::UpdateGalleries() { | |
| 166 InitWidgets(); | |
| 167 } | |
| 168 | |
| 169 void MediaGalleriesDialogGtk::UpdateGalleryInContainer( | |
| 170 const MediaGalleryPrefInfo& gallery, | |
| 171 bool permitted, | |
| 172 GtkWidget* checkbox_container) { | |
| 173 GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kLabelSpacing); | |
| 174 GtkWidget* widget = gtk_check_button_new(); | |
| 175 g_signal_connect(widget, "toggled", G_CALLBACK(OnToggledThunk), this); | |
| 176 gtk_box_pack_start(GTK_BOX(checkbox_container), hbox, FALSE, FALSE, 0); | |
| 177 gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0); | |
| 178 std::string details = | |
| 179 base::UTF16ToUTF8(gallery.GetGalleryAdditionalDetails()); | |
| 180 GtkWidget* details_label = gtk_label_new(details.c_str()); | |
| 181 gtk_label_set_line_wrap(GTK_LABEL(details_label), FALSE); | |
| 182 gtk_util::SetLabelColor(details_label, &kDeemphasizedTextColor); | |
| 183 gtk_box_pack_start(GTK_BOX(hbox), details_label, FALSE, FALSE, 0); | |
| 184 | |
| 185 gtk_widget_show(hbox); | |
| 186 if (gallery.pref_id != kInvalidMediaGalleryPrefId) | |
| 187 checkbox_map_[gallery.pref_id] = widget; | |
| 188 else | |
| 189 new_checkbox_map_[widget] = gallery; | |
| 190 | |
| 191 std::string tooltip_text = base::UTF16ToUTF8(gallery.GetGalleryTooltip()); | |
| 192 gtk_widget_set_tooltip_text(widget, tooltip_text.c_str()); | |
| 193 | |
| 194 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), permitted); | |
| 195 std::string label = base::UTF16ToUTF8(gallery.GetGalleryDisplayName()); | |
| 196 // TODO(gbillock): Would be nice to add middle elide behavior here. | |
| 197 gtk_button_set_label(GTK_BUTTON(widget), label.c_str()); | |
| 198 } | |
| 199 | |
| 200 void MediaGalleriesDialogGtk::OnToggled(GtkWidget* widget) { | |
| 201 if (confirm_) | |
| 202 gtk_widget_set_sensitive(confirm_, TRUE); | |
| 203 | |
| 204 for (CheckboxMap::const_iterator iter = checkbox_map_.begin(); | |
| 205 iter != checkbox_map_.end(); ++iter) { | |
| 206 if (iter->second == widget) { | |
| 207 controller_->DidToggleGalleryId( | |
| 208 iter->first, | |
| 209 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); | |
| 210 return; | |
| 211 } | |
| 212 } | |
| 213 for (NewCheckboxMap::const_iterator iter = new_checkbox_map_.begin(); | |
| 214 iter != new_checkbox_map_.end(); ++iter) { | |
| 215 if (iter->first == widget) { | |
| 216 controller_->DidToggleNewGallery( | |
| 217 iter->second, | |
| 218 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))); | |
| 219 return; | |
| 220 } | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 void MediaGalleriesDialogGtk::OnAddFolder(GtkWidget* widget) { | |
| 225 controller_->OnAddFolderClicked(); | |
| 226 } | |
| 227 | |
| 228 void MediaGalleriesDialogGtk::OnConfirm(GtkWidget* widget) { | |
| 229 accepted_ = true; | |
| 230 | |
| 231 if (window_) | |
| 232 gtk_widget_destroy(window_); | |
| 233 } | |
| 234 | |
| 235 void MediaGalleriesDialogGtk::OnCancel(GtkWidget* widget) { | |
| 236 if (window_) | |
| 237 gtk_widget_destroy(window_); | |
| 238 } | |
| 239 | |
| 240 void MediaGalleriesDialogGtk::OnDestroy(GtkWidget* widget) { | |
| 241 controller_->DialogFinished(accepted_); | |
| 242 } | |
| 243 | |
| 244 // MediaGalleriesDialogController ---------------------------------------------- | |
| 245 | |
| 246 // static | |
| 247 MediaGalleriesDialog* MediaGalleriesDialog::Create( | |
| 248 MediaGalleriesDialogController* controller) { | |
| 249 return new MediaGalleriesDialogGtk(controller); | |
| 250 } | |
| OLD | NEW |