async pagination



I put together a patch to make pagination asynchronous as well.

I ended up just adding a new signal

 gboolean (*paginate)       (GtkPrintOperation *operation,
			                    GtkPrintContext   *context);

 /**
  * GtkPrintOperation::paginate:
  * @operation: the #GtkPrintOperation on which the signal was emitted
  * @context: the #GtkPrintContext for the current operation
  *
  * Gets emitted after the begin-print signal, but before the actual
  * rendering starts. It keeps getting emitted until it returns %FALSE.
  *
  * This signal is intended to be used for paginating the document
  * in small chunks, to avoid blocking the user interface for a long
  * time. The signal handler should update the number of pages using
  * gtk_print_operation_set_n_pages(), and return %TRUE if the document
  * has been completely paginated.
  *
  * Returns: %TRUE to stop pagination
  *
  * Since: 2.10
  */

My quick tests seem to indicate that it works...

Matthias
Index: gtk/gtkprintoperation.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkprintoperation.c,v
retrieving revision 1.12
diff -u -r1.12 gtkprintoperation.c
--- gtk/gtkprintoperation.c	15 May 2006 18:33:41 -0000	1.12
+++ gtk/gtkprintoperation.c	16 May 2006 14:51:33 -0000
@@ -35,6 +35,7 @@
   DRAW_PAGE,
   END_PRINT,
   STATUS_CHANGED,
+  PAGINATE,
   LAST_SIGNAL
 };
 
@@ -252,7 +253,7 @@
    * Since: 2.10
    */
   signals[BEGIN_PRINT] =
-    g_signal_new ("begin_print",
+    g_signal_new ("begin-print",
 		  G_TYPE_FROM_CLASS (gobject_class),
 		  G_SIGNAL_RUN_LAST,
 		  G_STRUCT_OFFSET (GtkPrintOperationClass, begin_print),
@@ -261,6 +262,31 @@
 		  G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
 
   /**
+   * GtkPrintOperation::paginate:
+   * @operation: the #GtkPrintOperation on which the signal was emitted
+   * @context: the #GtkPrintContext for the current operation
+   *
+   * Gets emitted after the begin-print signal, but before the actual 
+   * rendering starts. It keeps getting emitted until it returns %FALSE. 
+   *
+   * This signal is intended to be used for paginating the document
+   * in small chunks, to avoid blocking the user interface for a long
+   * time. The signal handler should update the number of pages using
+   * gtk_print_operation_set_n_pages(), and return %TRUE if the document
+   * has been completely paginated.
+   *
+   * Since: 2.10
+   */
+  signals[PAGINATE] =
+    g_signal_new ("paginate",
+		  G_TYPE_FROM_CLASS (gobject_class),
+		  G_SIGNAL_RUN_LAST,
+		  G_STRUCT_OFFSET (GtkPrintOperationClass, paginate),
+		  _gtk_boolean_handled_accumulator, NULL,
+		  _gtk_marshal_BOOLEAN__OBJECT,
+		  G_TYPE_BOOLEAN, 1, GTK_TYPE_PRINT_CONTEXT);
+
+  /**
    * GtkPrintOperation::request-page-setup:
    * @operation: the #GtkPrintOperation on which the signal was emitted
    * @context: the #GtkPrintContext for the current operation
@@ -274,7 +300,7 @@
    * Since: 2.10
    */
   signals[REQUEST_PAGE_SETUP] =
-    g_signal_new ("request_page_setup",
+    g_signal_new ("request-page-setup",
 		  G_TYPE_FROM_CLASS (gobject_class),
 		  G_SIGNAL_RUN_LAST,
 		  G_STRUCT_OFFSET (GtkPrintOperationClass, request_page_setup),
@@ -307,7 +333,7 @@
    * Since: 2.10
    */
   signals[DRAW_PAGE] =
-    g_signal_new ("draw_page",
+    g_signal_new ("draw-page",
 		  G_TYPE_FROM_CLASS (gobject_class),
 		  G_SIGNAL_RUN_LAST,
 		  G_STRUCT_OFFSET (GtkPrintOperationClass, draw_page),
@@ -329,7 +355,7 @@
    * Since: 2.10
    */
   signals[END_PRINT] =
-    g_signal_new ("end_print",
+    g_signal_new ("end-print",
 		  G_TYPE_FROM_CLASS (gobject_class),
 		  G_SIGNAL_RUN_LAST,
 		  G_STRUCT_OFFSET (GtkPrintOperationClass, end_print),
@@ -1316,6 +1342,66 @@
   data = (PrintPagesData*)user_data;
   priv = data->op->priv;
 
+  if (priv->status == GTK_PRINT_STATUS_PREPARING)
+    {
+      if (g_signal_has_handler_pending (data->op, signals[PAGINATE], 0, FALSE))
+	{
+	  gboolean paginated = FALSE;
+	  g_signal_emit (data->op, signals[PAGINATE], 0, data->print_context, &paginated);
+	  if (!paginated)
+	    goto out;
+	}
+
+      /* FIXME handle this better */
+      if (priv->nr_of_pages == 0)
+	g_warning ("no pages to print");
+      
+      /* Initialize parts of PrintPagesData that depend on nr_of_pages
+       */
+      if (priv->print_pages == GTK_PRINT_PAGES_RANGES)
+	{
+	  data->ranges = priv->page_ranges;
+	  data->num_ranges = priv->num_page_ranges;
+	}
+      else if (priv->print_pages == GTK_PRINT_PAGES_CURRENT &&
+	       priv->current_page != -1)
+	{
+	  data->ranges = &data->one_range;
+	  data->num_ranges = 1;
+	  data->ranges[0].start = priv->current_page;
+	  data->ranges[0].end = priv->current_page;
+	}
+      else
+	{
+	  data->ranges = &data->one_range;
+	  data->num_ranges = 1;
+	  data->ranges[0].start = 0;
+	  data->ranges[0].end = priv->nr_of_pages - 1;
+	}
+      
+      if (data->op->priv->manual_reverse)
+	{
+	  data->range = data->num_ranges - 1;
+	  data->inc = -1;      
+	}
+      else
+	{
+	  data->range = 0;
+	  data->inc = 1;      
+	}
+      find_range (data);
+     
+      /* go back one page, since we preincrement below */
+      data->page = data->start - data->inc;
+      data->collated = data->collated_copies - 1;
+
+      _gtk_print_operation_set_status (data->op, 
+				       GTK_PRINT_STATUS_GENERATING_DATA, 
+				       NULL);
+
+      goto out;
+    }
+
   data->collated++;
   if (data->collated == data->collated_copies)
     {
@@ -1375,7 +1461,7 @@
 
   return !done;
 }
-  
+
 static void
 print_pages (GtkPrintOperation *op,
 	     gboolean           wait)
@@ -1384,78 +1470,34 @@
   GtkPageSetup *initial_page_setup;
   GtkPrintContext *print_context;
   int uncollated_copies, collated_copies;
-  GtkPageRange *ranges;
-  int num_ranges;
   PrintPagesData *data;
 
-  if (priv->manual_collation)
-    {
-      uncollated_copies = priv->manual_num_copies;
-      collated_copies = 1;
-    }
-  else
-    {
-      uncollated_copies = 1;
-      collated_copies = priv->manual_num_copies;
-    }
+  _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);  
 
   print_context = _gtk_print_context_new (op);
 
   initial_page_setup = create_page_setup (op);
   _gtk_print_context_set_page_setup (print_context, initial_page_setup);
 
-  _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);  
   g_signal_emit (op, signals[BEGIN_PRINT], 0, print_context);
-  
-  g_return_if_fail (priv->nr_of_pages > 0);
 
-  if (priv->print_pages == GTK_PRINT_PAGES_RANGES)
-    {
-      ranges = priv->page_ranges;
-      num_ranges = priv->num_page_ranges;
-    }
-  else if (priv->print_pages == GTK_PRINT_PAGES_CURRENT &&
-	   priv->current_page != -1)
+  if (priv->manual_collation)
     {
-      ranges = &data->one_range;
-      num_ranges = 1;
-      ranges[0].start = priv->current_page;
-      ranges[0].end = priv->current_page;
+      uncollated_copies = priv->manual_num_copies;
+      collated_copies = 1;
     }
   else
     {
-      ranges = &data->one_range;
-      num_ranges = 1;
-      ranges[0].start = 0;
-      ranges[0].end = priv->nr_of_pages - 1;
+      uncollated_copies = 1;
+      collated_copies = priv->manual_num_copies;
     }
-  
-  _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_GENERATING_DATA, NULL);
 
   data = g_new0 (PrintPagesData, 1);
   data->op = g_object_ref (op);
   data->uncollated_copies = uncollated_copies;
   data->collated_copies = collated_copies;
-  data->ranges = ranges;
-  data->num_ranges = num_ranges;
   data->initial_page_setup = initial_page_setup;
   data->print_context = print_context;
-
-  data->uncollated = 0; 
-  if (data->op->priv->manual_reverse)
-    {
-      data->range = data->num_ranges - 1;
-      data->inc = -1;      
-    }
-  else
-    {
-      data->range = 0;
-      data->inc = 1;      
-    }
-  find_range (data);
-
-  data->page = data->start - data->inc;
-  data->collated = data->collated_copies - 1;
 
   if (wait)
     {
Index: gtk/gtkprintoperation.h
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkprintoperation.h,v
retrieving revision 1.5
diff -u -r1.5 gtkprintoperation.h
--- gtk/gtkprintoperation.h	15 May 2006 16:22:37 -0000	1.5
+++ gtk/gtkprintoperation.h	16 May 2006 14:51:33 -0000
@@ -78,6 +78,8 @@
   void (*end_print)          (GtkPrintOperation *operation,
 		              GtkPrintContext   *context);
   void (*status_changed)     (GtkPrintOperation *operation);
+  gboolean (*paginate)       (GtkPrintOperation *operation,
+			      GtkPrintContext   *context);
   
   /* Padding for future expansion */
   void (*_gtk_reserved1) (void);
@@ -86,7 +88,6 @@
   void (*_gtk_reserved4) (void);
   void (*_gtk_reserved5) (void);
   void (*_gtk_reserved6) (void);
-  void (*_gtk_reserved7) (void);
 };
 
 typedef enum {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]