create_application_shortcuts_dialog_gtk.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/create_application_shortcuts_dialog_gtk.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/environment.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/shell_integration.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/shell_integration_linux.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_dialogs.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/gtk/gtk_util.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/web_applications/web_app_ui.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/web_applications/web_app.h"
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/api/icons/icons_handler.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/chromium_strings.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/locale_settings.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/gtk/gtk_hig_constants.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/gtk_util.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_skia.h"
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/gfx/image/image_skia_rep.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using extensions::Extension;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Size (in pixels) of the icon preview.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kIconPreviewSizePixels = 32;
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Minimum width (in pixels) of the shortcut description label.
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const int kDescriptionLabelMinimumWidthPixels = 200;
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Height (in lines) of the shortcut description label.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kDescriptionLabelHeightLines = 3;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowCreateWebAppShortcutsDialog(gfx::NativeWindow parent_window,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     content::WebContents* web_contents) {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new CreateWebApplicationShortcutsDialogGtk(parent_window, web_contents);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateChromeApplicationShortcutsDialogGtk::Show(GtkWindow* parent,
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     Profile* profile,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     const Extension* app) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  new CreateChromeApplicationShortcutsDialogGtk(parent, profile, app);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateApplicationShortcutsDialogGtk::CreateApplicationShortcutsDialogGtk(
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWindow* parent)
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : parent_(parent),
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    desktop_checkbox_(NULL),
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    menu_checkbox_(NULL),
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    favicon_pixbuf_(NULL),
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    create_dialog_(NULL),
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    error_dialog_(NULL) {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Will be balanced by Release later.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddRef();
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutsDialogGtk::CreateIconPixBuf(
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Image& image) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkia& image_skia = *(image.ToImageSkia());
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<gfx::ImageSkiaRep> image_reps = image_skia.image_reps();
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Find the smallest icon bigger or equal to the desired size. If it cannot be
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // found, find the biggest icon smaller than the desired size.
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkiaRep* smallest_larger = NULL;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const gfx::ImageSkiaRep* largest_smaller = NULL;
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<gfx::ImageSkiaRep>::const_iterator it = image_reps.begin();
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != image_reps.end(); ++it) {
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->pixel_width() >= kIconPreviewSizePixels) {
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!smallest_larger ||
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          it->pixel_width() < smallest_larger->pixel_width()) {
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        smallest_larger = &*it;
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (!largest_smaller ||
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          it->pixel_width() > largest_smaller->pixel_width()) {
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        largest_smaller = &*it;
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      }
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  GdkPixbuf* pixbuf;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (smallest_larger) {
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pixbuf = gfx::GdkPixbufFromSkBitmap(smallest_larger->sk_bitmap());
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else if (largest_smaller) {
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pixbuf = gfx::GdkPixbufFromSkBitmap(largest_smaller->sk_bitmap());
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  } else {
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Should never happen unless the image has no representations. Call
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // ToGdkPixbuf which will presumably return a null image representation.
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    pixbuf = static_cast<GdkPixbuf*>(g_object_ref(image.ToGdkPixbuf()));
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Prepare the icon. Scale it to the correct size to display in the dialog.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pixbuf_width = gdk_pixbuf_get_width(pixbuf);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int pixbuf_height = gdk_pixbuf_get_height(pixbuf);
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (pixbuf_width == pixbuf_height) {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Only scale the pixbuf if it's a square (for simplicity).
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Generally it should be square, if it's a favicon or app icon.
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    // Use the highest quality interpolation.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    favicon_pixbuf_ = gdk_pixbuf_scale_simple(pixbuf,
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              kIconPreviewSizePixels,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              kIconPreviewSizePixels,
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              GDK_INTERP_HYPER);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_object_unref(pixbuf);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    favicon_pixbuf_ = pixbuf;
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutsDialogGtk::CreateDialogBox(GtkWindow* parent) {
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Build the dialog.
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  create_dialog_ = gtk_dialog_new_with_buttons(
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_TITLE).c_str(),
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent,
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_NO_SEPARATOR),
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_realize(create_dialog_);
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_window_set_resizable(GTK_WINDOW(create_dialog_), false);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::AddButtonToDialog(create_dialog_,
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_CANCEL).c_str(),
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::AddButtonToDialog(create_dialog_,
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_COMMIT).c_str(),
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GTK_STOCK_APPLY, GTK_RESPONSE_ACCEPT);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* content_area =
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_dialog_get_content_area(GTK_DIALOG(create_dialog_));
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_set_spacing(GTK_BOX(content_area), ui::kContentAreaSpacing);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kControlSpacing);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_add(GTK_CONTAINER(content_area), vbox);
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create a box containing basic information about the new shortcut: an image
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // on the left, and a description on the right.
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* hbox = gtk_hbox_new(FALSE, ui::kControlSpacing);
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_set_border_width(GTK_CONTAINER(hbox),
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 ui::kControlSpacing);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Put the icon preview in place.
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* favicon_image = gtk_image_new_from_pixbuf(favicon_pixbuf_);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(hbox), favicon_image, FALSE, FALSE, 0);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create the label with application shortcut description.
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* description_label = gtk_label_new(NULL);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(hbox), description_label, FALSE, FALSE, 0);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_label_set_line_wrap(GTK_LABEL(description_label), TRUE);
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_realize(description_label);
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set the size request on the label so it knows where to line wrap. The width
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is the desired size of the dialog less the space reserved for padding and
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the image.
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int label_width;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::GetWidgetSizeFromResources(
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      description_label,
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_CREATE_SHORTCUTS_DIALOG_WIDTH_CHARS, -1, &label_width, NULL);
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  label_width -= ui::kControlSpacing * 3 +
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gdk_pixbuf_get_width(favicon_pixbuf_);
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Enforce a minimum width, so that very large icons do not cause the label
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // width to shrink to unreadable size, or become negative (which would crash).
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (label_width < kDescriptionLabelMinimumWidthPixels)
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    label_width = kDescriptionLabelMinimumWidthPixels;
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::SetLabelWidth(description_label, label_width);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string description(UTF16ToUTF8(shortcut_info_.description));
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string title(UTF16ToUTF8(shortcut_info_.title));
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_label_set_text(GTK_LABEL(description_label),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     (description.empty() ? title : description).c_str());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Label on top of the checkboxes.
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* checkboxes_label = gtk_label_new(
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_LABEL).c_str());
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_misc_set_alignment(GTK_MISC(checkboxes_label), 0, 0);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(vbox), checkboxes_label, FALSE, FALSE, 0);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Desktop checkbox.
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desktop_checkbox_ = gtk_check_button_new_with_label(
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_DESKTOP_CHKBOX).c_str());
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(vbox), desktop_checkbox_, FALSE, FALSE, 0);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(desktop_checkbox_), true);
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_signal_connect(desktop_checkbox_, "toggled",
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   G_CALLBACK(OnToggleCheckboxThunk), this);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Menu checkbox.
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_checkbox_ = gtk_check_button_new_with_label(
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_MENU_CHKBOX).c_str());
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(vbox), menu_checkbox_, FALSE, FALSE, 0);
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(menu_checkbox_), false);
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_signal_connect(menu_checkbox_, "toggled",
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   G_CALLBACK(OnToggleCheckboxThunk), this);
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_signal_connect(create_dialog_, "response",
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   G_CALLBACK(OnCreateDialogResponseThunk), this);
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_show_all(create_dialog_);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateApplicationShortcutsDialogGtk::~CreateApplicationShortcutsDialogGtk() {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_destroy(create_dialog_);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (error_dialog_)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gtk_widget_destroy(error_dialog_);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_object_unref(favicon_pixbuf_);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutsDialogGtk::OnCreateDialogResponse(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* widget, int response) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response == GTK_RESPONSE_ACCEPT) {
2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ShellIntegration::ShortcutLocations creation_locations;
2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    creation_locations.on_desktop =
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(desktop_checkbox_));
2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    creation_locations.in_applications_menu =
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(menu_checkbox_));
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::FILE, FROM_HERE,
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&CreateApplicationShortcutsDialogGtk::CreateDesktopShortcut,
2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   this, shortcut_info_, creation_locations));
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    OnCreatedShortcut();
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Release();
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutsDialogGtk::OnErrorDialogResponse(
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWidget* widget, int response) {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Release();
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutsDialogGtk::CreateDesktopShortcut(
2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info,
2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShellIntegration::ShortcutLocations& creation_locations) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<base::Environment> env(base::Environment::Create());
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string shortcut_template;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (ShellIntegrationLinux::GetDesktopShortcutTemplate(env.get(),
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        &shortcut_template)) {
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ShellIntegrationLinux::CreateDesktopShortcut(shortcut_info,
2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                 creation_locations,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 shortcut_template);
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Release();
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&CreateApplicationShortcutsDialogGtk::ShowErrorDialog,
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutsDialogGtk::ShowErrorDialog() {
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Hide the create dialog so that the user can no longer interact with it.
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_hide(create_dialog_);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  error_dialog_ = gtk_dialog_new_with_buttons(
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_ERROR_TITLE).c_str(),
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (GtkDialogFlags) (GTK_DIALOG_NO_SEPARATOR),
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GTK_STOCK_OK,
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GTK_RESPONSE_ACCEPT,
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_realize(error_dialog_);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_util::SetWindowSizeFromResources(
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GTK_WINDOW(error_dialog_),
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_CREATE_SHORTCUTS_ERROR_DIALOG_WIDTH_CHARS,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      IDS_CREATE_SHORTCUTS_ERROR_DIALOG_HEIGHT_LINES,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      false);  // resizable
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* content_area =
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_dialog_get_content_area(GTK_DIALOG(error_dialog_));
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_set_spacing(GTK_BOX(content_area), ui::kContentAreaSpacing);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* vbox = gtk_vbox_new(FALSE, ui::kControlSpacing);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_container_add(GTK_CONTAINER(content_area), vbox);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Label on top of the checkboxes.
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GtkWidget* description = gtk_label_new(
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF8(IDS_CREATE_SHORTCUTS_ERROR_LABEL).c_str());
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_label_set_line_wrap(GTK_LABEL(description), TRUE);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_misc_set_alignment(GTK_MISC(description), 0, 0);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_box_pack_start(GTK_BOX(vbox), description, FALSE, FALSE, 0);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  g_signal_connect(error_dialog_, "response",
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   G_CALLBACK(OnErrorDialogResponseThunk), this);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_widget_show_all(error_dialog_);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutsDialogGtk::OnToggleCheckbox(GtkWidget* sender) {
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gboolean can_accept = FALSE;
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(desktop_checkbox_)) ||
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(menu_checkbox_))) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    can_accept = TRUE;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gtk_dialog_set_response_sensitive(GTK_DIALOG(create_dialog_),
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    GTK_RESPONSE_ACCEPT,
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    can_accept);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateWebApplicationShortcutsDialogGtk::CreateWebApplicationShortcutsDialogGtk(
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GtkWindow* parent,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WebContents* web_contents)
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  : CreateApplicationShortcutsDialogGtk(parent),
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_contents_(web_contents) {
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get shortcut information now, it's needed for our UI.
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_app::GetShortcutInfoForTab(web_contents, &shortcut_info_);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateIconPixBuf(shortcut_info_.favicon);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDialogBox(parent);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateWebApplicationShortcutsDialogGtk::OnCreatedShortcut() {
3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Browser* browser = chrome::FindBrowserWithWebContents(web_contents_);
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome::ConvertTabToAppWindow(browser, web_contents_);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateChromeApplicationShortcutsDialogGtk::
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CreateChromeApplicationShortcutsDialogGtk(
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GtkWindow* parent,
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Profile* profile,
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        const Extension* app)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : CreateApplicationShortcutsDialogGtk(parent),
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        app_(app),
3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        profile_path_(profile->GetPath())  {
3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get shortcut information and icon now; they are needed for our UI.
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  web_app::UpdateShortcutInfoAndIconForApp(
3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      *app, profile,
3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::Bind(
3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          &CreateChromeApplicationShortcutsDialogGtk::OnShortcutInfoLoaded,
3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          this));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Called when the app's ShortcutInfo (with icon) is loaded.
3652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CreateChromeApplicationShortcutsDialogGtk::OnShortcutInfoLoaded(
3662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const ShellIntegration::ShortcutInfo& shortcut_info) {
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shortcut_info_ = shortcut_info;
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateIconPixBuf(shortcut_info_.favicon);
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateDialogBox(parent_);
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateChromeApplicationShortcutsDialogGtk::CreateDesktopShortcut(
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShellIntegration::ShortcutInfo& shortcut_info,
3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const ShellIntegration::ShortcutLocations& creation_locations) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (web_app::CreateShortcutsOnFileThread(shortcut_info, creation_locations)) {
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Release();
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&CreateChromeApplicationShortcutsDialogGtk::ShowErrorDialog,
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   this));
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
386