172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string>
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
93345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/environment.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/shell_integration.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/ui/gtk/gtk_util.h"
13ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "chrome/browser/ui/web_applications/web_app_ui.h"
15201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/extensions/extension.h"
16201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/extensions/extension_resource.h"
17dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/browser_thread.h"
18dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents.h"
19dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/tab_contents/tab_contents_delegate.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/locale_settings.h"
2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/base/l10n/l10n_util.h"
2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "ui/gfx/gtk_util.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Size (in pixels) of the icon preview.
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kIconPreviewSizePixels = 32;
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Height (in lines) of the shortcut description label.
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochconst int kDescriptionLabelHeightLines = 3;
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
37ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenvoid CreateWebApplicationShortcutsDialogGtk::Show(
38ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    GtkWindow* parent, TabContentsWrapper* tab_contents) {
39201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  new CreateWebApplicationShortcutsDialogGtk(parent, tab_contents);
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
42201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid CreateChromeApplicationShortcutsDialogGtk::Show(GtkWindow* parent,
43201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                                     const Extension* app) {
44201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  new CreateChromeApplicationShortcutsDialogGtk(parent, app);
45201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
46201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
47201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCreateApplicationShortcutsDialogGtk::CreateApplicationShortcutsDialogGtk(
49201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    GtkWindow* parent)
50201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  : parent_(parent),
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    desktop_checkbox_(NULL),
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    menu_checkbox_(NULL),
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    favicon_pixbuf_(NULL),
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    create_dialog_(NULL),
55201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    error_dialog_(NULL) {
56731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Will be balanced by Release later.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddRef();
60201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid CreateApplicationShortcutsDialogGtk::CreateIconPixBuf(
63201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    const SkBitmap& bitmap) {
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Prepare the icon. Try to scale it if it's too small, otherwise it would
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // look weird.
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GdkPixbuf* pixbuf = gfx::GdkPixbufFromSkBitmap(&shortcut_info_.favicon);
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int pixbuf_width = gdk_pixbuf_get_width(pixbuf);
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int pixbuf_height = gdk_pixbuf_get_height(pixbuf);
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pixbuf_width == pixbuf_height && pixbuf_width < kIconPreviewSizePixels) {
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Only scale the pixbuf if it's a square (for simplicity).
71201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    // Generally it should be square, if it's a favicon or app icon.
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Use the highest quality interpolation. The scaling is
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // going to have low quality anyway, because the initial image
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // is likely small.
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    favicon_pixbuf_ = gdk_pixbuf_scale_simple(pixbuf,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              kIconPreviewSizePixels,
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              kIconPreviewSizePixels,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              GDK_INTERP_HYPER);
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    g_object_unref(pixbuf);
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    favicon_pixbuf_ = pixbuf;
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
83201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid CreateApplicationShortcutsDialogGtk::CreateDialogBox(GtkWindow* parent) {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Build the dialog.
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  create_dialog_ = gtk_dialog_new_with_buttons(
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_TITLE).c_str(),
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      parent,
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NULL);
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_realize(create_dialog_);
9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  gtk_window_set_resizable(GTK_WINDOW(create_dialog_), false);
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_util::AddButtonToDialog(create_dialog_,
95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      l10n_util::GetStringUTF8(IDS_CANCEL).c_str(),
96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
97ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  gtk_util::AddButtonToDialog(create_dialog_,
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_COMMIT).c_str(),
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GTK_STOCK_APPLY, GTK_RESPONSE_ACCEPT);
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* content_area = GTK_DIALOG(create_dialog_)->vbox;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_set_spacing(GTK_BOX(content_area), gtk_util::kContentAreaSpacing);
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_add(GTK_CONTAINER(content_area), vbox);
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create a box containing basic information about the new shortcut: an image
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // on the left, and a description on the right.
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* hbox = gtk_hbox_new(FALSE, gtk_util::kControlSpacing);
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_set_border_width(GTK_CONTAINER(hbox),
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 gtk_util::kControlSpacing);
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Put the icon preview in place.
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* favicon_image = gtk_image_new_from_pixbuf(favicon_pixbuf_);
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_pack_start(GTK_BOX(hbox), favicon_image, FALSE, FALSE, 0);
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Create the label with application shortcut description.
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* description_label = gtk_label_new(NULL);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_pack_start(GTK_BOX(hbox), description_label, FALSE, FALSE, 0);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_label_set_line_wrap(GTK_LABEL(description_label), TRUE);
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_realize(description_label);
12321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Set the size request on the label so it knows where to line wrap. The width
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // is the desired size of the dialog less the space reserved for padding and
12621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // the image.
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  int label_width;
12821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  gtk_util::GetWidgetSizeFromResources(
12921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      description_label,
13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      IDS_CREATE_SHORTCUTS_DIALOG_WIDTH_CHARS, -1, &label_width, NULL);
13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  label_width -= gtk_util::kControlSpacing * 3 +
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      gdk_pixbuf_get_width(favicon_pixbuf_);
13372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  gtk_util::SetLabelWidth(description_label, label_width);
13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string description(UTF16ToUTF8(shortcut_info_.description));
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string title(UTF16ToUTF8(shortcut_info_.title));
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_label_set_text(GTK_LABEL(description_label),
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                     (description.empty() ? title : description).c_str());
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Label on top of the checkboxes.
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* checkboxes_label = gtk_label_new(
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_LABEL).c_str());
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_misc_set_alignment(GTK_MISC(checkboxes_label), 0, 0);
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_pack_start(GTK_BOX(vbox), checkboxes_label, FALSE, FALSE, 0);
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Desktop checkbox.
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  desktop_checkbox_ = gtk_check_button_new_with_label(
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_DESKTOP_CHKBOX).c_str());
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_pack_start(GTK_BOX(vbox), desktop_checkbox_, FALSE, FALSE, 0);
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(desktop_checkbox_), true);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(desktop_checkbox_, "toggled",
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnToggleCheckboxThunk), this);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Menu checkbox.
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  menu_checkbox_ = gtk_check_button_new_with_label(
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_MENU_CHKBOX).c_str());
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_pack_start(GTK_BOX(vbox), menu_checkbox_, FALSE, FALSE, 0);
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(menu_checkbox_), false);
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(menu_checkbox_, "toggled",
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnToggleCheckboxThunk), this);
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(create_dialog_, "response",
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnCreateDialogResponseThunk), this);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_show_all(create_dialog_);
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochCreateApplicationShortcutsDialogGtk::~CreateApplicationShortcutsDialogGtk() {
168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_destroy(create_dialog_);
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (error_dialog_)
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gtk_widget_destroy(error_dialog_);
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_object_unref(favicon_pixbuf_);
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CreateApplicationShortcutsDialogGtk::OnCreateDialogResponse(
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GtkWidget* widget, int response) {
180731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (response == GTK_RESPONSE_ACCEPT) {
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    shortcut_info_.create_on_desktop =
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(desktop_checkbox_));
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    shortcut_info_.create_in_applications_menu =
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(menu_checkbox_));
187731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         NewRunnableMethod(this,
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             &CreateApplicationShortcutsDialogGtk::CreateDesktopShortcut,
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             shortcut_info_));
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
192201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    OnCreatedShortcut();
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Release();
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CreateApplicationShortcutsDialogGtk::OnErrorDialogResponse(
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GtkWidget* widget, int response) {
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Release();
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CreateApplicationShortcutsDialogGtk::CreateDesktopShortcut(
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const ShellIntegration::ShortcutInfo& shortcut_info) {
205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_ptr<base::Environment> env(base::Environment::Create());
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string shortcut_template;
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (ShellIntegration::GetDesktopShortcutTemplate(env.get(),
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                   &shortcut_template)) {
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ShellIntegration::CreateDesktopShortcut(shortcut_info,
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                            shortcut_template);
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Release();
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewRunnableMethod(this,
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            &CreateApplicationShortcutsDialogGtk::ShowErrorDialog));
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CreateApplicationShortcutsDialogGtk::ShowErrorDialog() {
223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Hide the create dialog so that the user can no longer interact with it.
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_hide(create_dialog_);
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  error_dialog_ = gtk_dialog_new_with_buttons(
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_ERROR_TITLE).c_str(),
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NULL,
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      (GtkDialogFlags) (GTK_DIALOG_NO_SEPARATOR),
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GTK_STOCK_OK,
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GTK_RESPONSE_ACCEPT,
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NULL);
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_realize(error_dialog_);
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_util::SetWindowSizeFromResources(
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GTK_WINDOW(error_dialog_),
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDS_CREATE_SHORTCUTS_ERROR_DIALOG_WIDTH_CHARS,
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      IDS_CREATE_SHORTCUTS_ERROR_DIALOG_HEIGHT_LINES,
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      false);  // resizable
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* content_area = GTK_DIALOG(error_dialog_)->vbox;
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_set_spacing(GTK_BOX(content_area), gtk_util::kContentAreaSpacing);
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* vbox = gtk_vbox_new(FALSE, gtk_util::kControlSpacing);
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_container_add(GTK_CONTAINER(content_area), vbox);
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Label on top of the checkboxes.
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GtkWidget* description = gtk_label_new(
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetStringFUTF8(
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDS_CREATE_SHORTCUTS_ERROR_LABEL,
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          l10n_util::GetStringUTF16(IDS_PRODUCT_NAME)).c_str());
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_label_set_line_wrap(GTK_LABEL(description), TRUE);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_misc_set_alignment(GTK_MISC(description), 0, 0);
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_box_pack_start(GTK_BOX(vbox), description, FALSE, FALSE, 0);
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  g_signal_connect(error_dialog_, "response",
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                   G_CALLBACK(OnErrorDialogResponseThunk), this);
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_widget_show_all(error_dialog_);
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid CreateApplicationShortcutsDialogGtk::OnToggleCheckbox(GtkWidget* sender) {
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gboolean can_accept = FALSE;
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(desktop_checkbox_)) ||
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(menu_checkbox_))) {
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    can_accept = TRUE;
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  gtk_dialog_set_response_sensitive(GTK_DIALOG(create_dialog_),
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    GTK_RESPONSE_ACCEPT,
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    can_accept);
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
273201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
274201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochCreateWebApplicationShortcutsDialogGtk::CreateWebApplicationShortcutsDialogGtk(
275201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    GtkWindow* parent,
276ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TabContentsWrapper* tab_contents)
277201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  : CreateApplicationShortcutsDialogGtk(parent),
278201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    tab_contents_(tab_contents) {
279201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
280201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Get shortcut information now, it's needed for our UI.
281201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  web_app::GetShortcutInfoForTab(tab_contents_, &shortcut_info_);
282201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CreateIconPixBuf(shortcut_info_.favicon);
283201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
284201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CreateDialogBox(parent);
285201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
286201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
287201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid CreateWebApplicationShortcutsDialogGtk::OnCreatedShortcut() {
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (tab_contents_->tab_contents()->delegate())
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    tab_contents_->tab_contents()->delegate()->ConvertContentsToApplication(
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        tab_contents_->tab_contents());
291201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
292201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochCreateChromeApplicationShortcutsDialogGtk::
294201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    CreateChromeApplicationShortcutsDialogGtk(
295201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        GtkWindow* parent,
296201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        const Extension* app)
297201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      : CreateApplicationShortcutsDialogGtk(parent),
298201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        app_(app),
299201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this))  {
300201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
301201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Get shortcut information now, it's needed for our UI.
302dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  shortcut_info_.extension_id = app_->id();
303201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  shortcut_info_.url = GURL(app_->launch_web_url());
304201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  shortcut_info_.title = UTF8ToUTF16(app_->name());
305201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  shortcut_info_.description = UTF8ToUTF16(app_->description());
306201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
307201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Get the icon.
308201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const gfx::Size max_size(kIconPreviewSizePixels, kIconPreviewSizePixels);
309201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ExtensionResource icon_resource = app_->GetIconResource(
310201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch      kIconPreviewSizePixels, ExtensionIconSet::MATCH_BIGGER);
311201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
312201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // If no icon exists that is the desired size or larger, get the
313201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // largest icon available:
314201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (icon_resource.empty())
315201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    icon_resource = app_->GetIconResource(
316201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch        kIconPreviewSizePixels, ExtensionIconSet::MATCH_SMALLER);
317201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
318201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  tracker_.LoadImage(app_,
319201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                     icon_resource,
320201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                     max_size,
321201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                     ImageLoadingTracker::DONT_CACHE);
322201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
323201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
324201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// Called by tracker_ when the app's icon is loaded.
325201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdochvoid CreateChromeApplicationShortcutsDialogGtk::OnImageLoaded(
326ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    SkBitmap* image, const ExtensionResource& resource, int index) {
327201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  if (image->isNull()) {
328201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    NOTREACHED() << "Corrupt image in profile?";
329201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch    return;
330201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  }
331201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  shortcut_info_.favicon = *image;
332201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
333201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CreateIconPixBuf(*image);
334201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  CreateDialogBox(parent_);
335201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
336