firefox/mozilla-1129873-apppicker.p...

424 lines
16 KiB
Diff

diff -up mozilla-release/toolkit/mozapps/downloads/nsHelperAppDlg.js.1129873-apppicker mozilla-release/toolkit/mozapps/downloads/nsHelperAppDlg.js
--- mozilla-release/toolkit/mozapps/downloads/nsHelperAppDlg.js.1129873-apppicker 2015-05-25 23:28:55.000000000 +0200
+++ mozilla-release/toolkit/mozapps/downloads/nsHelperAppDlg.js 2015-06-09 09:37:35.313305562 +0200
@@ -1004,6 +1004,34 @@ nsUnknownContentTypeDialog.prototype = {
return file.leafName;
},
+ finishChooseApp: function() {
+ if (this.chosenApp) {
+ // 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_WIN
+ otherHandler.label = this.getFileDisplayName(this.chosenApp.executable);
+#else
+ otherHandler.label = this.chosenApp.name;
+#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");
+ if (!lastSelectedID)
+ lastSelectedID = "defaultHandler";
+ openHandler.selectedItem = this.dialogElement(lastSelectedID);
+ }
+ },
// chooseApp: Open file picker and prompt user for application.
chooseApp: function() {
#ifdef XP_WIN
@@ -1047,7 +1075,23 @@ nsUnknownContentTypeDialog.prototype = {
params.handlerApp.executable.isFile()) {
// Remember the file they chose to run.
this.chosenApp = params.handlerApp;
-
+ }
+#else
+#if MOZ_WIDGET_GTK == 3
+ var nsIApplicationChooser = Components.interfaces.nsIApplicationChooser;
+ var appChooser = Components.classes["@mozilla.org/applicationchooser;1"]
+ .createInstance(nsIApplicationChooser);
+ appChooser.init(this.mDialog, this.dialogElement("strings").getString("chooseAppFilePickerTitle"));
+ var contentTypeDialogObj = this;
+ let appChooserCallback = function appChooserCallback_done(aResult) {
+ if (aResult) {
+ contentTypeDialogObj.chosenApp = aResult.QueryInterface(Components.interfaces.nsILocalHandlerApp);
+ }
+ contentTypeDialogObj.finishChooseApp();
+ };
+ appChooser.open(this.mLauncher.MIMEInfo.MIMEType, appChooserCallback);
+ // The finishChooseApp is called from appChooserCallback
+ return;
#else
var nsIFilePicker = Components.interfaces.nsIFilePicker;
var fp = Components.classes["@mozilla.org/filepicker;1"]
@@ -1065,29 +1109,11 @@ nsUnknownContentTypeDialog.prototype = {
createInstance(Components.interfaces.nsILocalHandlerApp);
localHandlerApp.executable = fp.file;
this.chosenApp = localHandlerApp;
-#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));
- otherHandler.label = this.getFileDisplayName(this.chosenApp.executable);
- 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");
- if (!lastSelectedID)
- lastSelectedID = "defaultHandler";
- openHandler.selectedItem = this.dialogElement(lastSelectedID);
}
+#endif // MOZ_WIDGET_GTK3
+
+#endif // XP_WIN
+ this.finishChooseApp();
},
// Turn this on to get debugging messages.
diff -up mozilla-release/widget/gtk/moz.build.1129873-apppicker mozilla-release/widget/gtk/moz.build
--- mozilla-release/widget/gtk/moz.build.1129873-apppicker 2015-05-25 23:28:56.000000000 +0200
+++ mozilla-release/widget/gtk/moz.build 2015-06-09 09:37:35.313305562 +0200
@@ -74,6 +74,7 @@ if CONFIG['MOZ_ENABLE_GTK2']:
else:
UNIFIED_SOURCES += [
'gtk3drawing.c',
+ 'nsApplicationChooser.cpp',
]
include('/ipc/chromium/chromium-config.mozbuild')
diff -up mozilla-release/widget/gtk/mozgtk/mozgtk.c.1129873-apppicker mozilla-release/widget/gtk/mozgtk/mozgtk.c
--- mozilla-release/widget/gtk/mozgtk/mozgtk.c.1129873-apppicker 2015-05-25 23:28:56.000000000 +0200
+++ mozilla-release/widget/gtk/mozgtk/mozgtk.c 2015-06-09 09:37:35.313305562 +0200
@@ -533,6 +533,11 @@ 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
diff -up mozilla-release/widget/gtk/nsApplicationChooser.cpp.1129873-apppicker mozilla-release/widget/gtk/nsApplicationChooser.cpp
--- mozilla-release/widget/gtk/nsApplicationChooser.cpp.1129873-apppicker 2015-06-09 09:37:35.314305558 +0200
+++ mozilla-release/widget/gtk/nsApplicationChooser.cpp 2015-06-09 09:37:35.313305562 +0200
@@ -0,0 +1,123 @@
+/* -*- 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"
+#include "nsIMIMEInfo.h"
+#include "nsCExternalHandlerService.h"
+#include "nsGtkUtils.h"
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS(nsApplicationChooser, nsIApplicationChooser)
+
+nsApplicationChooser::nsApplicationChooser()
+{
+}
+
+nsApplicationChooser::~nsApplicationChooser()
+{
+}
+
+NS_IMETHODIMP
+nsApplicationChooser::Init(nsIDOMWindow* aParent, const nsACString& aTitle)
+{
+ NS_ENSURE_TRUE(aParent, NS_ERROR_FAILURE);
+ mParentWidget = widget::WidgetUtils::DOMWindowToWidget(aParent);
+ mWindowTitle.Assign(aTitle);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsApplicationChooser::Open(const nsACString& aContentType, nsIApplicationChooserFinishedCallback *aCallback)
+{
+ MOZ_ASSERT(aCallback);
+ if (mCallback) {
+ NS_WARNING("Chooser is already in progress.");
+ return NS_ERROR_ALREADY_INITIALIZED;
+ }
+ mCallback = aCallback;
+ 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),
+ PromiseFlatCString(aContentType).get());
+ gtk_app_chooser_dialog_set_heading(GTK_APP_CHOOSER_DIALOG(chooser), mWindowTitle.BeginReading());
+ NS_ADDREF_THIS();
+ g_signal_connect(chooser, "response", G_CALLBACK(OnResponse), this);
+ g_signal_connect(chooser, "destroy", G_CALLBACK(OnDestroy), this);
+ gtk_widget_show(chooser);
+ return NS_OK;
+}
+
+/* static */ void
+nsApplicationChooser::OnResponse(GtkWidget* chooser, gint response_id, gpointer user_data)
+{
+ static_cast<nsApplicationChooser*>(user_data)->Done(chooser, response_id);
+}
+
+/* static */ void
+nsApplicationChooser::OnDestroy(GtkWidget *chooser, gpointer user_data)
+{
+ static_cast<nsApplicationChooser*>(user_data)->Done(chooser, GTK_RESPONSE_CANCEL);
+}
+
+void nsApplicationChooser::Done(GtkWidget* chooser, gint response)
+{
+ nsCOMPtr<nsILocalHandlerApp> localHandler;
+ nsresult rv;
+ switch (response) {
+ case GTK_RESPONSE_OK:
+ case GTK_RESPONSE_ACCEPT:
+ {
+ localHandler = do_CreateInstance(NS_LOCALHANDLERAPP_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Out of memory.");
+ break;
+ }
+ GAppInfo *app_info = gtk_app_chooser_get_app_info(GTK_APP_CHOOSER(chooser));
+
+ nsCOMPtr<nsIFile> localExecutable;
+ gchar *fileWithFullPath = g_find_program_in_path(g_app_info_get_executable(app_info));
+ rv = NS_NewNativeLocalFile(nsDependentCString(fileWithFullPath), false, getter_AddRefs(localExecutable));
+ g_free(fileWithFullPath);
+ if (NS_FAILED(rv)) {
+ NS_WARNING("Cannot create local filename.");
+ localHandler = nullptr;
+ } else {
+ localHandler->SetExecutable(localExecutable);
+ localHandler->SetName(NS_ConvertUTF8toUTF16(g_app_info_get_display_name(app_info)));
+ }
+ g_object_unref(app_info);
+ }
+
+ break;
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_CLOSE:
+ case GTK_RESPONSE_DELETE_EVENT:
+ break;
+ default:
+ NS_WARNING("Unexpected response");
+ break;
+ }
+
+ // A "response" signal won't be sent again but "destroy" will be.
+ g_signal_handlers_disconnect_by_func(chooser, FuncToGpointer(OnDestroy), this);
+ gtk_widget_destroy(chooser);
+
+ if (mCallback) {
+ mCallback->Done(localHandler);
+ mCallback = nullptr;
+ }
+ NS_RELEASE_THIS();
+}
+
diff -up mozilla-release/widget/gtk/nsApplicationChooser.h.1129873-apppicker mozilla-release/widget/gtk/nsApplicationChooser.h
--- mozilla-release/widget/gtk/nsApplicationChooser.h.1129873-apppicker 2015-06-09 09:37:35.314305558 +0200
+++ mozilla-release/widget/gtk/nsApplicationChooser.h 2015-06-09 09:37:35.314305558 +0200
@@ -0,0 +1,28 @@
+/* -*- 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/. */
+
+#ifndef nsApplicationChooser_h__
+#define nsApplicationChooser_h__
+
+#include <gtk/gtk.h>
+#include "nsIApplicationChooser.h"
+
+class nsApplicationChooser : public nsIApplicationChooser
+{
+public:
+ nsApplicationChooser();
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIAPPLICATIONCHOOSER
+ void Done(GtkWidget* chooser, gint response);
+
+private:
+ ~nsApplicationChooser();
+ nsCOMPtr<nsIWidget> mParentWidget;
+ nsCString mWindowTitle;
+ nsCOMPtr<nsIApplicationChooserFinishedCallback> mCallback;
+ static void OnResponse(GtkWidget* chooser, gint response_id, gpointer user_data);
+ static void OnDestroy(GtkWidget* chooser, gpointer user_data);
+};
+#endif
diff -up mozilla-release/widget/gtk/nsWidgetFactory.cpp.1129873-apppicker mozilla-release/widget/gtk/nsWidgetFactory.cpp
--- mozilla-release/widget/gtk/nsWidgetFactory.cpp.1129873-apppicker 2015-05-25 23:28:56.000000000 +0200
+++ mozilla-release/widget/gtk/nsWidgetFactory.cpp 2015-06-09 09:37:35.314305558 +0200
@@ -21,6 +21,9 @@
#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"
@@ -152,6 +155,25 @@ nsFilePickerConstructor(nsISupports *aOu
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 = 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)
@@ -175,6 +197,9 @@ 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
@@ -206,6 +231,9 @@ static const mozilla::Module::CIDEntry k
{ &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
@@ -239,6 +267,9 @@ static const mozilla::Module::ContractID
{ "@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
diff -up mozilla-release/widget/moz.build.1129873-apppicker mozilla-release/widget/moz.build
--- mozilla-release/widget/moz.build.1129873-apppicker 2015-05-25 23:28:56.000000000 +0200
+++ mozilla-release/widget/moz.build 2015-06-09 09:36:01.000000000 +0200
@@ -207,6 +207,10 @@ if toolkit in ('qt', 'gtk2', 'gtk3', 'wi
UNIFIED_SOURCES += [
'nsNativeTheme.cpp',
]
+if toolkit == 'gtk3':
+ XPIDL_SOURCES += [
+ 'nsIApplicationChooser.idl',
+ ]
if not CONFIG['MOZ_B2G']:
DEFINES['MOZ_CROSS_PROCESS_IME'] = True
diff -up mozilla-release/widget/nsIApplicationChooser.idl.1129873-apppicker mozilla-release/widget/nsIApplicationChooser.idl
--- mozilla-release/widget/nsIApplicationChooser.idl.1129873-apppicker 2015-06-09 09:37:35.314305558 +0200
+++ mozilla-release/widget/nsIApplicationChooser.idl 2015-06-09 09:37:35.314305558 +0200
@@ -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"
+#include "nsIMIMEInfo.idl"
+interface nsIDOMWindow;
+
+[scriptable, function, uuid(8144404d-e6c7-4861-bcca-47de912ee811)]
+interface nsIApplicationChooserFinishedCallback : nsISupports
+{
+ void done(in nsIHandlerApp handlerApp);
+};
+
+[scriptable, uuid(8413fc42-d6c4-4d78-bf70-64cd78ebcc5c)]
+interface nsIApplicationChooser : nsISupports
+{
+ /**
+ * 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
+ *
+ */
+ void init(in nsIDOMWindow parent, in ACString title);
+
+ /**
+ * Open application chooser dialog.
+ *
+ * @param contentType content type of file to open
+ * @param applicationChooserFinishedCallback callback fuction to run when dialog is closed
+ */
+ void open(in ACString contentType, in nsIApplicationChooserFinishedCallback applicationChooserFinishedCallback);
+};
+
diff -up mozilla-release/widget/nsWidgetsCID.h.1129873-apppicker mozilla-release/widget/nsWidgetsCID.h
--- mozilla-release/widget/nsWidgetsCID.h.1129873-apppicker 2015-05-25 23:28:56.000000000 +0200
+++ mozilla-release/widget/nsWidgetsCID.h 2015-06-09 09:37:35.315305554 +0200
@@ -24,6 +24,11 @@
{ 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, \