From ad0d549d4cc13433f77c1ac8f0ab379c83d93f28 Mon Sep 17 00:00:00 2001 From: Simon Hausmann Date: Fri, 24 Feb 2012 16:36:50 +0100 Subject: Imported WebKit commit bb52bf3c0119e8a128cd93afe5572413a8617de9 (http://svn.webkit.org/repository/webkit/trunk@108790) --- .../UIProcess/API/gtk/WebKitPrintOperation.cpp | 410 +++++++++++++++++++++ 1 file changed, 410 insertions(+) create mode 100644 Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp (limited to 'Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp') diff --git a/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp new file mode 100644 index 000000000..a20ccb2a6 --- /dev/null +++ b/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp @@ -0,0 +1,410 @@ +/* + * 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 "WebKitPrintOperation.h" + +#include "PrintInfo.h" +#include "WebKitPrintOperationPrivate.h" +#include "WebKitPrivate.h" +#include "WebKitWebViewBasePrivate.h" +#include "WebPageProxy.h" +#include +#include +#include +#include + +#ifdef HAVE_GTK_UNIX_PRINTING +#include +#endif + +using namespace WebKit; + +enum { + PROP_0, + + PROP_WEB_VIEW, + PROP_PRINT_SETTINGS, + PROP_PAGE_SETUP +}; + +enum { + FINISHED, + + LAST_SIGNAL +}; + +struct _WebKitPrintOperationPrivate { + WebKitWebView* webView; + gulong webViewDestroyedId; + + GRefPtr printSettings; + GRefPtr pageSetup; +}; + +static guint signals[LAST_SIGNAL] = { 0, }; + +G_DEFINE_TYPE(WebKitPrintOperation, webkit_print_operation, G_TYPE_OBJECT) + +static void webkitPrintOperationFinalize(GObject* object) +{ + WebKitPrintOperationPrivate* priv = WEBKIT_PRINT_OPERATION(object)->priv; + g_signal_handler_disconnect(priv->webView, priv->webViewDestroyedId); + + priv->~WebKitPrintOperationPrivate(); + G_OBJECT_CLASS(webkit_print_operation_parent_class)->finalize(object); +} + +static void webViewDestroyed(GtkWidget* webView, GObject* printOperation) +{ + g_object_unref(printOperation); +} + +static void webkitPrintOperationConstructed(GObject* object) +{ + WebKitPrintOperation* printOperation = WEBKIT_PRINT_OPERATION(object); + WebKitPrintOperationPrivate* priv = printOperation->priv; + + if (G_OBJECT_CLASS(webkit_print_operation_parent_class)->constructed) + G_OBJECT_CLASS(webkit_print_operation_parent_class)->constructed(object); + + priv->webViewDestroyedId = g_signal_connect(priv->webView, "destroy", G_CALLBACK(webViewDestroyed), printOperation); +} + +static void webkitPrintOperationGetProperty(GObject* object, guint propId, GValue* value, GParamSpec* paramSpec) +{ + WebKitPrintOperation* printOperation = WEBKIT_PRINT_OPERATION(object); + + switch (propId) { + case PROP_WEB_VIEW: + g_value_take_object(value, printOperation->priv->webView); + break; + case PROP_PRINT_SETTINGS: + g_value_set_object(value, printOperation->priv->printSettings.get()); + break; + case PROP_PAGE_SETUP: + g_value_set_object(value, printOperation->priv->pageSetup.get()); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkitPrintOperationSetProperty(GObject* object, guint propId, const GValue* value, GParamSpec* paramSpec) +{ + WebKitPrintOperation* printOperation = WEBKIT_PRINT_OPERATION(object); + + switch (propId) { + case PROP_WEB_VIEW: + printOperation->priv->webView = WEBKIT_WEB_VIEW(g_value_get_object(value)); + break; + case PROP_PRINT_SETTINGS: + webkit_print_operation_set_print_settings(printOperation, GTK_PRINT_SETTINGS(g_value_get_object(value))); + break; + case PROP_PAGE_SETUP: + webkit_print_operation_set_page_setup(printOperation, GTK_PAGE_SETUP(g_value_get_object(value))); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, propId, paramSpec); + } +} + +static void webkit_print_operation_init(WebKitPrintOperation* printOperation) +{ + WebKitPrintOperationPrivate* priv = G_TYPE_INSTANCE_GET_PRIVATE(printOperation, WEBKIT_TYPE_PRINT_OPERATION, WebKitPrintOperationPrivate); + printOperation->priv = priv; + new (priv) WebKitPrintOperationPrivate(); +} + +static void webkit_print_operation_class_init(WebKitPrintOperationClass* printOperationClass) +{ + GObjectClass* gObjectClass = G_OBJECT_CLASS(printOperationClass); + gObjectClass->finalize = webkitPrintOperationFinalize; + gObjectClass->constructed = webkitPrintOperationConstructed; + gObjectClass->get_property = webkitPrintOperationGetProperty; + gObjectClass->set_property = webkitPrintOperationSetProperty; + + /** + * WebKitPrintOperation:web-view: + * + * The #WebKitWebView that will be printed. + */ + g_object_class_install_property(gObjectClass, + PROP_WEB_VIEW, + g_param_spec_object("web-view", + _("Web View"), + _("The web view that will be printed"), + WEBKIT_TYPE_WEB_VIEW, + static_cast(WEBKIT_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY))); + + /** + * WebKitPrintOperation:print-settings: + * + * The initial #GtkPrintSettings for the print operation. + */ + g_object_class_install_property(gObjectClass, + PROP_PRINT_SETTINGS, + g_param_spec_object("print-settings", + _("Print Settings"), + _("The initial print settings for the print operation"), + GTK_TYPE_PRINT_SETTINGS, + WEBKIT_PARAM_READWRITE)); + /** + * WebKitPrintOperation:page-setup: + * + * The initial #GtkPageSetup for the print operation. + */ + g_object_class_install_property(gObjectClass, + PROP_PAGE_SETUP, + g_param_spec_object("page-setup", + _("Page Setup"), + _("The initial page setup for the print operation"), + GTK_TYPE_PAGE_SETUP, + WEBKIT_PARAM_READWRITE)); + + /** + * WebKitPrintOperation::finished: + * @print_operation: the #WebKitPrintOperation on which the signal was emitted + * + * Emitted when the print operation has finished doing everything + * required for printing. + */ + signals[FINISHED] = + g_signal_new("finished", + G_TYPE_FROM_CLASS(gObjectClass), + G_SIGNAL_RUN_LAST, + 0, 0, 0, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + + g_type_class_add_private(printOperationClass, sizeof(WebKitPrintOperationPrivate)); +} + +#ifdef HAVE_GTK_UNIX_PRINTING +static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOperation* printOperation, GtkWindow* parent) +{ + GtkPrintUnixDialog* printDialog = GTK_PRINT_UNIX_DIALOG(gtk_print_unix_dialog_new(0, parent)); + gtk_print_unix_dialog_set_manual_capabilities(printDialog, static_cast(GTK_PRINT_CAPABILITY_NUMBER_UP + | GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT + | GTK_PRINT_CAPABILITY_PAGE_SET + | GTK_PRINT_CAPABILITY_REVERSE + | GTK_PRINT_CAPABILITY_COPIES + | GTK_PRINT_CAPABILITY_COLLATE + | GTK_PRINT_CAPABILITY_SCALE)); + + WebKitPrintOperationPrivate* priv = printOperation->priv; + if (priv->printSettings) + gtk_print_unix_dialog_set_settings(printDialog, priv->printSettings.get()); + + if (priv->pageSetup) + gtk_print_unix_dialog_set_page_setup(printDialog, priv->pageSetup.get()); + + gtk_print_unix_dialog_set_embed_page_setup(printDialog, TRUE); + + 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; + } + + gtk_widget_destroy(GTK_WIDGET(printDialog)); + + return returnValue; +} +#else +// TODO: We need to add an implementation for Windows. +static WebKitPrintOperationResponse webkitPrintOperationRunDialog(WebKitPrintOperation*, GtkWindow*) +{ + notImplemented(); + return WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL; +} +#endif + +static void drawPagesForPrintingCompleted(WKErrorRef, void* context) +{ + GRefPtr printOperation = adoptGRef(WEBKIT_PRINT_OPERATION(context)); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView)); + page->endPrinting(); + g_signal_emit(printOperation.get(), signals[FINISHED], 0, NULL); +} + +static void webkitPrintOperationPrintPagesForFrame(WebKitPrintOperation* printOperation, WebFrameProxy* webFrame, GtkPrintSettings* printSettings, GtkPageSetup* pageSetup) +{ + PrintInfo printInfo(printSettings, pageSetup); + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView)); + page->drawPagesForPrinting(webFrame, printInfo, VoidCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted)); +} + +WebKitPrintOperationResponse webkitPrintOperationRunDialogForFrame(WebKitPrintOperation* printOperation, GtkWindow* parent, WebFrameProxy* webFrame) +{ + WebKitPrintOperationPrivate* priv = printOperation->priv; + if (!parent) { + GtkWidget* toplevel = gtk_widget_get_toplevel(GTK_WIDGET(priv->webView)); + if (WebCore::widgetIsOnscreenToplevelWindow(toplevel)) + parent = GTK_WINDOW(toplevel); + } + + WebKitPrintOperationResponse response = webkitPrintOperationRunDialog(printOperation, parent); + if (response == WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL) + return response; + + webkitPrintOperationPrintPagesForFrame(printOperation, webFrame, priv->printSettings.get(), priv->pageSetup.get()); + return response; +} + +/** + * webkit_print_operation_new: + * @web_view: a #WebKitWebView + * + * Create a new #WebKitPrintOperation to print @web_view contents. + * + * Returns: (transfer full): a new #WebKitPrintOperation. + */ +WebKitPrintOperation* webkit_print_operation_new(WebKitWebView* webView) +{ + g_return_val_if_fail(WEBKIT_IS_WEB_VIEW(webView), 0); + + return WEBKIT_PRINT_OPERATION(g_object_new(WEBKIT_TYPE_PRINT_OPERATION, "web-view", webView, NULL)); +} + +/** + * webkit_print_operation_get_print_settings: + * @print_operation: a #WebKitPrintOperation + * + * Return the current print settings of @print_operation. It returns %NULL until + * either webkit_print_operation_set_print_settings() or webkit_print_operation_run_dialog() + * have been called. + * + * Returns: (transfer none): the current #GtkPrintSettings of @print_operation. + */ +GtkPrintSettings* webkit_print_operation_get_print_settings(WebKitPrintOperation* printOperation) +{ + g_return_val_if_fail(WEBKIT_IS_PRINT_OPERATION(printOperation), 0); + + return printOperation->priv->printSettings.get(); +} + +/** + * webkit_print_operation_set_print_settings: + * @print_operation: a #WebKitPrintOperation + * @print_settings: a #GtkPrintSettings to set + * + * Set the current print settings of @print_operation. Current print settings are used for + * the initial values of the print dialog when webkit_print_operation_run_dialog() is called. + */ +void webkit_print_operation_set_print_settings(WebKitPrintOperation* printOperation, GtkPrintSettings* printSettings) +{ + g_return_if_fail(WEBKIT_IS_PRINT_OPERATION(printOperation)); + g_return_if_fail(GTK_IS_PRINT_SETTINGS(printSettings)); + + if (printOperation->priv->printSettings.get() == printSettings) + return; + + printOperation->priv->printSettings = printSettings; + g_object_notify(G_OBJECT(printOperation), "print-settings"); +} + +/** + * webkit_print_operation_get_page_setup: + * @print_operation: a #WebKitPrintOperation + * + * Return the current page setup of @print_operation. It returns %NULL until + * either webkit_print_operation_set_print_settings() or webkit_print_operation_run_dialog() + * have been called. + * + * Returns: (transfer none): the current #GtkPageSetup of @print_operation. + */ +GtkPageSetup* webkit_print_operation_get_page_setup(WebKitPrintOperation* printOperation) +{ + g_return_val_if_fail(WEBKIT_IS_PRINT_OPERATION(printOperation), 0); + + return printOperation->priv->pageSetup.get(); +} + +/** + * webkit_print_operation_set_page_setup: + * @print_operation: a #WebKitPrintOperation + * @page_setup: a #GtkPageSetup to set + * + * Set the current page setup of @print_operation. Current page setup is used for the + * initial values of the print dialog when webkit_print_operation_run_dialog() is called. + */ +void webkit_print_operation_set_page_setup(WebKitPrintOperation* printOperation, GtkPageSetup* pageSetup) +{ + g_return_if_fail(WEBKIT_IS_PRINT_OPERATION(printOperation)); + g_return_if_fail(GTK_IS_PAGE_SETUP(pageSetup)); + + if (printOperation->priv->pageSetup.get() == pageSetup) + return; + + printOperation->priv->pageSetup = pageSetup; + g_object_notify(G_OBJECT(printOperation), "page-setup"); +} + +/** + * webkit_print_operation_run_dialog: + * @print_operation: a #WebKitPrintOperation + * @parent: (allow-none): transient parent of the print dialog + * + * Run the print dialog and start printing using the options selected by + * the user. This method returns when the print dialog is closed. + * If the print dialog is cancelled %WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL + * is returned. If the user clicks on the print button, %WEBKIT_PRINT_OPERATION_RESPONSE_PRINT + * is returned and the print operation starts. In this case, the WebKitPrintOperation::finished + * signal is emitted when the operation finishes. + * If the print dialog is not cancelled current print settings and page setup of @print_operation + * are updated with options selected by the user when Print button is pressed in print dialog. + * You can get the updated print settings and page setup by calling + * webkit_print_operation_get_print_settings() and webkit_print_operation_get_page_setup() + * after this method. + * + * Returns: the #WebKitPrintOperationResponse of the print dialog + */ +WebKitPrintOperationResponse webkit_print_operation_run_dialog(WebKitPrintOperation* printOperation, GtkWindow* parent) +{ + g_return_val_if_fail(WEBKIT_IS_PRINT_OPERATION(printOperation), WEBKIT_PRINT_OPERATION_RESPONSE_CANCEL); + + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView)); + return webkitPrintOperationRunDialogForFrame(printOperation, parent, page->mainFrame()); +} + +/** + * webkit_print_operation_print: + * @print_operation: a #WebKitPrintOperation + * + * Start a print operation using current print settings and page setup + * without showing the print dialog. If either print settings or page setup + * are not set with webkit_print_operation_set_print_settings() and + * webkit_print_operation_set_page_setup(), the default options will be used + * and the print job will be sent to the default printer. + * The WebKitPrintOperation::finished signal is emitted when the printing + * operation finishes. + */ +void webkit_print_operation_print(WebKitPrintOperation* printOperation) +{ + g_return_if_fail(WEBKIT_IS_PRINT_OPERATION(printOperation)); + + WebKitPrintOperationPrivate* priv = printOperation->priv; + GRefPtr printSettings = priv->printSettings ? priv->printSettings : adoptGRef(gtk_print_settings_new()); + GRefPtr pageSetup = priv->pageSetup ? priv->pageSetup : adoptGRef(gtk_page_setup_new()); + + WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView)); + webkitPrintOperationPrintPagesForFrame(printOperation, page->mainFrame(), printSettings.get(), pageSetup.get()); +} -- cgit v1.2.1