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