*/
#include "config.h"
-#include "string.h"
+
+#include <errno.h>
+#include <stdlib.h>
+
+#include <string.h>
#include "gtkprintoperation-private.h"
#include "gtkmarshalers.h"
#include <cairo-pdf.h>
#include "gtkintl.h"
#include "gtkprivate.h"
+#include "gtkmessagedialog.h"
#include "gtkalias.h"
+#define SHOW_PROGRESS_TIME 1200
+
#define GTK_PRINT_OPERATION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_PRINT_OPERATION, GtkPrintOperationPrivate))
-enum {
+enum
+{
+ DONE,
BEGIN_PRINT,
+ PAGINATE,
REQUEST_PAGE_SETUP,
DRAW_PAGE,
END_PRINT,
STATUS_CHANGED,
+ CREATE_CUSTOM_WIDGET,
+ CUSTOM_WIDGET_APPLY,
+ PREVIEW,
LAST_SIGNAL
};
-enum {
+enum
+{
PROP_0,
PROP_DEFAULT_PAGE_SETUP,
PROP_PRINT_SETTINGS,
PROP_N_PAGES,
PROP_CURRENT_PAGE,
PROP_USE_FULL_PAGE,
+ PROP_TRACK_PRINT_STATUS,
PROP_UNIT,
- PROP_SHOW_DIALOG,
- PROP_PDF_TARGET,
+ PROP_SHOW_PROGRESS,
+ PROP_ALLOW_ASYNC,
+ PROP_EXPORT_FILENAME,
PROP_STATUS,
- PROP_STATUS_STRING
+ PROP_STATUS_STRING,
+ PROP_CUSTOM_TAB_LABEL
};
static guint signals[LAST_SIGNAL] = { 0 };
static int job_nr = 0;
-G_DEFINE_TYPE (GtkPrintOperation, gtk_print_operation, G_TYPE_OBJECT)
+static void preview_iface_init (GtkPrintOperationPreviewIface *iface);
+static GtkPageSetup *create_page_setup (GtkPrintOperation *op);
+static void common_render_page (GtkPrintOperation *op,
+ gint page_nr);
+
+
+G_DEFINE_TYPE_WITH_CODE (GtkPrintOperation, gtk_print_operation, G_TYPE_OBJECT,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_PRINT_OPERATION_PREVIEW,
+ preview_iface_init))
/**
* gtk_print_error_quark:
if (priv->print_settings)
g_object_unref (priv->print_settings);
- g_free (priv->pdf_target);
+ if (priv->print_context)
+ g_object_unref (priv->print_context);
+
+ g_free (priv->export_filename);
g_free (priv->job_name);
+ g_free (priv->custom_tab_label);
+ g_free (priv->status_string);
+
+ if (priv->print_pages_idle_id > 0)
+ g_source_remove (priv->print_pages_idle_id);
+ if (priv->show_progress_timeout_id > 0)
+ g_source_remove (priv->show_progress_timeout_id);
+
+ if (priv->error)
+ g_error_free (priv->error);
+
G_OBJECT_CLASS (gtk_print_operation_parent_class)->finalize (object);
}
priv->nr_of_pages = -1;
priv->current_page = -1;
priv->use_full_page = FALSE;
- priv->show_dialog = TRUE;
- priv->pdf_target = NULL;
+ priv->show_progress = FALSE;
+ priv->export_filename = NULL;
+ priv->track_print_status = FALSE;
+ priv->is_sync = FALSE;
+ priv->rloop = NULL;
priv->unit = GTK_UNIT_PIXEL;
appname = g_get_application_name ();
- priv->job_name = g_strdup_printf ("%s job #%d", appname, ++job_nr);
+ if (appname == NULL)
+ appname = "";
+ /* translators: this string is the default job title for print
+ * jobs. %s gets replaced by the application name, %d gets replaced
+ * by the job number.
+ */
+ priv->job_name = g_strdup_printf (_("%s job #%d"), appname, ++job_nr);
+}
+
+static void
+preview_iface_render_page (GtkPrintOperationPreview *preview,
+ gint page_nr)
+{
+
+ GtkPrintOperation *op;
+
+ op = GTK_PRINT_OPERATION (preview);
+ common_render_page (op, page_nr);
+}
+
+static void
+preview_iface_end_preview (GtkPrintOperationPreview *preview)
+{
+ GtkPrintOperation *op;
+
+ op = GTK_PRINT_OPERATION (preview);
+
+ g_signal_emit (op, signals[END_PRINT], 0, op->priv->print_context);
+
+ if (op->priv->rloop)
+ g_main_loop_quit (op->priv->rloop);
+
+ if (op->priv->end_run)
+ op->priv->end_run (op, op->priv->is_sync, TRUE);
+
+ _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
+
+ g_signal_emit (op, signals[DONE], 0, GTK_PRINT_OPERATION_RESULT_APPLY);
+}
+
+static gboolean
+preview_iface_is_selected (GtkPrintOperationPreview *preview,
+ gint page_nr)
+{
+ GtkPrintOperation *op;
+ GtkPrintOperationPrivate *priv;
+ int i;
+
+ op = GTK_PRINT_OPERATION (preview);
+ priv = op->priv;
+
+ switch (priv->print_pages)
+ {
+ case GTK_PRINT_PAGES_ALL:
+ return (page_nr >= 0) && (page_nr < priv->nr_of_pages);
+ case GTK_PRINT_PAGES_CURRENT:
+ return page_nr == priv->current_page;
+ case GTK_PRINT_PAGES_RANGES:
+ for (i = 0; i < priv->num_page_ranges; i++)
+ {
+ if (page_nr >= priv->page_ranges[i].start &&
+ (page_nr <= priv->page_ranges[i].end || priv->page_ranges[i].end == -1))
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
+static void
+preview_iface_init (GtkPrintOperationPreviewIface *iface)
+{
+ iface->render_page = preview_iface_render_page;
+ iface->end_preview = preview_iface_end_preview;
+ iface->is_selected = preview_iface_is_selected;
+}
+
+static void
+preview_start_page (GtkPrintOperation *op,
+ GtkPrintContext *print_context,
+ GtkPageSetup *page_setup)
+{
+ g_signal_emit_by_name (op, "got-page-size", print_context, page_setup);
}
+static void
+preview_end_page (GtkPrintOperation *op,
+ GtkPrintContext *print_context)
+{
+}
+
+static void
+preview_end_run (GtkPrintOperation *op,
+ gboolean wait,
+ gboolean cancelled)
+{
+ g_free (op->priv->page_ranges);
+ op->priv->page_ranges = NULL;
+}
+
+
static void
gtk_print_operation_set_property (GObject *object,
guint prop_id,
case PROP_USE_FULL_PAGE:
gtk_print_operation_set_use_full_page (op, g_value_get_boolean (value));
break;
+ case PROP_TRACK_PRINT_STATUS:
+ gtk_print_operation_set_track_print_status (op, g_value_get_boolean (value));
+ break;
case PROP_UNIT:
gtk_print_operation_set_unit (op, g_value_get_enum (value));
break;
- case PROP_SHOW_DIALOG:
- gtk_print_operation_set_show_dialog (op, g_value_get_boolean (value));
+ case PROP_ALLOW_ASYNC:
+ gtk_print_operation_set_allow_async (op, g_value_get_boolean (value));
+ break;
+ case PROP_SHOW_PROGRESS:
+ gtk_print_operation_set_show_progress (op, g_value_get_boolean (value));
+ break;
+ case PROP_EXPORT_FILENAME:
+ gtk_print_operation_set_export_filename (op, g_value_get_string (value));
break;
- case PROP_PDF_TARGET:
- gtk_print_operation_set_pdf_target (op, g_value_get_string (value));
+ case PROP_CUSTOM_TAB_LABEL:
+ gtk_print_operation_set_custom_tab_label (op, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
case PROP_USE_FULL_PAGE:
g_value_set_boolean (value, priv->use_full_page);
break;
+ case PROP_TRACK_PRINT_STATUS:
+ g_value_set_boolean (value, priv->track_print_status);
+ break;
case PROP_UNIT:
g_value_set_enum (value, priv->unit);
break;
- case PROP_SHOW_DIALOG:
- g_value_set_boolean (value, priv->show_dialog);
+ case PROP_ALLOW_ASYNC:
+ g_value_set_boolean (value, priv->allow_async);
+ break;
+ case PROP_SHOW_PROGRESS:
+ g_value_set_boolean (value, priv->show_progress);
break;
- case PROP_PDF_TARGET:
- g_value_set_string (value, priv->pdf_target);
+ case PROP_EXPORT_FILENAME:
+ g_value_set_string (value, priv->export_filename);
break;
case PROP_STATUS:
g_value_set_enum (value, priv->status);
case PROP_STATUS_STRING:
g_value_set_string (value, priv->status_string);
break;
+ case PROP_CUSTOM_TAB_LABEL:
+ g_value_set_string (value, priv->custom_tab_label);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
+typedef struct
+{
+ GtkPrintOperationPreview *preview;
+ GtkPrintContext *print_context;
+ GtkWindow *parent;
+ cairo_surface_t *surface;
+ gchar *filename;
+ guint page_nr;
+ gboolean wait;
+} PreviewOp;
+
+static void
+preview_print_idle_done (gpointer data)
+{
+ GtkPrintOperation *op;
+ PreviewOp *pop = (PreviewOp *) data;
+
+ op = GTK_PRINT_OPERATION (pop->preview);
+
+ cairo_surface_finish (pop->surface);
+ /* Surface is destroyed in launch_preview */
+ _gtk_print_operation_platform_backend_launch_preview (op,
+ pop->surface,
+ pop->parent,
+ pop->filename);
+
+ g_free (pop->filename);
+
+ gtk_print_operation_preview_end_preview (pop->preview);
+
+ g_object_unref (op);
+ g_free (pop);
+}
+
+static gboolean
+preview_print_idle (gpointer data)
+{
+ PreviewOp *pop;
+ GtkPrintOperation *op;
+ gboolean retval = TRUE;
+ cairo_t *cr;
+
+ pop = (PreviewOp *) data;
+ op = GTK_PRINT_OPERATION (pop->preview);
+
+ gtk_print_operation_preview_render_page (pop->preview, pop->page_nr);
+
+ cr = gtk_print_context_get_cairo_context (pop->print_context);
+ _gtk_print_operation_platform_backend_preview_end_page (op, pop->surface, cr);
+
+ /* TODO: print out sheets not pages and follow ranges */
+ pop->page_nr++;
+ if (op->priv->nr_of_pages <= pop->page_nr)
+ retval = FALSE;
+
+ return retval;
+}
+
+static void
+preview_got_page_size (GtkPrintOperationPreview *preview,
+ GtkPrintContext *context,
+ GtkPageSetup *page_setup,
+ PreviewOp *pop)
+{
+ GtkPrintOperation *op = GTK_PRINT_OPERATION (preview);
+ cairo_t *cr;
+
+ _gtk_print_operation_platform_backend_resize_preview_surface (op, page_setup, pop->surface);
+
+ cr = gtk_print_context_get_cairo_context (pop->print_context);
+ _gtk_print_operation_platform_backend_preview_start_page (op, pop->surface, cr);
+
+}
+
+static void
+preview_ready (GtkPrintOperationPreview *preview,
+ GtkPrintContext *context,
+ PreviewOp *pop)
+{
+ pop->page_nr = 0;
+ pop->print_context = context;
+
+ g_object_ref (preview);
+
+ gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE + 10,
+ preview_print_idle,
+ pop,
+ preview_print_idle_done);
+}
+
+
+static gboolean
+gtk_print_operation_preview_handler (GtkPrintOperation *op,
+ GtkPrintOperationPreview *preview,
+ GtkPrintContext *context,
+ GtkWindow *parent)
+{
+ gdouble dpi_x, dpi_y;
+ PreviewOp *pop;
+ GtkPageSetup *page_setup;
+ cairo_t *cr;
+
+ pop = g_new0 (PreviewOp, 1);
+ pop->filename = NULL;
+ pop->preview = preview;
+ pop->parent = parent;
+
+ page_setup = gtk_print_context_get_page_setup (context);
+
+ pop->surface =
+ _gtk_print_operation_platform_backend_create_preview_surface (op,
+ page_setup,
+ &dpi_x, &dpi_y,
+ &pop->filename);
+
+ if (pop->surface == NULL)
+ {
+ g_free (pop);
+ return FALSE;
+ }
+
+ cr = cairo_create (pop->surface);
+ gtk_print_context_set_cairo_context (op->priv->print_context, cr,
+ dpi_x, dpi_y);
+ cairo_destroy (cr);
+
+ g_signal_connect (preview, "ready", (GCallback) preview_ready, pop);
+ g_signal_connect (preview, "got-page-size", (GCallback) preview_got_page_size, pop);
+
+ return TRUE;
+}
+
+static GtkWidget *
+gtk_print_operation_create_custom_widget (GtkPrintOperation *operation)
+{
+ return NULL;
+}
+
+static void
+gtk_print_operation_done (GtkPrintOperation *operation,
+ GtkPrintOperationResult result)
+{
+ GtkPrintOperationPrivate *priv = operation->priv;
+
+ if (priv->print_context)
+ {
+ g_object_unref (priv->print_context);
+ priv->print_context = NULL;
+ }
+}
+
+static gboolean
+custom_widget_accumulator (GSignalInvocationHint *ihint,
+ GValue *return_accu,
+ const GValue *handler_return,
+ gpointer dummy)
+{
+ gboolean continue_emission;
+ GtkWidget *widget;
+
+ widget = g_value_get_object (handler_return);
+ if (widget != NULL)
+ g_value_set_object (return_accu, widget);
+ continue_emission = (widget == NULL);
+
+ return continue_emission;
+}
+
static void
gtk_print_operation_class_init (GtkPrintOperationClass *class)
{
gobject_class->set_property = gtk_print_operation_set_property;
gobject_class->get_property = gtk_print_operation_get_property;
gobject_class->finalize = gtk_print_operation_finalize;
+
+ class->preview = gtk_print_operation_preview_handler;
+ class->create_custom_widget = gtk_print_operation_create_custom_widget;
+ class->done = gtk_print_operation_done;
g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
+ /**
+ * GtkPrintOperation::done:
+ * @operation: the #GtkPrintOperation on which the signal was emitted
+ * @result: the result of the print operation
+ *
+ * Emitted when the print operation run has finished doing
+ * everything required for printing.
+ *
+ * @result gives you information about what happened during the run.
+ * If @result is %GTK_PRINT_OPERATION_RESULT_ERROR then you can call
+ * gtk_print_operation_get_error() for more information.
+ *
+ * If you enabled print status tracking then
+ * gtk_print_operation_is_finished() may still return %FALSE
+ * after #GtkPrintOperation::done was emitted.
+ *
+ * Since: 2.10
+ */
+ signals[DONE] =
+ g_signal_new (I_("done"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkPrintOperationClass, done),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__ENUM,
+ G_TYPE_NONE, 1, GTK_TYPE_PRINT_OPERATION_RESULT);
+
/**
* GtkPrintOperation::begin-print:
* @operation: the #GtkPrintOperation on which the signal was emitted
* @context: the #GtkPrintContext for the current operation
*
- * Gets emitted after the user has finished changing print settings
+ * Emitted after the user has finished changing print settings
* in the dialog, before the actual rendering starts.
*
- * A typical use for this signal is to use the parameters from the
+ * A typical use for ::begin-print is to use the parameters from the
* #GtkPrintContext and paginate the document accordingly, and then
* set the number of pages with gtk_print_operation_set_n_pages().
*
* Since: 2.10
*/
signals[BEGIN_PRINT] =
- g_signal_new ("begin_print",
+ g_signal_new (I_("begin-print"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, begin_print),
g_cclosure_marshal_VOID__OBJECT,
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
+ *
+ * Emitted after the #GtkPrintOperation::begin-print signal, but before
+ * the actual rendering starts. It keeps getting emitted until a connected
+ * signal handler returns %TRUE.
+ *
+ * The ::paginate signal is intended to be used for paginating a 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.
+ *
+ * Return value: %TRUE if pagination is complete
+ *
+ * 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:
* @operation: the #GtkPrintOperation on which the signal was emitted
* @context: the #GtkPrintContext for the current operation
- * @page_nr: the number of the currently printed page
+ * @page_nr: the number of the currently printed page (0-based)
* @setup: the #GtkPageSetup
*
- * Gets emitted once for every page that is printed, to give
+ * Emitted once for every page that is printed, to give
* the application a chance to modify the page setup. Any changes
* done to @setup will be in force only for printing this page.
*
* Since: 2.10
*/
signals[REQUEST_PAGE_SETUP] =
- g_signal_new ("request_page_setup",
+ g_signal_new (I_("request-page-setup"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, request_page_setup),
* GtkPrintOperation::draw-page:
* @operation: the #GtkPrintOperation on which the signal was emitted
* @context: the #GtkPrintContext for the current operation
- * @page_nr: the number of the currently printed page
+ * @page_nr: the number of the currently printed page (0-based)
*
- * Gets emitted for every page that is printed. The signal handler
+ * Emitted for every page that is printed. The signal handler
* must render the @page_nr's page onto the cairo context obtained
- * from @context using gtk_print_context_get_cairo().
- *
- * <informalexample><programlisting>
- * FIXME: need an example here
- * </programlisting></informalexample>
+ * from @context using gtk_print_context_get_cairo_context().
+ * |[
+ * static void
+ * draw_page (GtkPrintOperation *operation,
+ * GtkPrintContext *context,
+ * gint page_nr,
+ * gpointer user_data)
+ * {
+ * cairo_t *cr;
+ * PangoLayout *layout;
+ * gdouble width, text_height;
+ * gint layout_height;
+ * PangoFontDescription *desc;
+ *
+ * cr = gtk_print_context_get_cairo_context (context);
+ * width = gtk_print_context_get_width (context);
+ *
+ * cairo_rectangle (cr, 0, 0, width, HEADER_HEIGHT);
+ *
+ * cairo_set_source_rgb (cr, 0.8, 0.8, 0.8);
+ * cairo_fill (cr);
+ *
+ * layout = gtk_print_context_create_pango_layout (context);
+ *
+ * desc = pango_font_description_from_string ("sans 14");
+ * pango_layout_set_font_description (layout, desc);
+ * pango_font_description_free (desc);
+ *
+ * pango_layout_set_text (layout, "some text", -1);
+ * pango_layout_set_width (layout, width * PANGO_SCALE);
+ * pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER);
+ *
+ * pango_layout_get_size (layout, NULL, &layout_height);
+ * text_height = (gdouble)layout_height / PANGO_SCALE;
+ *
+ * cairo_move_to (cr, width / 2, (HEADER_HEIGHT - text_height) / 2);
+ * pango_cairo_show_layout (cr, layout);
+ *
+ * g_object_unref (layout);
+ * }
+ * ]|
*
* Use gtk_print_operation_set_use_full_page() and
* gtk_print_operation_set_unit() before starting the print operation
* Since: 2.10
*/
signals[DRAW_PAGE] =
- g_signal_new ("draw_page",
+ g_signal_new (I_("draw-page"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, draw_page),
* @operation: the #GtkPrintOperation on which the signal was emitted
* @context: the #GtkPrintContext for the current operation
*
- * Gets emitted after all pages have been rendered.
+ * Emitted after all pages have been rendered.
* A handler for this signal can clean up any resources that have
- * been allocated in the ::begin-print handler.
+ * been allocated in the #GtkPrintOperation::begin-print handler.
*
* Since: 2.10
*/
signals[END_PRINT] =
- g_signal_new ("end_print",
+ g_signal_new (I_("end-print"),
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, end_print),
* GtkPrintOperation::status-changed:
* @operation: the #GtkPrintOperation on which the signal was emitted
*
- * Gets emitted at between the various phases of the print operation.
+ * Emitted at between the various phases of the print operation.
* See #GtkPrintStatus for the phases that are being discriminated.
* Use gtk_print_operation_get_status() to find out the current
* status.
* Since: 2.10
*/
signals[STATUS_CHANGED] =
- g_signal_new ("status-changed",
- G_TYPE_FROM_CLASS (class),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkPrintOperationClass, status_changed),
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ g_signal_new (I_("status-changed"),
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkPrintOperationClass, status_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
+
+
+ /**
+ * GtkPrintOperation::create-custom-widget:
+ * @operation: the #GtkPrintOperation on which the signal was emitted
+ *
+ * Emitted when displaying the print dialog. If you return a
+ * widget in a handler for this signal it will be added to a custom
+ * tab in the print dialog. You typically return a container widget
+ * with multiple widgets in it.
+ *
+ * The print dialog owns the returned widget, and its lifetime is not
+ * controlled by the application. However, the widget is guaranteed
+ * to stay around until the #GtkPrintOperation::custom-widget-apply
+ * signal is emitted on the operation. Then you can read out any
+ * information you need from the widgets.
+ *
+ * Returns: A custom widget that gets embedded in the print dialog,
+ * or %NULL
+ *
+ * Since: 2.10
+ */
+ signals[CREATE_CUSTOM_WIDGET] =
+ g_signal_new (I_("create-custom-widget"),
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkPrintOperationClass, create_custom_widget),
+ custom_widget_accumulator, NULL,
+ _gtk_marshal_OBJECT__VOID,
+ G_TYPE_OBJECT, 0);
+
+ /**
+ * GtkPrintOperation::custom-widget-apply:
+ * @operation: the #GtkPrintOperation on which the signal was emitted
+ * @widget: the custom widget added in create-custom-widget
+ *
+ * Emitted right before #GtkPrintOperation::begin-print if you added
+ * a custom widget in the #GtkPrintOperation:;create-custom-widget handler.
+ * When you get this signal you should read the information from the
+ * custom widgets, as the widgets are not guaraneed to be around at a
+ * later time.
+ *
+ * Since: 2.10
+ */
+ signals[CUSTOM_WIDGET_APPLY] =
+ g_signal_new (I_("custom-widget-apply"),
+ G_TYPE_FROM_CLASS (class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkPrintOperationClass, custom_widget_apply),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
+
+ /**
+ * GtkPrintOperation::preview:
+ * @operation: the #GtkPrintOperation on which the signal was emitted
+ * @preview: the #GtkPrintPreviewOperation for the current operation
+ * @context: the #GtkPrintContext that will be used
+ * @parent: the #GtkWindow to use as window parent, or %NULL
+ *
+ * Gets emitted when a preview is requested from the native dialog.
+ *
+ * The default handler for this signal uses an external viewer
+ * application to preview.
+ *
+ * To implement a custom print preview, an application must return
+ * %TRUE from its handler for this signal. In order to use the
+ * provided @context for the preview implementation, it must be
+ * given a suitable cairo context with gtk_print_context_set_cairo_context().
+ *
+ * The custom preview implementation can use
+ * gtk_print_operation_preview_is_selected() and
+ * gtk_print_operation_preview_render_page() to find pages which
+ * are selected for print and render them. The preview must be
+ * finished by calling gtk_print_operation_preview_end_preview()
+ * (typically in response to the user clicking a close button).
+ *
+ * Returns: %TRUE if the listener wants to take over control of the preview
+ *
+ * Since: 2.10
+ */
+ signals[PREVIEW] =
+ g_signal_new (I_("preview"),
+ G_TYPE_FROM_CLASS (gobject_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GtkPrintOperationClass, preview),
+ _gtk_boolean_handled_accumulator, NULL,
+ _gtk_marshal_BOOLEAN__OBJECT_OBJECT_OBJECT,
+ G_TYPE_BOOLEAN, 3,
+ GTK_TYPE_PRINT_OPERATION_PREVIEW,
+ GTK_TYPE_PRINT_CONTEXT,
+ GTK_TYPE_WINDOW);
+
/**
* GtkPrintOperation:default-page-setup:
*
*
* This page setup will be used by gtk_print_operation_run(),
* but it can be overridden on a per-page basis by connecting
- * to the ::request-page-setup signal.
+ * to the #GtkPrintOperation::request-page-setup signal.
*
* Since: 2.10
*/
*
* The #GtkPrintSettings used for initializing the dialog.
*
- * Setting this property is typically used to re-establish print
- * settings from a previous print operation, see gtk_print_operation_run().
+ * Setting this property is typically used to re-establish
+ * print settings from a previous print operation, see
+ * gtk_print_operation_run().
*
* Since: 2.10
*/
/**
* GtkPrintOperation:job-name:
*
- * A string used to identify the job (e.g. in monitoring applications like eggcups).
+ * A string used to identify the job (e.g. in monitoring
+ * applications like eggcups).
*
- * If you don't set a job name, GTK+ picks a default one by numbering successive
- * print jobs.
+ * If you don't set a job name, GTK+ picks a default one
+ * by numbering successive print jobs.
*
* Since: 2.10
*/
* The number of pages in the document.
*
* This <emphasis>must</emphasis> be set to a positive number
- * before the rendering starts. It may be set in a ::begin-print signal hander.
+ * before the rendering starts. It may be set in a
+ * #GtkPrintOperation::begin-print signal hander.
*
- * Note that the page numbers passed to the ::request-page-setup and ::draw-page
- * signals are 0-based, i.e. if the user chooses to print all pages, the last
- * ::draw-page signal will be for page @n_pages - 1.
+ * Note that the page numbers passed to the
+ * #GtkPrintOperation::request-page-setup and
+ * #GtkPrintOperation::draw-page signals are 0-based, i.e. if
+ * the user chooses to print all pages, the last ::draw-page signal
+ * will be for page @n_pages - 1.
*
* Since: 2.10
*/
PROP_CURRENT_PAGE,
g_param_spec_int ("current-page",
P_("Current Page"),
- P_("The current page in the document."),
+ P_("The current page in the document"),
-1,
G_MAXINT,
-1,
/**
* GtkPrintOperation:use-full-page:
*
- * If %TRUE, the transformation for the cairo context obtained from
- * #GtkPrintContext puts the origin at the top left corner of the page
- * (which may not be the top left corner of the sheet, depending on page
- * orientation and the number of pages per sheet). Otherwise, the origin
- * is at the top left corner of the imageable area (i.e. inside the margins).
+ * If %TRUE, the transformation for the cairo context obtained
+ * from #GtkPrintContext puts the origin at the top left corner
+ * of the page (which may not be the top left corner of the sheet,
+ * depending on page orientation and the number of pages per sheet).
+ * Otherwise, the origin is at the top left corner of the imageable
+ * area (i.e. inside the margins).
*
* Since: 2.10
*/
PROP_USE_FULL_PAGE,
g_param_spec_boolean ("use-full-page",
P_("Use full page"),
- P_("%TRUE if the the origin of the context should be at the corner of the page and not the corner of the imageable area"),
+ P_("TRUE if the origin of the context should be at the corner of the page and not the corner of the imageable area"),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
+
+ /**
+ * GtkPrintOperation:track-print-status:
+ *
+ * If %TRUE, the print operation will try to continue report on
+ * the status of the print job in the printer queues and printer.
+ * This can allow your application to show things like "out of paper"
+ * issues, and when the print job actually reaches the printer.
+ * However, this is often implemented using polling, and should
+ * not be enabled unless needed.
+ *
+ * Since: 2.10
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_TRACK_PRINT_STATUS,
+ g_param_spec_boolean ("track-print-status",
+ P_("Track Print Status"),
+ P_("TRUE if the print operation will continue to report on the print job status after the print data has been sent to the printer or print server."),
FALSE,
GTK_PARAM_READWRITE));
* GtkPrintOperation:unit:
*
* The transformation for the cairo context obtained from
- * #GtkPrintContext is set up in such a way that distances are measured
- * in units of @unit.
+ * #GtkPrintContext is set up in such a way that distances
+ * are measured in units of @unit.
*
* Since: 2.10
*/
GTK_UNIT_PIXEL,
GTK_PARAM_READWRITE));
-
+
/**
- * GtkPrintOperation:show-dialog:
+ * GtkPrintOperation:show-progress:
*
- * Determines whether calling gtk_print_operation_run() will present
- * a print dialog to the user, or just print to the default printer.
+ * Determines whether to show a progress dialog during the
+ * print operation.
*
* Since: 2.10
*/
g_object_class_install_property (gobject_class,
- PROP_SHOW_DIALOG,
- g_param_spec_boolean ("show-dialog",
+ PROP_SHOW_PROGRESS,
+ g_param_spec_boolean ("show-progress",
P_("Show Dialog"),
- P_("%TRUE if gtk_print_operation_run() should show the print dialog."),
- TRUE,
+ P_("TRUE if a progress dialog is shown while printing."),
+ FALSE,
+ GTK_PARAM_READWRITE));
+
+ /**
+ * GtkPrintOperation:allow-async:
+ *
+ * Determines whether the print operation may run asynchronously or not.
+ *
+ * Some systems don't support asynchronous printing, but those that do
+ * will return %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS as the status, and
+ * emit the #GtkPrintOperation::done signal when the operation is actually
+ * done.
+ *
+ * The Windows port does not support asynchronous operation at all (this
+ * is unlikely to change). On other platforms, all actions except for
+ * %GTK_PRINT_OPERATION_ACTION_EXPORT support asynchronous operation.
+ *
+ * Since: 2.10
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_ALLOW_ASYNC,
+ g_param_spec_boolean ("allow-async",
+ P_("Allow Async"),
+ P_("TRUE if print process may run asynchronous."),
+ FALSE,
GTK_PARAM_READWRITE));
/**
- * GtkPrintOperation:pdf-target:
+ * GtkPrintOperation:export-filename:
*
- * The name of a PDF file to generate instead of showing the print dialog.
+ * The name of a file to generate instead of showing the print dialog.
+ * Currently, PDF is the only supported format.
*
- * The indended use of this property is for implementing "Export to PDF"
- * actions.
+ * The intended use of this property is for implementing
+ * "Export to PDF" actions.
*
* "Print to PDF" support is independent of this and is done
- * by letting the user pick the "Print to PDF" item from the list
- * of printers in the print dialog.
+ * by letting the user pick the "Print to PDF" item from the
+ * list of printers in the print dialog.
*
* Since: 2.10
*/
g_object_class_install_property (gobject_class,
- PROP_JOB_NAME,
- g_param_spec_string ("pdf-target",
- P_("PDF target filename"),
- P_(""),
+ PROP_EXPORT_FILENAME,
+ g_param_spec_string ("export-filename",
+ P_("Export filename"),
+ P_("Export filename"),
NULL,
GTK_PARAM_READWRITE));
* The string is translated and suitable for displaying the print
* status e.g. in a #GtkStatusbar.
*
- * See the ::status property for a status value that is suitable
- * for programmatic use.
+ * See the #GtkPrintOperation:status property for a status value that
+ * is suitable for programmatic use.
*
* Since: 2.10
*/
GTK_PARAM_READABLE));
+ /**
+ * GtkPrintOperation:custom-tab-label:
+ *
+ * Used as the label of the tab containing custom widgets.
+ * Note that this property may be ignored on some platforms.
+ *
+ * If this is %NULL, GTK+ uses a default label.
+ *
+ * Since: 2.10
+ */
+ g_object_class_install_property (gobject_class,
+ PROP_CUSTOM_TAB_LABEL,
+ g_param_spec_string ("custom-tab-label",
+ P_("Custom tab label"),
+ P_("Label for the tab containing custom widgets."),
+ NULL,
+ GTK_PARAM_READWRITE));
+
}
/**
*
* This page setup will be used by gtk_print_operation_run(),
* but it can be overridden on a per-page basis by connecting
- * to the ::request-page-setup signal.
+ * to the #GtkPrintOperation::request-page-setup signal.
*
* Since: 2.10
**/
GtkPrintOperationPrivate *priv;
g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
- g_return_if_fail (g_utf8_validate (job_name, -1, NULL));
+ g_return_if_fail (job_name != NULL);
priv = op->priv;
* Sets the number of pages in the document.
*
* This <emphasis>must</emphasis> be set to a positive number
- * before the rendering starts. It may be set in a ::begin-print
- * signal hander.
+ * before the rendering starts. It may be set in a
+ * #GtkPrintOperation::begin-print signal hander.
*
- * Note that the page numbers passed to the ::request-page-setup
- * and ::draw-page signals are 0-based, i.e. if the user chooses
- * to print all pages, the last ::draw-page signal will be
- * for page @n_pages - 1.
+ * Note that the page numbers passed to the
+ * #GtkPrintOperation::request-page-setup
+ * and #GtkPrintOperation::draw-page signals are 0-based, i.e. if
+ * the user chooses to print all pages, the last ::draw-page signal
+ * will be for page @n_pages - 1.
*
* Since: 2.10
**/
{
priv->nr_of_pages = n_pages;
- g_object_notify (G_OBJECT (op), "number-of-pages");
+ g_object_notify (G_OBJECT (op), "n-pages");
}
}
}
}
+/**
+ * gtk_print_operation_set_track_print_status:
+ * @op: a #GtkPrintOperation
+ * @track_status: %TRUE to track status after printing
+ *
+ * If track_status is %TRUE, the print operation will try to continue report
+ * on the status of the print job in the printer queues and printer. This
+ * can allow your application to show things like "out of paper" issues,
+ * and when the print job actually reaches the printer.
+ *
+ * This function is often implemented using some form of polling, so it should
+ * not be enabled unless needed.
+ *
+ * Since: 2.10
+ */
+void
+gtk_print_operation_set_track_print_status (GtkPrintOperation *op,
+ gboolean track_status)
+{
+ GtkPrintOperationPrivate *priv;
+
+ g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
+
+ priv = op->priv;
+
+ if (priv->track_print_status != track_status)
+ {
+ priv->track_print_status = track_status;
+
+ g_object_notify (G_OBJECT (op), "track-print-status");
+ }
+}
+
void
_gtk_print_operation_set_status (GtkPrintOperation *op,
GtkPrintStatus status,
{
GtkPrintOperationPrivate *priv = op->priv;
static const gchar *status_strs[] = {
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Initial state"),
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Preparing to print"),
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Generating data"),
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Sending data"),
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Waiting"),
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Blocking on issue"),
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Printing"),
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Finished"),
- /* translators, strip the prefix up to and including the first | */
- N_("print operation status|Finished with error")
+ NC_("print operation status", "Initial state"),
+ NC_("print operation status", "Preparing to print"),
+ NC_("print operation status", "Generating data"),
+ NC_("print operation status", "Sending data"),
+ NC_("print operation status", "Waiting"),
+ NC_("print operation status", "Blocking on issue"),
+ NC_("print operation status", "Printing"),
+ NC_("print operation status", "Finished"),
+ NC_("print operation status", "Finished with error")
};
if (status < 0 || status > GTK_PRINT_STATUS_FINISHED_ABORTED)
status = GTK_PRINT_STATUS_FINISHED_ABORTED;
if (string == NULL)
- string = g_strip_context (status_strs[status],
- gettext (status_strs[status]));
+ string = g_dpgettext2 (GETTEXT_PACKAGE, "print operation status", status_strs[status]);
if (priv->status == status &&
strcmp (string, priv->status_string) == 0)
* is finished, either successfully (%GTK_PRINT_STATUS_FINISHED)
* or unsuccessfully (%GTK_PRINT_STATUS_FINISHED_ABORTED).
*
+ * Note: when you enable print status tracking the print operation
+ * can be in a non-finished state even after done has been called, as
+ * the operation status then tracks the print job status on the printer.
+ *
* Return value: %TRUE, if the print operation is finished.
*
* Since: 2.10
priv->status == GTK_PRINT_STATUS_FINISHED;
}
-
/**
- * gtk_print_operation_set_show_dialog:
+ * gtk_print_operation_set_show_progress:
* @op: a #GtkPrintOperation
- * @show_dialog: %TRUE to show the print dialog
+ * @show_progress: %TRUE to show a progress dialog
*
- * Sets whether calling gtk_print_operation_run() will present
- * a print dialog to the user, or just print to the default printer.
+ * If @show_progress is %TRUE, the print operation will show a
+ * progress dialog during the print operation.
+ *
+ * Since: 2.10
+ */
+void
+gtk_print_operation_set_show_progress (GtkPrintOperation *op,
+ gboolean show_progress)
+{
+ GtkPrintOperationPrivate *priv;
+
+ g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
+
+ priv = op->priv;
+
+ show_progress = show_progress != FALSE;
+
+ if (priv->show_progress != show_progress)
+ {
+ priv->show_progress = show_progress;
+
+ g_object_notify (G_OBJECT (op), "show-progress");
+ }
+}
+
+/**
+ * gtk_print_operation_set_allow_async:
+ * @op: a #GtkPrintOperation
+ * @allow_async: %TRUE to allow asynchronous operation
+ *
+ * Sets whether the gtk_print_operation_run() may return
+ * before the print operation is completed. Note that
+ * some platforms may not allow asynchronous operation.
*
* Since: 2.10
*/
void
-gtk_print_operation_set_show_dialog (GtkPrintOperation *op,
- gboolean show_dialog)
+gtk_print_operation_set_allow_async (GtkPrintOperation *op,
+ gboolean allow_async)
{
GtkPrintOperationPrivate *priv;
priv = op->priv;
- show_dialog = show_dialog != FALSE;
+ allow_async = allow_async != FALSE;
- if (priv->show_dialog != show_dialog)
+ if (priv->allow_async != allow_async)
{
- priv->show_dialog = show_dialog;
+ priv->allow_async = allow_async;
- g_object_notify (G_OBJECT (op), "show-dialog");
+ g_object_notify (G_OBJECT (op), "allow-async");
}
}
+
+/**
+ * gtk_print_operation_set_custom_tab_label:
+ * @op: a #GtkPrintOperation
+ * @label: the label to use, or %NULL to use the default label
+ *
+ * Sets the label for the tab holding custom widgets.
+ *
+ * Since: 2.10
+ */
+void
+gtk_print_operation_set_custom_tab_label (GtkPrintOperation *op,
+ const gchar *label)
+{
+ GtkPrintOperationPrivate *priv;
+
+ g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
+
+ priv = op->priv;
+
+ g_free (priv->custom_tab_label);
+ priv->custom_tab_label = g_strdup (label);
+
+ g_object_notify (G_OBJECT (op), "custom-tab-label");
+}
+
+
/**
- * gtk_print_operation_set_pdf_target:
+ * gtk_print_operation_set_export_filename:
* @op: a #GtkPrintOperation
- * @filename: the filename for the PDF file
+ * @filename: the filename for the exported file
*
- * Sets up the #GtkPrintOperation to generate a PDF file instead
+ * Sets up the #GtkPrintOperation to generate a file instead
* of showing the print dialog. The indended use of this function
- * is for implementing "Export to PDF" actions.
+ * is for implementing "Export to PDF" actions. Currently, PDF
+ * is the only supported format.
*
* "Print to PDF" support is independent of this and is done
* by letting the user pick the "Print to PDF" item from the list
* Since: 2.10
*/
void
-gtk_print_operation_set_pdf_target (GtkPrintOperation *op,
- const gchar *filename)
+gtk_print_operation_set_export_filename (GtkPrintOperation *op,
+ const gchar *filename)
{
GtkPrintOperationPrivate *priv;
priv = op->priv;
- g_free (priv->pdf_target);
- priv->pdf_target = g_strdup (filename);
+ g_free (priv->export_filename);
+ priv->export_filename = g_strdup (filename);
- g_object_notify (G_OBJECT (op), "pdf-target");
+ g_object_notify (G_OBJECT (op), "export-filename");
}
/* Creates the initial page setup used for printing unless the
GtkPageSetup *page_setup)
{
GtkPaperSize *paper_size;
- double w, h;
+ cairo_surface_t *surface = op->priv->platform_data;
+ gdouble w, h;
paper_size = gtk_page_setup_get_paper_size (page_setup);
w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
- cairo_pdf_surface_set_size (op->priv->surface, w, h);
+ cairo_pdf_surface_set_size (surface, w, h);
}
static void
{
cairo_t *cr;
- cr = gtk_print_context_get_cairo (print_context);
+ cr = gtk_print_context_get_cairo_context (print_context);
cairo_show_page (cr);
}
static void
pdf_end_run (GtkPrintOperation *op,
- gboolean wait)
+ gboolean wait,
+ gboolean cancelled)
{
GtkPrintOperationPrivate *priv = op->priv;
+ cairo_surface_t *surface = priv->platform_data;
+
+ cairo_surface_finish (surface);
+ cairo_surface_destroy (surface);
- cairo_surface_destroy (priv->surface);
- priv->surface = NULL;
+ priv->platform_data = NULL;
+ priv->free_platform_data = NULL;
}
static GtkPrintOperationResult
run_pdf (GtkPrintOperation *op,
GtkWindow *parent,
- gboolean *do_print,
- GError **error)
+ gboolean *do_print)
{
GtkPrintOperationPrivate *priv = op->priv;
GtkPageSetup *page_setup;
- double width, height;
- /* This will be overwritten later by the non-default size, but
- we need to pass some size: */
+ cairo_surface_t *surface;
+ cairo_t *cr;
+ gdouble width, height;
+
+ priv->print_context = _gtk_print_context_new (op);
page_setup = create_page_setup (op);
+ _gtk_print_context_set_page_setup (priv->print_context, page_setup);
+
+ /* This will be overwritten later by the non-default size, but
+ we need to pass some size: */
width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
g_object_unref (page_setup);
- priv->surface = cairo_pdf_surface_create (priv->pdf_target,
- width, height);
- cairo_pdf_surface_set_dpi (priv->surface, 300, 300);
-
- priv->dpi_x = 72;
- priv->dpi_y = 72;
+ surface = cairo_pdf_surface_create (priv->export_filename,
+ width, height);
+ if (cairo_surface_status (surface) != CAIRO_STATUS_SUCCESS)
+ {
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_GENERAL,
+ cairo_status_to_string (cairo_surface_status (surface)));
+ *do_print = FALSE;
+ return GTK_PRINT_OPERATION_RESULT_ERROR;
+ }
+
+ /* this would crash on a nil surface */
+ cairo_surface_set_fallback_resolution (surface, 300, 300);
+
+ priv->platform_data = surface;
+ priv->free_platform_data = (GDestroyNotify) cairo_surface_destroy;
+ cr = cairo_create (surface);
+ gtk_print_context_set_cairo_context (op->priv->print_context,
+ cr, 72, 72);
+ cairo_destroy (cr);
+
+
priv->print_pages = GTK_PRINT_PAGES_ALL;
priv->page_ranges = NULL;
priv->num_page_ranges = 0;
return GTK_PRINT_OPERATION_RESULT_APPLY;
}
-static void
-print_pages (GtkPrintOperation *op,
- gboolean wait)
+typedef struct
{
- GtkPrintOperationPrivate *priv = op->priv;
- int page, range;
- GtkPageSetup *initial_page_setup, *page_setup;
- GtkPrintContext *print_context;
- cairo_t *cr;
- int uncollated_copies, collated_copies;
- int i, j;
+ GtkPrintOperation *op;
+ gint uncollated_copies;
+ gint collated_copies;
+ gint uncollated, collated, total;
+
+ gint range, num_ranges;
GtkPageRange *ranges;
GtkPageRange one_range;
- int num_ranges;
- if (priv->manual_collation)
+ gint page, start, end, inc;
+
+ GtkWidget *progress;
+
+ gboolean initialized;
+ gboolean is_preview;
+} PrintPagesData;
+
+static void
+find_range (PrintPagesData *data)
+{
+ GtkPageRange *range;
+
+ range = &data->ranges[data->range];
+
+ if (data->inc < 0)
{
- uncollated_copies = priv->manual_num_copies;
- collated_copies = 1;
+ data->start = range->end;
+ data->end = range->start - 1;
}
else
{
- uncollated_copies = 1;
- collated_copies = priv->manual_num_copies;
+ data->start = range->start;
+ data->end = range->end + 1;
}
+}
+
+static void
+clamp_page_ranges (PrintPagesData *data)
+{
+ GtkPrintOperationPrivate *priv;
+ gint num_of_correct_ranges;
+ gint i;
+
+ priv = data->op->priv;
+
+ num_of_correct_ranges = 0;
+
+ for (i = 0; i < data->num_ranges; i++)
+ if ((data->ranges[i].start >= 0) &&
+ (data->ranges[i].start < priv->nr_of_pages) &&
+ (data->ranges[i].end >= 0) &&
+ (data->ranges[i].end < priv->nr_of_pages))
+ {
+ data->ranges[num_of_correct_ranges] = data->ranges[i];
+ num_of_correct_ranges++;
+ }
+ else if ((data->ranges[i].start >= 0) &&
+ (data->ranges[i].start < priv->nr_of_pages) &&
+ (data->ranges[i].end >= priv->nr_of_pages))
+ {
+ data->ranges[i].end = priv->nr_of_pages - 1;
+ data->ranges[num_of_correct_ranges] = data->ranges[i];
+ num_of_correct_ranges++;
+ }
+ else if ((data->ranges[i].end >= 0) &&
+ (data->ranges[i].end < priv->nr_of_pages) &&
+ (data->ranges[i].start < 0))
+ {
+ data->ranges[i].start = 0;
+ data->ranges[num_of_correct_ranges] = data->ranges[i];
+ num_of_correct_ranges++;
+ }
+
+ data->num_ranges = num_of_correct_ranges;
+}
+
+static gboolean
+increment_page_sequence (PrintPagesData *data)
+{
+ GtkPrintOperationPrivate *priv = data->op->priv;
+
+ do {
+ data->page += data->inc;
+ if (data->page == data->end)
+ {
+ data->range += data->inc;
+ if (data->range == -1 || data->range == data->num_ranges)
+ {
+ data->uncollated++;
+ if (data->uncollated == data->uncollated_copies)
+ return FALSE;
+
+ data->range = data->inc < 0 ? data->num_ranges - 1 : 0;
+ }
+ find_range (data);
+ data->page = data->start;
+ }
+ }
+ while ((priv->manual_page_set == GTK_PAGE_SET_EVEN && data->page % 2 == 0) ||
+ (priv->manual_page_set == GTK_PAGE_SET_ODD && data->page % 2 == 1));
+
+ return TRUE;
+}
- print_context = _gtk_print_context_new (op);
+static void
+print_pages_idle_done (gpointer user_data)
+{
+ PrintPagesData *data;
+ GtkPrintOperationPrivate *priv;
- initial_page_setup = create_page_setup (op);
- _gtk_print_context_set_page_setup (print_context, initial_page_setup);
+ data = (PrintPagesData*)user_data;
+ priv = data->op->priv;
- _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);
+ priv->print_pages_idle_id = 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->show_progress_timeout_id > 0)
{
- ranges = &one_range;
- num_ranges = 1;
- ranges[0].start = priv->current_page;
- ranges[0].end = priv->current_page;
+ g_source_remove (priv->show_progress_timeout_id);
+ priv->show_progress_timeout_id = 0;
}
- else
+
+ if (data->progress)
+ gtk_widget_destroy (data->progress);
+
+ if (priv->rloop && !data->is_preview)
+ g_main_loop_quit (priv->rloop);
+
+ if (!data->is_preview)
+ g_signal_emit (data->op, signals[DONE], 0,
+ priv->cancelled ?
+ GTK_PRINT_OPERATION_RESULT_CANCEL :
+ GTK_PRINT_OPERATION_RESULT_APPLY);
+
+ g_object_unref (data->op);
+ g_free (data);
+}
+
+static void
+update_progress (PrintPagesData *data)
+{
+ GtkPrintOperationPrivate *priv;
+ gchar *text = NULL;
+
+ priv = data->op->priv;
+
+ if (data->progress)
{
- ranges = &one_range;
- num_ranges = 1;
- ranges[0].start = 0;
- ranges[0].end = priv->nr_of_pages - 1;
+ if (priv->status == GTK_PRINT_STATUS_PREPARING)
+ {
+ if (priv->nr_of_pages > 0)
+ text = g_strdup_printf (_("Preparing %d"), priv->nr_of_pages);
+ else
+ text = g_strdup (_("Preparing"));
+ }
+ else if (priv->status == GTK_PRINT_STATUS_GENERATING_DATA)
+ text = g_strdup_printf (_("Printing %d"), data->total);
+
+ if (text)
+ {
+ g_object_set (data->progress, "text", text, NULL);
+ g_free (text);
+ }
}
+ }
+
+static void
+common_render_page (GtkPrintOperation *op,
+ gint page_nr)
+{
+ GtkPrintOperationPrivate *priv = op->priv;
+ GtkPageSetup *page_setup;
+ GtkPrintContext *print_context;
+ cairo_t *cr;
+
+ print_context = priv->print_context;
+
+ page_setup = create_page_setup (op);
+
+ g_signal_emit (op, signals[REQUEST_PAGE_SETUP], 0,
+ print_context, page_nr, page_setup);
+
+ _gtk_print_context_set_page_setup (print_context, page_setup);
+
+ priv->start_page (op, print_context, page_setup);
+
+ cr = gtk_print_context_get_cairo_context (print_context);
+
+ cairo_save (cr);
+ if (priv->manual_scale != 1.0)
+ cairo_scale (cr,
+ priv->manual_scale,
+ priv->manual_scale);
- _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_GENERATING_DATA, NULL);
+ if (priv->manual_orientation)
+ _gtk_print_context_rotate_according_to_orientation (print_context);
+
+ if (!priv->use_full_page)
+ _gtk_print_context_translate_into_margin (print_context);
+
+ g_signal_emit (op, signals[DRAW_PAGE], 0,
+ print_context, page_nr);
+
+ priv->end_page (op, print_context);
+
+ cairo_restore (cr);
+
+ g_object_unref (page_setup);
+}
+
+static gboolean
+print_pages_idle (gpointer user_data)
+{
+ PrintPagesData *data;
+ GtkPrintOperationPrivate *priv;
+ GtkPageSetup *page_setup;
+ gboolean done = FALSE;
+ gint i;
- for (i = 0; i < uncollated_copies; i++)
+ data = (PrintPagesData*)user_data;
+ priv = data->op->priv;
+
+ if (priv->status == GTK_PRINT_STATUS_PREPARING)
{
- for (range = 0; range < num_ranges; range ++)
+ if (!data->initialized)
{
- int start, end, inc;
- int low = ranges[range].start;
- int high = ranges[range].end;
-
- if (priv->manual_reverse)
+ data->initialized = TRUE;
+ page_setup = create_page_setup (data->op);
+ _gtk_print_context_set_page_setup (priv->print_context,
+ page_setup);
+ g_object_unref (page_setup);
+
+ g_signal_emit (data->op, signals[BEGIN_PRINT], 0, priv->print_context);
+
+ if (priv->manual_collation)
{
- start = high;
- end = low - 1;
- inc = -1;
+ data->uncollated_copies = priv->manual_num_copies;
+ data->collated_copies = 1;
}
else
{
- start = low;
- end = high + 1;
- inc = 1;
- }
- for (page = start; page != end; page += inc)
- {
- if ((priv->manual_page_set == GTK_PAGE_SET_EVEN && page % 2 == 0) ||
- (priv->manual_page_set == GTK_PAGE_SET_ODD && page % 2 == 1))
- continue;
-
- for (j = 0; j < collated_copies; j++)
- {
- page_setup = gtk_page_setup_copy (initial_page_setup);
- g_signal_emit (op, signals[REQUEST_PAGE_SETUP], 0, print_context, page, page_setup);
-
- _gtk_print_context_set_page_setup (print_context, page_setup);
- priv->start_page (op, print_context, page_setup);
-
- cr = gtk_print_context_get_cairo (print_context);
-
- cairo_save (cr);
- if (priv->manual_scale != 100.0)
- cairo_scale (cr,
- priv->manual_scale,
- priv->manual_scale);
-
- if (priv->manual_orientation)
- _gtk_print_context_rotate_according_to_orientation (print_context);
-
- if (!priv->use_full_page)
- _gtk_print_context_translate_into_margin (print_context);
-
- g_signal_emit (op, signals[DRAW_PAGE], 0,
- print_context, page);
-
- priv->end_page (op, print_context);
-
- cairo_restore (cr);
-
- g_object_unref (page_setup);
-
- /* Iterate the mainloop so that we redraw windows */
- while (gtk_events_pending ())
- gtk_main_iteration ();
- }
+ data->uncollated_copies = 1;
+ data->collated_copies = priv->manual_num_copies;
}
+
+ goto out;
}
+
+ if (g_signal_has_handler_pending (data->op, signals[PAGINATE], 0, FALSE))
+ {
+ gboolean paginated = FALSE;
+
+ g_signal_emit (data->op, signals[PAGINATE], 0, priv->print_context, &paginated);
+ if (!paginated)
+ goto out;
+ }
+
+ /* Initialize parts of PrintPagesData that depend on nr_of_pages
+ */
+ if (priv->print_pages == GTK_PRINT_PAGES_RANGES)
+ {
+ if (priv->page_ranges == NULL)
+ {
+ g_warning ("no pages to print");
+ priv->cancelled = TRUE;
+ goto out;
+ }
+ data->ranges = priv->page_ranges;
+ data->num_ranges = priv->num_page_ranges;
+ for (i = 0; i < data->num_ranges; i++)
+ if (data->ranges[i].end == -1 ||
+ data->ranges[i].end >= priv->nr_of_pages)
+ data->ranges[i].end = priv->nr_of_pages - 1;
+ }
+ 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;
+ }
+
+ clamp_page_ranges (data);
+
+ if (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->total++;
+ data->collated++;
+ if (data->collated == data->collated_copies)
+ {
+ data->collated = 0;
+ if (!increment_page_sequence (data))
+ {
+ done = TRUE;
+
+ goto out;
+ }
+ }
+
+ if (data->is_preview && !priv->cancelled)
+ {
+ done = TRUE;
+
+ g_signal_emit_by_name (data->op, "ready", priv->print_context);
+ goto out;
+ }
+
+ common_render_page (data->op, data->page);
+
+ out:
+
+ if (priv->cancelled)
+ {
+ _gtk_print_operation_set_status (data->op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
+
+ data->is_preview = FALSE;
+ done = TRUE;
}
+
+ if (done && !data->is_preview)
+ {
+ g_signal_emit (data->op, signals[END_PRINT], 0, priv->print_context);
+ priv->end_run (data->op, priv->is_sync, priv->cancelled);
+ }
+
+ update_progress (data);
+
+ return !done;
+}
- g_signal_emit (op, signals[END_PRINT], 0, print_context);
+static void
+handle_progress_response (GtkWidget *dialog,
+ gint response,
+ gpointer data)
+{
+ GtkPrintOperation *op = (GtkPrintOperation *)data;
+
+ gtk_widget_hide (dialog);
+ gtk_print_operation_cancel (op);
+}
+
+static gboolean
+show_progress_timeout (PrintPagesData *data)
+{
+ gtk_window_present (GTK_WINDOW (data->progress));
- g_object_unref (print_context);
- g_object_unref (initial_page_setup);
+ data->op->priv->show_progress_timeout_id = 0;
- cairo_surface_finish (priv->surface);
- priv->end_run (op, wait);
+ return FALSE;
}
+static void
+print_pages (GtkPrintOperation *op,
+ GtkWindow *parent,
+ gboolean do_print,
+ GtkPrintOperationResult result)
+{
+ GtkPrintOperationPrivate *priv = op->priv;
+ PrintPagesData *data;
+
+ if (!do_print)
+ {
+ _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
+ g_signal_emit (op, signals[DONE], 0, result);
+ return;
+ }
+
+ _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_PREPARING, NULL);
+
+ data = g_new0 (PrintPagesData, 1);
+ data->op = g_object_ref (op);
+ data->is_preview = (priv->action == GTK_PRINT_OPERATION_ACTION_PREVIEW);
+
+ if (priv->show_progress)
+ {
+ GtkWidget *progress;
+
+ progress = gtk_message_dialog_new (parent, 0,
+ GTK_MESSAGE_OTHER,
+ GTK_BUTTONS_CANCEL,
+ _("Preparing"));
+ g_signal_connect (progress, "response",
+ G_CALLBACK (handle_progress_response), op);
+
+ priv->show_progress_timeout_id =
+ gdk_threads_add_timeout (SHOW_PROGRESS_TIME,
+ (GSourceFunc)show_progress_timeout,
+ data);
+
+ data->progress = progress;
+ }
+
+ if (data->is_preview)
+ {
+ gboolean handled;
+
+ g_signal_emit_by_name (op, "preview",
+ GTK_PRINT_OPERATION_PREVIEW (op),
+ priv->print_context,
+ parent,
+ &handled);
+
+ if (!handled)
+ {
+ GtkWidget *error_dialog;
+
+ error_dialog = gtk_message_dialog_new (parent,
+ GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_MESSAGE_ERROR,
+ GTK_BUTTONS_OK,
+ _("Error creating print preview"));
+
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (error_dialog),
+ _("The most probable reason is that a temporary file could not be created."));
+
+ if (parent && parent->group)
+ gtk_window_group_add_window (parent->group, GTK_WINDOW (error_dialog));
+
+ g_signal_connect (error_dialog, "response",
+ G_CALLBACK (gtk_widget_destroy), NULL);
+
+ gtk_widget_show (error_dialog);
+
+ print_pages_idle_done (data);
+
+ return;
+ }
+
+ if (gtk_print_context_get_cairo_context (priv->print_context) == NULL)
+ {
+ /* Programmer error */
+ g_error ("You must set a cairo context on the print context");
+ }
+
+ priv->start_page = preview_start_page;
+ priv->end_page = preview_end_page;
+ priv->end_run = preview_end_run;
+
+ priv->print_pages = gtk_print_settings_get_print_pages (priv->print_settings);
+ priv->page_ranges = gtk_print_settings_get_page_ranges (priv->print_settings,
+ &priv->num_page_ranges);
+ priv->manual_num_copies = 1;
+ priv->manual_collation = FALSE;
+ priv->manual_reverse = FALSE;
+ priv->manual_page_set = GTK_PAGE_SET_ALL;
+ priv->manual_scale = 1.0;
+ priv->manual_orientation = TRUE;
+ }
+
+ priv->print_pages_idle_id = gdk_threads_add_idle_full (G_PRIORITY_DEFAULT_IDLE + 10,
+ print_pages_idle,
+ data,
+ print_pages_idle_done);
+
+ /* Recursive main loop to make sure we don't exit on sync operations */
+ if (priv->is_sync)
+ {
+ priv->rloop = g_main_loop_new (NULL, FALSE);
+
+ g_object_ref (op);
+ GDK_THREADS_LEAVE ();
+ g_main_loop_run (priv->rloop);
+ GDK_THREADS_ENTER ();
+
+ g_main_loop_unref (priv->rloop);
+ priv->rloop = NULL;
+ g_object_unref (op);
+ }
+}
+
+/**
+ * gtk_print_operation_get_error:
+ * @op: a #GtkPrintOperation
+ * @error: return location for the error
+ *
+ * Call this when the result of a print operation is
+ * %GTK_PRINT_OPERATION_RESULT_ERROR, either as returned by
+ * gtk_print_operation_run(), or in the #GtkPrintOperation::done signal
+ * handler. The returned #GError will contain more details on what went wrong.
+ *
+ * Since: 2.10
+ **/
+void
+gtk_print_operation_get_error (GtkPrintOperation *op,
+ GError **error)
+{
+ g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
+
+ g_propagate_error (error, op->priv->error);
+
+ op->priv->error = NULL;
+}
+
+
/**
* gtk_print_operation_run:
* @op: a #GtkPrintOperation
+ * @action: the action to start
* @parent: Transient parent of the dialog, or %NULL
* @error: Return location for errors, or %NULL
*
* Runs the print operation, by first letting the user modify
- * print settings in the print dialog, and then print the
- * document.
+ * print settings in the print dialog, and then print the document.
*
- * Note that this function does not return until the rendering of all
- * pages is complete. You can connect to the ::status-changed signal on
- * @op to obtain some information about the progress of the print operation.
+ * Normally that this function does not return until the rendering of all
+ * pages is complete. You can connect to the
+ * #GtkPrintOperation::status-changed signal on @op to obtain some
+ * information about the progress of the print operation.
* Furthermore, it may use a recursive mainloop to show the print dialog.
- * See gtk_print_operation_run_async() if this is a problem.
- *
- * <informalexample><programlisting>
- * FIXME: need an example here
- * </programlisting></informalexample>
+ *
+ * If you call gtk_print_operation_set_allow_async() or set the
+ * #GtkPrintOperation:allow-async property the operation will run
+ * asynchronously if this is supported on the platform. The
+ * #GtkPrintOperation::done signal will be emitted with the result of the
+ * operation when the it is done (i.e. when the dialog is canceled, or when
+ * the print succeeds or fails).
+ * |[
+ * if (settings != NULL)
+ * gtk_print_operation_set_print_settings (print, settings);
+ *
+ * if (page_setup != NULL)
+ * gtk_print_operation_set_default_page_setup (print, page_setup);
+ *
+ * g_signal_connect (print, "begin-print",
+ * G_CALLBACK (begin_print), &data);
+ * g_signal_connect (print, "draw-page",
+ * G_CALLBACK (draw_page), &data);
+ *
+ * res = gtk_print_operation_run (print,
+ * GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ * parent,
+ * &error);
+ *
+ * if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
+ * {
+ * error_dialog = gtk_message_dialog_new (GTK_WINDOW (parent),
+ * GTK_DIALOG_DESTROY_WITH_PARENT,
+ * GTK_MESSAGE_ERROR,
+ * GTK_BUTTONS_CLOSE,
+ * "Error printing file:\n%s",
+ * error->message);
+ * g_signal_connect (error_dialog, "response",
+ * G_CALLBACK (gtk_widget_destroy), NULL);
+ * gtk_widget_show (error_dialog);
+ * g_error_free (error);
+ * }
+ * else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
+ * {
+ * if (settings != NULL)
+ * g_object_unref (settings);
+ * settings = g_object_ref (gtk_print_operation_get_print_settings (print));
+ * }
+ * ]|
+ *
+ * Note that gtk_print_operation_run() can only be called once on a
+ * given #GtkPrintOperation.
*
* Return value: the result of the print operation. A return value of
- * %GTK_PRINT_OPERATION_RESULT_APPLY indicates that the printing was
+ * %GTK_PRINT_OPERATION_RESULT_APPLY indicates that the printing was
* completed successfully. In this case, it is a good idea to obtain
* the used print settings with gtk_print_operation_get_print_settings()
- * and store them for reuse with the next print operation.
+ * and store them for reuse with the next print operation. A value of
+ * %GTK_PRINT_OPERATION_RESULT_IN_PROGRESS means the operation is running
+ * asynchronously, and will emit the #GtkPrintOperation::done signal when
+ * done.
*
* Since: 2.10
**/
GtkPrintOperationResult
-gtk_print_operation_run (GtkPrintOperation *op,
- GtkWindow *parent,
- GError **error)
+gtk_print_operation_run (GtkPrintOperation *op,
+ GtkPrintOperationAction action,
+ GtkWindow *parent,
+ GError **error)
{
GtkPrintOperationPrivate *priv;
GtkPrintOperationResult result;
+ GtkPageSetup *page_setup;
gboolean do_print;
+ gboolean run_print_pages;
g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op),
GTK_PRINT_OPERATION_RESULT_ERROR);
-
+ g_return_val_if_fail (op->priv->status == GTK_PRINT_STATUS_INITIAL,
+ GTK_PRINT_OPERATION_RESULT_ERROR);
priv = op->priv;
+
+ run_print_pages = TRUE;
+ do_print = FALSE;
+ priv->error = NULL;
+ priv->action = action;
- if (priv->pdf_target != NULL)
- result = run_pdf (op, parent, &do_print, error);
+ if (priv->print_settings == NULL)
+ priv->print_settings = gtk_print_settings_new ();
+
+ if (action == GTK_PRINT_OPERATION_ACTION_EXPORT)
+ {
+ /* note: if you implement async EXPORT, update the docs
+ * docs for the allow-async property.
+ */
+ priv->is_sync = TRUE;
+ g_return_val_if_fail (priv->export_filename != NULL, GTK_PRINT_OPERATION_RESULT_ERROR);
+ result = run_pdf (op, parent, &do_print);
+ }
+ else if (action == GTK_PRINT_OPERATION_ACTION_PREVIEW)
+ {
+ priv->is_sync = !priv->allow_async;
+ priv->print_context = _gtk_print_context_new (op);
+ page_setup = create_page_setup (op);
+ _gtk_print_context_set_page_setup (priv->print_context, page_setup);
+ g_object_unref (page_setup);
+ do_print = TRUE;
+ result = priv->is_sync ? GTK_PRINT_OPERATION_RESULT_APPLY : GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
+ }
+#ifndef G_OS_WIN32
+ else if (priv->allow_async)
+ {
+ priv->is_sync = FALSE;
+ _gtk_print_operation_platform_backend_run_dialog_async (op,
+ action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ parent,
+ print_pages);
+ result = GTK_PRINT_OPERATION_RESULT_IN_PROGRESS;
+ run_print_pages = FALSE; /* print_pages is called asynchronously from dialog */
+ }
+#endif
else
- result = _gtk_print_operation_platform_backend_run_dialog (op,
- parent,
- &do_print,
- error);
- if (do_print)
- print_pages (op, TRUE);
- else
- _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
+ {
+ priv->is_sync = TRUE;
+ result = _gtk_print_operation_platform_backend_run_dialog (op,
+ action == GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+ parent,
+ &do_print);
+ }
+
+ if (run_print_pages)
+ print_pages (op, parent, do_print, result);
+ if (priv->error && error)
+ *error = g_error_copy (priv->error);
+
return result;
}
/**
- * gtk_print_operation_run_async:
+ * gtk_print_operation_cancel:
* @op: a #GtkPrintOperation
- * @parent: Transient parent of the dialog, or %NULL
- *
- * Runs the print operation, by first letting the user modify
- * print settings in the print dialog, and then print the
- * document.
*
- * In contrast to gtk_print_operation_run(), this function returns after
- * showing the print dialog on platforms that support this, and handles
- * the printing by connecting a signal handler to the ::response signal
- * of the dialog.
- *
- * If you use this function, it is recommended that you store the modified
- * #GtkPrintSettings in a ::begin-print or ::end-print signal handler.
- *
+ * Cancels a running print operation. This function may
+ * be called from a #GtkPrintOperation::begin-print,
+ * #GtkPrintOperation::paginate or #GtkPrintOperation::draw-page
+ * signal handler to stop the currently running print
+ * operation.
+ *
* Since: 2.10
- **/
+ */
void
-gtk_print_operation_run_async (GtkPrintOperation *op,
- GtkWindow *parent)
+gtk_print_operation_cancel (GtkPrintOperation *op)
{
- GtkPrintOperationPrivate *priv;
- gboolean do_print;
-
- g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
-
- priv = op->priv;
-
- if (priv->pdf_target != NULL)
- {
- run_pdf (op, parent, &do_print, NULL);
- if (do_print)
- print_pages (op, FALSE);
- else
- _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
- }
- else
- _gtk_print_operation_platform_backend_run_dialog_async (op,
- parent,
- print_pages);
+ g_return_if_fail (GTK_IS_PRINT_OPERATION (op));
+
+ op->priv->cancelled = TRUE;
}
+
#define __GTK_PRINT_OPERATION_C__
#include "gtkaliasdef.c"