async pagination
- From: "Matthias Clasen" <matthias clasen gmail com>
- To: "GTK Devel List" <gtk-devel-list gnome org>
- Subject: async pagination
- Date: Tue, 16 May 2006 11:00:54 -0400
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]