Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / ui / gtk / extensions / media_galleries_dialog_gtk.cc
blob5f59cb46e5fda9b4a340070f6034703e92cec425
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.
5 #include "chrome/browser/ui/gtk/extensions/media_galleries_dialog_gtk.h"
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"
16 using web_modal::WebContentsModalDialogManager;
18 namespace {
20 // Color used for additional attachment detail text for galleries.
21 const GdkColor kDeemphasizedTextColor = GDK_COLOR_RGB(0x96, 0x96, 0x96);
23 // Width and height of the scrollable area in which galleries are shown.
24 const int kGalleryControlScrollableWidth = 280;
25 const int kGalleryControlScrollableHeight = 192;
27 } // namespace
29 typedef MediaGalleriesDialogController::GalleryPermissionsVector
30 GalleryPermissionsVector;
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();
46 // May be NULL during tests.
47 if (controller->web_contents()) {
48 window_ = CreateWebContentsModalDialogGtk(contents_.get(), confirm_);
50 WebContentsModalDialogManager* web_contents_modal_dialog_manager =
51 WebContentsModalDialogManager::FromWebContents(
52 controller->web_contents());
53 web_contents_modal_dialog_manager->ShowDialog(window_);
57 MediaGalleriesDialogGtk::~MediaGalleriesDialogGtk() {
60 void MediaGalleriesDialogGtk::InitWidgets() {
61 gtk_util::RemoveAllChildren(contents_.get());
62 checkbox_map_.clear();
63 new_checkbox_map_.clear();
64 confirm_ = NULL;
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);
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);
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);
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);
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);
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);
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);
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);
131 GtkWidget* bottom_area = gtk_hbox_new(FALSE, ui::kControlSpacing);
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);
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);
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);
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());
162 gtk_widget_show_all(contents_.get());
165 void MediaGalleriesDialogGtk::UpdateGalleries() {
166 InitWidgets();
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);
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;
191 std::string tooltip_text = base::UTF16ToUTF8(gallery.GetGalleryTooltip());
192 gtk_widget_set_tooltip_text(widget, tooltip_text.c_str());
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());
200 void MediaGalleriesDialogGtk::OnToggled(GtkWidget* widget) {
201 if (confirm_)
202 gtk_widget_set_sensitive(confirm_, TRUE);
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;
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;
224 void MediaGalleriesDialogGtk::OnAddFolder(GtkWidget* widget) {
225 controller_->OnAddFolderClicked();
228 void MediaGalleriesDialogGtk::OnConfirm(GtkWidget* widget) {
229 accepted_ = true;
231 if (window_)
232 gtk_widget_destroy(window_);
235 void MediaGalleriesDialogGtk::OnCancel(GtkWidget* widget) {
236 if (window_)
237 gtk_widget_destroy(window_);
240 void MediaGalleriesDialogGtk::OnDestroy(GtkWidget* widget) {
241 controller_->DialogFinished(accepted_);
244 // MediaGalleriesDialogController ----------------------------------------------
246 // static
247 MediaGalleriesDialog* MediaGalleriesDialog::Create(
248 MediaGalleriesDialogController* controller) {
249 return new MediaGalleriesDialogGtk(controller);