try: -b do -p all -u all -t none
authorJan Horak <jhorak@redhat.com>
Mon, 02 Feb 2015 14:36:24 +0100
changeset 372564 c6e94821baf2e4672af8cbd6e896b814ee6d3500
parent 347871 70de2960aa877d7755ee6f66bf2d4c4c46bfed2c
child 392026 e833aef2bb2654ccd16abf0ba3428700551886b7
push id51815
push userjhorak@redhat.com
push dateMon, 02 Feb 2015 13:36:57 +0000
treeherdertry@c6e94821baf2 [default view] [failures only]
milestone37.0a1
try: -b do -p all -u all -t none
toolkit/mozapps/downloads/nsHelperAppDlg.js
widget/gtk/moz.build
widget/gtk/mozgtk/mozgtk.c
widget/gtk/nsApplicationChooser.cpp
widget/gtk/nsWidgetFactory.cpp
widget/moz.build
widget/nsIApplicationChooser.idl
widget/nsWidgetsCID.h
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js
+++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js
@@ -1038,16 +1038,30 @@ nsUnknownContentTypeDialog.prototype = {
 
     if (params.handlerApp &&
         params.handlerApp.executable &&
         params.handlerApp.executable.isFile()) {
       // Remember the file they chose to run.
       this.chosenApp = params.handlerApp;
 
 #else
+#ifdef XP_LINUX
+      
+    var nsIApplicationChooser = Components.interfaces.nsIApplicationChooser;
+    var ac = Components.classes["@mozilla.org/applicationchooser;1"]
+                       .createInstance(nsIApplicationChooser);
+    ac.init(this.mDialog, this.dialogElement("strings").getString("chooseAppFilePickerTitle"));
+    ac.show(this.mLauncher.MIMEInfo.MIMEType);
+    if (ac.appCmdline) {
+      var localHandlerApp =
+        Components.classes["@mozilla.org/uriloader/local-handler-app;1"].
+                   createInstance(Components.interfaces.nsILocalHandlerApp);
+      localHandlerApp.executable = new FileUtils.File(ac.appCmdline);
+      this.chosenApp = localHandlerApp;
+#else
     var nsIFilePicker = Components.interfaces.nsIFilePicker;
     var fp = Components.classes["@mozilla.org/filepicker;1"]
                        .createInstance(nsIFilePicker);
     fp.init(this.mDialog,
             this.dialogElement("strings").getString("chooseAppFilePickerTitle"),
             nsIFilePicker.modeOpen);
 
     fp.appendFilters(nsIFilePicker.filterApps);
@@ -1056,25 +1070,31 @@ nsUnknownContentTypeDialog.prototype = {
       // Remember the file they chose to run.
       var localHandlerApp =
         Components.classes["@mozilla.org/uriloader/local-handler-app;1"].
                    createInstance(Components.interfaces.nsILocalHandlerApp);
       localHandlerApp.executable = fp.file;
       this.chosenApp = localHandlerApp;
 #endif
 
+#endif
+
       // Show the "handler" menulist since we have a (user-specified)
       // application now.
       this.dialogElement("modeDeck").setAttribute("selectedIndex", "0");
 
       // Update dialog.
       var otherHandler = this.dialogElement("otherHandler");
       otherHandler.removeAttribute("hidden");
       otherHandler.setAttribute("path", this.getPath(this.chosenApp.executable));
+#ifdef XP_LINUX
+      otherHandler.label = ac.appName;
+#else
       otherHandler.label = this.getFileDisplayName(this.chosenApp.executable);
+#endif
       this.dialogElement("openHandler").selectedIndex = 1;
       this.dialogElement("openHandler").setAttribute("lastSelectedItemID", "otherHandler");
 
       this.dialogElement("mode").selectedItem = this.dialogElement("open");
     }
     else {
       var openHandler = this.dialogElement("openHandler");
       var lastSelectedID = openHandler.getAttribute("lastSelectedItemID");
--- a/widget/gtk/moz.build
+++ b/widget/gtk/moz.build
@@ -69,16 +69,17 @@ if CONFIG['ACCESSIBILITY']:
 
 if CONFIG['MOZ_ENABLE_GTK2']:
     UNIFIED_SOURCES += [
         'gtk2drawing.c',
     ]
 else:
     UNIFIED_SOURCES += [
         'gtk3drawing.c',
+        'nsApplicationChooser.cpp',
     ]
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 FINAL_LIBRARY = 'xul'
 
 LOCAL_INCLUDES += [
     '/layout/generic',
--- a/widget/gtk/mozgtk/mozgtk.c
+++ b/widget/gtk/mozgtk/mozgtk.c
@@ -528,16 +528,21 @@ STUB(gtk_style_context_save)
 STUB(gtk_style_context_set_path)
 STUB(gtk_style_context_set_state)
 STUB(gtk_tree_view_column_get_button)
 STUB(gtk_widget_get_preferred_size)
 STUB(gtk_widget_get_style_context)
 STUB(gtk_widget_path_append_type)
 STUB(gtk_widget_path_new)
 STUB(gtk_widget_set_visual)
+STUB(gtk_app_chooser_dialog_new_for_content_type)
+STUB(gtk_app_chooser_get_type)
+STUB(gtk_app_chooser_get_app_info)
+STUB(gtk_app_chooser_dialog_get_type)
+STUB(gtk_app_chooser_dialog_set_heading)
 #endif
 
 #ifdef GTK2_SYMBOLS
 STUB(gdk_drawable_get_screen)
 STUB(gdk_rgb_get_colormap)
 STUB(gdk_rgb_get_visual)
 STUB(gdk_window_lookup)
 STUB(gdk_window_set_back_pixmap)
new file mode 100644
--- /dev/null
+++ b/widget/gtk/nsApplicationChooser.cpp
@@ -0,0 +1,93 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/Types.h"
+
+#include <gtk/gtk.h>
+
+#include "nsApplicationChooser.h"
+#include "WidgetUtils.h"
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS(nsApplicationChooser, nsIApplicationChooser)
+
+nsApplicationChooser::nsApplicationChooser()
+{
+  /* member initializers and constructor code */
+}
+
+nsApplicationChooser::~nsApplicationChooser()
+{
+  /* destructor code */
+}
+
+NS_IMETHODIMP
+nsApplicationChooser::Init(nsIDOMWindow* aParent, const nsACString & title)
+{
+  NS_ENSURE_TRUE(aParent, NS_ERROR_FAILURE);
+  nsCOMPtr<nsIWidget> widget = widget::WidgetUtils::DOMWindowToWidget(aParent);
+  NS_ENSURE_TRUE(widget, NS_ERROR_FAILURE);
+  mParentWidget = widget;
+  mTitle.Assign(title);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationChooser::Show(const nsACString & contentType, int16_t *aResult)
+{
+  NS_ENSURE_ARG_POINTER(aResult);
+  
+  NS_ENSURE_TRUE(mParentWidget, NS_ERROR_FAILURE);
+  GtkWindow *parent_widget =
+    GTK_WINDOW(mParentWidget->GetNativeData(NS_NATIVE_SHELLWIDGET));
+
+  GtkWidget* chooser = gtk_app_chooser_dialog_new_for_content_type(parent_widget,
+                             (GtkDialogFlags) (GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_USE_HEADER_BAR),
+                             contentType.BeginReading());
+  gtk_app_chooser_dialog_set_heading(GTK_APP_CHOOSER_DIALOG(chooser), mTitle.BeginReading());
+
+  gint result = gtk_dialog_run(GTK_DIALOG(chooser));
+  switch (result)
+  {
+    case GTK_RESPONSE_ACCEPT:
+    case GTK_RESPONSE_OK:
+      {
+        GAppInfo *app_info = gtk_app_chooser_get_app_info(GTK_APP_CHOOSER(chooser));
+        mAppCmdline.Adopt(g_find_program_in_path(g_app_info_get_executable(app_info)));
+        mAppName.Assign(g_app_info_get_display_name(app_info));
+        *aResult = returnOK;
+      }
+      break;
+    default:
+      *aResult = returnCancel;
+      break;
+  }
+  gtk_widget_destroy(chooser);
+  return NS_OK;
+}
+
+/* attribute ACString appCmdline; */
+NS_IMETHODIMP nsApplicationChooser::GetAppCmdline(nsACString & aAppCmdline)
+{
+    aAppCmdline.Assign(mAppCmdline);
+}
+NS_IMETHODIMP nsApplicationChooser::SetAppCmdline(const nsACString & aAppCmdline)
+{
+    mAppCmdline.Assign(aAppCmdline);
+}
+
+/* attribute ACString appName; */
+NS_IMETHODIMP nsApplicationChooser::GetAppName(nsACString & aAppName)
+{
+    aAppName.Assign(mAppName);
+}
+NS_IMETHODIMP nsApplicationChooser::SetAppName(const nsACString & aAppName)
+{
+    mAppName.Assign(aAppName);
+}
+
+
+
--- a/widget/gtk/nsWidgetFactory.cpp
+++ b/widget/gtk/nsWidgetFactory.cpp
@@ -15,16 +15,19 @@
 #include "nsWindow.h"
 #include "nsTransferable.h"
 #include "nsHTMLFormatConverter.h"
 #ifdef MOZ_X11
 #include "nsClipboardHelper.h"
 #include "nsClipboard.h"
 #include "nsDragService.h"
 #endif
+#if (MOZ_WIDGET_GTK == 3)
+#include "nsApplicationChooser.h"
+#endif
 #include "nsColorPicker.h"
 #include "nsFilePicker.h"
 #include "nsSound.h"
 #include "nsBidiKeyboard.h"
 #include "nsScreenManagerGtk.h"
 #include "nsGTKToolkit.h"
 #include "WakeLockListener.h"
 
@@ -56,16 +59,22 @@ using namespace mozilla;
 using namespace mozilla::widget;
 
 /* from nsFilePicker.js */
 #define XULFILEPICKER_CID \
   { 0x54ae32f8, 0x1dd2, 0x11b2, \
     { 0xa2, 0x09, 0xdf, 0x7c, 0x50, 0x53, 0x70, 0xf8} }
 static NS_DEFINE_CID(kXULFilePickerCID, XULFILEPICKER_CID);
 
+/*#define XULAPPLICATIONCHOOSER_CID \
+  { 0xb9405e90, 0xe4f5, 0x4b2d, \
+    { 0xba, 0xe2, 0x42, 0xa8, 0xd7, 0xb1, 0x90, 0xc0} }
+static NS_DEFINE_CID(kXULApplicationChooserCID, XULAPPLICATIONCHOOSER_CID);
+*/
+
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsChildWindow)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsTransferable)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBidiKeyboard)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsHTMLFormatConverter)
 #ifdef MOZ_X11
 NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsIdleServiceGTK, nsIdleServiceGTK::GetInstance)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsClipboardHelper)
@@ -146,16 +155,36 @@ nsFilePickerConstructor(nsISupports *aOu
 
   if (!picker) {
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
   return picker->QueryInterface(aIID, aResult);
 }
 
+#if (MOZ_WIDGET_GTK == 3)
+static nsresult
+nsApplicationChooserConstructor(nsISupports *aOuter, REFNSIID aIID,
+                                void **aResult)
+{
+  *aResult = nullptr;
+  if (aOuter != nullptr) {
+    return NS_ERROR_NO_AGGREGATION;
+  }
+  nsCOMPtr<nsIApplicationChooser> chooser;
+  chooser = new nsApplicationChooser;
+
+  if (!chooser) {
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  return chooser->QueryInterface(aIID, aResult);
+}
+#endif
+
 static nsresult
 nsColorPickerConstructor(nsISupports *aOuter, REFNSIID aIID,
                          void **aResult)
 {
     *aResult = nullptr;
     if (aOuter != nullptr) {
         return NS_ERROR_NO_AGGREGATION;
     }
@@ -169,16 +198,19 @@ nsColorPickerConstructor(nsISupports *aO
     return picker->QueryInterface(aIID, aResult);
 }
 
 NS_DEFINE_NAMED_CID(NS_WINDOW_CID);
 NS_DEFINE_NAMED_CID(NS_CHILD_CID);
 NS_DEFINE_NAMED_CID(NS_APPSHELL_CID);
 NS_DEFINE_NAMED_CID(NS_COLORPICKER_CID);
 NS_DEFINE_NAMED_CID(NS_FILEPICKER_CID);
+#if (MOZ_WIDGET_GTK == 3)
+NS_DEFINE_NAMED_CID(NS_APPLICATIONCHOOSER_CID);
+#endif
 NS_DEFINE_NAMED_CID(NS_SOUND_CID);
 NS_DEFINE_NAMED_CID(NS_TRANSFERABLE_CID);
 #ifdef MOZ_X11
 NS_DEFINE_NAMED_CID(NS_CLIPBOARD_CID);
 NS_DEFINE_NAMED_CID(NS_CLIPBOARDHELPER_CID);
 NS_DEFINE_NAMED_CID(NS_DRAGSERVICE_CID);
 #endif
 NS_DEFINE_NAMED_CID(NS_HTMLFORMATCONVERTER_CID);
@@ -200,16 +232,19 @@ NS_DEFINE_NAMED_CID(NS_GFXINFO_CID);
 
 
 static const mozilla::Module::CIDEntry kWidgetCIDs[] = {
     { &kNS_WINDOW_CID, false, nullptr, nsWindowConstructor },
     { &kNS_CHILD_CID, false, nullptr, nsChildWindowConstructor },
     { &kNS_APPSHELL_CID, false, nullptr, nsAppShellConstructor },
     { &kNS_COLORPICKER_CID, false, nullptr, nsColorPickerConstructor, Module::MAIN_PROCESS_ONLY },
     { &kNS_FILEPICKER_CID, false, nullptr, nsFilePickerConstructor, Module::MAIN_PROCESS_ONLY },
+#if (MOZ_WIDGET_GTK == 3)
+    { &kNS_APPLICATIONCHOOSER_CID, false, nullptr, nsApplicationChooserConstructor, Module::MAIN_PROCESS_ONLY },
+#endif
     { &kNS_SOUND_CID, false, nullptr, nsSoundConstructor, Module::MAIN_PROCESS_ONLY },
     { &kNS_TRANSFERABLE_CID, false, nullptr, nsTransferableConstructor },
 #ifdef MOZ_X11
     { &kNS_CLIPBOARD_CID, false, nullptr, nsClipboardConstructor, Module::MAIN_PROCESS_ONLY },
     { &kNS_CLIPBOARDHELPER_CID, false, nullptr, nsClipboardHelperConstructor },
     { &kNS_DRAGSERVICE_CID, false, nullptr, nsDragServiceConstructor, Module::MAIN_PROCESS_ONLY },
 #endif
     { &kNS_HTMLFORMATCONVERTER_CID, false, nullptr, nsHTMLFormatConverterConstructor },
@@ -233,16 +268,19 @@ static const mozilla::Module::CIDEntry k
 };
 
 static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
     { "@mozilla.org/widget/window/gtk;1", &kNS_WINDOW_CID },
     { "@mozilla.org/widgets/child_window/gtk;1", &kNS_CHILD_CID },
     { "@mozilla.org/widget/appshell/gtk;1", &kNS_APPSHELL_CID },
     { "@mozilla.org/colorpicker;1", &kNS_COLORPICKER_CID, Module::MAIN_PROCESS_ONLY },
     { "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::MAIN_PROCESS_ONLY },
+#if (MOZ_WIDGET_GTK == 3)
+    { "@mozilla.org/applicationchooser;1", &kNS_APPLICATIONCHOOSER_CID, Module::MAIN_PROCESS_ONLY },
+#endif
     { "@mozilla.org/sound;1", &kNS_SOUND_CID, Module::MAIN_PROCESS_ONLY },
     { "@mozilla.org/widget/transferable;1", &kNS_TRANSFERABLE_CID },
 #ifdef MOZ_X11
     { "@mozilla.org/widget/clipboard;1", &kNS_CLIPBOARD_CID, Module::MAIN_PROCESS_ONLY },
     { "@mozilla.org/widget/clipboardhelper;1", &kNS_CLIPBOARDHELPER_CID },
     { "@mozilla.org/widget/dragservice;1", &kNS_DRAGSERVICE_CID, Module::MAIN_PROCESS_ONLY },
 #endif
     { "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID },
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -6,16 +6,21 @@
 
 toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
 
 if toolkit in ('cocoa', 'qt', 'android', 'gonk'):
     DIRS += [toolkit]
 if toolkit in ('qt', 'android', 'gonk', 'gtk2', 'gtk3'):
     EXPORTS += ['nsIPrintDialogService.h']
 
+if toolkit == 'gtk3':
+    XPIDL_SOURCES += [
+        'nsIApplicationChooser.idl',
+    ]
+
 if toolkit == 'windows':
     DIRS += ['windows']
 
     XPIDL_SOURCES += [
         'nsIJumpListBuilder.idl',
         'nsIJumpListItem.idl',
         'nsIPrintSettingsWin.idl',
         'nsITaskbarOverlayIconController.idl',
new file mode 100644
--- /dev/null
+++ b/widget/nsIApplicationChooser.idl
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+interface nsIDOMWindow;
+
+[scriptable, uuid(8413fc42-d6c4-4d78-bf70-64cd78ebcc5c)]
+interface nsIApplicationChooser : nsISupports
+{
+  const short returnOK        = 0;              // User hit Ok, process selection
+  const short returnCancel    = 1;              // User hit cancel, ignore selection
+
+  /**
+   * Show application chooser window.
+   *
+   * @param    contentType   content type of file to open
+   * return returnOK when user accepts the dialog, returnCancel otherwise
+   */
+  short show(in ACString contentType);
+
+ /**
+  * Initialize the application chooser picker widget.  The application chooser 
+  * is not valid until this method is called.
+  *
+  * @param      parent   nsIDOMWindow parent.  This dialog will be dependent
+  *                      on this parent. parent must be non-null.
+  * @param      title    The title for the file widget
+  * @param      mode     load, save, or get folder
+  *
+  */
+  void init(in nsIDOMWindow parent, in ACString title);
+
+  attribute ACString appCmdline;
+  attribute ACString appName;
+};
+
--- a/widget/nsWidgetsCID.h
+++ b/widget/nsWidgetsCID.h
@@ -19,16 +19,21 @@
 { 0xba7de611, 0x6088, 0x11d3,  \
     { 0xa8, 0x3e, 0x0, 0x10, 0x5a, 0x18, 0x34, 0x19 } }
 
 /* bd57cee8-1dd1-11b2-9fe7-95cf4709aea3 */
 #define NS_FILEPICKER_CID \
 { 0xbd57cee8, 0x1dd1, 0x11b2, \
     {0x9f, 0xe7, 0x95, 0xcf, 0x47, 0x09, 0xae, 0xa3} }
 
+/* e221df9b-3d66-4045-9a66-5720949f8d10 */
+#define NS_APPLICATIONCHOOSER_CID \
+{ 0xe221df9b, 0x3d66, 0x4045, \
+    {0x9a, 0x66, 0x57, 0x20, 0x94, 0x9f, 0x8d, 0x10} }
+
 /* 0f872c8c-3ee6-46bd-92a2-69652c6b474e */
 #define NS_COLORPICKER_CID \
 { 0x0f872c8c, 0x3ee6, 0x46bd, \
   { 0x92, 0xa2, 0x69, 0x65, 0x2c, 0x6b, 0x47, 0x4e } }
 
 /* 2d96b3df-c051-11d1-a827-0040959a28c9 */
 #define NS_APPSHELL_CID \
 { 0x2d96b3df, 0xc051, 0x11d1, \