Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1021)

Side by Side Diff: chrome/browser/ui/gtk/extensions/extension_install_dialog_gtk.cc

Issue 10696042: [gtk] add oauth2 scopes zippies in extension install dialog (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: i18n Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 <gtk/gtk.h> 5 #include <gtk/gtk.h>
6 6
7 #include "base/i18n/rtl.h" 7 #include "base/i18n/rtl.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "chrome/browser/extensions/bundle_installer.h" 10 #include "chrome/browser/extensions/bundle_installer.h"
(...skipping 13 matching lines...) Expand all
24 #include "ui/base/resource/resource_bundle.h" 24 #include "ui/base/resource/resource_bundle.h"
25 #include "ui/gfx/gtk_util.h" 25 #include "ui/gfx/gtk_util.h"
26 26
27 using content::OpenURLParams; 27 using content::OpenURLParams;
28 using extensions::BundleInstaller; 28 using extensions::BundleInstaller;
29 29
30 namespace { 30 namespace {
31 31
32 const int kLeftColumnMinWidth = 250; 32 const int kLeftColumnMinWidth = 250;
33 const int kImageSize = 69; 33 const int kImageSize = 69;
34 const int kDetailIndent = 20;
34 35
35 // Additional padding (beyond on ui::kControlSpacing) all sides of each 36 // Additional padding (beyond on ui::kControlSpacing) all sides of each
36 // permission in the permissions list. 37 // permission in the permissions list.
37 const int kPermissionsPadding = 2; 38 const int kPermissionsPadding = 2;
38 const int kExtensionsPadding = kPermissionsPadding; 39 const int kExtensionsPadding = kPermissionsPadding;
39 40
40 const double kRatingTextSize = 12.1; // 12.1px = 9pt @ 96dpi 41 const double kRatingTextSize = 12.1; // 12.1px = 9pt @ 96dpi
41 42
42 // Adds a Skia image as an icon control to the given container. 43 // Adds a Skia image as an icon control to the given container.
43 void AddResourceIcon(const gfx::ImageSkia* icon, void* data) { 44 void AddResourceIcon(const gfx::ImageSkia* icon, void* data) {
44 GtkWidget* container = static_cast<GtkWidget*>(data); 45 GtkWidget* container = static_cast<GtkWidget*>(data);
45 GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(*icon); 46 GdkPixbuf* icon_pixbuf = gfx::GdkPixbufFromSkBitmap(*icon);
46 GtkWidget* icon_widget = gtk_image_new_from_pixbuf(icon_pixbuf); 47 GtkWidget* icon_widget = gtk_image_new_from_pixbuf(icon_pixbuf);
47 g_object_unref(icon_pixbuf); 48 g_object_unref(icon_pixbuf);
48 gtk_box_pack_start(GTK_BOX(container), icon_widget, FALSE, FALSE, 0); 49 gtk_box_pack_start(GTK_BOX(container), icon_widget, FALSE, FALSE, 0);
49 } 50 }
50 51
52 void OnZippyButtonRealize(GtkWidget* event_box, gpointer unused) {
53 gdk_window_set_cursor(event_box->window, gfx::GetCursor(GDK_HAND2));
54 }
55
56 gboolean OnZippyButtonRelease(GtkWidget* event_box,
57 GdkEvent* event,
58 GtkWidget* detail_box) {
59 if (event->button.button != 1)
60 return FALSE;
61
62 GtkWidget* arrow =
63 GTK_WIDGET(gtk_object_get_data(GTK_OBJECT(event_box), "arrow"));
64
65 if (gtk_widget_get_visible(detail_box)) {
66 gtk_widget_hide(detail_box);
67 gtk_arrow_set(GTK_ARROW(arrow), GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
68 } else {
69 gtk_widget_set_no_show_all(detail_box, FALSE);
70 gtk_widget_show_all(detail_box);
71 gtk_widget_set_no_show_all(detail_box, TRUE);
72 gtk_arrow_set(GTK_ARROW(arrow), GTK_ARROW_DOWN, GTK_SHADOW_OUT);
73 }
74
75 return TRUE;
76 }
77
51 } // namespace 78 } // namespace
52 79
53 namespace browser { 80 namespace browser {
54 81
55 // Displays the dialog when constructed, deletes itself when dialog is 82 // Displays the dialog when constructed, deletes itself when dialog is
56 // dismissed. Success/failure is passed back through the 83 // dismissed. Success/failure is passed back through the
57 // ExtensionInstallPrompt::Delegate instance. 84 // ExtensionInstallPrompt::Delegate instance.
58 class ExtensionInstallDialog { 85 class ExtensionInstallDialog {
59 public: 86 public:
60 ExtensionInstallDialog(Browser* browser, 87 ExtensionInstallDialog(Browser* browser,
61 GtkWindow* parent, 88 GtkWindow* parent,
62 ExtensionInstallPrompt::Delegate *delegate, 89 ExtensionInstallPrompt::Delegate *delegate,
63 const ExtensionInstallPrompt::Prompt& prompt); 90 const ExtensionInstallPrompt::Prompt& prompt);
64 private: 91 private:
65 ~ExtensionInstallDialog(); 92 ~ExtensionInstallDialog();
66 93
67 CHROMEGTK_CALLBACK_1(ExtensionInstallDialog, void, OnResponse, int); 94 CHROMEGTK_CALLBACK_1(ExtensionInstallDialog, void, OnResponse, int);
68 CHROMEGTK_CALLBACK_0(ExtensionInstallDialog, void, OnStoreLinkClick); 95 CHROMEGTK_CALLBACK_0(ExtensionInstallDialog, void, OnStoreLinkClick);
69 96
97 GtkWidget* CreateWidgetForIssueAdvice(
98 const IssueAdviceInfoEntry& issue_advice, int pixel_width);
99
70 Browser* browser_; 100 Browser* browser_;
71 ExtensionInstallPrompt::Delegate* delegate_; 101 ExtensionInstallPrompt::Delegate* delegate_;
72 std::string extension_id_; // Set for INLINE_INSTALL_PROMPT. 102 std::string extension_id_; // Set for INLINE_INSTALL_PROMPT.
73 GtkWidget* dialog_; 103 GtkWidget* dialog_;
74 }; 104 };
75 105
76 ExtensionInstallDialog::ExtensionInstallDialog( 106 ExtensionInstallDialog::ExtensionInstallDialog(
77 Browser* browser, 107 Browser* browser,
78 GtkWindow* parent, 108 GtkWindow* parent,
79 ExtensionInstallPrompt::Delegate *delegate, 109 ExtensionInstallPrompt::Delegate *delegate,
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
120 150
121 // Create a two column layout for the top (item data on the left, icon on 151 // Create a two column layout for the top (item data on the left, icon on
122 // the right). 152 // the right).
123 GtkWidget* top_content_hbox = gtk_hbox_new(FALSE, ui::kContentAreaSpacing); 153 GtkWidget* top_content_hbox = gtk_hbox_new(FALSE, ui::kContentAreaSpacing);
124 gtk_box_pack_start(GTK_BOX(content_vbox), top_content_hbox, TRUE, TRUE, 0); 154 gtk_box_pack_start(GTK_BOX(content_vbox), top_content_hbox, TRUE, TRUE, 0);
125 155
126 // Create a new vbox for the left column. 156 // Create a new vbox for the left column.
127 GtkWidget* left_column_area = gtk_vbox_new(FALSE, ui::kControlSpacing); 157 GtkWidget* left_column_area = gtk_vbox_new(FALSE, ui::kControlSpacing);
128 gtk_box_pack_start(GTK_BOX(top_content_hbox), left_column_area, 158 gtk_box_pack_start(GTK_BOX(top_content_hbox), left_column_area,
129 TRUE, TRUE, 0); 159 TRUE, TRUE, 0);
160 gtk_widget_set_size_request(left_column_area, kLeftColumnMinWidth, -1);
130 161
131 GtkWidget* heading_vbox = gtk_vbox_new(FALSE, 0); 162 GtkWidget* heading_vbox = gtk_vbox_new(FALSE, 0);
132 // If we are not going to show anything else, vertically center the title. 163 // If we are not going to show anything else, vertically center the title.
133 bool center_heading = 164 bool center_heading =
134 !show_permissions && !show_oauth_issues && !is_inline_install; 165 !show_permissions && !show_oauth_issues && !is_inline_install;
135 gtk_box_pack_start(GTK_BOX(left_column_area), heading_vbox, center_heading, 166 gtk_box_pack_start(GTK_BOX(left_column_area), heading_vbox, center_heading,
136 center_heading, 0); 167 center_heading, 0);
137 168
138 // Heading 169 // Heading
139 GtkWidget* heading_label = gtk_util::CreateBoldLabel( 170 GtkWidget* heading_label = gtk_util::CreateBoldLabel(
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 for (size_t i = 0; i < prompt.GetPermissionCount(); ++i) { 261 for (size_t i = 0; i < prompt.GetPermissionCount(); ++i) {
231 GtkWidget* permission_label = gtk_label_new(UTF16ToUTF8( 262 GtkWidget* permission_label = gtk_label_new(UTF16ToUTF8(
232 prompt.GetPermission(i)).c_str()); 263 prompt.GetPermission(i)).c_str());
233 gtk_util::SetLabelWidth(permission_label, kLeftColumnMinWidth); 264 gtk_util::SetLabelWidth(permission_label, kLeftColumnMinWidth);
234 gtk_box_pack_start(GTK_BOX(permissions_container), permission_label, 265 gtk_box_pack_start(GTK_BOX(permissions_container), permission_label,
235 FALSE, FALSE, kPermissionsPadding); 266 FALSE, FALSE, kPermissionsPadding);
236 } 267 }
237 } 268 }
238 269
239 if (show_oauth_issues) { 270 if (show_oauth_issues) {
240 GtkWidget* oauth_issues_container; 271 // If permissions are shown, then the scopes will go below them and take
241 if (is_inline_install) { 272 // up the entire width of the dialog. Otherwise the scopes will go where
242 oauth_issues_container = content_vbox; 273 // the permissions usually go.
243 gtk_box_pack_start(GTK_BOX(content_vbox), gtk_hseparator_new(), 274 GtkWidget* oauth_issues_container =
244 FALSE, FALSE, ui::kControlSpacing); 275 show_permissions ? content_vbox : left_column_area;
245 } else { 276 int pixel_width = kLeftColumnMinWidth +
246 oauth_issues_container = left_column_area; 277 (show_permissions ? kImageSize : 0);
247 }
248 278
249 GtkWidget* oauth_issues_header = gtk_util::CreateBoldLabel( 279 GtkWidget* oauth_issues_header = gtk_util::CreateBoldLabel(
250 "The app wants these scopes:"); 280 UTF16ToUTF8(prompt.GetOAuthHeading()).c_str());
251 gtk_util::SetLabelWidth(oauth_issues_header, kLeftColumnMinWidth); 281 gtk_util::SetLabelWidth(oauth_issues_header, pixel_width);
252 gtk_box_pack_start(GTK_BOX(oauth_issues_container), oauth_issues_header, 282 gtk_box_pack_start(GTK_BOX(oauth_issues_container), oauth_issues_header,
253 FALSE, FALSE, 0); 283 FALSE, FALSE, 0);
254 284
255 // TODO(estade): display the issue details under zippies. 285 // TODO(estade): display the issue details under zippies.
256 for (size_t i = 0; i < prompt.GetOAuthIssueCount(); ++i) { 286 for (size_t i = 0; i < prompt.GetOAuthIssueCount(); ++i) {
257 GtkWidget* label = gtk_label_new( 287 GtkWidget* issue_advice_widget =
258 prompt.GetOAuthIssue(i).description.c_str()); 288 CreateWidgetForIssueAdvice(prompt.GetOAuthIssue(i), pixel_width);
259 gtk_util::SetLabelWidth(label, kLeftColumnMinWidth); 289 gtk_box_pack_start(GTK_BOX(oauth_issues_container), issue_advice_widget,
260 gtk_box_pack_start(GTK_BOX(oauth_issues_container), label,
261 FALSE, FALSE, kPermissionsPadding); 290 FALSE, FALSE, kPermissionsPadding);
262 } 291 }
263 } 292 }
264 293
265 g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this); 294 g_signal_connect(dialog_, "response", G_CALLBACK(OnResponseThunk), this);
266 gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE); 295 gtk_window_set_resizable(GTK_WINDOW(dialog_), FALSE);
267 296
268 gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_CLOSE); 297 gtk_dialog_set_default_response(GTK_DIALOG(dialog_), GTK_RESPONSE_CLOSE);
269 gtk_widget_show_all(dialog_); 298 gtk_widget_show_all(dialog_);
270 gtk_widget_grab_focus(close_button); 299 gtk_widget_grab_focus(close_button);
271 } 300 }
272 301
273 ExtensionInstallDialog::~ExtensionInstallDialog() { 302 ExtensionInstallDialog::~ExtensionInstallDialog() {
274 } 303 }
275 304
276 void ExtensionInstallDialog::OnResponse(GtkWidget* dialog, int response_id) { 305 void ExtensionInstallDialog::OnResponse(GtkWidget* dialog, int response_id) {
277 if (response_id == GTK_RESPONSE_ACCEPT) { 306 if (response_id == GTK_RESPONSE_ACCEPT)
278 delegate_->InstallUIProceed(); 307 delegate_->InstallUIProceed();
279 } else { 308 else
280 delegate_->InstallUIAbort(true); 309 delegate_->InstallUIAbort(true);
281 }
282 310
283 gtk_widget_destroy(dialog_); 311 gtk_widget_destroy(dialog_);
284 delete this; 312 delete this;
285 } 313 }
286 314
287 void ExtensionInstallDialog::OnStoreLinkClick(GtkWidget* sender) { 315 void ExtensionInstallDialog::OnStoreLinkClick(GtkWidget* sender) {
288 GURL store_url( 316 GURL store_url(
289 extension_urls::GetWebstoreItemDetailURLPrefix() + extension_id_); 317 extension_urls::GetWebstoreItemDetailURLPrefix() + extension_id_);
290 browser_->OpenURL(OpenURLParams( 318 browser_->OpenURL(OpenURLParams(
291 store_url, content::Referrer(), NEW_FOREGROUND_TAB, 319 store_url, content::Referrer(), NEW_FOREGROUND_TAB,
292 content::PAGE_TRANSITION_LINK, false)); 320 content::PAGE_TRANSITION_LINK, false));
293 321
294 OnResponse(dialog_, GTK_RESPONSE_CLOSE); 322 OnResponse(dialog_, GTK_RESPONSE_CLOSE);
295 } 323 }
296 324
325 GtkWidget* ExtensionInstallDialog::CreateWidgetForIssueAdvice(
326 const IssueAdviceInfoEntry& issue_advice, int pixel_width) {
327 GtkWidget* box = gtk_vbox_new(FALSE, ui::kControlSpacing);
328 GtkWidget* header = gtk_hbox_new(FALSE, 0);
329 GtkWidget* event_box = gtk_event_box_new();
330 gtk_container_add(GTK_CONTAINER(event_box), header);
331 gtk_box_pack_start(GTK_BOX(box), event_box, FALSE, FALSE,
332 kPermissionsPadding);
333
334 GtkWidget* arrow = NULL;
335 GtkWidget* label = NULL;
336 int label_pixel_width = pixel_width;
337
338 if (issue_advice.details.empty()) {
339 label = gtk_label_new(l10n_util::GetStringFUTF8(
340 IDS_EXTENSION_PERMISSION_LINE,
341 UTF8ToUTF16(issue_advice.description)).c_str());
342 } else {
343 arrow = gtk_arrow_new(GTK_ARROW_RIGHT, GTK_SHADOW_OUT);
344 GtkRequisition req;
345 gtk_widget_size_request(arrow, &req);
346 label_pixel_width -= req.width;
347
348 label = gtk_label_new(issue_advice.description.c_str());
349
350 GtkWidget* detail_box = gtk_vbox_new(FALSE, ui::kControlSpacing);
351 gtk_box_pack_start(GTK_BOX(box), detail_box, FALSE, FALSE, 0);
352 gtk_widget_set_no_show_all(detail_box, TRUE);
353 gtk_object_set_data(GTK_OBJECT(event_box), "arrow", arrow);
354
355 for (size_t i = 0; i < issue_advice.details.size(); ++i) {
356 std::string text = l10n_util::GetStringFUTF8(
357 IDS_EXTENSION_PERMISSION_LINE, UTF8ToUTF16(issue_advice.details[i]));
358 GtkWidget* label = gtk_label_new(text.c_str());
359 gtk_util::SetLabelWidth(label, pixel_width - kDetailIndent);
360
361 GtkWidget* align = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
362 gtk_alignment_set_padding(GTK_ALIGNMENT(align), 0, 0, kDetailIndent, 0);
363 gtk_container_add(GTK_CONTAINER(align), label);
364 gtk_box_pack_start(GTK_BOX(detail_box), align, FALSE, FALSE,
365 kPermissionsPadding);
366 }
367
368 g_signal_connect(event_box, "realize",
369 G_CALLBACK(OnZippyButtonRealize), NULL);
370 g_signal_connect(event_box, "button-release-event",
371 G_CALLBACK(OnZippyButtonRelease), detail_box);
372 }
373
374 gtk_util::SetLabelWidth(label, label_pixel_width);
375 if (arrow)
376 gtk_box_pack_start(GTK_BOX(header), arrow, FALSE, FALSE, 0);
377 gtk_box_pack_start(GTK_BOX(header), label, TRUE, TRUE, 0);
378
379 return box;
380 }
381
297 } // namespace browser 382 } // namespace browser
298 383
299 void ShowExtensionInstallDialogImpl( 384 void ShowExtensionInstallDialogImpl(
300 Browser* browser, 385 Browser* browser,
301 ExtensionInstallPrompt::Delegate* delegate, 386 ExtensionInstallPrompt::Delegate* delegate,
302 const ExtensionInstallPrompt::Prompt& prompt) { 387 const ExtensionInstallPrompt::Prompt& prompt) {
303 BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>( 388 BrowserWindowGtk* browser_window = static_cast<BrowserWindowGtk*>(
304 browser->window()); 389 browser->window());
305 if (!browser_window) { 390 if (!browser_window) {
306 delegate->InstallUIAbort(false); 391 delegate->InstallUIAbort(false);
307 return; 392 return;
308 } 393 }
309 394
310 new browser::ExtensionInstallDialog(browser, browser_window->window(), 395 new browser::ExtensionInstallDialog(browser, browser_window->window(),
311 delegate, prompt); 396 delegate, prompt);
312 } 397 }
OLDNEW
« chrome/app/generated_resources.grd ('K') | « chrome/browser/extensions/extension_install_prompt.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698