summaryrefslogtreecommitdiff
path: root/Source/WebKit/gtk/webkit/webkitfilechooserrequest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit/gtk/webkit/webkitfilechooserrequest.cpp')
-rw-r--r--Source/WebKit/gtk/webkit/webkitfilechooserrequest.cpp367
1 files changed, 367 insertions, 0 deletions
diff --git a/Source/WebKit/gtk/webkit/webkitfilechooserrequest.cpp b/Source/WebKit/gtk/webkit/webkitfilechooserrequest.cpp
new file mode 100644
index 000000000..c1373ed49
--- /dev/null
+++ b/Source/WebKit/gtk/webkit/webkitfilechooserrequest.cpp
@@ -0,0 +1,367 @@
+/*
+ * Copyright (C) 2012 Igalia S.L.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB. If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "webkitfilechooserrequest.h"
+
+#include "FileChooser.h"
+#include "FileSystem.h"
+#include "webkitfilechooserrequestprivate.h"
+#include "webkitglobalsprivate.h"
+#include <glib/gi18n-lib.h>
+#include <wtf/gobject/GOwnPtr.h>
+#include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
+
+using namespace WebCore;
+
+/**
+ * SECTION:webkitfilechooserrequest
+ * @Short_description: A request to open a file chooser
+ * @Title: WebKitFileChooserRequest
+ * @See_also: #WebKitWebView
+ *
+ * Whenever the user interacts with an &lt;input type='file' /&gt;
+ * HTML element, WebKit will need to show a dialog to choose one or
+ * more files to be uploaded to the server along with the rest of the
+ * form data. For that to happen in a general way, instead of just
+ * opening a #GtkFileChooserDialog (which might be not desirable in
+ * some cases, such as when an embedding applications prefers to use
+ * its own file chooser dialog), WebKit will fire the
+ * #WebKitWebView::run-file-chooser signal with a
+ * #WebKitFileChooserRequest object, which will allow the client
+ * application to specify the files to be selected, to inspect the
+ * details of the request (e.g. if multiple selection should be
+ * allowed) and to cancel the request, in case nothing was selected.
+ *
+ * In case the client application does not wish to handle this signal,
+ * WebKit will provide a default handler which will asynchronously run
+ * a regular #GtkFileChooserDialog for the user to interact with.
+ */
+G_DEFINE_TYPE(WebKitFileChooserRequest, webkit_file_chooser_request, G_TYPE_OBJECT)
+
+struct _WebKitFileChooserRequestPrivate {
+ RefPtr<FileChooser> chooser;
+ GRefPtr<GtkFileFilter> filter;
+ GRefPtr<GPtrArray> mimeTypes;
+ GRefPtr<GPtrArray> selectedFiles;
+};
+
+enum {
+ PROP_0,
+ PROP_FILTER,
+ PROP_MIME_TYPES,
+ PROP_SELECT_MULTIPLE,
+ PROP_SELECTED_FILES,
+};
+
+static void webkit_file_chooser_request_init(WebKitFileChooserRequest* request)
+{
+ request->priv = G_TYPE_INSTANCE_GET_PRIVATE(request, WEBKIT_TYPE_FILE_CHOOSER_REQUEST, WebKitFileChooserRequestPrivate);
+ new (request->priv) WebKitFileChooserRequestPrivate();
+}
+
+static void webkit_file_chooser_request_finalize(GObject* object)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(object);
+
+ request->priv->~WebKitFileChooserRequestPrivate();
+ G_OBJECT_CLASS(webkit_file_chooser_request_parent_class)->finalize(object);
+}
+
+static void webkit_file_chooser_request_get_property(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(object);
+ switch (propId) {
+ case PROP_FILTER:
+ g_value_set_object(value, webkit_file_chooser_request_get_mime_types_filter(request));
+ break;
+ case PROP_MIME_TYPES:
+ g_value_set_boxed(value, webkit_file_chooser_request_get_mime_types(request));
+ break;
+ case PROP_SELECT_MULTIPLE:
+ g_value_set_boolean(value, webkit_file_chooser_request_get_select_multiple(request));
+ break;
+ case PROP_SELECTED_FILES:
+ g_value_set_boxed(value, webkit_file_chooser_request_get_selected_files(request));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+ break;
+ }
+}
+
+static void webkit_file_chooser_request_class_init(WebKitFileChooserRequestClass* requestClass)
+{
+ GObjectClass* objectClass = G_OBJECT_CLASS(requestClass);
+ objectClass->finalize = webkit_file_chooser_request_finalize;
+ objectClass->get_property = webkit_file_chooser_request_get_property;
+ g_type_class_add_private(requestClass, sizeof(WebKitFileChooserRequestPrivate));
+
+ /**
+ * WebKitFileChooserRequest:filter:
+ *
+ * The filter currently associated with the request. See
+ * webkit_file_chooser_request_get_mime_types_filter() for more
+ * details.
+ *
+ * Since: 1.10
+ */
+ g_object_class_install_property(objectClass,
+ PROP_FILTER,
+ g_param_spec_object("filter",
+ _("MIME types filter"),
+ _("The filter currently associated with the request"),
+ GTK_TYPE_FILE_FILTER,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitFileChooserRequest:mime-types:
+ *
+ * A %NULL-terminated array of strings containing the list of MIME
+ * types the file chooser dialog should handle. See
+ * webkit_file_chooser_request_get_mime_types() for more details.
+ *
+ * Since: 1.10
+ */
+ g_object_class_install_property(objectClass,
+ PROP_MIME_TYPES,
+ g_param_spec_boxed("mime-types",
+ _("MIME types"),
+ _("The list of MIME types associated with the request"),
+ G_TYPE_STRV,
+ WEBKIT_PARAM_READABLE)); /**
+ * WebKitFileChooserRequest:select-multiple:
+ *
+ * Whether the file chooser should allow selecting multiple
+ * files. See
+ * webkit_file_chooser_request_get_select_multiple() for
+ * more details.
+ *
+ * Since: 1.10
+ */
+ g_object_class_install_property(objectClass,
+ PROP_SELECT_MULTIPLE,
+ g_param_spec_boolean("select-multiple",
+ _("Select multiple files"),
+ _("Whether the file chooser should allow selecting multiple files"),
+ FALSE,
+ WEBKIT_PARAM_READABLE));
+ /**
+ * WebKitFileChooserRequest:selected-files:
+ *
+ * A %NULL-terminated array of strings containing the list of
+ * selected files associated to the current request. See
+ * webkit_file_chooser_request_get_selected_files() for more details.
+ *
+ * Since: 1.10
+ */
+ g_object_class_install_property(objectClass,
+ PROP_SELECTED_FILES,
+ g_param_spec_boxed("selected-files",
+ _("Selected files"),
+ _("The list of selected files associated with the request"),
+ G_TYPE_STRV,
+ WEBKIT_PARAM_READABLE));
+}
+
+WebKitFileChooserRequest* webkit_file_chooser_request_create(PassRefPtr<FileChooser> chooser)
+{
+ WebKitFileChooserRequest* request = WEBKIT_FILE_CHOOSER_REQUEST(g_object_new(WEBKIT_TYPE_FILE_CHOOSER_REQUEST, NULL));
+ request->priv->chooser = chooser;
+ return request;
+}
+
+/**
+ * webkit_file_chooser_request_get_mime_types:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the list of MIME types the file chooser dialog should handle,
+ * in the format specified in RFC 2046 for "media types". Its contents
+ * depend on the value of the 'accept' attribute for HTML input
+ * elements. This function should normally be called before presenting
+ * the file chooser dialog to the user, to decide whether to allow the
+ * user to select multiple files at once or only one.
+ *
+ * Returns: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings if a list of accepted MIME types
+ * is defined or %NULL otherwise, meaning that any MIME type should be
+ * accepted. This array and its contents are owned by WebKitGTK+ and
+ * should not be modified or freed.
+ *
+ * Since: 1.10
+ */
+const gchar* const* webkit_file_chooser_request_get_mime_types(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->mimeTypes)
+ return reinterpret_cast<gchar**>(request->priv->mimeTypes->pdata);
+
+ FileChooserSettings settings = request->priv->chooser->settings();
+ size_t numOfMimeTypes = settings.acceptMIMETypes.size();
+ if (!numOfMimeTypes)
+ return 0;
+
+ request->priv->mimeTypes = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+ for (size_t i = 0; i < numOfMimeTypes; ++i) {
+ String mimeTypeString = settings.acceptMIMETypes[i];
+ if (mimeTypeString.isEmpty())
+ continue;
+ g_ptr_array_add(request->priv->mimeTypes.get(), g_strdup(mimeTypeString.utf8().data()));
+ }
+ g_ptr_array_add(request->priv->mimeTypes.get(), 0);
+
+ return reinterpret_cast<gchar**>(request->priv->mimeTypes->pdata);
+}
+
+/**
+ * webkit_file_chooser_request_get_mime_types_filter:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the filter currently associated with the request, ready to be
+ * used by #GtkFileChooser. This function should normally be called
+ * before presenting the file chooser dialog to the user, to decide
+ * whether to apply a filter so the user would not be allowed to
+ * select files with other MIME types.
+ *
+ * See webkit_file_chooser_request_get_mime_types() if you are
+ * interested in getting the list of accepted MIME types.
+ *
+ * Returns: (transfer none): a #GtkFileFilter if a list of accepted
+ * MIME types is defined or %NULL otherwise. The returned object is
+ * owned by WebKitGTK+ should not be modified or freed.
+ *
+ * Since: 1.10
+ */
+GtkFileFilter* webkit_file_chooser_request_get_mime_types_filter(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->filter)
+ return request->priv->filter.get();
+
+ FileChooserSettings settings = request->priv->chooser->settings();
+ size_t numOfMimeTypes = settings.acceptMIMETypes.size();
+ if (!numOfMimeTypes)
+ return 0;
+
+ // Do not use adoptGRef here, since we want to sink the floating
+ // reference for the new instance of GtkFileFilter, so we make
+ // sure we keep the ownership during the lifetime of the request.
+ request->priv->filter = gtk_file_filter_new();
+ for (size_t i = 0; i < numOfMimeTypes; ++i) {
+ String mimeTypeString = settings.acceptMIMETypes[i];
+ if (mimeTypeString.isEmpty())
+ continue;
+ gtk_file_filter_add_mime_type(request->priv->filter.get(), mimeTypeString.utf8().data());
+ }
+
+ return request->priv->filter.get();
+}
+
+/**
+ * webkit_file_chooser_request_get_select_multiple:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Determine whether the file chooser associated to this
+ * #WebKitFileChooserRequest should allow selecting multiple files,
+ * which depends on the HTML input element having a 'multiple'
+ * attribute defined.
+ *
+ * Returns: %TRUE if the file chooser should allow selecting multiple files or %FALSE otherwise.
+ *
+ * Since: 1.10
+ */
+gboolean webkit_file_chooser_request_get_select_multiple(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), FALSE);
+ return request->priv->chooser->settings().allowsMultipleFiles;
+}
+
+/**
+ * webkit_file_chooser_request_select_files:
+ * @request: a #WebKitFileChooserRequest
+ * @files: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings, containing paths to local files.
+ *
+ * Ask WebKit to select local files for upload and complete the
+ * request.
+ *
+ * Since: 1.10
+ */
+void webkit_file_chooser_request_select_files(WebKitFileChooserRequest* request, const gchar* const* files)
+{
+ g_return_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request));
+ g_return_if_fail(files);
+
+ Vector<String> names;
+ GRefPtr<GPtrArray> selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+
+ for (int i = 0; files[i]; i++) {
+ names.append(filenameToString(files[i]));
+ g_ptr_array_add(selectedFiles.get(), g_strdup(files[i]));
+ }
+
+ g_ptr_array_add(selectedFiles.get(), 0);
+ request->priv->chooser->chooseFiles(names);
+ request->priv->selectedFiles = selectedFiles;
+}
+
+/**
+ * webkit_file_chooser_request_get_selected_files:
+ * @request: a #WebKitFileChooserRequest
+ *
+ * Get the list of selected files currently associated to the
+ * request. Initially, the return value of this method contains any
+ * files selected in previous file chooser requests for this HTML
+ * input element. Once webkit_file_chooser_request_select_files, the
+ * value will reflect whatever files are given.
+ *
+ * This function should normally be called only before presenting the
+ * file chooser dialog to the user, to decide whether to perform some
+ * extra action, like pre-selecting the files from a previous request.
+ *
+ * Returns: (array zero-terminated=1) (transfer none): a
+ * %NULL-terminated array of strings if there are selected files
+ * associated with the request or %NULL otherwise. This array and its
+ * contents are owned by WebKitGTK+ and should not be modified or
+ * freed.
+ *
+ * Since: 1.10
+ */
+const gchar* const* webkit_file_chooser_request_get_selected_files(WebKitFileChooserRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_FILE_CHOOSER_REQUEST(request), 0);
+ if (request->priv->selectedFiles)
+ return reinterpret_cast<gchar**>(request->priv->selectedFiles->pdata);
+
+ FileChooserSettings settings = request->priv->chooser->settings();
+ size_t numOfFiles = settings.selectedFiles.size();
+ if (!numOfFiles)
+ return 0;
+
+ request->priv->selectedFiles = adoptGRef(g_ptr_array_new_with_free_func(g_free));
+ for (size_t i = 0; i < numOfFiles; ++i) {
+ if (settings.selectedFiles[i].isEmpty())
+ continue;
+ CString filename = fileSystemRepresentation(settings.selectedFiles[i]);
+ g_ptr_array_add(request->priv->selectedFiles.get(), g_strdup(filename.data()));
+ }
+ g_ptr_array_add(request->priv->selectedFiles.get(), 0);
+
+ return reinterpret_cast<gchar**>(request->priv->selectedFiles->pdata);
+}