forked from AuroraMiddleware/gtk
Add gtkprintoperationpreview.[ch] Set default preview command. Hardcoded
2006-06-02 Alexander Larsson <alexl@redhat.com> * gtk/Makefile.am: Add gtkprintoperationpreview.[ch] Set default preview command. Hardcoded for now. * gtk/gtkmarshalers.list: Add BOOLEAN:OBJECT,OBJECT,OBJECT * gtk/gtkprintbackend.c: Add preview command property. * gtk/gtkprintcontext.[ch]: Make less dependent on PrintOperation for output settings Externally set cairo_t and dpi. Resettable. Create fontmap without metrics hinting (so that print preview text layout doesn't depend on zoom level). * gtk/gtkprintoperation-private.h: * gtk/gtkprintoperation-unix.c: * gtk/gtkprintoperation.[ch]: Initial work on print preview API and default implementation using an external preview app. * gtk/gtkprintoperation-win32.c: Some needed updates. Not done, needs more work. * gtk/gtkprintoperationpreview.[ch]: New interface used in print preview api. * gtk/gtkprintunixdialog.c: Add print preview dialog. * tests/print-editor.c: Test using an custom print preview widget.
This commit is contained in:
parent
caf6c4196d
commit
fad69ba06c
36
ChangeLog
36
ChangeLog
@ -1,3 +1,39 @@
|
||||
2006-06-02 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gtk/Makefile.am:
|
||||
Add gtkprintoperationpreview.[ch]
|
||||
Set default preview command. Hardcoded for now.
|
||||
|
||||
* gtk/gtkmarshalers.list:
|
||||
Add BOOLEAN:OBJECT,OBJECT,OBJECT
|
||||
|
||||
* gtk/gtkprintbackend.c:
|
||||
Add preview command property.
|
||||
|
||||
* gtk/gtkprintcontext.[ch]:
|
||||
Make less dependent on PrintOperation for output settings
|
||||
Externally set cairo_t and dpi. Resettable.
|
||||
Create fontmap without metrics hinting (so that print preview
|
||||
text layout doesn't depend on zoom level).
|
||||
|
||||
* gtk/gtkprintoperation-private.h:
|
||||
* gtk/gtkprintoperation-unix.c:
|
||||
* gtk/gtkprintoperation.[ch]:
|
||||
Initial work on print preview API and default implementation
|
||||
using an external preview app.
|
||||
|
||||
* gtk/gtkprintoperation-win32.c:
|
||||
Some needed updates. Not done, needs more work.
|
||||
|
||||
* gtk/gtkprintoperationpreview.[ch]:
|
||||
New interface used in print preview api.
|
||||
|
||||
* gtk/gtkprintunixdialog.c:
|
||||
Add print preview dialog.
|
||||
|
||||
* tests/print-editor.c:
|
||||
Test using an custom print preview widget.
|
||||
|
||||
2006-06-02 Emmanuele Bassi <ebassi@gnome.org>
|
||||
|
||||
* gtk/gtkrecentmanager.c
|
||||
|
@ -1,3 +1,39 @@
|
||||
2006-06-02 Alexander Larsson <alexl@redhat.com>
|
||||
|
||||
* gtk/Makefile.am:
|
||||
Add gtkprintoperationpreview.[ch]
|
||||
Set default preview command. Hardcoded for now.
|
||||
|
||||
* gtk/gtkmarshalers.list:
|
||||
Add BOOLEAN:OBJECT,OBJECT,OBJECT
|
||||
|
||||
* gtk/gtkprintbackend.c:
|
||||
Add preview command property.
|
||||
|
||||
* gtk/gtkprintcontext.[ch]:
|
||||
Make less dependent on PrintOperation for output settings
|
||||
Externally set cairo_t and dpi. Resettable.
|
||||
Create fontmap without metrics hinting (so that print preview
|
||||
text layout doesn't depend on zoom level).
|
||||
|
||||
* gtk/gtkprintoperation-private.h:
|
||||
* gtk/gtkprintoperation-unix.c:
|
||||
* gtk/gtkprintoperation.[ch]:
|
||||
Initial work on print preview API and default implementation
|
||||
using an external preview app.
|
||||
|
||||
* gtk/gtkprintoperation-win32.c:
|
||||
Some needed updates. Not done, needs more work.
|
||||
|
||||
* gtk/gtkprintoperationpreview.[ch]:
|
||||
New interface used in print preview api.
|
||||
|
||||
* gtk/gtkprintunixdialog.c:
|
||||
Add print preview dialog.
|
||||
|
||||
* tests/print-editor.c:
|
||||
Test using an custom print preview widget.
|
||||
|
||||
2006-06-02 Emmanuele Bassi <ebassi@gnome.org>
|
||||
|
||||
* gtk/gtkrecentmanager.c
|
||||
|
@ -4,6 +4,7 @@ SUBDIRS=theme-bits
|
||||
|
||||
if OS_UNIX
|
||||
SUBDIRS += xdgmime
|
||||
GTK_PRINT_PREVIEW_COMMAND="evince %f"
|
||||
endif
|
||||
|
||||
DIST_SUBDIRS=theme-bits xdgmime
|
||||
@ -25,6 +26,7 @@ INCLUDES = \
|
||||
-DGTK_HOST=\"$(host)\" \
|
||||
-DGTK_COMPILATION \
|
||||
-DGTK_PRINT_BACKENDS=\"$(GTK_PRINT_BACKENDS)\" \
|
||||
-DGTK_PRINT_PREVIEW_COMMAND=\"$(GTK_PRINT_PREVIEW_COMMAND)\" \
|
||||
-I$(top_builddir)/gtk \
|
||||
-I$(top_srcdir) -I../gdk \
|
||||
-I$(top_srcdir)/gdk \
|
||||
@ -231,6 +233,7 @@ gtk_public_h_sources = \
|
||||
gtkpreview.h \
|
||||
gtkprintcontext.h \
|
||||
gtkprintoperation.h \
|
||||
gtkprintoperationpreview.h \
|
||||
gtkprintsettings.h \
|
||||
gtkprivate.h \
|
||||
gtkprogress.h \
|
||||
@ -487,6 +490,7 @@ gtk_c_sources = \
|
||||
gtkpreview.c \
|
||||
gtkprintcontext.c \
|
||||
gtkprintoperation.c \
|
||||
gtkprintoperationpreview.c \
|
||||
gtkprintsettings.c \
|
||||
gtkprintutils.c \
|
||||
gtkprogress.c \
|
||||
|
@ -32,6 +32,7 @@ BOOLEAN:OBJECT,INT,INT,UINT
|
||||
BOOLEAN:OBJECT,STRING,STRING,BOXED
|
||||
BOOLEAN:OBJECT,BOXED
|
||||
BOOLEAN:OBJECT,BOXED,BOXED
|
||||
BOOLEAN:OBJECT,OBJECT,OBJECT
|
||||
BOOLEAN:OBJECT,STRING,STRING
|
||||
BOOLEAN:INT
|
||||
BOOLEAN:INT,INT
|
||||
|
@ -191,7 +191,7 @@ _gtk_print_backend_module_create (GtkPrintBackendModule *pb_module)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
GtkPrintBackend *
|
||||
static GtkPrintBackend *
|
||||
_gtk_print_backend_create (const char *backend_name)
|
||||
{
|
||||
GSList *l;
|
||||
@ -200,7 +200,6 @@ _gtk_print_backend_create (const char *backend_name)
|
||||
GtkPrintBackendModule *pb_module;
|
||||
GtkPrintBackend *pb;
|
||||
|
||||
/* TODO: make module loading code work */
|
||||
for (l = loaded_backends; l != NULL; l = l->next)
|
||||
{
|
||||
pb_module = l->data;
|
||||
@ -255,6 +254,11 @@ gtk_print_backend_initialize (void)
|
||||
GTK_PRINT_BACKENDS,
|
||||
GTK_PARAM_READWRITE));
|
||||
|
||||
gtk_settings_install_property (g_param_spec_string ("gtk-print-preview-command",
|
||||
P_("Default command to run when displaying a print preview"),
|
||||
P_("Command to run when displaying a print preview"),
|
||||
GTK_PRINT_PREVIEW_COMMAND,
|
||||
GTK_PARAM_READWRITE));
|
||||
initialized = TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -40,6 +40,9 @@ struct _GtkPrintContext
|
||||
GtkPageSetup *page_setup;
|
||||
PangoFontMap *fontmap;
|
||||
|
||||
gdouble surface_dpi_x;
|
||||
gdouble surface_dpi_y;
|
||||
|
||||
gdouble pixels_per_unit_x;
|
||||
gdouble pixels_per_unit_y;
|
||||
};
|
||||
@ -60,8 +63,8 @@ gtk_print_context_finalize (GObject *object)
|
||||
if (context->page_setup)
|
||||
g_object_unref (context->page_setup);
|
||||
|
||||
cairo_destroy (context->cr);
|
||||
|
||||
if (context->cr)
|
||||
cairo_destroy (context->cr);
|
||||
|
||||
G_OBJECT_CLASS (gtk_print_context_parent_class)->finalize (object);
|
||||
}
|
||||
@ -83,15 +86,31 @@ gtk_print_context_class_init (GtkPrintContextClass *class)
|
||||
GtkPrintContext *
|
||||
_gtk_print_context_new (GtkPrintOperation *op)
|
||||
{
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
GtkPrintContext *context;
|
||||
|
||||
context = g_object_new (GTK_TYPE_PRINT_CONTEXT, NULL);
|
||||
|
||||
context->op = op;
|
||||
context->cr = cairo_create (priv->surface);
|
||||
context->cr = NULL;
|
||||
context->fontmap = pango_cairo_font_map_new ();
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
switch (priv->unit)
|
||||
void
|
||||
gtk_print_context_set_cairo_context (GtkPrintContext *context,
|
||||
cairo_t *cr,
|
||||
double dpi_x,
|
||||
double dpi_y)
|
||||
{
|
||||
if (context->cr)
|
||||
cairo_destroy (context->cr);
|
||||
|
||||
context->cr = cairo_reference (cr);
|
||||
context->surface_dpi_x = dpi_x;
|
||||
context->surface_dpi_y = dpi_y;
|
||||
|
||||
switch (context->op->priv->unit)
|
||||
{
|
||||
default:
|
||||
case GTK_UNIT_PIXEL:
|
||||
@ -100,34 +119,31 @@ _gtk_print_context_new (GtkPrintOperation *op)
|
||||
context->pixels_per_unit_y = 1.0;
|
||||
break;
|
||||
case GTK_UNIT_POINTS:
|
||||
context->pixels_per_unit_x = priv->dpi_x / POINTS_PER_INCH;
|
||||
context->pixels_per_unit_y = priv->dpi_y / POINTS_PER_INCH;
|
||||
context->pixels_per_unit_x = dpi_x / POINTS_PER_INCH;
|
||||
context->pixels_per_unit_y = dpi_y / POINTS_PER_INCH;
|
||||
break;
|
||||
case GTK_UNIT_INCH:
|
||||
context->pixels_per_unit_x = priv->dpi_x;
|
||||
context->pixels_per_unit_y = priv->dpi_y;
|
||||
context->pixels_per_unit_x = dpi_x;
|
||||
context->pixels_per_unit_y = dpi_y;
|
||||
break;
|
||||
case GTK_UNIT_MM:
|
||||
context->pixels_per_unit_x = priv->dpi_x / MM_PER_INCH;
|
||||
context->pixels_per_unit_y = priv->dpi_y / MM_PER_INCH;
|
||||
context->pixels_per_unit_x = dpi_x / MM_PER_INCH;
|
||||
context->pixels_per_unit_y = dpi_y / MM_PER_INCH;
|
||||
break;
|
||||
}
|
||||
cairo_scale (context->cr,
|
||||
context->pixels_per_unit_x,
|
||||
context->pixels_per_unit_y);
|
||||
|
||||
context->fontmap = pango_cairo_font_map_new ();
|
||||
/* We use the unit-scaled resolution, as we still want fonts given in points to work */
|
||||
pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (context->fontmap),
|
||||
priv->dpi_y / context->pixels_per_unit_y);
|
||||
|
||||
return context;
|
||||
dpi_y / context->pixels_per_unit_y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
_gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context)
|
||||
{
|
||||
GtkPrintOperationPrivate *priv = context->op->priv;
|
||||
cairo_t *cr = context->cr;
|
||||
cairo_matrix_t matrix;
|
||||
GtkPaperSize *paper_size;
|
||||
@ -136,9 +152,9 @@ _gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context)
|
||||
paper_size = gtk_page_setup_get_paper_size (context->page_setup);
|
||||
|
||||
width = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
|
||||
width = width * priv->dpi_x / context->pixels_per_unit_x;
|
||||
width = width * context->surface_dpi_x / context->pixels_per_unit_x;
|
||||
height = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH);
|
||||
height = height * priv->dpi_y / context->pixels_per_unit_y;
|
||||
height = height * context->surface_dpi_y / context->pixels_per_unit_y;
|
||||
|
||||
switch (gtk_page_setup_get_orientation (context->page_setup))
|
||||
{
|
||||
@ -188,8 +204,8 @@ _gtk_print_context_translate_into_margin (GtkPrintContext *context)
|
||||
top = gtk_page_setup_get_top_margin (context->page_setup, GTK_UNIT_INCH);
|
||||
|
||||
cairo_translate (context->cr,
|
||||
left * priv->dpi_x / context->pixels_per_unit_x,
|
||||
top * priv->dpi_y / context->pixels_per_unit_y);
|
||||
left * context->surface_dpi_x / context->pixels_per_unit_x,
|
||||
top * context->surface_dpi_y / context->pixels_per_unit_y);
|
||||
}
|
||||
|
||||
void
|
||||
@ -272,7 +288,7 @@ gtk_print_context_get_width (GtkPrintContext *context)
|
||||
width = gtk_page_setup_get_page_width (context->page_setup, GTK_UNIT_INCH);
|
||||
|
||||
/* Really dpi_x? What about landscape? what does dpi_x mean in that case? */
|
||||
return width * priv->dpi_x / context->pixels_per_unit_x;
|
||||
return width * context->surface_dpi_x / context->pixels_per_unit_x;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -300,8 +316,8 @@ gtk_print_context_get_height (GtkPrintContext *context)
|
||||
else
|
||||
height = gtk_page_setup_get_page_height (context->page_setup, GTK_UNIT_INCH);
|
||||
|
||||
/* Really dpi_x? What about landscape? what does dpi_x mean in that case? */
|
||||
return height * priv->dpi_y / context->pixels_per_unit_y;
|
||||
/* Really dpi_y? What about landscape? what does dpi_y mean in that case? */
|
||||
return height * context->surface_dpi_y / context->pixels_per_unit_y;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -320,7 +336,7 @@ gtk_print_context_get_dpi_x (GtkPrintContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
|
||||
|
||||
return context->op->priv->dpi_x;
|
||||
return context->surface_dpi_x;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -339,7 +355,7 @@ gtk_print_context_get_dpi_y (GtkPrintContext *context)
|
||||
{
|
||||
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), 0);
|
||||
|
||||
return context->op->priv->dpi_y;
|
||||
return context->surface_dpi_y;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -376,10 +392,16 @@ PangoContext *
|
||||
gtk_print_context_create_pango_context (GtkPrintContext *context)
|
||||
{
|
||||
PangoContext *pango_context;
|
||||
cairo_font_options_t *options;
|
||||
|
||||
g_return_val_if_fail (GTK_IS_PRINT_CONTEXT (context), NULL);
|
||||
|
||||
pango_context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (context->fontmap));
|
||||
|
||||
options = cairo_font_options_create ();
|
||||
cairo_font_options_set_hint_metrics (options, CAIRO_HINT_METRICS_OFF);
|
||||
pango_cairo_context_set_font_options (pango_context, options);
|
||||
cairo_font_options_destroy (options);
|
||||
|
||||
return pango_context;
|
||||
}
|
||||
|
@ -51,6 +51,11 @@ PangoFontMap *gtk_print_context_get_pango_fontmap (GtkPrintContext *context);
|
||||
PangoContext *gtk_print_context_create_pango_context (GtkPrintContext *context);
|
||||
PangoLayout *gtk_print_context_create_pango_layout (GtkPrintContext *context);
|
||||
|
||||
/* Needed for preview implementations */
|
||||
void gtk_print_context_set_cairo_context (GtkPrintContext *context,
|
||||
cairo_t *cr,
|
||||
double dpi_x,
|
||||
double dpi_y);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
@ -46,9 +46,11 @@ struct _GtkPrintOperationPrivate
|
||||
guint print_pages_idle_id;
|
||||
guint show_progress_timeout_id;
|
||||
|
||||
GtkPrintContext *print_context;
|
||||
|
||||
/* Data for the print job: */
|
||||
cairo_surface_t *surface;
|
||||
gdouble dpi_x, dpi_y;
|
||||
/* cairo_surface_t *surface; */
|
||||
/* gdouble dpi_x, dpi_y; */
|
||||
|
||||
GtkPrintPages print_pages;
|
||||
GtkPageRange *page_ranges;
|
||||
@ -78,17 +80,29 @@ struct _GtkPrintOperationPrivate
|
||||
gboolean cancelled);
|
||||
};
|
||||
|
||||
GtkPrintOperationResult _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *operation,
|
||||
GtkWindow *parent,
|
||||
gboolean *do_print,
|
||||
GError **error);
|
||||
|
||||
typedef void (* GtkPrintOperationPrintFunc) (GtkPrintOperation *op,
|
||||
GtkWindow *parent);
|
||||
GtkWindow *parent,
|
||||
gboolean is_preview);
|
||||
|
||||
void _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
GtkPrintOperationPrintFunc print_cb);
|
||||
GtkPrintOperationResult _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *operation,
|
||||
GtkWindow *parent,
|
||||
gboolean *do_print,
|
||||
GError **error);
|
||||
void _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
GtkPrintOperationPrintFunc print_cb);
|
||||
void _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
const char *filename);
|
||||
cairo_surface_t * _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *op,
|
||||
GtkPageSetup *page_setup,
|
||||
gdouble *dpi_x,
|
||||
gdouble *dpi_y,
|
||||
const gchar *target);
|
||||
void _gtk_print_operation_platform_backend_resize_preview_surface (GtkPrintOperation *op,
|
||||
GtkPageSetup *page_setup,
|
||||
cairo_surface_t *surface);
|
||||
|
||||
void _gtk_print_operation_set_status (GtkPrintOperation *op,
|
||||
GtkPrintStatus status,
|
||||
|
@ -25,6 +25,9 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "gtkprintoperation-private.h"
|
||||
#include "gtkmarshal.h"
|
||||
@ -41,13 +44,17 @@
|
||||
#include "gtkalias.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
GtkPrintJob *job; /* the job we are sending to the printer */
|
||||
gulong job_status_changed_tag;
|
||||
GtkWindow *parent; /* just in case we need to throw error dialogs */
|
||||
GMainLoop *loop;
|
||||
gboolean data_sent;
|
||||
|
||||
/* Real printing (not preview: */
|
||||
GtkPrintJob *job; /* the job we are sending to the printer */
|
||||
cairo_surface_t *surface;
|
||||
gulong job_status_changed_tag;
|
||||
|
||||
|
||||
} GtkPrintOperationUnix;
|
||||
|
||||
typedef struct _PrinterFinder PrinterFinder;
|
||||
@ -62,21 +69,24 @@ unix_start_page (GtkPrintOperation *op,
|
||||
GtkPrintContext *print_context,
|
||||
GtkPageSetup *page_setup)
|
||||
{
|
||||
GtkPrintOperationUnix *op_unix;
|
||||
GtkPaperSize *paper_size;
|
||||
cairo_surface_type_t type;
|
||||
double w, h;
|
||||
|
||||
op_unix = op->priv->platform_data;
|
||||
|
||||
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);
|
||||
|
||||
type = cairo_surface_get_type (op->priv->surface);
|
||||
type = cairo_surface_get_type (op_unix->surface);
|
||||
|
||||
if (type == CAIRO_SURFACE_TYPE_PS)
|
||||
cairo_ps_surface_set_size (op->priv->surface, w, h);
|
||||
cairo_ps_surface_set_size (op_unix->surface, w, h);
|
||||
else if (type == CAIRO_SURFACE_TYPE_PDF)
|
||||
cairo_pdf_surface_set_size (op->priv->surface, w, h);
|
||||
cairo_pdf_surface_set_size (op_unix->surface, w, h);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -102,6 +112,112 @@ op_unix_free (GtkPrintOperationUnix *op_unix)
|
||||
g_free (op_unix);
|
||||
}
|
||||
|
||||
static char *
|
||||
shell_command_substitute_file (const gchar *cmd,
|
||||
const gchar *filename)
|
||||
{
|
||||
const char *inptr, *start;
|
||||
char *result;
|
||||
GString *final;
|
||||
|
||||
g_return_val_if_fail (cmd != NULL, NULL);
|
||||
g_return_val_if_fail (filename != NULL, NULL);
|
||||
|
||||
result = NULL;
|
||||
final = g_string_new (NULL);
|
||||
|
||||
start = inptr = cmd;
|
||||
|
||||
while ((inptr = strchr (inptr, '%')) != NULL)
|
||||
{
|
||||
g_string_append_len (final, start, inptr - start);
|
||||
inptr++;
|
||||
switch (*inptr)
|
||||
{
|
||||
case 'f':
|
||||
g_string_append (final, filename ? filename : "");
|
||||
break;
|
||||
|
||||
case '%':
|
||||
g_string_append_c (final, '%');
|
||||
break;
|
||||
|
||||
default:
|
||||
g_string_append_c (final, '%');
|
||||
if (*inptr)
|
||||
g_string_append_c (final, *inptr);
|
||||
break;
|
||||
}
|
||||
if (*inptr)
|
||||
inptr++;
|
||||
start = inptr;
|
||||
}
|
||||
g_string_append (final, start);
|
||||
|
||||
result = final->str;
|
||||
|
||||
g_string_free (final, FALSE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
const char *filename)
|
||||
{
|
||||
int argc;
|
||||
gchar **argv;
|
||||
gchar *cmd;
|
||||
gchar *preview_cmd;
|
||||
GtkSettings *settings;
|
||||
gchar *quoted_filename;
|
||||
GdkScreen *screen;
|
||||
GError *error = NULL;
|
||||
|
||||
settings = gtk_settings_get_default ();
|
||||
g_object_get (settings, "gtk-print-preview-command", &preview_cmd, NULL);
|
||||
|
||||
quoted_filename = g_shell_quote (filename);
|
||||
cmd = shell_command_substitute_file (preview_cmd, quoted_filename);
|
||||
g_shell_parse_argv (cmd, &argc, &argv, &error);
|
||||
|
||||
if (error !=NULL)
|
||||
goto out;
|
||||
|
||||
if (parent)
|
||||
screen = gtk_window_get_screen (parent);
|
||||
else
|
||||
screen = gdk_screen_get_default ();
|
||||
|
||||
gdk_spawn_on_screen (screen, NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error);
|
||||
|
||||
out:
|
||||
if (error != NULL)
|
||||
{
|
||||
GtkWidget *edialog;
|
||||
edialog = gtk_message_dialog_new (parent,
|
||||
GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
_("Error launching preview") /* FIXME better text */);
|
||||
gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog),
|
||||
"%s", error->message);
|
||||
gtk_window_set_modal (GTK_WINDOW (edialog), TRUE);
|
||||
g_signal_connect (edialog, "response",
|
||||
G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
|
||||
gtk_window_present (GTK_WINDOW (edialog));
|
||||
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
g_free (cmd);
|
||||
g_free (quoted_filename);
|
||||
g_free (preview_cmd);
|
||||
g_strfreev (argv);
|
||||
}
|
||||
|
||||
static void
|
||||
unix_finish_send (GtkPrintJob *job,
|
||||
void *user_data,
|
||||
@ -129,6 +245,7 @@ unix_finish_send (GtkPrintJob *job,
|
||||
}
|
||||
|
||||
op_unix->data_sent = TRUE;
|
||||
|
||||
if (op_unix->loop)
|
||||
g_main_loop_quit (op_unix->loop);
|
||||
}
|
||||
@ -140,6 +257,8 @@ unix_end_run (GtkPrintOperation *op,
|
||||
{
|
||||
GtkPrintOperationUnix *op_unix = op->priv->platform_data;
|
||||
|
||||
cairo_surface_finish (op_unix->surface);
|
||||
|
||||
if (cancelled)
|
||||
return;
|
||||
|
||||
@ -147,10 +266,11 @@ unix_end_run (GtkPrintOperation *op,
|
||||
op_unix->loop = g_main_loop_new (NULL, FALSE);
|
||||
|
||||
/* TODO: Check for error */
|
||||
gtk_print_job_send (op_unix->job,
|
||||
unix_finish_send,
|
||||
op_unix, NULL,
|
||||
NULL);
|
||||
if (op_unix->job != NULL)
|
||||
gtk_print_job_send (op_unix->job,
|
||||
unix_finish_send,
|
||||
op_unix, NULL,
|
||||
NULL);
|
||||
|
||||
if (wait)
|
||||
{
|
||||
@ -253,64 +373,70 @@ finish_print (PrintResponseData *rdata,
|
||||
{
|
||||
GtkPrintOperation *op = rdata->op;
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
gboolean is_preview;
|
||||
|
||||
priv->start_page = unix_start_page;
|
||||
priv->end_page = unix_end_page;
|
||||
priv->end_run = unix_end_run;
|
||||
is_preview = rdata->result == GTK_PRINT_OPERATION_RESULT_PREVIEW;
|
||||
|
||||
if (rdata->do_print)
|
||||
{
|
||||
GtkPrintOperationUnix *op_unix;
|
||||
|
||||
gtk_print_operation_set_print_settings (op, settings);
|
||||
|
||||
op_unix = g_new0 (GtkPrintOperationUnix, 1);
|
||||
op_unix->job = gtk_print_job_new (priv->job_name,
|
||||
printer,
|
||||
settings,
|
||||
page_setup);
|
||||
priv->print_context = _gtk_print_context_new (op);
|
||||
_gtk_print_context_set_page_setup (priv->print_context, page_setup);
|
||||
|
||||
gtk_print_job_set_track_print_status (op_unix->job, priv->track_print_status);
|
||||
|
||||
rdata->op->priv->surface = gtk_print_job_get_surface (op_unix->job, rdata->error);
|
||||
if (op->priv->surface == NULL)
|
||||
if (!is_preview)
|
||||
{
|
||||
rdata->do_print = FALSE;
|
||||
op_unix_free (op_unix);
|
||||
rdata->result = GTK_PRINT_OPERATION_RESULT_ERROR;
|
||||
goto out;
|
||||
}
|
||||
GtkPrintOperationUnix *op_unix;
|
||||
cairo_t *cr;
|
||||
|
||||
op_unix = g_new0 (GtkPrintOperationUnix, 1);
|
||||
priv->platform_data = op_unix;
|
||||
priv->free_platform_data = (GDestroyNotify) op_unix_free;
|
||||
op_unix->parent = rdata->parent;
|
||||
|
||||
priv->start_page = unix_start_page;
|
||||
priv->end_page = unix_end_page;
|
||||
priv->end_run = unix_end_run;
|
||||
|
||||
op_unix->job = gtk_print_job_new (priv->job_name,
|
||||
printer,
|
||||
settings,
|
||||
page_setup);
|
||||
gtk_print_job_set_track_print_status (op_unix->job, priv->track_print_status);
|
||||
|
||||
op_unix->surface = gtk_print_job_get_surface (op_unix->job, rdata->error);
|
||||
if (op_unix->surface == NULL) {
|
||||
rdata->do_print = FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
cr = cairo_create (op_unix->surface);
|
||||
gtk_print_context_set_cairo_context (op->priv->print_context,
|
||||
cr, 72, 72);
|
||||
cairo_destroy (cr);
|
||||
|
||||
_gtk_print_operation_set_status (op, gtk_print_job_get_status (op_unix->job), NULL);
|
||||
op_unix->job_status_changed_tag =
|
||||
g_signal_connect (op_unix->job, "status-changed",
|
||||
G_CALLBACK (job_status_changed_cb), op);
|
||||
|
||||
op_unix->parent = rdata->parent;
|
||||
|
||||
priv->dpi_x = 72;
|
||||
priv->dpi_y = 72;
|
||||
|
||||
priv->platform_data = op_unix;
|
||||
priv->free_platform_data = (GDestroyNotify) op_unix_free;
|
||||
|
||||
priv->print_pages = op_unix->job->print_pages;
|
||||
priv->page_ranges = op_unix->job->page_ranges;
|
||||
priv->num_page_ranges = op_unix->job->num_page_ranges;
|
||||
|
||||
priv->manual_num_copies = op_unix->job->num_copies;
|
||||
priv->manual_collation = op_unix->job->collate;
|
||||
priv->manual_reverse = op_unix->job->reverse;
|
||||
priv->manual_page_set = op_unix->job->page_set;
|
||||
priv->manual_scale = op_unix->job->scale;
|
||||
priv->manual_orientation = op_unix->job->rotate_to_orientation;
|
||||
_gtk_print_operation_set_status (op, gtk_print_job_get_status (op_unix->job), NULL);
|
||||
|
||||
op_unix->job_status_changed_tag =
|
||||
g_signal_connect (op_unix->job, "status-changed",
|
||||
G_CALLBACK (job_status_changed_cb), op);
|
||||
|
||||
priv->print_pages = op_unix->job->print_pages;
|
||||
priv->page_ranges = op_unix->job->page_ranges;
|
||||
priv->num_page_ranges = op_unix->job->num_page_ranges;
|
||||
|
||||
priv->manual_num_copies = op_unix->job->num_copies;
|
||||
priv->manual_collation = op_unix->job->collate;
|
||||
priv->manual_reverse = op_unix->job->reverse;
|
||||
priv->manual_page_set = op_unix->job->page_set;
|
||||
priv->manual_scale = op_unix->job->scale;
|
||||
priv->manual_orientation = op_unix->job->rotate_to_orientation;
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
out:
|
||||
if (rdata->print_cb)
|
||||
{
|
||||
if (rdata->do_print)
|
||||
rdata->print_cb (op, rdata->parent);
|
||||
rdata->print_cb (op, rdata->parent, is_preview);
|
||||
else
|
||||
_gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
|
||||
}
|
||||
@ -319,7 +445,7 @@ finish_print (PrintResponseData *rdata,
|
||||
rdata->destroy (rdata);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
handle_print_response (GtkWidget *dialog,
|
||||
gint response,
|
||||
gpointer data)
|
||||
@ -335,24 +461,31 @@ handle_print_response (GtkWidget *dialog,
|
||||
rdata->result = GTK_PRINT_OPERATION_RESULT_APPLY;
|
||||
|
||||
printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
if (printer == NULL)
|
||||
goto out;
|
||||
|
||||
if (printer != NULL)
|
||||
rdata->do_print = TRUE;
|
||||
}
|
||||
else if (response == GTK_RESPONSE_APPLY)
|
||||
{
|
||||
/* print preview */
|
||||
rdata->result = GTK_PRINT_OPERATION_RESULT_PREVIEW;
|
||||
rdata->do_print = TRUE;
|
||||
}
|
||||
|
||||
if (rdata->do_print)
|
||||
{
|
||||
settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (pd));
|
||||
|
||||
|
||||
g_signal_emit_by_name (rdata->op, "custom-widget-apply", rdata->op->priv->custom_widget);
|
||||
}
|
||||
|
||||
out:
|
||||
}
|
||||
|
||||
finish_print (rdata, printer, page_setup, settings);
|
||||
|
||||
if (settings)
|
||||
g_object_unref (settings);
|
||||
|
||||
|
||||
gtk_widget_destroy (GTK_WIDGET (pd));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -436,6 +569,39 @@ _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation
|
||||
}
|
||||
}
|
||||
|
||||
cairo_surface_t *
|
||||
_gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *op,
|
||||
GtkPageSetup *page_setup,
|
||||
gdouble *dpi_x,
|
||||
gdouble *dpi_y,
|
||||
const gchar *target)
|
||||
{
|
||||
GtkPaperSize *paper_size;
|
||||
double 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);
|
||||
|
||||
*dpi_x = *dpi_y = 72;
|
||||
return cairo_pdf_surface_create (target, w, h);
|
||||
}
|
||||
|
||||
void
|
||||
_gtk_print_operation_platform_backend_resize_preview_surface (GtkPrintOperation *op,
|
||||
GtkPageSetup *page_setup,
|
||||
cairo_surface_t *surface)
|
||||
{
|
||||
GtkPaperSize *paper_size;
|
||||
double 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 (surface, w, h);
|
||||
}
|
||||
|
||||
|
||||
GtkPrintOperationResult
|
||||
_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
|
||||
GtkWindow *parent,
|
||||
@ -459,6 +625,7 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
|
||||
if (op->priv->show_dialog)
|
||||
{
|
||||
pd = get_print_dialog (op, parent);
|
||||
|
||||
response = gtk_dialog_run (GTK_DIALOG (pd));
|
||||
handle_print_response (pd, response, &rdata);
|
||||
}
|
||||
@ -477,6 +644,7 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
g_main_loop_unref (rdata.loop);
|
||||
rdata.loop = NULL;
|
||||
}
|
||||
|
||||
*do_print = rdata.do_print;
|
||||
|
@ -492,6 +492,7 @@ win32_end_run (GtkPrintOperation *op,
|
||||
GlobalFree(op_win32->devmode);
|
||||
GlobalFree(op_win32->devnames);
|
||||
|
||||
cairo_surface_finish (op->priv->surface);
|
||||
cairo_surface_destroy (op->priv->surface);
|
||||
op->priv->surface = NULL;
|
||||
|
||||
|
@ -19,6 +19,10 @@
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string.h>
|
||||
#include "gtkprintoperation-private.h"
|
||||
#include "gtkmarshalers.h"
|
||||
@ -41,6 +45,7 @@ enum {
|
||||
STATUS_CHANGED,
|
||||
CREATE_CUSTOM_WIDGET,
|
||||
CUSTOM_WIDGET_APPLY,
|
||||
PREVIEW,
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
@ -65,7 +70,15 @@ enum {
|
||||
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:
|
||||
@ -145,6 +158,94 @@ gtk_print_operation_init (GtkPrintOperation *operation)
|
||||
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);
|
||||
|
||||
op->priv->end_run (op, op->priv->is_sync, TRUE);
|
||||
}
|
||||
|
||||
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)
|
||||
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;
|
||||
|
||||
_gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_print_operation_set_property (GObject *object,
|
||||
guint prop_id,
|
||||
@ -256,6 +357,151 @@ gtk_print_operation_get_property (GObject *object,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
op = GTK_PRINT_OPERATION (pop->preview);
|
||||
|
||||
_gtk_print_operation_platform_backend_launch_preview (op,
|
||||
pop->parent,
|
||||
pop->filename);
|
||||
|
||||
g_free (pop->filename);
|
||||
cairo_surface_finish (pop->surface);
|
||||
cairo_surface_destroy (pop->surface);
|
||||
|
||||
gtk_print_operation_preview_end_preview (pop->preview);
|
||||
g_free (pop);
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
}
|
||||
|
||||
static gboolean
|
||||
preview_print_idle (gpointer data)
|
||||
{
|
||||
PreviewOp *pop;
|
||||
GtkPrintOperation *op;
|
||||
gboolean retval = TRUE;
|
||||
cairo_t *cr;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
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);
|
||||
cairo_show_page (cr);
|
||||
|
||||
/* TODO: print out sheets not pages and follow ranges */
|
||||
pop->page_nr++;
|
||||
if (op->priv->nr_of_pages <= pop->page_nr)
|
||||
retval = FALSE;
|
||||
|
||||
GDK_THREADS_LEAVE ();
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void
|
||||
preview_got_page_size (GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context,
|
||||
GtkPageSetup *page_setup,
|
||||
PreviewOp *pop)
|
||||
{
|
||||
GtkPrintOperation *op = GTK_PRINT_OPERATION (preview);
|
||||
|
||||
_gtk_print_operation_platform_backend_resize_preview_surface (op, page_setup, pop->surface);
|
||||
}
|
||||
|
||||
static void
|
||||
preview_ready (GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context,
|
||||
PreviewOp *pop)
|
||||
{
|
||||
|
||||
pop->page_nr = 0;
|
||||
pop->print_context = context;
|
||||
|
||||
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
preview_print_idle,
|
||||
pop,
|
||||
preview_print_idle_done);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_print_operation_preview_handler:
|
||||
*
|
||||
* Default handler for preview operations
|
||||
**/
|
||||
static gboolean
|
||||
gtk_print_operation_preview_handler (GtkPrintOperation *op,
|
||||
GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context,
|
||||
GtkWindow *parent)
|
||||
{
|
||||
gdouble dpi_x, dpi_y;
|
||||
gchar *tmp_dir;
|
||||
gchar *dir_template;
|
||||
gchar *preview_filename;
|
||||
PreviewOp *pop;
|
||||
GtkPageSetup *page_setup;
|
||||
cairo_t *cr;
|
||||
|
||||
dir_template = g_build_filename (g_get_tmp_dir (), "print-preview-XXXXXX", NULL);
|
||||
|
||||
/* use temp dirs because apps like evince need to have extentions
|
||||
to determine the mine type */
|
||||
tmp_dir = mkdtemp(dir_template);
|
||||
|
||||
preview_filename = g_build_filename (tmp_dir,
|
||||
"Print Preview.pdf",
|
||||
NULL);
|
||||
|
||||
g_free (dir_template);
|
||||
|
||||
pop = g_new0 (PreviewOp, 1);
|
||||
pop->filename = preview_filename;
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
@ -287,7 +533,8 @@ 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;
|
||||
|
||||
g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
|
||||
@ -530,6 +777,36 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class)
|
||||
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.
|
||||
* If you handle this you must set the cairo context on the printing context.
|
||||
*
|
||||
* If you don't override this a default implementation using an external
|
||||
* viewer will be used.
|
||||
*
|
||||
* 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:
|
||||
*
|
||||
@ -1436,6 +1713,7 @@ pdf_start_page (GtkPrintOperation *op,
|
||||
GtkPageSetup *page_setup)
|
||||
{
|
||||
GtkPaperSize *paper_size;
|
||||
cairo_surface_t *surface = op->priv->platform_data;
|
||||
double w, h;
|
||||
|
||||
paper_size = gtk_page_setup_get_paper_size (page_setup);
|
||||
@ -1443,7 +1721,7 @@ pdf_start_page (GtkPrintOperation *op,
|
||||
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
|
||||
@ -1462,9 +1740,10 @@ pdf_end_run (GtkPrintOperation *op,
|
||||
gboolean cancelled)
|
||||
{
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
cairo_surface_t *surface = priv->platform_data;
|
||||
|
||||
cairo_surface_destroy (priv->surface);
|
||||
priv->surface = NULL;
|
||||
cairo_surface_finish (surface);
|
||||
cairo_surface_destroy (surface);
|
||||
}
|
||||
|
||||
static GtkPrintOperationResult
|
||||
@ -1475,6 +1754,8 @@ run_pdf (GtkPrintOperation *op,
|
||||
{
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
GtkPageSetup *page_setup;
|
||||
cairo_surface_t *surface;
|
||||
cairo_t *cr;
|
||||
double width, height;
|
||||
/* This will be overwritten later by the non-default size, but
|
||||
we need to pass some size: */
|
||||
@ -1484,13 +1765,19 @@ run_pdf (GtkPrintOperation *op,
|
||||
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->pdf_target,
|
||||
width, height);
|
||||
cairo_pdf_surface_set_dpi (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;
|
||||
@ -1524,10 +1811,11 @@ typedef struct
|
||||
|
||||
gint page, start, end, inc;
|
||||
|
||||
GtkPageSetup *initial_page_setup;
|
||||
GtkPrintContext *print_context;
|
||||
gboolean initialized;
|
||||
|
||||
GtkWidget *progress;
|
||||
|
||||
gboolean is_preview;
|
||||
} PrintPagesData;
|
||||
|
||||
static void
|
||||
@ -1599,12 +1887,9 @@ print_pages_idle_done (gpointer user_data)
|
||||
if (data->progress)
|
||||
gtk_widget_destroy (data->progress);
|
||||
|
||||
g_object_unref (data->print_context);
|
||||
g_object_unref (data->initial_page_setup);
|
||||
|
||||
g_object_unref (data->op);
|
||||
|
||||
if (priv->rloop)
|
||||
if (priv->rloop && !data->is_preview)
|
||||
g_main_loop_quit (priv->rloop);
|
||||
|
||||
g_free (data);
|
||||
@ -1640,13 +1925,56 @@ update_progress (PrintPagesData *data)
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
cairo_t *cr;
|
||||
gboolean done = FALSE;
|
||||
|
||||
GDK_THREADS_ENTER ();
|
||||
@ -1656,15 +1984,15 @@ print_pages_idle (gpointer user_data)
|
||||
|
||||
if (priv->status == GTK_PRINT_STATUS_PREPARING)
|
||||
{
|
||||
if (!data->print_context)
|
||||
if (!data->initialized)
|
||||
{
|
||||
data->print_context = _gtk_print_context_new (data->op);
|
||||
data->initial_page_setup = create_page_setup (data->op);
|
||||
|
||||
_gtk_print_context_set_page_setup (data->print_context,
|
||||
data->initial_page_setup);
|
||||
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, data->print_context);
|
||||
g_signal_emit (data->op, signals[BEGIN_PRINT], 0, priv->print_context);
|
||||
|
||||
if (priv->manual_collation)
|
||||
{
|
||||
@ -1684,7 +2012,7 @@ print_pages_idle (gpointer user_data)
|
||||
{
|
||||
gboolean paginated = FALSE;
|
||||
|
||||
g_signal_emit (data->op, signals[PAGINATE], 0, data->print_context, &paginated);
|
||||
g_signal_emit (data->op, signals[PAGINATE], 0, priv->print_context, &paginated);
|
||||
if (!paginated)
|
||||
goto out;
|
||||
}
|
||||
@ -1751,36 +2079,18 @@ print_pages_idle (gpointer user_data)
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->is_preview)
|
||||
{
|
||||
done = TRUE;
|
||||
|
||||
page_setup = gtk_page_setup_copy (data->initial_page_setup);
|
||||
g_signal_emit (data->op, signals[REQUEST_PAGE_SETUP], 0,
|
||||
data->print_context, data->page, page_setup);
|
||||
|
||||
_gtk_print_context_set_page_setup (data->print_context, page_setup);
|
||||
priv->start_page (data->op, data->print_context, page_setup);
|
||||
|
||||
cr = gtk_print_context_get_cairo_context (data->print_context);
|
||||
|
||||
cairo_save (cr);
|
||||
if (priv->manual_scale != 1.0)
|
||||
cairo_scale (cr,
|
||||
priv->manual_scale,
|
||||
priv->manual_scale);
|
||||
|
||||
if (priv->manual_orientation)
|
||||
_gtk_print_context_rotate_according_to_orientation (data->print_context);
|
||||
|
||||
if (!priv->use_full_page)
|
||||
_gtk_print_context_translate_into_margin (data->print_context);
|
||||
|
||||
g_signal_emit (data->op, signals[DRAW_PAGE], 0,
|
||||
data->print_context, data->page);
|
||||
|
||||
priv->end_page (data->op, data->print_context);
|
||||
|
||||
cairo_restore (cr);
|
||||
|
||||
g_object_unref (page_setup);
|
||||
g_object_ref (data->op);
|
||||
|
||||
g_signal_emit_by_name (data->op, "ready", priv->print_context);
|
||||
goto out;
|
||||
}
|
||||
|
||||
common_render_page (data->op, data->page);
|
||||
|
||||
out:
|
||||
|
||||
@ -1791,11 +2101,9 @@ print_pages_idle (gpointer user_data)
|
||||
done = TRUE;
|
||||
}
|
||||
|
||||
if (done)
|
||||
if (done && !data->is_preview)
|
||||
{
|
||||
g_signal_emit (data->op, signals[END_PRINT], 0, data->print_context);
|
||||
|
||||
cairo_surface_finish (priv->surface);
|
||||
g_signal_emit (data->op, signals[END_PRINT], 0, priv->print_context);
|
||||
priv->end_run (data->op, priv->is_sync, priv->cancelled);
|
||||
}
|
||||
|
||||
@ -1833,15 +2141,17 @@ show_progress_timeout (PrintPagesData *data)
|
||||
|
||||
static void
|
||||
print_pages (GtkPrintOperation *op,
|
||||
GtkWindow *parent)
|
||||
GtkWindow *parent,
|
||||
gboolean is_preview)
|
||||
{
|
||||
GtkPrintOperationPrivate *priv = op->priv;
|
||||
PrintPagesData *data;
|
||||
|
||||
|
||||
_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 = is_preview;
|
||||
|
||||
if (priv->show_progress)
|
||||
{
|
||||
@ -1862,6 +2172,37 @@ print_pages (GtkPrintOperation *op,
|
||||
data->progress = progress;
|
||||
}
|
||||
|
||||
if (is_preview)
|
||||
{
|
||||
gboolean handled;
|
||||
|
||||
g_signal_emit_by_name (op, "preview",
|
||||
GTK_PRINT_OPERATION_PREVIEW (op),
|
||||
op->priv->print_context,
|
||||
parent,
|
||||
&handled);
|
||||
|
||||
if (!handled ||
|
||||
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 = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
print_pages_idle,
|
||||
data,
|
||||
@ -1877,9 +2218,10 @@ print_pages (GtkPrintOperation *op,
|
||||
GDK_THREADS_LEAVE ();
|
||||
g_main_loop_run (priv->rloop);
|
||||
GDK_THREADS_ENTER ();
|
||||
|
||||
g_main_loop_unref (priv->rloop);
|
||||
priv->rloop = NULL;
|
||||
}
|
||||
g_main_loop_unref (priv->rloop);
|
||||
priv->rloop = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1964,7 +2306,7 @@ gtk_print_operation_run (GtkPrintOperation *op,
|
||||
&do_print,
|
||||
error);
|
||||
if (do_print)
|
||||
print_pages (op, parent);
|
||||
print_pages (op, parent, result == GTK_PRINT_OPERATION_RESULT_PREVIEW);
|
||||
else
|
||||
_gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
|
||||
|
||||
@ -2006,7 +2348,7 @@ gtk_print_operation_run_async (GtkPrintOperation *op,
|
||||
{
|
||||
run_pdf (op, parent, &do_print, NULL);
|
||||
if (do_print)
|
||||
print_pages (op, parent);
|
||||
print_pages (op, parent, FALSE);
|
||||
else
|
||||
_gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "gtkpagesetup.h"
|
||||
#include "gtkprintsettings.h"
|
||||
#include "gtkprintcontext.h"
|
||||
#include "gtkprintoperationpreview.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
@ -84,7 +85,13 @@ struct _GtkPrintOperationClass
|
||||
GtkWidget *(*create_custom_widget) (GtkPrintOperation *operation);
|
||||
void (*custom_widget_apply) (GtkPrintOperation *operation,
|
||||
GtkWidget *widget);
|
||||
|
||||
|
||||
gboolean (*preview) (GtkPrintOperation *operation,
|
||||
GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context,
|
||||
GtkWindow *parent);
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
@ -98,7 +105,8 @@ struct _GtkPrintOperationClass
|
||||
typedef enum {
|
||||
GTK_PRINT_OPERATION_RESULT_ERROR,
|
||||
GTK_PRINT_OPERATION_RESULT_APPLY,
|
||||
GTK_PRINT_OPERATION_RESULT_CANCEL
|
||||
GTK_PRINT_OPERATION_RESULT_CANCEL,
|
||||
GTK_PRINT_OPERATION_RESULT_PREVIEW
|
||||
} GtkPrintOperationResult;
|
||||
|
||||
#define GTK_PRINT_ERROR gtk_print_error_quark ()
|
||||
|
116
gtk/gtkprintoperationpreview.c
Normal file
116
gtk/gtkprintoperationpreview.c
Normal file
@ -0,0 +1,116 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtkprintoperationpreview.c: Abstract print preview interface
|
||||
* Copyright (C) 2006, Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "gtkprintoperationpreview.h"
|
||||
#include "gtkmarshalers.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
static void gtk_print_operation_preview_base_init (gpointer g_iface);
|
||||
|
||||
GType
|
||||
gtk_print_operation_preview_get_type (void)
|
||||
{
|
||||
static GType print_operation_preview_type = 0;
|
||||
|
||||
if (!print_operation_preview_type)
|
||||
{
|
||||
static const GTypeInfo print_operation_preview_info =
|
||||
{
|
||||
sizeof (GtkPrintOperationPreviewIface), /* class_size */
|
||||
gtk_print_operation_preview_base_init, /* base_init */
|
||||
NULL, /* base_finalize */
|
||||
NULL,
|
||||
NULL, /* class_finalize */
|
||||
NULL, /* class_data */
|
||||
0,
|
||||
0, /* n_preallocs */
|
||||
NULL
|
||||
};
|
||||
|
||||
print_operation_preview_type =
|
||||
g_type_register_static (G_TYPE_INTERFACE, I_("GtkPrintOperationPreview"),
|
||||
&print_operation_preview_info, 0);
|
||||
|
||||
g_type_interface_add_prerequisite (print_operation_preview_type, G_TYPE_OBJECT);
|
||||
}
|
||||
|
||||
return print_operation_preview_type;
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_print_operation_preview_base_init (gpointer g_iface)
|
||||
{
|
||||
static gboolean initialized = FALSE;
|
||||
|
||||
if (!initialized)
|
||||
{
|
||||
g_signal_new (I_("ready"),
|
||||
GTK_TYPE_PRINT_OPERATION_PREVIEW,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintOperationPreviewIface, ready),
|
||||
NULL, NULL,
|
||||
g_cclosure_marshal_VOID__OBJECT,
|
||||
G_TYPE_NONE, 1,
|
||||
G_TYPE_OBJECT);
|
||||
|
||||
g_signal_new (I_("got-page-size"),
|
||||
GTK_TYPE_PRINT_OPERATION_PREVIEW,
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (GtkPrintOperationPreviewIface, ready),
|
||||
NULL, NULL,
|
||||
_gtk_marshal_VOID__OBJECT_OBJECT,
|
||||
G_TYPE_NONE, 2,
|
||||
GTK_TYPE_PRINT_CONTEXT,
|
||||
GTK_TYPE_PAGE_SETUP);
|
||||
|
||||
initialized = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
gtk_print_operation_preview_render_page (GtkPrintOperationPreview *preview,
|
||||
gint page_nr)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_PRINT_OPERATION_PREVIEW (preview));
|
||||
|
||||
GTK_PRINT_OPERATION_PREVIEW_GET_IFACE (preview)->render_page (preview,
|
||||
page_nr);
|
||||
}
|
||||
|
||||
void
|
||||
gtk_print_operation_preview_end_preview (GtkPrintOperationPreview *preview)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_PRINT_OPERATION_PREVIEW (preview));
|
||||
|
||||
GTK_PRINT_OPERATION_PREVIEW_GET_IFACE (preview)->end_preview (preview);
|
||||
}
|
||||
|
||||
gboolean
|
||||
gtk_print_operation_preview_is_selected (GtkPrintOperationPreview *preview,
|
||||
gint page_nr)
|
||||
{
|
||||
g_return_if_fail (GTK_IS_PRINT_OPERATION_PREVIEW (preview));
|
||||
|
||||
return GTK_PRINT_OPERATION_PREVIEW_GET_IFACE (preview)->is_selected (preview, page_nr);
|
||||
}
|
||||
|
78
gtk/gtkprintoperationpreview.h
Normal file
78
gtk/gtkprintoperationpreview.h
Normal file
@ -0,0 +1,78 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* gtkprintoperationpreview.h: Abstract print preview interface
|
||||
* Copyright (C) 2006, Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the
|
||||
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
* Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_PRINT_OPERATION_PREVIEW_H__
|
||||
#define __GTK_PRINT_OPERATION_PREVIEW_H__
|
||||
|
||||
#include <glib-object.h>
|
||||
#include <cairo.h>
|
||||
|
||||
#include "gtkprintcontext.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_PRINT_OPERATION_PREVIEW (gtk_print_operation_preview_get_type ())
|
||||
#define GTK_PRINT_OPERATION_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_OPERATION_PREVIEW, GtkPrintOperationPreview))
|
||||
#define GTK_IS_PRINT_OPERATION_PREVIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_OPERATION_PREVIEW))
|
||||
#define GTK_PRINT_OPERATION_PREVIEW_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GTK_TYPE_PRINT_OPERATION_PREVIEW, GtkPrintOperationPreviewIface))
|
||||
|
||||
typedef struct _GtkPrintOperationPreview GtkPrintOperationPreview; /*dummy typedef */
|
||||
typedef struct _GtkPrintOperationPreviewIface GtkPrintOperationPreviewIface;
|
||||
|
||||
|
||||
struct _GtkPrintOperationPreviewIface
|
||||
{
|
||||
GTypeInterface g_iface;
|
||||
|
||||
/* signals */
|
||||
void (*ready) (GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context);
|
||||
void (*got_page_size) (GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context,
|
||||
GtkPageSetup *page_setup);
|
||||
|
||||
|
||||
/* methods */
|
||||
void (*render_page) (GtkPrintOperationPreview *preview,
|
||||
gint page_nr);
|
||||
gboolean (*is_selected) (GtkPrintOperationPreview *preview,
|
||||
gint page_nr);
|
||||
void (*end_preview) (GtkPrintOperationPreview *preview);
|
||||
|
||||
|
||||
/* Padding for future expansion */
|
||||
void (*_gtk_reserved1) (void);
|
||||
void (*_gtk_reserved2) (void);
|
||||
void (*_gtk_reserved3) (void);
|
||||
void (*_gtk_reserved4) (void);
|
||||
void (*_gtk_reserved5) (void);
|
||||
void (*_gtk_reserved6) (void);
|
||||
void (*_gtk_reserved7) (void);
|
||||
};
|
||||
|
||||
GType gtk_print_operation_preview_get_type (void) G_GNUC_CONST;
|
||||
|
||||
void gtk_print_operation_preview_render_page (GtkPrintOperationPreview *preview,
|
||||
gint page_nr);
|
||||
void gtk_print_operation_preview_end_preview (GtkPrintOperationPreview *preview);
|
||||
gboolean gtk_print_operation_preview_is_selected (GtkPrintOperationPreview *preview,
|
||||
gint page_nr);
|
||||
|
||||
#endif /* __GTK_PRINT_OPERATION_PREVIEW_H__ */
|
@ -275,7 +275,8 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog)
|
||||
(GCallback) gtk_print_unix_dialog_destroy,
|
||||
NULL);
|
||||
|
||||
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
|
||||
gtk_dialog_add_buttons (GTK_DIALOG (dialog),
|
||||
GTK_STOCK_PRINT_PREVIEW, GTK_RESPONSE_APPLY,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_PRINT, GTK_RESPONSE_OK,
|
||||
NULL);
|
||||
|
@ -1,3 +1,4 @@
|
||||
#include <math.h>
|
||||
#include <pango/pangocairo.h>
|
||||
#include <gtk/gtk.h>
|
||||
#include <gtk/gtkprintoperation.h>
|
||||
@ -303,7 +304,6 @@ begin_print (GtkPrintOperation *operation,
|
||||
gtk_print_operation_set_n_pages (operation, g_list_length (page_breaks) + 1);
|
||||
|
||||
print_data->page_breaks = page_breaks;
|
||||
|
||||
}
|
||||
|
||||
static void
|
||||
@ -317,6 +317,7 @@ draw_page (GtkPrintOperation *operation,
|
||||
int start, end, i;
|
||||
PangoLayoutIter *iter;
|
||||
double start_pos;
|
||||
|
||||
if (page_nr == 0)
|
||||
start = 0;
|
||||
else
|
||||
@ -430,17 +431,195 @@ custom_widget_apply (GtkPrintOperation *operation,
|
||||
data->font = g_strdup (selected_font);
|
||||
}
|
||||
|
||||
typedef struct
|
||||
{
|
||||
GtkPrintOperation *op;
|
||||
GtkPrintOperationPreview *preview;
|
||||
GtkWidget *spin;
|
||||
GtkWidget *area;
|
||||
gint page;
|
||||
PrintData *data;
|
||||
gdouble dpi_x, dpi_y;
|
||||
} PreviewOp;
|
||||
|
||||
static gboolean
|
||||
preview_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event,
|
||||
gpointer data)
|
||||
{
|
||||
PreviewOp *pop = data;
|
||||
|
||||
gdk_window_clear (pop->area->window);
|
||||
gtk_print_operation_preview_render_page (pop->preview,
|
||||
pop->page - 1);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
preview_ready (GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context,
|
||||
gpointer data)
|
||||
{
|
||||
PreviewOp *pop = data;
|
||||
gint n_pages;
|
||||
|
||||
g_object_get (pop->op, "n-pages", &n_pages, NULL);
|
||||
|
||||
gtk_spin_button_set_range (GTK_SPIN_BUTTON (pop->spin),
|
||||
1.0, n_pages);
|
||||
|
||||
g_signal_connect (pop->area, "expose_event",
|
||||
G_CALLBACK (preview_expose),
|
||||
pop);
|
||||
|
||||
gtk_widget_queue_draw (pop->area);
|
||||
}
|
||||
|
||||
static void
|
||||
preview_got_page_size (GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context,
|
||||
GtkPageSetup *page_setup,
|
||||
gpointer data)
|
||||
{
|
||||
PreviewOp *pop = data;
|
||||
GtkPaperSize *paper_size;
|
||||
double w, h;
|
||||
cairo_t *cr;
|
||||
gdouble dpi_x, dpi_y;
|
||||
|
||||
paper_size = gtk_page_setup_get_paper_size (page_setup);
|
||||
|
||||
w = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
|
||||
h = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH);
|
||||
|
||||
cr = gdk_cairo_create (pop->area->window);
|
||||
|
||||
dpi_x = pop->area->allocation.width/w;
|
||||
dpi_y = pop->area->allocation.height/h;
|
||||
|
||||
if (fabs (dpi_x - pop->dpi_x) > 0.001 ||
|
||||
fabs (dpi_y - pop->dpi_y) > 0.001)
|
||||
{
|
||||
gtk_print_context_set_cairo_context (context, cr, dpi_x, dpi_y);
|
||||
pop->dpi_x = dpi_x;
|
||||
pop->dpi_y = dpi_y;
|
||||
}
|
||||
|
||||
pango_cairo_update_layout (cr, pop->data->layout);
|
||||
cairo_destroy (cr);
|
||||
}
|
||||
|
||||
static void
|
||||
update_page (GtkSpinButton *widget,
|
||||
gpointer data)
|
||||
{
|
||||
PreviewOp *pop = data;
|
||||
|
||||
pop->page = gtk_spin_button_get_value_as_int (widget);
|
||||
gtk_widget_queue_draw (pop->area);
|
||||
}
|
||||
|
||||
static void
|
||||
preview_destroy (GtkWindow *window,
|
||||
PreviewOp *pop)
|
||||
{
|
||||
gtk_print_operation_preview_end_preview (pop->preview);
|
||||
g_object_unref (pop->op);
|
||||
|
||||
g_free (pop);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
do_preview (GtkPrintOperation *op,
|
||||
GtkPrintOperationPreview *preview,
|
||||
GtkPrintContext *context,
|
||||
GtkWindow *parent,
|
||||
gpointer data)
|
||||
{
|
||||
GtkPrintSettings *settings;
|
||||
GtkWidget *window, *close, *page, *hbox, *vbox, *da;
|
||||
gdouble width, height;
|
||||
cairo_t *cr;
|
||||
PreviewOp *pop;
|
||||
PrintData *print_data = data;
|
||||
|
||||
pop = g_new0 (PreviewOp, 1);
|
||||
|
||||
pop->data = print_data;
|
||||
settings = gtk_print_operation_get_print_settings (op);
|
||||
|
||||
width = 200;
|
||||
height = 300;
|
||||
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (window),
|
||||
GTK_WINDOW (main_window));
|
||||
vbox = gtk_vbox_new (FALSE, 0);
|
||||
gtk_container_add (GTK_CONTAINER (window), vbox);
|
||||
hbox = gtk_hbox_new (FALSE, 0);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), hbox,
|
||||
FALSE, FALSE, 0);
|
||||
page = gtk_spin_button_new_with_range (1, 100, 1);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), page, FALSE, FALSE, 0);
|
||||
|
||||
close = gtk_button_new_from_stock (GTK_STOCK_CLOSE);
|
||||
gtk_box_pack_start (GTK_BOX (hbox), close, FALSE, FALSE, 0);
|
||||
|
||||
da = gtk_drawing_area_new ();
|
||||
gtk_widget_set_size_request (GTK_WIDGET (da), width, height);
|
||||
gtk_box_pack_start (GTK_BOX (vbox), da, TRUE, TRUE, 0);
|
||||
|
||||
gtk_widget_set_double_buffered (da, FALSE);
|
||||
|
||||
gtk_widget_realize (da);
|
||||
|
||||
cr = gdk_cairo_create (da->window);
|
||||
|
||||
/* TODO: What dpi to use here? This will be used for pagination.. */
|
||||
gtk_print_context_set_cairo_context (context, cr, 72, 72);
|
||||
cairo_destroy (cr);
|
||||
|
||||
pop->op = op;
|
||||
pop->preview = preview;
|
||||
pop->spin = page;
|
||||
pop->area = da;
|
||||
pop->page = 1;
|
||||
|
||||
g_signal_connect (page, "value-changed",
|
||||
G_CALLBACK (update_page), pop);
|
||||
g_signal_connect_swapped (close, "clicked",
|
||||
G_CALLBACK (gtk_widget_destroy), window);
|
||||
|
||||
g_signal_connect (preview, "ready",
|
||||
G_CALLBACK (preview_ready), pop);
|
||||
g_signal_connect (preview, "got-page-size",
|
||||
G_CALLBACK (preview_got_page_size), pop);
|
||||
|
||||
g_signal_connect (window, "destroy",
|
||||
G_CALLBACK (preview_destroy), pop);
|
||||
|
||||
gtk_widget_show_all (window);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* FIXME had to move this to the heap, since previewing
|
||||
* returns too early from the sync api
|
||||
*/
|
||||
PrintData *print_data;
|
||||
|
||||
static void
|
||||
do_print (GtkAction *action)
|
||||
{
|
||||
GtkWidget *error_dialog;
|
||||
GtkPrintOperation *print;
|
||||
PrintData print_data;
|
||||
GtkPrintOperationResult res;
|
||||
GError *error;
|
||||
|
||||
print_data.text = get_text ();
|
||||
print_data.font = g_strdup ("Sans 12");
|
||||
print_data = g_new0 (PrintData, 1);
|
||||
|
||||
print_data->text = get_text ();
|
||||
print_data->font = g_strdup ("Sans 12");
|
||||
|
||||
print = gtk_print_operation_new ();
|
||||
|
||||
@ -452,12 +631,15 @@ do_print (GtkAction *action)
|
||||
if (page_setup != NULL)
|
||||
gtk_print_operation_set_default_page_setup (print, page_setup);
|
||||
|
||||
g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), &print_data);
|
||||
g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), &print_data);
|
||||
g_signal_connect (print, "create_custom_widget", G_CALLBACK (create_custom_widget), &print_data);
|
||||
g_signal_connect (print, "custom_widget_apply", G_CALLBACK (custom_widget_apply), &print_data);
|
||||
|
||||
g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), print_data);
|
||||
g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), print_data);
|
||||
g_signal_connect (print, "create_custom_widget", G_CALLBACK (create_custom_widget), print_data);
|
||||
g_signal_connect (print, "custom_widget_apply", G_CALLBACK (custom_widget_apply), print_data);
|
||||
g_signal_connect (print, "preview", G_CALLBACK (do_preview), print_data);
|
||||
|
||||
error = NULL;
|
||||
|
||||
#if 1
|
||||
res = gtk_print_operation_run (print, GTK_WINDOW (main_window), &error);
|
||||
|
||||
if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
|
||||
@ -467,7 +649,7 @@ do_print (GtkAction *action)
|
||||
GTK_MESSAGE_ERROR,
|
||||
GTK_BUTTONS_CLOSE,
|
||||
"Error printing file:\n%s",
|
||||
error->message);
|
||||
error ? error->message : "no details");
|
||||
g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
|
||||
gtk_widget_show (error_dialog);
|
||||
g_error_free (error);
|
||||
@ -489,10 +671,15 @@ do_print (GtkAction *action)
|
||||
g_signal_connect (print, "status_changed",
|
||||
G_CALLBACK (status_changed_cb), NULL);
|
||||
}
|
||||
#else
|
||||
gtk_print_operation_run_async (print, GTK_WINDOW (main_window));
|
||||
#endif
|
||||
|
||||
g_object_unref (print);
|
||||
#if 0
|
||||
g_free (print_data.text);
|
||||
g_free (print_data.font);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
|
Loading…
Reference in New Issue
Block a user