Commit 74026576 authored by Matthias Clasen's avatar Matthias Clasen Committed by Matthias Clasen

Add a GtkPrintOperation:: paginate signal that gets emitted to paginate a

2006-05-18  Matthias Clasen  <mclasen@redhat.com>

	* gtk/gtkprintoperation.h:
	* gtk/gtkprintoperation.c: Add a GtkPrintOperation:: paginate signal
	that gets emitted to paginate a document in chunks.
parent b44689fe
2006-05-18 Matthias Clasen <mclasen@redhat.com> 2006-05-18 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkprintoperation.h:
* gtk/gtkprintoperation.c: Add a GtkPrintOperation:: paginate signal
that gets emitted to paginate a document in chunks.
* gtk/gtkprintoperation-private.h:
* gtk/gtkmarshalers.list: Add necessary glue.
* gtk/gtkcalendar.c (gtk_calendar_drag_motion): Don't produce * gtk/gtkcalendar.c (gtk_calendar_drag_motion): Don't produce
a stuck drag if shift is held. (#341734, Sebastien Bacher) a stuck drag if shift is held. (#341734, Sebastien Bacher)
......
2006-05-18 Matthias Clasen <mclasen@redhat.com> 2006-05-18 Matthias Clasen <mclasen@redhat.com>
* gtk/gtkprintoperation.h:
* gtk/gtkprintoperation.c: Add a GtkPrintOperation:: paginate signal
that gets emitted to paginate a document in chunks.
* gtk/gtkprintoperation-private.h:
* gtk/gtkmarshalers.list: Add necessary glue.
* gtk/gtkcalendar.c (gtk_calendar_drag_motion): Don't produce * gtk/gtkcalendar.c (gtk_calendar_drag_motion): Don't produce
a stuck drag if shift is held. (#341734, Sebastien Bacher) a stuck drag if shift is held. (#341734, Sebastien Bacher)
......
...@@ -26,6 +26,7 @@ BOOLEAN:BOXED,BOXED ...@@ -26,6 +26,7 @@ BOOLEAN:BOXED,BOXED
BOOLEAN:ENUM BOOLEAN:ENUM
BOOLEAN:ENUM,DOUBLE BOOLEAN:ENUM,DOUBLE
BOOLEAN:ENUM,INT BOOLEAN:ENUM,INT
BOOLEAN:OBJECT
BOOLEAN:OBJECT,UINT,FLAGS BOOLEAN:OBJECT,UINT,FLAGS
BOOLEAN:OBJECT,INT,INT,UINT BOOLEAN:OBJECT,INT,INT,UINT
BOOLEAN:OBJECT,STRING,STRING,BOXED BOOLEAN:OBJECT,STRING,STRING,BOXED
......
...@@ -40,6 +40,8 @@ struct _GtkPrintOperationPrivate ...@@ -40,6 +40,8 @@ struct _GtkPrintOperationPrivate
gboolean track_print_status; gboolean track_print_status;
char *pdf_target; char *pdf_target;
guint print_pages_idle_id;
/* Data for the print job: */ /* Data for the print job: */
cairo_surface_t *surface; cairo_surface_t *surface;
double dpi_x, dpi_y; double dpi_x, dpi_y;
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
enum { enum {
BEGIN_PRINT, BEGIN_PRINT,
PAGINATE,
REQUEST_PAGE_SETUP, REQUEST_PAGE_SETUP,
DRAW_PAGE, DRAW_PAGE,
END_PRINT, END_PRINT,
...@@ -99,6 +100,9 @@ gtk_print_operation_finalize (GObject *object) ...@@ -99,6 +100,9 @@ gtk_print_operation_finalize (GObject *object)
g_free (priv->pdf_target); g_free (priv->pdf_target);
g_free (priv->job_name); g_free (priv->job_name);
if (priv->print_pages_idle_id > 0)
g_source_remove (priv->print_pages_idle_id);
G_OBJECT_CLASS (gtk_print_operation_parent_class)->finalize (object); G_OBJECT_CLASS (gtk_print_operation_parent_class)->finalize (object);
} }
...@@ -260,6 +264,36 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class) ...@@ -260,6 +264,36 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class)
g_cclosure_marshal_VOID__OBJECT, g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT); 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.
*
* If you don't need to do pagination in chunks, you can simply do
* it all in the begin-print handler, and set the number of pages
* from there.
*
* Since: 2.10
*/
signals[PAGINATE] =
g_signal_new (I_("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: * GtkPrintOperation::request-page-setup:
* @operation: the #GtkPrintOperation on which the signal was emitted * @operation: the #GtkPrintOperation on which the signal was emitted
...@@ -1309,6 +1343,24 @@ increment_page_sequence (PrintPagesData *data) ...@@ -1309,6 +1343,24 @@ increment_page_sequence (PrintPagesData *data)
return TRUE; return TRUE;
} }
static void
print_pages_idle_done (gpointer user_data)
{
PrintPagesData *data;
GtkPrintOperationPrivate *priv;
data = (PrintPagesData*)user_data;
priv = data->op->priv;
g_object_unref (data->print_context);
g_object_unref (data->initial_page_setup);
g_object_unref (data->op);
g_free (data);
priv->print_pages_idle_id = 0;
}
static gboolean static gboolean
print_pages_idle (gpointer user_data) print_pages_idle (gpointer user_data)
{ {
...@@ -1323,6 +1375,66 @@ print_pages_idle (gpointer user_data) ...@@ -1323,6 +1375,66 @@ print_pages_idle (gpointer user_data)
data = (PrintPagesData*)user_data; data = (PrintPagesData*)user_data;
priv = data->op->priv; 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++; data->collated++;
if (data->collated == data->collated_copies) if (data->collated == data->collated_copies)
{ {
...@@ -1331,15 +1443,9 @@ print_pages_idle (gpointer user_data) ...@@ -1331,15 +1443,9 @@ print_pages_idle (gpointer user_data)
{ {
g_signal_emit (data->op, signals[END_PRINT], 0, data->print_context); g_signal_emit (data->op, signals[END_PRINT], 0, data->print_context);
g_object_unref (data->print_context);
g_object_unref (data->initial_page_setup);
cairo_surface_finish (data->op->priv->surface); cairo_surface_finish (data->op->priv->surface);
priv->end_run (data->op, TRUE); priv->end_run (data->op, TRUE);
g_object_unref (data->op);
g_free (data);
done = TRUE; done = TRUE;
goto out; goto out;
...@@ -1391,79 +1497,35 @@ print_pages (GtkPrintOperation *op, ...@@ -1391,79 +1497,35 @@ print_pages (GtkPrintOperation *op,
GtkPageSetup *initial_page_setup; GtkPageSetup *initial_page_setup;
GtkPrintContext *print_context; GtkPrintContext *print_context;
int uncollated_copies, collated_copies; int uncollated_copies, collated_copies;
GtkPageRange *ranges;
int num_ranges;
PrintPagesData *data; PrintPagesData *data;
if (priv->manual_collation) _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);
{
uncollated_copies = priv->manual_num_copies;
collated_copies = 1;
}
else
{
uncollated_copies = 1;
collated_copies = priv->manual_num_copies;
}
print_context = _gtk_print_context_new (op); print_context = _gtk_print_context_new (op);
initial_page_setup = create_page_setup (op); initial_page_setup = create_page_setup (op);
_gtk_print_context_set_page_setup (print_context, initial_page_setup); _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_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) if (priv->manual_collation)
{
ranges = priv->page_ranges;
num_ranges = priv->num_page_ranges;
}
else if (priv->print_pages == GTK_PRINT_PAGES_CURRENT &&
priv->current_page != -1)
{ {
ranges = &data->one_range; uncollated_copies = priv->manual_num_copies;
num_ranges = 1; collated_copies = 1;
ranges[0].start = priv->current_page;
ranges[0].end = priv->current_page;
} }
else else
{ {
ranges = &data->one_range; uncollated_copies = 1;
num_ranges = 1; collated_copies = priv->manual_num_copies;
ranges[0].start = 0;
ranges[0].end = priv->nr_of_pages - 1;
} }
_gtk_print_operation_set_status (op, GTK_PRINT_STATUS_GENERATING_DATA, NULL);
data = g_new0 (PrintPagesData, 1); data = g_new0 (PrintPagesData, 1);
data->op = g_object_ref (op); data->op = g_object_ref (op);
data->uncollated_copies = uncollated_copies; data->uncollated_copies = uncollated_copies;
data->collated_copies = collated_copies; data->collated_copies = collated_copies;
data->ranges = ranges;
data->num_ranges = num_ranges;
data->initial_page_setup = initial_page_setup; data->initial_page_setup = initial_page_setup;
data->print_context = print_context; 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) if (wait)
{ {
/* FIXME replace this with a recursive mainloop */ /* FIXME replace this with a recursive mainloop */
...@@ -1475,7 +1537,10 @@ print_pages (GtkPrintOperation *op, ...@@ -1475,7 +1537,10 @@ print_pages (GtkPrintOperation *op,
} }
} }
else else
g_idle_add (print_pages_idle, data); priv->print_pages_idle_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
print_pages_idle,
data,
print_pages_idle_done);
} }
/** /**
...@@ -1493,7 +1558,7 @@ print_pages (GtkPrintOperation *op, ...@@ -1493,7 +1558,7 @@ print_pages (GtkPrintOperation *op,
* @op to obtain some information about the progress of the print operation. * @op to obtain some information about the progress of the print operation.
* Furthermore, it may use a recursive mainloop to show the print dialog. * Furthermore, it may use a recursive mainloop to show the print dialog.
* See gtk_print_operation_run_async() if this is a problem. * See gtk_print_operation_run_async() if this is a problem.
* *
* <informalexample><programlisting> * <informalexample><programlisting>
* FIXME: need an example here * FIXME: need an example here
* </programlisting></informalexample> * </programlisting></informalexample>
......
...@@ -66,18 +66,20 @@ struct _GtkPrintOperationClass ...@@ -66,18 +66,20 @@ struct _GtkPrintOperationClass
{ {
GObjectClass parent_class; GObjectClass parent_class;
void (*begin_print) (GtkPrintOperation *operation, void (*begin_print) (GtkPrintOperation *operation,
GtkPrintContext *context); GtkPrintContext *context);
void (*request_page_setup) (GtkPrintOperation *operation, gboolean (*paginate) (GtkPrintOperation *operation,
GtkPrintContext *context, GtkPrintContext *context);
gint page_nr, void (*request_page_setup) (GtkPrintOperation *operation,
GtkPageSetup *setup); GtkPrintContext *context,
void (*draw_page) (GtkPrintOperation *operation, gint page_nr,
GtkPrintContext *context, GtkPageSetup *setup);
gint page_nr); void (*draw_page) (GtkPrintOperation *operation,
void (*end_print) (GtkPrintOperation *operation, GtkPrintContext *context,
GtkPrintContext *context); gint page_nr);
void (*status_changed) (GtkPrintOperation *operation); void (*end_print) (GtkPrintOperation *operation,
GtkPrintContext *context);
void (*status_changed) (GtkPrintOperation *operation);
/* Padding for future expansion */ /* Padding for future expansion */
void (*_gtk_reserved1) (void); void (*_gtk_reserved1) (void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment