Title: [211481] trunk
Revision
211481
Author
tpop...@redhat.com
Date
2017-02-01 06:14:36 -0800 (Wed, 01 Feb 2017)

Log Message

[GTK] Add an API to add a custom tab into the print dialog
https://bugs.webkit.org/show_bug.cgi?id=151998

Reviewed by Carlos Garcia Campos.

Source/WebKit2:

Add a new create-custom-widget signal to the WebKitPrintOperation. The
signal is emitted before the dialog is displayed and it gives an
opportunity to embed a custom widget in the dialog. You can do so by
creating a new WebKitPrintCustomWidget and returning it from the
create-custom-widget signal handler. The WebKitPrintCustomWidget is
emitting two signals:
  - update - emitted when the currently selected printer is changed,
             to be able to actualize the custom widget based on the
             current printer
  - apply - emitted when the dialog is closed, just before the
            printing will start, to be able e.g. to change content
            based on the custom widget state.

* PlatformGTK.cmake:
* UIProcess/API/gtk/WebKitAutocleanups.h:
* UIProcess/API/gtk/WebKitPrintCustomWidget.cpp: Added.
(webkitPrintCustomWidgetSetProperty):
(webkit_print_custom_widget_class_init):
(webkit_print_custom_widget_new):
(webkit_print_custom_widget_get_widget):
(webkit_print_custom_widget_get_title):
(webkitPrintCustomWidgetEmitCustomWidgetApplySignal):
(webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal):
* UIProcess/API/gtk/WebKitPrintCustomWidget.h: Added.
* UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h: Added.
* UIProcess/API/gtk/WebKitPrintOperation.cpp:
(webkitPrintOperationAccumulatorObjectHandled):
(webkit_print_operation_class_init):
(notifySelectedPrinterCallback):
(webkitPrintOperationRunDialog):
* UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
* UIProcess/API/gtk/docs/webkit2gtk-4.0.types:
* UIProcess/API/gtk/docs/webkit2gtk-docs.sgml:
* UIProcess/API/gtk/webkit2.h:

Tools:

Add a new WebKitPrintOperation/custom-widget test in TestPrinting
that is testing a newly added API.

* TestWebKitAPI/Tests/WebKit2Gtk/TestPrinting.cpp:
(testPrintCustomWidget):
(beforeAll):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (211480 => 211481)


--- trunk/Source/WebKit2/ChangeLog	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Source/WebKit2/ChangeLog	2017-02-01 14:14:36 UTC (rev 211481)
@@ -1,3 +1,45 @@
+2017-02-01  Tomas Popela  <tpop...@redhat.com>
+
+        [GTK] Add an API to add a custom tab into the print dialog
+        https://bugs.webkit.org/show_bug.cgi?id=151998
+
+        Reviewed by Carlos Garcia Campos.
+
+        Add a new create-custom-widget signal to the WebKitPrintOperation. The
+        signal is emitted before the dialog is displayed and it gives an
+        opportunity to embed a custom widget in the dialog. You can do so by
+        creating a new WebKitPrintCustomWidget and returning it from the
+        create-custom-widget signal handler. The WebKitPrintCustomWidget is
+        emitting two signals:
+          - update - emitted when the currently selected printer is changed,
+                     to be able to actualize the custom widget based on the
+                     current printer
+          - apply - emitted when the dialog is closed, just before the
+                    printing will start, to be able e.g. to change content
+                    based on the custom widget state.
+
+        * PlatformGTK.cmake:
+        * UIProcess/API/gtk/WebKitAutocleanups.h:
+        * UIProcess/API/gtk/WebKitPrintCustomWidget.cpp: Added.
+        (webkitPrintCustomWidgetSetProperty):
+        (webkit_print_custom_widget_class_init):
+        (webkit_print_custom_widget_new):
+        (webkit_print_custom_widget_get_widget):
+        (webkit_print_custom_widget_get_title):
+        (webkitPrintCustomWidgetEmitCustomWidgetApplySignal):
+        (webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal):
+        * UIProcess/API/gtk/WebKitPrintCustomWidget.h: Added.
+        * UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h: Added.
+        * UIProcess/API/gtk/WebKitPrintOperation.cpp:
+        (webkitPrintOperationAccumulatorObjectHandled):
+        (webkit_print_operation_class_init):
+        (notifySelectedPrinterCallback):
+        (webkitPrintOperationRunDialog):
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
+        * UIProcess/API/gtk/docs/webkit2gtk-4.0.types:
+        * UIProcess/API/gtk/docs/webkit2gtk-docs.sgml:
+        * UIProcess/API/gtk/webkit2.h:
+
 2017-02-01  Antti Koivisto  <an...@apple.com>
 
         Load resources speculatively

Modified: trunk/Source/WebKit2/PlatformGTK.cmake (211480 => 211481)


--- trunk/Source/WebKit2/PlatformGTK.cmake	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Source/WebKit2/PlatformGTK.cmake	2017-02-01 14:14:36 UTC (rev 211481)
@@ -208,6 +208,9 @@
     UIProcess/API/gtk/WebKitPolicyDecision.cpp
     UIProcess/API/gtk/WebKitPolicyDecision.h
     UIProcess/API/gtk/WebKitPolicyDecisionPrivate.h
+    UIProcess/API/gtk/WebKitPrintCustomWidget.cpp
+    UIProcess/API/gtk/WebKitPrintCustomWidget.h
+    UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h
     UIProcess/API/gtk/WebKitPrintOperation.cpp
     UIProcess/API/gtk/WebKitPrintOperation.h
     UIProcess/API/gtk/WebKitPrintOperationPrivate.h
@@ -539,6 +542,7 @@
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPermissionRequest.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPlugin.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPolicyDecision.h
+    ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPrintCustomWidget.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitPrintOperation.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitResponsePolicyDecision.h
     ${WEBKIT2_DIR}/UIProcess/API/gtk/WebKitScriptDialog.h

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h (211480 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitAutocleanups.h	2017-02-01 14:14:36 UTC (rev 211481)
@@ -55,6 +55,7 @@
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPermissionRequest, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPlugin, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPolicyDecision, g_object_unref)
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPrintCustomWidget, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitPrintOperation, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitResponsePolicyDecision, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (WebKitSecurityManager, g_object_unref)

Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp (0 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.cpp	2017-02-01 14:14:36 UTC (rev 211481)
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2017 Red Hat Inc.
+ *
+ * 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 "WebKitPrintCustomWidget.h"
+
+#include "WebKitPrintCustomWidgetPrivate.h"
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+#include <wtf/glib/GRefPtr.h>
+
+using namespace WebKit;
+
+/**
+ * SECTION: WebKitPrintCustomWidget
+ * @Short_description: Allows to embed a custom widget in print dialog
+ * @Title: WebKitPrintCustomWidget
+ * @See_also: #WebKitPrintOperation
+ *
+ * A WebKitPrintCustomWidget allows to embed a custom widget in the print
+ * dialog by connecting to the #WebKitPrintOperation::create-custom-widget
+ * signal, creating a new WebKitPrintCustomWidget with
+ * webkit_print_custom_widget_new() and returning it from there. You can later
+ * use webkit_print_operation_run_dialog() to display the dialog.
+ *
+ * Since: 2.16
+ */
+
+enum {
+    APPLY,
+    UPDATE,
+
+    LAST_SIGNAL
+};
+
+enum {
+    PROP_0,
+
+    PROP_WIDGET,
+    PROP_TITLE
+};
+
+struct _WebKitPrintCustomWidgetPrivate {
+    CString title;
+    GRefPtr<GtkWidget> widget;
+};
+
+static guint signals[LAST_SIGNAL] = { 0, };
+
+WEBKIT_DEFINE_TYPE(WebKitPrintCustomWidget, webkit_print_custom_widget, G_TYPE_OBJECT)
+
+static void webkitPrintCustomWidgetGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec)
+{
+    WebKitPrintCustomWidget* printCustomWidget = WEBKIT_PRINT_CUSTOM_WIDGET(object);
+
+    switch (propId) {
+    case PROP_WIDGET:
+        g_value_set_object(value, webkit_print_custom_widget_get_widget(printCustomWidget));
+        break;
+    case PROP_TITLE:
+        g_value_set_string(value, webkit_print_custom_widget_get_title(printCustomWidget));
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+    }
+}
+
+static void webkitPrintCustomWidgetSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec)
+{
+    WebKitPrintCustomWidget* printCustomWidget = WEBKIT_PRINT_CUSTOM_WIDGET(object);
+
+    switch (propId) {
+    case PROP_WIDGET:
+        printCustomWidget->priv->widget = GTK_WIDGET(g_value_get_object(value));
+        break;
+    case PROP_TITLE:
+        printCustomWidget->priv->title = g_value_get_string(value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec);
+    }
+}
+
+static void webkit_print_custom_widget_class_init(WebKitPrintCustomWidgetClass* printCustomWidgetClass)
+{
+    GObjectClass* objectClass = G_OBJECT_CLASS(printCustomWidgetClass);
+    objectClass->get_property = webkitPrintCustomWidgetGetProperty;
+    objectClass->set_property = webkitPrintCustomWidgetSetProperty;
+
+    /**
+     * WebKitPrintCustomWidget:widget:
+     *
+     * The custom #GtkWidget that will be embedded in the dialog.
+     *
+     * Since: 2.16
+     */
+    g_object_class_install_property(
+        objectClass,
+        PROP_WIDGET,
+        g_param_spec_object(
+            "widget",
+            _("Widget"),
+            _("Widget that will be added to the print dialog."),
+            GTK_TYPE_WIDGET,
+            static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
+
+    /**
+     * WebKitPrintCustomWidget:title:
+     *
+     * The title of the custom widget.
+     *
+     * Since: 2.16
+     */
+    g_object_class_install_property(
+        objectClass,
+        PROP_TITLE,
+        g_param_spec_string(
+            "title",
+            _("Title"),
+            _("Title of the widget that will be added to the print dialog."),
+            nullptr,
+            static_cast<GParamFlags>(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)));
+
+    /**
+     * WebKitPrintCustomWidget::update:
+     * @print_custom_widget: the #WebKitPrintCustomWidget on which the signal was emitted
+     * @page_setup: actual page setup
+     * @print_settings: actual print settings
+     *
+     * Emitted after change of selected printer in the dialog. The actual page setup
+     * and print settings are available and the custom widget can actualize itself
+     * according to their values.
+     *
+     * Since: 2.16
+     */
+    signals[UPDATE] =
+        g_signal_new(
+            "update",
+            G_TYPE_FROM_CLASS(printCustomWidgetClass),
+            G_SIGNAL_RUN_LAST,
+            G_STRUCT_OFFSET(WebKitPrintCustomWidgetClass, update),
+            0, 0,
+            g_cclosure_marshal_generic,
+            G_TYPE_NONE, 2,
+            GTK_TYPE_PAGE_SETUP, GTK_TYPE_PRINT_SETTINGS);
+
+    /**
+     * WebKitPrintCustomWidget::apply:
+     * @print_custom_widget: the #WebKitPrintCustomWidget on which the signal was emitted
+     *
+     * Emitted right before the printing will start. You should read the information
+     * from the widget and update the content based on it if necessary. The widget
+     * is not guaranteed to be valid at a later time.
+     *
+     * Since: 2.16
+     */
+    signals[APPLY] =
+        g_signal_new(
+            "apply",
+            G_TYPE_FROM_CLASS(printCustomWidgetClass),
+            G_SIGNAL_RUN_LAST,
+            G_STRUCT_OFFSET(WebKitPrintCustomWidgetClass, apply),
+            0, 0,
+            g_cclosure_marshal_VOID__VOID,
+            G_TYPE_NONE, 0);
+}
+
+/**
+ * webkit_print_custom_widget_new:
+ * @widget: a #GtkWidget
+ * @title: a @widget's title
+ *
+ * Create a new #WebKitPrintCustomWidget with given @widget and @title. The @widget
+ * ownership is taken and it is destroyed together with the dialog even if this
+ * object could still be alive at that point. You typically want to pass a container
+ * widget with multiple widgets in it.
+ *
+ * Returns: (transfer full): a new #WebKitPrintOperation.
+ *
+ * Since: 2.16
+ */
+WebKitPrintCustomWidget* webkit_print_custom_widget_new(GtkWidget* widget, const char* title)
+{
+    g_return_val_if_fail(GTK_IS_WIDGET(widget), nullptr);
+    g_return_val_if_fail(title, nullptr);
+
+    return WEBKIT_PRINT_CUSTOM_WIDGET(g_object_new(WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, "widget", widget, "title", title, nullptr));
+}
+
+/**
+ * webkit_print_custom_widget_get_widget:
+ * @print_custom_widget: a #WebKitPrintCustomWidget
+ *
+ * Return the value of #WebKitPrintCustomWidget:widget property for the given
+ * @print_custom_widget object. The returned value will always be valid if called
+ * from #WebKitPrintCustomWidget::apply or #WebKitPrintCustomWidget::update
+ * callbacks, but it will be %NULL if called after the
+ * #WebKitPrintCustomWidget::apply signal is emitted.
+ *
+ * Returns: (transfer none): a #GtkWidget.
+ *
+ * Since: 2.16
+ */
+GtkWidget* webkit_print_custom_widget_get_widget(WebKitPrintCustomWidget* printCustomWidget)
+{
+    g_return_val_if_fail(WEBKIT_IS_PRINT_CUSTOM_WIDGET(printCustomWidget), nullptr);
+
+    return printCustomWidget->priv->widget.get();
+}
+
+/**
+ * webkit_print_custom_widget_get_title:
+ * @print_custom_widget: a #WebKitPrintCustomWidget
+ *
+ * Return the value of #WebKitPrintCustomWidget:title property for the given
+ * @print_custom_widget object.
+ *
+ * Returns: Title of the @print_custom_widget.
+ *
+ * Since: 2.16
+ */
+const gchar* webkit_print_custom_widget_get_title(WebKitPrintCustomWidget* printCustomWidget)
+{
+    g_return_val_if_fail(WEBKIT_IS_PRINT_CUSTOM_WIDGET(printCustomWidget), nullptr);
+
+    return printCustomWidget->priv->title.data();
+}
+
+void webkitPrintCustomWidgetEmitCustomWidgetApplySignal(WebKitPrintCustomWidget* printCustomWidget)
+{
+    g_signal_emit(printCustomWidget, signals[APPLY], 0);
+    printCustomWidget->priv->widget = nullptr;
+}
+
+void webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(WebKitPrintCustomWidget *printCustomWidget, GtkPageSetup *pageSetup, GtkPrintSettings *printSettings)
+{
+    g_signal_emit(printCustomWidget, signals[UPDATE], 0, pageSetup, printSettings);
+}

Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h (0 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidget.h	2017-02-01 14:14:36 UTC (rev 211481)
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2017 Red Hat Inc.
+ *
+ * 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.
+ */
+
+#if !defined(__WEBKIT2_H_INSIDE__) && !defined(WEBKIT2_COMPILATION) && !defined(__WEBKIT_WEB_EXTENSION_H_INSIDE__)
+#error "Only <webkit2/webkit2.h> can be included directly."
+#endif
+
+#ifndef WebKitPrintCustomWidget_h
+#define WebKitPrintCustomWidget_h
+
+#include <glib-object.h>
+#include <webkit2/WebKitDefines.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define WEBKIT_TYPE_PRINT_CUSTOM_WIDGET            (webkit_print_custom_widget_get_type())
+#define WEBKIT_PRINT_CUSTOM_WIDGET(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidget))
+#define WEBKIT_IS_PRINT_CUSTOM_WIDGET(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), WEBKIT_TYPE_PRINT_CUSTOM_WIDGET))
+#define WEBKIT_PRINT_CUSTOM_WIDGET_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),  WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidgetClass))
+#define WEBKIT_IS_PRINT_CUSTOM_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),  WEBKIT_TYPE_PRINT_CUSTOM_WIDGET))
+#define WEBKIT_PRINT_CUSTOM_WIDGET_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj),  WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, WebKitPrintCustomWidgetClass))
+
+typedef struct _WebKitPrintCustomWidget        WebKitPrintCustomWidget;
+typedef struct _WebKitPrintCustomWidgetClass   WebKitPrintCustomWidgetClass;
+typedef struct _WebKitPrintCustomWidgetPrivate WebKitPrintCustomWidgetPrivate;
+
+struct _WebKitPrintCustomWidget {
+    GObject parent;
+
+    WebKitPrintCustomWidgetPrivate *priv;
+};
+
+struct _WebKitPrintCustomWidgetClass {
+    GObjectClass parent_class;
+
+    void    (* apply)               (WebKitPrintCustomWidget *print_custom_widget,
+                                     GtkWidget               *widget);
+    void    (* update)              (WebKitPrintCustomWidget *print_custom_widget,
+                                     GtkWidget               *widget,
+                                     GtkPageSetup            *page_setup,
+                                     GtkPrintSettings        *print_settings);
+
+    void    (*_webkit_reserved0) (void);
+    void    (*_webkit_reserved1) (void);
+    void    (*_webkit_reserved2) (void);
+    void    (*_webkit_reserved3) (void);
+};
+
+WEBKIT_API GType
+webkit_print_custom_widget_get_type   (void);
+
+WEBKIT_API WebKitPrintCustomWidget *
+webkit_print_custom_widget_new        (GtkWidget               *widget,
+                                       const char              *title);
+
+WEBKIT_API GtkWidget *
+webkit_print_custom_widget_get_widget (WebKitPrintCustomWidget *print_custom_widget);
+
+WEBKIT_API const gchar *
+webkit_print_custom_widget_get_title  (WebKitPrintCustomWidget *print_custom_widget);
+
+G_END_DECLS
+
+#endif

Added: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h (0 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h	                        (rev 0)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintCustomWidgetPrivate.h	2017-02-01 14:14:36 UTC (rev 211481)
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2017 Red Hat Inc.
+ *
+ * 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.
+ */
+
+#pragma once
+
+#include "WebKitPrintCustomWidget.h"
+#include "WebKitPrivate.h"
+#include <gtk/gtk.h>
+
+void webkitPrintCustomWidgetEmitCustomWidgetApplySignal(WebKitPrintCustomWidget*);
+void webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(WebKitPrintCustomWidget*, GtkPageSetup*, GtkPrintSettings*);

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp (211480 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp	2017-02-01 14:14:36 UTC (rev 211481)
@@ -20,6 +20,7 @@
 #include "config.h"
 #include "WebKitPrintOperation.h"
 
+#include "WebKitPrintCustomWidgetPrivate.h"
 #include "WebKitPrintOperationPrivate.h"
 #include "WebKitPrivate.h"
 #include "WebKitWebViewBasePrivate.h"
@@ -60,6 +61,7 @@
 enum {
     FINISHED,
     FAILED,
+    CREATE_CUSTOM_WIDGET,
 
     LAST_SIGNAL
 };
@@ -128,6 +130,15 @@
     }
 }
 
+static gboolean webkitPrintOperationAccumulatorObjectHandled(GSignalInvocationHint*, GValue* returnValue, const GValue* handlerReturn, gpointer)
+{
+    void* object = g_value_get_object(handlerReturn);
+    if (object)
+        g_value_set_object(returnValue, object);
+
+    return !object;
+}
+
 static void webkit_print_operation_class_init(WebKitPrintOperationClass* printOperationClass)
 {
     GObjectClass* gObjectClass = G_OBJECT_CLASS(printOperationClass);
@@ -206,9 +217,37 @@
             g_cclosure_marshal_VOID__BOXED,
             G_TYPE_NONE, 1,
             G_TYPE_ERROR | G_SIGNAL_TYPE_STATIC_SCOPE);
+
+    /**
+     * WebKitPrintOperation::create-custom-widget:
+     * @print_operation: the #WebKitPrintOperation on which the signal was emitted
+     *
+     * Emitted when displaying the print dialog with webkit_print_operation_run_dialog().
+     * The returned #WebKitPrintCustomWidget will be added to the print dialog and
+     * it will be owned by the @print_operation. However, the object is guaranteed
+     * to be alive until the #WebKitPrintCustomWidget::apply is emitted.
+     *
+     * Returns: (transfer full): A #WebKitPrintCustomWidget that will be embedded in the dialog.
+     *
+     * Since: 2.16
+     */
+    signals[CREATE_CUSTOM_WIDGET] =
+        g_signal_new(
+            "create-custom-widget",
+            G_TYPE_FROM_CLASS(gObjectClass),
+            G_SIGNAL_RUN_LAST,
+            0,
+            webkitPrintOperationAccumulatorObjectHandled, 0,
+            g_cclosure_marshal_generic,
+            WEBKIT_TYPE_PRINT_CUSTOM_WIDGET, 0);
 }
 
 #if HAVE(GTK_UNIX_PRINTING)
+static void notifySelectedPrinterCallback(GtkPrintUnixDialog* dialog, GParamSpec*, WebKitPrintCustomWidget* printCustomWidget)
+{
+    webkitPrintCustomWidgetEmitUpdateCustomWidgetSignal(printCustomWidget, gtk_print_unix_dialog_get_page_setup(dialog), gtk_print_unix_dialog_get_settings(dialog));
+}
+
 static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOperation* printOperation, GtkWindow* parent)
 {
     GtkPrintUnixDialog* printDialog = GTK_PRINT_UNIX_DIALOG(gtk_print_unix_dialog_new(0, parent));
@@ -233,11 +272,23 @@
 
     gtk_print_unix_dialog_set_embed_page_setup(printDialog, TRUE);
 
+    GRefPtr<WebKitPrintCustomWidget> customWidget;
+    g_signal_emit(printOperation, signals[CREATE_CUSTOM_WIDGET], 0, &customWidget.outPtr());
+    if (customWidget) {
+        const gchar* widgetTitle = webkit_print_custom_widget_get_title(customWidget.get());
+        GtkWidget* widget = webkit_print_custom_widget_get_widget(customWidget.get());
+
+        g_signal_connect(printDialog, "notify::selected-printer", G_CALLBACK(notifySelectedPrinterCallback), customWidget.get());
+        gtk_print_unix_dialog_add_custom_tab(printDialog, widget, gtk_label_new(widgetTitle));
+    }
+
     WebKitPrintOperationResponse returnValue = WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL;
     if (gtk_dialog_run(GTK_DIALOG(printDialog)) == GTK_RESPONSE_OK) {
         priv->printSettings = adoptGRef(gtk_print_unix_dialog_get_settings(printDialog));
         priv->pageSetup = gtk_print_unix_dialog_get_page_setup(printDialog);
         returnValue = WEBKIT_PRINT_OPERATION_RESPONSE_PRINT;
+        if (customWidget)
+            webkitPrintCustomWidgetEmitCustomWidgetApplySignal(customWidget.get());
     }
 
     gtk_widget_destroy(GTK_WIDGET(printDialog));

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (211480 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt	2017-02-01 14:14:36 UTC (rev 211481)
@@ -1471,3 +1471,24 @@
 WebKitColorChooserRequestPrivate
 webkit_color_chooser_request_get_type
 </SECTION>
+
+<SECTION>
+<FILE>WebKitPrintCustomWidget</FILE>
+WebKitPrintCustomWidget
+webkit_print_custom_widget_new
+webkit_print_custom_widget_get_widget
+webkit_print_custom_widget_get_title
+
+<SUBSECTION Standard>
+WebKitPrintCustomWidgetClass
+WEBKIT_TYPE_PRINT_CUSTOM_WIDGET
+WEBKIT_PRINT_CUSTOM_WIDGET
+WEBKIT_IS_PRINT_CUSTOM_WIDGET
+WEBKIT_PRINT_CUSTOM_WIDGET_CLASS
+WEBKIT_IS_PRINT_CUSTOM_WIDGET_CLASS
+WEBKIT_PRINT_CUSTOM_WIDGET_GET_CLASS
+
+<SUBSECTION Private>
+WebKitPrintCustomWidgetPrivate
+webkit_print_custom_widget_get_type
+</SECTION>

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types (211480 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-4.0.types	2017-02-01 14:14:36 UTC (rev 211481)
@@ -34,3 +34,4 @@
 webkit_install_missing_media_plugins_permission_request_get_type
 webkit_console_message_get_type
 webkit_web_view_session_state_get_type
+webkit_print_custom_widget_get_type

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml (211480 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-docs.sgml	2017-02-01 14:14:36 UTC (rev 211481)
@@ -31,6 +31,7 @@
     <xi:include href=""
     <xi:include href=""
     <xi:include href=""
+    <xi:include href=""
     <xi:include href=""
     <xi:include href=""
     <xi:include href=""

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h (211480 => 211481)


--- trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/webkit2.h	2017-02-01 14:14:36 UTC (rev 211481)
@@ -58,6 +58,7 @@
 #include <webkit2/WebKitNotificationPermissionRequest.h>
 #include <webkit2/WebKitPermissionRequest.h>
 #include <webkit2/WebKitPlugin.h>
+#include <webkit2/WebKitPrintCustomWidget.h>
 #include <webkit2/WebKitPrintOperation.h>
 #include <webkit2/WebKitResponsePolicyDecision.h>
 #include <webkit2/WebKitScriptDialog.h>

Modified: trunk/Tools/ChangeLog (211480 => 211481)


--- trunk/Tools/ChangeLog	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Tools/ChangeLog	2017-02-01 14:14:36 UTC (rev 211481)
@@ -1,3 +1,17 @@
+2017-02-01  Tomas Popela  <tpop...@redhat.com>
+
+        [GTK] Add an API to add a custom tab into the print dialog
+        https://bugs.webkit.org/show_bug.cgi?id=151998
+
+        Reviewed by Carlos Garcia Campos.
+
+        Add a new WebKitPrintOperation/custom-widget test in TestPrinting
+        that is testing a newly added API.
+
+        * TestWebKitAPI/Tests/WebKit2Gtk/TestPrinting.cpp:
+        (testPrintCustomWidget):
+        (beforeAll):
+
 2017-02-01  Enrique Ocaña González  <eoca...@igalia.com>
 
         [GStreamer][MSE] qtdemux: Update the tfdt patch to the version finally accepted upstream

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestPrinting.cpp (211480 => 211481)


--- trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestPrinting.cpp	2017-02-01 13:38:49 UTC (rev 211480)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKit2Gtk/TestPrinting.cpp	2017-02-01 14:14:36 UTC (rev 211481)
@@ -286,6 +286,196 @@
     test->loadHtml("<html><body _onLoad_=\"w = window.open();w.print();w.close();\"></body></html>", 0);
     test->waitUntilPrintFinishedAndViewClosed();
 }
+
+class PrintCustomWidgetTest: public WebViewTest {
+public:
+    MAKE_GLIB_TEST_FIXTURE(PrintCustomWidgetTest);
+
+    static void applyCallback(WebKitPrintCustomWidget*, PrintCustomWidgetTest* test)
+    {
+        test->m_applyEmitted = true;
+    }
+
+    static gboolean scheduleJumpToCustomWidget(PrintCustomWidgetTest* test)
+    {
+        test->jumpToCustomWidget();
+
+        return FALSE;
+    }
+
+    static void updateCallback(WebKitPrintCustomWidget* customWidget, GtkPageSetup*, GtkPrintSettings*, PrintCustomWidgetTest* test)
+    {
+        g_assert(test->m_widget == webkit_print_custom_widget_get_widget(customWidget));
+
+        test->m_updateEmitted = true;
+        // Would be nice to avoid the 1 second timeout here - but I didn't found
+        // a way to do so without making the test flaky.
+        g_timeout_add_seconds(1, reinterpret_cast<GSourceFunc>(scheduleJumpToCustomWidget), test);
+    }
+
+    static void widgetRealizeCallback(GtkWidget* widget, PrintCustomWidgetTest* test)
+    {
+        g_assert(GTK_IS_LABEL(widget));
+        g_assert(!g_strcmp0(gtk_label_get_text(GTK_LABEL(widget)), "Label"));
+
+        test->m_widgetRealized = true;
+        test->startPrinting();
+    }
+
+    static WebKitPrintCustomWidget* createCustomWidgetCallback(WebKitPrintOperation* printOperation, PrintCustomWidgetTest* test)
+    {
+        test->m_createEmitted = true;
+        WebKitPrintCustomWidget* printCustomWidget = test->createPrintCustomWidget();
+        test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printCustomWidget));
+        g_signal_connect(printCustomWidget, "apply", G_CALLBACK(applyCallback), test);
+        g_signal_connect(printCustomWidget, "update", G_CALLBACK(updateCallback), test);
+
+        GtkWidget* widget = webkit_print_custom_widget_get_widget(printCustomWidget);
+        test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(widget));
+        g_signal_connect(widget, "realize", G_CALLBACK(widgetRealizeCallback), test);
+
+        return printCustomWidget;
+    }
+
+    static gboolean scheduleMovementThroughDialog(PrintCustomWidgetTest* test)
+    {
+        test->jumpToFirstPrinter();
+
+        return FALSE;
+    }
+
+    static gboolean openPrintDialog(PrintCustomWidgetTest* test)
+    {
+        g_idle_add(reinterpret_cast<GSourceFunc>(scheduleMovementThroughDialog), test);
+        test->m_response = webkit_print_operation_run_dialog(test->m_printOperation.get(), GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(test->m_webView))));
+
+        return FALSE;
+    }
+
+    static void printOperationFinished(WebKitPrintOperation* printOperation, PrintCustomWidgetTest* test)
+    {
+        test->printFinished();
+    }
+
+    void printFinished()
+    {
+        g_assert(m_outputFile);
+        g_file_delete(m_outputFile.get(), nullptr, nullptr);
+        m_outputFile = nullptr;
+        g_main_loop_quit(m_mainLoop);
+    }
+
+    void sendKeyEvent(unsigned gdkKeyValue, GdkEventType type, unsigned modifiers)
+    {
+        GdkEvent* event = gdk_event_new(type);
+        event->key.keyval = gdkKeyValue;
+        event->key.state = modifiers;
+        event->key.window = gtk_widget_get_window(GTK_WIDGET(m_webView));
+        event->key.time = GDK_CURRENT_TIME;
+        g_object_ref(event->key.window);
+        gdk_event_set_device(event, gdk_device_manager_get_client_pointer(gdk_display_get_device_manager(gdk_display_get_default())));
+
+        GUniqueOutPtr<GdkKeymapKey> keys;
+        gint nKeys;
+        if (gdk_keymap_get_entries_for_keyval(gdk_keymap_get_default(), gdkKeyValue, &keys.outPtr(), &nKeys))
+            event->key.hardware_keycode = keys.get()[0].keycode;
+
+        gtk_main_do_event(event);
+
+        gdk_event_free(event);
+    }
+
+    void sendKeyPressAndReleaseEvent(unsigned gdkKeyValue, unsigned modifiers = 0)
+    {
+        sendKeyEvent(gdkKeyValue, GDK_KEY_PRESS, modifiers);
+        sendKeyEvent(gdkKeyValue, GDK_KEY_RELEASE, modifiers);
+    }
+
+    WebKitPrintOperation* createWebKitPrintOperation()
+    {
+        m_printOperation = adoptGRef(webkit_print_operation_new(m_webView));
+        g_assert(m_printOperation);
+        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_printOperation.get()));
+
+        g_signal_connect(m_printOperation.get(), "create-custom-widget", G_CALLBACK(createCustomWidgetCallback), this);
+        g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printOperationFinished), this);
+    }
+
+    WebKitPrintCustomWidget* createPrintCustomWidget()
+    {
+        m_widget = gtk_label_new("Label");
+        return webkit_print_custom_widget_new(m_widget, "Custom Widget");
+    }
+
+    void startPrinting()
+    {
+        // To start printing it is enough to press the Return key
+        sendKeyPressAndReleaseEvent(GDK_KEY_Return);
+    }
+
+    void jumpToFirstPrinter()
+    {
+        // Initially the GtkNotebook has focus, so we just need to press the Tab
+        // key to jump to the first printer
+        sendKeyPressAndReleaseEvent(GDK_KEY_Tab);
+    }
+
+    void jumpToCustomWidget()
+    {
+        // Jump back to the GtkNotebook
+        sendKeyPressAndReleaseEvent(GDK_KEY_Tab, GDK_SHIFT_MASK);
+        // Custom widget is on the third tab
+        sendKeyPressAndReleaseEvent(GDK_KEY_Right);
+        sendKeyPressAndReleaseEvent(GDK_KEY_Right);
+    }
+
+    void openDialogMoveThroughItAndWaitUntilClosed()
+    {
+        g_idle_add(reinterpret_cast<GSourceFunc>(openPrintDialog), this);
+        g_main_loop_run(m_mainLoop);
+    }
+
+    GRefPtr<WebKitPrintOperation> m_printOperation;
+    GRefPtr<GFile> m_outputFile;
+    GtkWidget* m_widget;
+    bool m_widgetRealized {false};
+    bool m_applyEmitted {false};
+    bool m_updateEmitted {false};
+    bool m_createEmitted {false};
+    WebKitPrintOperationResponse m_response {WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL};
+};
+
+static void testPrintCustomWidget(PrintCustomWidgetTest* test, gconstpointer)
+{
+    test->showInWindowAndWaitUntilMapped(GTK_WINDOW_TOPLEVEL, 0, 0);
+
+    test->loadHtml("<html><body>Text</body></html>", 0);
+    test->waitUntilLoadFinished();
+
+    test->createWebKitPrintOperation();
+
+    GRefPtr<GtkPrinter> printer = adoptGRef(findPrintToFilePrinter());
+    if (!printer) {
+        g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found");
+        return;
+    }
+
+    GUniquePtr<char> outputFilename(g_build_filename(Test::dataDirectory(), "webkit-close-after-print.pdf", nullptr));
+    test->m_outputFile = adoptGRef(g_file_new_for_path(outputFilename.get()));
+    GUniquePtr<char> outputURI(g_file_get_uri(test->m_outputFile.get()));
+
+    GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new());
+    gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get());
+    webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get());
+
+    test->openDialogMoveThroughItAndWaitUntilClosed();
+
+    g_assert(test->m_response == WEBKIT_PRINT_OPERATION_RESPONSE_PRINT);
+    g_assert(test->m_createEmitted);
+    g_assert(test->m_widgetRealized);
+    g_assert(test->m_updateEmitted);
+    g_assert(test->m_applyEmitted);
+}
 #endif // HAVE_GTK_UNIX_PRINTING
 
 void beforeAll()
@@ -296,6 +486,7 @@
     PrintTest::add("WebKitPrintOperation", "print", testPrintOperationPrint);
     PrintTest::add("WebKitPrintOperation", "print-errors", testPrintOperationErrors);
     CloseAfterPrintTest::add("WebKitPrintOperation", "close-after-print", testPrintOperationCloseAfterPrint);
+    PrintCustomWidgetTest::add("WebKitPrintOperation", "custom-widget", testPrintCustomWidget);
 #endif
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to