Title: [110714] trunk/Source
Revision
110714
Author
[email protected]
Date
2012-03-14 10:56:59 -0700 (Wed, 14 Mar 2012)

Log Message

[GTK] Handle printing errors in WebKit2
https://bugs.webkit.org/show_bug.cgi?id=77197

Reviewed by Gustavo Noronha Silva.

Source/WebCore:

* platform/gtk/ErrorsGtk.cpp:
(WebCore::printError): Create a generic print error.
(WebCore::printerNotFoundError): Create a print error to notify
that the selected printer could not be found.
(WebCore::invalidPageRangeToPrint): Create a print error when the
selected page range is invalid and there are no pages to print.
* platform/gtk/ErrorsGtk.h:
(WebCore): Add print error doamin.

Source/WebKit2:

* UIProcess/API/gtk/WebKitError.cpp:
(webkit_print_error_quark): Add new error domain for print
errors.
* UIProcess/API/gtk/WebKitError.h: Ad print errors.
* UIProcess/API/gtk/WebKitPrintOperation.cpp:
(webkit_print_operation_class_init): Add
WebKitPrintOperation::failed signal.
(drawPagesForPrintingCompleted): Emit WebKitPrintOperation::failed
when the print operation failed with the given error.
(webkitPrintOperationPrintPagesForFrame): Use
PrintFinishedCallback instead of a VoidCallback.
* UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Add new symbols.
* UIProcess/API/gtk/tests/TestPrinting.cpp:
(testPrintOperationPrint):
(testPrintOperationErrors): Test different print errors are
correctly reported.
(beforeAll):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::close): Invalidate print finished callbacks
map.
(WebKit::WebPageProxy::printFinishedCallback): Callback called
when the print operation has finished in the web process.
(WebKit::WebPageProxy::processDidCrash): Invalidate print finished
callbacks map.
(WebKit::WebPageProxy::drawPagesForPrinting): Use a
PrintFinishedCallback instead of a VoidCallback.
* UIProcess/WebPageProxy.h:
(WebKit): Delcare PrintFinishedCallback as a generic callback.
(WebPageProxy):
* UIProcess/WebPageProxy.messages.in: Use PrintFinishedCallback
instead of VoidCallback as callback argument of
DrawPagesForPrinting message.
* WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp:
(WebKit::PrintPagesData::PrintPagesData): Mark the data as invalid
when there are no pages to print.
(PrintPagesData): Add isValid parameter to mark the data struct as
invalid.
(WebKit::WebPrintOperationGtk::printPagesIdleDone): Call
printPagesDone() instead of printDone().
(WebKit::WebPrintOperationGtk::printPagesDone): Renamed.
(WebKit::WebPrintOperationGtk::printDone): Notify the UI process
that the print operation has finsihed.
(WebKit::WebPrintOperationGtk::print): Finish the print if the
PrintPagesData struct is not valid.
* WebProcess/WebPage/gtk/WebPrintOperationGtk.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (110713 => 110714)


--- trunk/Source/WebCore/ChangeLog	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebCore/ChangeLog	2012-03-14 17:56:59 UTC (rev 110714)
@@ -1,3 +1,19 @@
+2012-03-14  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Handle printing errors in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=77197
+
+        Reviewed by Gustavo Noronha Silva.
+
+        * platform/gtk/ErrorsGtk.cpp:
+        (WebCore::printError): Create a generic print error.
+        (WebCore::printerNotFoundError): Create a print error to notify
+        that the selected printer could not be found.
+        (WebCore::invalidPageRangeToPrint): Create a print error when the
+        selected page range is invalid and there are no pages to print.
+        * platform/gtk/ErrorsGtk.h:
+        (WebCore): Add print error doamin.
+
 2012-03-14  Nikolas Zimmermann  <[email protected]>
 
         Make SVGUseElement respect & support externalResourcesRequired

Modified: trunk/Source/WebCore/platform/gtk/ErrorsGtk.cpp (110713 => 110714)


--- trunk/Source/WebCore/platform/gtk/ErrorsGtk.cpp	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebCore/platform/gtk/ErrorsGtk.cpp	2012-03-14 17:56:59 UTC (rev 110714)
@@ -20,6 +20,9 @@
 #include "config.h"
 #include "ErrorsGtk.h"
 
+#include "DocumentLoader.h"
+#include "Frame.h"
+#include "PrintContext.h"
 #include "ResourceError.h"
 #include "ResourceRequest.h"
 #include "ResourceResponse.h"
@@ -87,4 +90,25 @@
                          response.url().string(), errorMessage);
 }
 
+ResourceError printError(const PrintContext* printContext, const String& errorMessage)
+{
+    DocumentLoader* documentLoader = printContext->frame()->loader()->documentLoader();
+    return ResourceError(errorDomainPrint, PrintErrorGeneral,
+                         documentLoader ? documentLoader->url() : KURL(), errorMessage);
+}
+
+ResourceError printerNotFoundError(const PrintContext* printContext)
+{
+    DocumentLoader* documentLoader = printContext->frame()->loader()->documentLoader();
+    return ResourceError(errorDomainPrint, PrintErrorPrinterNotFound,
+                         documentLoader ? documentLoader->url() : KURL(), _("Printer not found"));
+}
+
+ResourceError invalidPageRangeToPrint(const PrintContext* printContext)
+{
+    DocumentLoader* documentLoader = printContext->frame()->loader()->documentLoader();
+    return ResourceError(errorDomainPrint, PrintErrorInvalidPageRange,
+                         documentLoader ? documentLoader->url() : KURL(), _("Invalid page range"));
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/gtk/ErrorsGtk.h (110713 => 110714)


--- trunk/Source/WebCore/platform/gtk/ErrorsGtk.h	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebCore/platform/gtk/ErrorsGtk.h	2012-03-14 17:56:59 UTC (rev 110714)
@@ -24,6 +24,7 @@
 
 namespace WebCore {
 
+class PrintContext;
 class ResourceError;
 class ResourceRequest;
 class ResourceResponse;
@@ -32,6 +33,7 @@
 const char* const errorDomainPolicy = "WebKitPolicyError";
 const char* const errorDomainPlugin = "WebKitPluginError";
 const char* const errorDomainDownload = "WebKitDownloadError";
+const char* const errorDomainPrint = "WebKitPrintError";
 
 enum NetworkError {
     NetworkErrorFailed = 399,
@@ -65,6 +67,12 @@
     DownloadErrorDestination = 401
 };
 
+enum PrintError {
+    PrintErrorGeneral = 599,
+    PrintErrorPrinterNotFound = 500,
+    PrintErrorInvalidPageRange = 501
+};
+
 ResourceError cancelledError(const ResourceRequest&);
 ResourceError blockedError(const ResourceRequest&);
 ResourceError cannotShowURLError(const ResourceRequest&);
@@ -75,6 +83,9 @@
 ResourceError downloadNetworkError(const ResourceError&);
 ResourceError downloadCancelledByUserError(const ResourceResponse&);
 ResourceError downloadDestinationError(const ResourceResponse&, const String& errorMessage);
+ResourceError printError(const PrintContext*, const String& errorMessage);
+ResourceError printerNotFoundError(const PrintContext*);
+ResourceError invalidPageRangeToPrint(const PrintContext*);
 
 }
 

Modified: trunk/Source/WebKit2/ChangeLog (110713 => 110714)


--- trunk/Source/WebKit2/ChangeLog	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/ChangeLog	2012-03-14 17:56:59 UTC (rev 110714)
@@ -1,3 +1,56 @@
+2012-03-14  Carlos Garcia Campos  <[email protected]>
+
+        [GTK] Handle printing errors in WebKit2
+        https://bugs.webkit.org/show_bug.cgi?id=77197
+
+        Reviewed by Gustavo Noronha Silva.
+
+        * UIProcess/API/gtk/WebKitError.cpp:
+        (webkit_print_error_quark): Add new error domain for print
+        errors.
+        * UIProcess/API/gtk/WebKitError.h: Ad print errors.
+        * UIProcess/API/gtk/WebKitPrintOperation.cpp:
+        (webkit_print_operation_class_init): Add
+        WebKitPrintOperation::failed signal.
+        (drawPagesForPrintingCompleted): Emit WebKitPrintOperation::failed
+        when the print operation failed with the given error.
+        (webkitPrintOperationPrintPagesForFrame): Use
+        PrintFinishedCallback instead of a VoidCallback.
+        * UIProcess/API/gtk/docs/webkit2gtk-sections.txt: Add new symbols.
+        * UIProcess/API/gtk/tests/TestPrinting.cpp:
+        (testPrintOperationPrint):
+        (testPrintOperationErrors): Test different print errors are
+        correctly reported.
+        (beforeAll):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::close): Invalidate print finished callbacks
+        map.
+        (WebKit::WebPageProxy::printFinishedCallback): Callback called
+        when the print operation has finished in the web process.
+        (WebKit::WebPageProxy::processDidCrash): Invalidate print finished
+        callbacks map.
+        (WebKit::WebPageProxy::drawPagesForPrinting): Use a
+        PrintFinishedCallback instead of a VoidCallback.
+        * UIProcess/WebPageProxy.h:
+        (WebKit): Delcare PrintFinishedCallback as a generic callback.
+        (WebPageProxy):
+        * UIProcess/WebPageProxy.messages.in: Use PrintFinishedCallback
+        instead of VoidCallback as callback argument of
+        DrawPagesForPrinting message.
+        * WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp:
+        (WebKit::PrintPagesData::PrintPagesData): Mark the data as invalid
+        when there are no pages to print.
+        (PrintPagesData): Add isValid parameter to mark the data struct as
+        invalid.
+        (WebKit::WebPrintOperationGtk::printPagesIdleDone): Call
+        printPagesDone() instead of printDone().
+        (WebKit::WebPrintOperationGtk::printPagesDone): Renamed.
+        (WebKit::WebPrintOperationGtk::printDone): Notify the UI process
+        that the print operation has finsihed.
+        (WebKit::WebPrintOperationGtk::print): Finish the print if the
+        PrintPagesData struct is not valid.
+        * WebProcess/WebPage/gtk/WebPrintOperationGtk.h:
+
 2012-03-13  Jer Noble  <[email protected]>
 
         Lion Intel Debug WebKit2 Tests crashing under [WKFullScreenWindowController _startEnterFullScreenAnimationWithDuration:]

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp (110713 => 110714)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitError.cpp	2012-03-14 17:56:59 UTC (rev 110714)
@@ -68,3 +68,12 @@
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_NETWORK, DownloadErrorNetwork);
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_CANCELLED_BY_USER, DownloadErrorCancelledByUser);
 COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_DOWNLOAD_ERROR_DESTINATION, DownloadErrorDestination);
+
+GQuark webkit_print_error_quark()
+{
+    return g_quark_from_static_string(WebCore::errorDomainPrint);
+}
+
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_GENERAL, PrintErrorGeneral);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND, PrintErrorPrinterNotFound);
+COMPILE_ASSERT_MATCHING_ENUM(WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE, PrintErrorInvalidPageRange);

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/WebKitError.h (110713 => 110714)


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitError.h	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitError.h	2012-03-14 17:56:59 UTC (rev 110714)
@@ -29,10 +29,11 @@
 
 G_BEGIN_DECLS
 
-#define WEBKIT_NETWORK_ERROR webkit_network_error_quark ()
-#define WEBKIT_POLICY_ERROR  webkit_policy_error_quark ()
-#define WEBKIT_PLUGIN_ERROR  webkit_plugin_error_quark ()
+#define WEBKIT_NETWORK_ERROR  webkit_network_error_quark ()
+#define WEBKIT_POLICY_ERROR   webkit_policy_error_quark ()
+#define WEBKIT_PLUGIN_ERROR   webkit_plugin_error_quark ()
 #define WEBKIT_DOWNLOAD_ERROR webkit_download_error_quark ()
+#define WEBKIT_PRINT_ERROR    webkit_print_error_quark ()
 
 /**
  * WebKitNetworkError:
@@ -104,6 +105,20 @@
     WEBKIT_DOWNLOAD_ERROR_DESTINATION = 401
 } WebKitDownloadError;
 
+/**
+ * WebKitPrintError:
+ * @WEBKIT_PRINT_ERROR_GENERAL: Unspecified error during a print operation
+ * @WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND: Selected printer cannot be found
+ * @WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE: Invalid page range
+ *
+ * Enum values used to denote the various print errors.
+ */
+typedef enum {
+    WEBKIT_PRINT_ERROR_GENERAL = 599,
+    WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND = 500,
+    WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE = 501
+} WebKitPrintError;
+
 WEBKIT_API GQuark
 webkit_network_error_quark  (void);
 
@@ -116,6 +131,9 @@
 WEBKIT_API GQuark
 webkit_download_error_quark (void);
 
+WEBKIT_API GQuark
+webkit_print_error_quark    (void);
+
 G_END_DECLS
 
 #endif

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


--- trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/WebKitPrintOperation.cpp	2012-03-14 17:56:59 UTC (rev 110714)
@@ -28,7 +28,9 @@
 #include <WebCore/GtkUtilities.h>
 #include <WebCore/NotImplemented.h>
 #include <glib/gi18n-lib.h>
+#include <wtf/gobject/GOwnPtr.h>
 #include <wtf/gobject/GRefPtr.h>
+#include <wtf/text/CString.h>
 
 #ifdef HAVE_GTK_UNIX_PRINTING
 #include <gtk/gtkunixprint.h>
@@ -46,6 +48,7 @@
 
 enum {
     FINISHED,
+    FAILED,
 
     LAST_SIGNAL
 };
@@ -193,6 +196,24 @@
                      g_cclosure_marshal_VOID__VOID,
                      G_TYPE_NONE, 0);
 
+    /**
+     * WebKitPrintOperation::failed:
+     * @print_operation: the #WebKitPrintOperation on which the signal was emitted
+     * @error: the #GError that was triggered
+     *
+     * Emitted when an error occurs while printing. The given @error, of the domain
+     * %WEBKIT_PRINT_ERROR, contains further details of the failure.
+     * The #WebKitPrintOperation::finished signal is emitted after this one.
+     */
+    signals[FAILED] =
+        g_signal_new("failed",
+                     G_TYPE_FROM_CLASS(gObjectClass),
+                     G_SIGNAL_RUN_LAST,
+                     0, 0, 0,
+                     g_cclosure_marshal_VOID__POINTER,
+                     G_TYPE_NONE, 1,
+                     G_TYPE_POINTER);
+
     g_type_class_add_private(printOperationClass, sizeof(WebKitPrintOperationPrivate));
 }
 
@@ -237,11 +258,19 @@
 }
 #endif
 
-static void drawPagesForPrintingCompleted(WKErrorRef, void* context)
+static void drawPagesForPrintingCompleted(WKErrorRef wkPrintError, WKErrorRef, void* context)
 {
     GRefPtr<WebKitPrintOperation> printOperation = adoptGRef(WEBKIT_PRINT_OPERATION(context));
     WebPageProxy* page = webkitWebViewBaseGetPage(WEBKIT_WEB_VIEW_BASE(printOperation->priv->webView));
     page->endPrinting();
+
+    const WebCore::ResourceError& resourceError = toImpl(wkPrintError)->platformError();
+    if (!resourceError.isNull()) {
+        GOwnPtr<GError> printError(g_error_new_literal(g_quark_from_string(resourceError.domain().utf8().data()),
+                                                     resourceError.errorCode(),
+                                                     resourceError.localizedDescription().utf8().data()));
+        g_signal_emit(printOperation.get(), signals[FAILED], 0, printError.get());
+    }
     g_signal_emit(printOperation.get(), signals[FINISHED], 0, NULL);
 }
 
@@ -249,7 +278,7 @@
 {
     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));
+    page->drawPagesForPrinting(webFrame, printInfo, PrintFinishedCallback::create(g_object_ref(printOperation), &drawPagesForPrintingCompleted));
 }
 
 WebKitPrintOperationResponse webkitPrintOperationRunDialogForFrame(WebKitPrintOperation* printOperation, GtkWindow* parent, WebFrameProxy* webFrame)
@@ -368,7 +397,8 @@
  * 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.
+ * signal is emitted when the operation finishes. If an error occurs while printing, the signal
+ * #WebKitPrintOperation::failed is emitted before #WebKitPrintOperation::finished.
  * 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
@@ -395,7 +425,8 @@
  * 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.
+ * operation finishes. If an error occurs while printing the signal
+ * #WebKitPrintOperation::failed is emitted before #WebKitPrintOperation::finished.
  */
 void webkit_print_operation_print(WebKitPrintOperation* printOperation)
 {

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt (110713 => 110714)


--- trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/docs/webkit2gtk-sections.txt	2012-03-14 17:56:59 UTC (rev 110714)
@@ -463,14 +463,17 @@
 WEBKIT_PLUGIN_ERROR
 WEBKIT_POLICY_ERROR
 WEBKIT_DOWNLOAD_ERROR
+WEBKIT_PRINT_ERROR
 WebKitNetworkError
 WebKitPluginError
 WebKitPolicyError
 WebKitDownloadError
+WebKitPrintError
 webkit_network_error_quark
 webkit_plugin_error_quark
 webkit_policy_error_quark
 webkit_download_error_quark
+webkit_print_error_quark
 </SECTION>
 
 <SECTION>

Modified: trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp (110713 => 110714)


--- trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/tests/TestPrinting.cpp	2012-03-14 17:56:59 UTC (rev 110714)
@@ -72,37 +72,63 @@
 }
 
 #ifdef HAVE_GTK_UNIX_PRINTING
-static void testPrintOperationPrintLoadChanged(WebKitWebView*, WebKitLoadEvent loadEvent, WebViewTest* test)
-{
-    if (loadEvent != WEBKIT_LOAD_FINISHED)
-        return;
-    g_main_loop_quit(test->m_mainLoop);
-}
+class PrintTest: public WebViewTest {
+public:
+    MAKE_GLIB_TEST_FIXTURE(PrintTest);
 
-static void testPrintOperationPrintFinished(WebKitPrintOperation* printOperation, WebViewTest* test)
-{
-    g_object_unref(printOperation);
-    g_main_loop_quit(test->m_mainLoop);
-}
+    static void printFinishedCallback(WebKitPrintOperation*, PrintTest* test)
+    {
+        g_main_loop_quit(test->m_mainLoop);
+    }
 
-static gboolean testPrintOperationPrintPrinter(GtkPrinter* printer, gpointer userData)
-{
-    if (strcmp(gtk_printer_get_name(printer), "Print to File"))
-        return FALSE;
+    static void printFailedCallback(WebKitPrintOperation*, GError* error, PrintTest* test)
+    {
+        g_assert(test->m_expectedError);
+        g_assert(error);
+        g_assert(g_error_matches(error, WEBKIT_PRINT_ERROR, test->m_expectedError));
+    }
 
-    GtkPrinter** foundPrinter = static_cast<GtkPrinter**>(userData);
-    *foundPrinter = static_cast<GtkPrinter*>(g_object_ref(printer));
-    return TRUE;
-}
+    PrintTest()
+        : m_expectedError(0)
+    {
+        m_printOperation = adoptGRef(webkit_print_operation_new(m_webView));
+        assertObjectIsDeletedWhenTestFinishes(G_OBJECT(m_printOperation.get()));
+        g_signal_connect(m_printOperation.get(), "finished", G_CALLBACK(printFinishedCallback), this);
+        g_signal_connect(m_printOperation.get(), "failed", G_CALLBACK(printFailedCallback), this);
+    }
 
-static void testPrintOperationPrint(WebViewTest* test, gconstpointer)
+    static gboolean testPrintOperationPrintPrinter(GtkPrinter* printer, gpointer userData)
+    {
+        if (strcmp(gtk_printer_get_name(printer), "Print to File"))
+            return FALSE;
+
+        GtkPrinter** foundPrinter = static_cast<GtkPrinter**>(userData);
+        *foundPrinter = static_cast<GtkPrinter*>(g_object_ref(printer));
+        return TRUE;
+    }
+
+    GtkPrinter* findPrintToFilePrinter()
+    {
+        GtkPrinter* printer = 0;
+        gtk_enumerate_printers(testPrintOperationPrintPrinter, &printer, 0, TRUE);
+        return printer;
+    }
+
+    void waitUntilPrintFinished()
+    {
+        g_main_loop_run(m_mainLoop);
+    }
+
+    GRefPtr<WebKitPrintOperation> m_printOperation;
+    unsigned int m_expectedError;
+};
+
+static void testPrintOperationPrint(PrintTest* test, gconstpointer)
 {
-    g_signal_connect(test->m_webView, "load-changed", G_CALLBACK(testPrintOperationPrintLoadChanged), test);
     test->loadHtml("<html><body>WebKitGTK+ printing test</body></html>", 0);
-    g_main_loop_run(test->m_mainLoop);
+    test->waitUntilLoadFinished();
 
-    GtkPrinter* printer = 0;
-    gtk_enumerate_printers(testPrintOperationPrintPrinter, &printer, 0, TRUE);
+    GRefPtr<GtkPrinter> printer = adoptGRef(test->findPrintToFilePrinter());
     if (!printer) {
         g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found");
         return;
@@ -113,16 +139,12 @@
     GOwnPtr<char> outputURI(g_file_get_uri(outputFile.get()));
 
     GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new());
-    gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer));
+    gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
     gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, outputURI.get());
-    g_object_unref(printer);
 
-    GRefPtr<WebKitPrintOperation> printOperation = webkit_print_operation_new(test->m_webView);
-    test->assertObjectIsDeletedWhenTestFinishes(G_OBJECT(printOperation.get()));
-    g_signal_connect(printOperation.get(), "finished", G_CALLBACK(testPrintOperationPrintFinished), test);
-    webkit_print_operation_set_print_settings(printOperation.get(), printSettings.get());
-    webkit_print_operation_print(printOperation.get());
-    g_main_loop_run(test->m_mainLoop);
+    webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get());
+    webkit_print_operation_print(test->m_printOperation.get());
+    test->waitUntilPrintFinished();
 
     GRefPtr<GFileInfo> fileInfo = adoptGRef(g_file_query_info(outputFile.get(), G_FILE_ATTRIBUTE_STANDARD_SIZE","G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
                                                               static_cast<GFileQueryInfoFlags>(0), 0, 0));
@@ -132,6 +154,40 @@
 
     g_file_delete(outputFile.get(), 0, 0);
 }
+
+static void testPrintOperationErrors(PrintTest* test, gconstpointer)
+{
+    test->loadHtml("<html><body>WebKitGTK+ printing errors test</body></html>", 0);
+    test->waitUntilLoadFinished();
+
+    GRefPtr<GtkPrinter> printer = adoptGRef(test->findPrintToFilePrinter());
+    if (!printer) {
+        g_message("%s", "Cannot test WebKitPrintOperation/print: no suitable printer found");
+        return;
+    }
+
+    // General Error: invalid filename.
+    test->m_expectedError = WEBKIT_PRINT_ERROR_GENERAL;
+    GRefPtr<GtkPrintSettings> printSettings = adoptGRef(gtk_print_settings_new());
+    gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
+    gtk_print_settings_set(printSettings.get(), GTK_PRINT_SETTINGS_OUTPUT_URI, "file:///foo/bar");
+    webkit_print_operation_set_print_settings(test->m_printOperation.get(), printSettings.get());
+    webkit_print_operation_print(test->m_printOperation.get());
+    test->waitUntilPrintFinished();
+
+    // Printer not found error.
+    test->m_expectedError = WEBKIT_PRINT_ERROR_PRINTER_NOT_FOUND;
+    gtk_print_settings_set_printer(printSettings.get(), "The fake WebKit printer");
+    webkit_print_operation_print(test->m_printOperation.get());
+    test->waitUntilPrintFinished();
+
+    // No pages to print: print even pages for a single page document.
+    test->m_expectedError = WEBKIT_PRINT_ERROR_INVALID_PAGE_RANGE;
+    gtk_print_settings_set_printer(printSettings.get(), gtk_printer_get_name(printer.get()));
+    gtk_print_settings_set_page_set(printSettings.get(), GTK_PAGE_SET_EVEN);
+    webkit_print_operation_print(test->m_printOperation.get());
+    test->waitUntilPrintFinished();
+}
 #endif // HAVE_GTK_UNIX_PRINTING
 
 void beforeAll()
@@ -142,7 +198,8 @@
     WebViewTest::add("WebKitPrintOperation", "printing-settings", testPrintOperationPrintSettings);
     WebViewTest::add("WebKitWebView", "print-requested", testWebViewPrintRequested);
 #ifdef HAVE_GTK_UNIX_PRINTING
-    WebViewTest::add("WebKitPrintOperation", "print", testPrintOperationPrint);
+    PrintTest::add("WebKitPrintOperation", "print", testPrintOperationPrint);
+    PrintTest::add("WebKitPrintOperation", "print-errors", testPrintOperationErrors);
 #endif
 }
 

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp (110713 => 110714)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.cpp	2012-03-14 17:56:59 UTC (rev 110714)
@@ -396,6 +396,9 @@
     m_loadDependentStringCallbackIDs.clear();
     invalidateCallbackMap(m_scriptValueCallbacks);
     invalidateCallbackMap(m_computedPagesCallbacks);
+#if PLATFORM(GTK)
+    invalidateCallbackMap(m_printFinishedCallbacks);
+#endif
 
     Vector<WebEditCommandProxy*> editCommandVector;
     copyToVector(m_editCommandSet, editCommandVector);
@@ -3183,6 +3186,20 @@
     callback->performCallbackWithReturnValue(commandName.impl(), isEnabled, state);
 }
 
+#if PLATFORM(GTK)
+void WebPageProxy::printFinishedCallback(const ResourceError& printError, uint64_t callbackID)
+{
+    RefPtr<PrintFinishedCallback> callback = m_printFinishedCallbacks.take(callbackID);
+    if (!callback) {
+        // FIXME: Log error or assert.
+        return;
+    }
+
+    RefPtr<WebError> error = WebError::create(printError);
+    callback->performCallbackWithReturnValue(error.get());
+}
+#endif
+
 void WebPageProxy::focusedFrameChanged(uint64_t frameID)
 {
     if (!frameID) {
@@ -3286,6 +3303,9 @@
     invalidateCallbackMap(m_scriptValueCallbacks);
     invalidateCallbackMap(m_computedPagesCallbacks);
     invalidateCallbackMap(m_validateCommandCallbacks);
+#if PLATFORM(GTK)
+    invalidateCallbackMap(m_printFinishedCallbacks);
+#endif
 
     Vector<WebEditCommandProxy*> editCommandVector;
     copyToVector(m_editCommandSet, editCommandVector);
@@ -3600,16 +3620,16 @@
     process()->send(Messages::WebPage::DrawPagesToPDF(frame->frameID(), printInfo, first, count, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
 }
 #elif PLATFORM(GTK)
-void WebPageProxy::drawPagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<VoidCallback> didPrintCallback)
+void WebPageProxy::drawPagesForPrinting(WebFrameProxy* frame, const PrintInfo& printInfo, PassRefPtr<PrintFinishedCallback> didPrintCallback)
 {
-    RefPtr<VoidCallback> callback = didPrintCallback;
+    RefPtr<PrintFinishedCallback> callback = didPrintCallback;
     if (!isValid()) {
         callback->invalidate();
         return;
     }
 
     uint64_t callbackID = callback->callbackID();
-    m_voidCallbacks.set(callbackID, callback.get());
+    m_printFinishedCallbacks.set(callbackID, callback.get());
     m_isInPrintingMode = true;
     process()->send(Messages::WebPage::DrawPagesForPrinting(frame->frameID(), printInfo, callbackID), m_pageID, m_isPerformingDOMPrintOperation ? CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply : 0);
 }

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (110713 => 110714)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h	2012-03-14 17:56:59 UTC (rev 110714)
@@ -154,6 +154,10 @@
 typedef GenericCallback<WKStringRef, StringImpl*> StringCallback;
 typedef GenericCallback<WKSerializedScriptValueRef, WebSerializedScriptValue*> ScriptValueCallback;
 
+#if PLATFORM(GTK)
+typedef GenericCallback<WKErrorRef> PrintFinishedCallback;
+#endif
+
 #if ENABLE(TOUCH_EVENTS)
 struct QueuedTouchEvents {
     QueuedTouchEvents(const NativeWebTouchEvent& event)
@@ -600,7 +604,7 @@
     void drawRectToPDF(WebFrameProxy*, const PrintInfo&, const WebCore::IntRect&, PassRefPtr<DataCallback>);
     void drawPagesToPDF(WebFrameProxy*, const PrintInfo&, uint32_t first, uint32_t count, PassRefPtr<DataCallback>);
 #elif PLATFORM(GTK)
-    void drawPagesForPrinting(WebFrameProxy*, const PrintInfo&, PassRefPtr<VoidCallback>);
+    void drawPagesForPrinting(WebFrameProxy*, const PrintInfo&, PassRefPtr<PrintFinishedCallback>);
 #endif
 
     const String& pendingAPIRequestURL() const { return m_pendingAPIRequestURL; }
@@ -838,6 +842,9 @@
     void scriptValueCallback(const CoreIPC::DataReference&, uint64_t);
     void computedPagesCallback(const Vector<WebCore::IntRect>&, double totalScaleFactorForPrinting, uint64_t);
     void validateCommandCallback(const String&, bool, int, uint64_t);
+#if PLATFORM(GTK)
+    void printFinishedCallback(const WebCore::ResourceError&, uint64_t);
+#endif
 
     void focusedFrameChanged(uint64_t frameID);
     void frameSetLargestFrameChanged(uint64_t frameID);
@@ -915,6 +922,9 @@
     HashMap<uint64_t, RefPtr<ScriptValueCallback> > m_scriptValueCallbacks;
     HashMap<uint64_t, RefPtr<ComputedPagesCallback> > m_computedPagesCallbacks;
     HashMap<uint64_t, RefPtr<ValidateCommandCallback> > m_validateCommandCallbacks;
+#if PLATFORM(GTK)
+    HashMap<uint64_t, RefPtr<PrintFinishedCallback> > m_printFinishedCallbacks;
+#endif
 
     HashSet<WebEditCommandProxy*> m_editCommandSet;
 

Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (110713 => 110714)


--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in	2012-03-14 17:56:59 UTC (rev 110714)
@@ -144,6 +144,9 @@
     ScriptValueCallback(CoreIPC::DataReference resultData, uint64_t callbackID)
     ComputedPagesCallback(Vector<WebCore::IntRect> pageRects, double totalScaleFactorForPrinting, uint64_t callbackID)
     ValidateCommandCallback(WTF::String command, bool isEnabled, int32_t state, uint64_t callbackID)
+#if PLATFORM(GTK)
+    PrintFinishedCallback(WebCore::ResourceError error, uint64_t callbackID)
+#endif
 
     PageScaleFactorDidChange(double scaleFactor)
 

Modified: trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp (110713 => 110714)


--- trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.cpp	2012-03-14 17:56:59 UTC (rev 110714)
@@ -26,8 +26,10 @@
 #include "config.h"
 #include "WebPrintOperationGtk.h"
 
+#include "WebCoreArgumentCoders.h"
 #include "WebPage.h"
 #include "WebPageProxyMessages.h"
+#include <WebCore/ErrorsGtk.h>
 #include <WebCore/IntRect.h>
 #include <WebCore/NotImplemented.h>
 #include <WebCore/PlatformContextCairo.h>
@@ -72,13 +74,14 @@
     static void enumeratePrintersFinished(WebPrintOperationGtkUnix* printOperation)
     {
         if (!printOperation->m_printJob) {
-            // FIXME: Printing error.
+            printOperation->printDone(printerNotFoundError(printOperation->m_printContext));
             return;
         }
 
-        cairo_surface_t* surface = gtk_print_job_get_surface(printOperation->m_printJob.get(), 0);
+        GOwnPtr<GError> error;
+        cairo_surface_t* surface = gtk_print_job_get_surface(printOperation->m_printJob.get(), &error.outPtr());
         if (!surface) {
-            // FIXME: Printing error.
+            printOperation->printDone(printError(printOperation->m_printContext, error->message));
             return;
         }
 
@@ -143,8 +146,9 @@
             cairo_show_page(cr);
     }
 
-    static void printJobComplete(GtkPrintJob* printJob, WebPrintOperationGtkUnix* printOperation, const GError*)
+    static void printJobComplete(GtkPrintJob* printJob, WebPrintOperationGtkUnix* printOperation, const GError* error)
     {
+        printOperation->printDone(error ? printError(printOperation->m_printContext, error->message) : WebCore::ResourceError());
         printOperation->m_printJob = 0;
     }
 
@@ -210,6 +214,7 @@
         , collated(0)
         , uncollated(0)
         , isDone(false)
+        , isValid(true)
     {
         if (printOperation->collateCopies()) {
             collatedCopies = printOperation->copies();
@@ -247,6 +252,11 @@
             for (int i = 0; i < printOperation->pageCount(); ++i)
                 pages.append(i);
         }
+
+        if (!pages.size()) {
+            isValid = false;
+            return;
+        }
         printOperation->setNumberOfPagesToPrint(pages.size());
 
         size_t numberUp = printOperation->numberUp();
@@ -282,9 +292,11 @@
             break;
         }
 
-        // FIXME: check pagePostion is between [0..pages.size() - 1]
-        // and cancel the operation otherwise when error reporting
-        // is implemented.
+        if (sheetNumber * numberUp >= pages.size()) {
+            isValid = false;
+            return;
+        }
+
         printOperation->setPagePosition(sheetNumber * numberUp);
         pageNumber = pages[printOperation->pagePosition()];
         firstPagePosition = printOperation->pagePosition();
@@ -361,6 +373,7 @@
     size_t uncollatedCopies;
 
     bool isDone : 1;
+    bool isValid : 1;
 };
 
 PassRefPtr<WebPrintOperationGtk> WebPrintOperationGtk::create(WebPage* page, const PrintInfo& printInfo)
@@ -656,31 +669,42 @@
 {
     PrintPagesData* data = ""
 
-    data->printOperation->printDone();
+    data->printOperation->printPagesDone();
     delete data;
 }
 
-void WebPrintOperationGtk::printDone()
+void WebPrintOperationGtk::printPagesDone()
 {
     m_printPagesIdleId = 0;
-
     endPrint();
-    // Job is now sent to the printer, we can notify the UI process that we are done.
-    m_webPage->send(Messages::WebPageProxy::VoidCallback(m_callbackID));
     m_cairoContext = 0;
 }
 
+void WebPrintOperationGtk::printDone(const WebCore::ResourceError& error)
+{
+    if (m_printPagesIdleId)
+        g_source_remove(m_printPagesIdleId);
+    m_printPagesIdleId = 0;
+
+    // Print finished or failed, notify the UI process that we are done.
+    m_webPage->send(Messages::WebPageProxy::PrintFinishedCallback(error, m_callbackID));
+}
+
 void WebPrintOperationGtk::print(cairo_surface_t* surface, double xDPI, double yDPI)
 {
     ASSERT(m_printContext);
 
+    OwnPtr<PrintPagesData> data = "" PrintPagesData(this));
+    if (!data->isValid) {
+        printDone(invalidPageRangeToPrint(m_printContext));
+        return;
+    }
+
     m_xDPI = xDPI;
     m_yDPI = yDPI;
     m_cairoContext = adoptRef(cairo_create(surface));
-
-    PrintPagesData* data = "" PrintPagesData(this);
     m_printPagesIdleId = gdk_threads_add_idle_full(G_PRIORITY_DEFAULT_IDLE + 10, printPagesIdle,
-                                                   data, printPagesIdleDone);
+                                                   data.leakPtr(), printPagesIdleDone);
 }
 
 }

Modified: trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h (110713 => 110714)


--- trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h	2012-03-14 17:32:27 UTC (rev 110713)
+++ trunk/Source/WebKit2/WebProcess/WebPage/gtk/WebPrintOperationGtk.h	2012-03-14 17:56:59 UTC (rev 110714)
@@ -38,6 +38,7 @@
 
 namespace WebCore {
 class PrintContext;
+class ResourceError;
 };
 
 namespace WebKit {
@@ -49,6 +50,7 @@
     static PassRefPtr<WebPrintOperationGtk> create(WebPage*, const PrintInfo&);
     ~WebPrintOperationGtk();
 
+    WebCore::PrintContext* printContext() const { return m_printContext; }
     GtkPrintSettings* printSettings() const { return m_printSettings.get(); }
     GtkPageSetup* pageSetup() const { return m_pageSetup.get(); }
     void setNumberOfPagesToPrint(size_t numberOfPages) { m_numberOfPagesToPrint = numberOfPages; }
@@ -87,7 +89,8 @@
     void getRowsAndColumnsOfPagesPerSheet(size_t& rows, size_t& columns);
     void getPositionOfPageInSheet(size_t rows, size_t columns, int& x, int&y);
     void prepareContextToDraw();
-    void printDone();
+    void printPagesDone();
+    void printDone(const WebCore::ResourceError&);
 
     WebPage* m_webPage;
     GRefPtr<GtkPrintSettings> m_printSettings;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to