summaryrefslogtreecommitdiff
path: root/src/eom-print.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eom-print.c')
-rw-r--r--src/eom-print.c369
1 files changed, 369 insertions, 0 deletions
diff --git a/src/eom-print.c b/src/eom-print.c
new file mode 100644
index 0000000..17c0ed9
--- /dev/null
+++ b/src/eom-print.c
@@ -0,0 +1,369 @@
+/* Eye of Mate - Print Operations
+ *
+ * Copyright (C) 2005-2008 The Free Software Foundation
+ *
+ * Author: Claudio Saavedra <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <gtk/gtk.h>
+#include <glib/gi18n.h>
+#include "eom-image.h"
+#include "eom-print.h"
+#include "eom-print-image-setup.h"
+#include "eom-util.h"
+#include "eom-debug.h"
+
+#ifdef HAVE_RSVG
+#include <librsvg/rsvg-cairo.h>
+#endif
+
+#define EOM_PRINT_SETTINGS_FILE "eom-print-settings.ini"
+#define EOM_PAGE_SETUP_GROUP "Page Setup"
+#define EOM_PRINT_SETTINGS_GROUP "Print Settings"
+
+typedef struct {
+ EomImage *image;
+ gdouble left_margin;
+ gdouble top_margin;
+ gdouble scale_factor;
+ GtkUnit unit;
+} EomPrintData;
+
+static void
+eom_print_draw_page (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gint page_nr,
+ gpointer user_data)
+{
+ cairo_t *cr;
+ gdouble dpi_x, dpi_y;
+ gdouble x0, y0;
+ gdouble scale_factor;
+ gdouble p_width, p_height;
+ gint width, height;
+ EomPrintData *data;
+ GtkPageSetup *page_setup;
+
+ eom_debug (DEBUG_PRINTING);
+
+ data = (EomPrintData *) user_data;
+
+ scale_factor = data->scale_factor/100;
+
+ dpi_x = gtk_print_context_get_dpi_x (context);
+ dpi_y = gtk_print_context_get_dpi_y (context);
+
+ switch (data->unit) {
+ case GTK_UNIT_INCH:
+ x0 = data->left_margin * dpi_x;
+ y0 = data->top_margin * dpi_y;
+ break;
+ case GTK_UNIT_MM:
+ x0 = data->left_margin * dpi_x/25.4;
+ y0 = data->top_margin * dpi_y/25.4;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ cr = gtk_print_context_get_cairo_context (context);
+
+ cairo_translate (cr, x0, y0);
+
+ page_setup = gtk_print_context_get_page_setup (context);
+ p_width = gtk_page_setup_get_page_width (page_setup, GTK_UNIT_POINTS);
+ p_height = gtk_page_setup_get_page_height (page_setup, GTK_UNIT_POINTS);
+
+ eom_image_get_size (data->image, &width, &height);
+
+ /* this is both a workaround for a bug in cairo's PDF backend, and
+ a way to ensure we are not printing outside the page margins */
+ cairo_rectangle (cr, 0, 0, MIN (width*scale_factor, p_width), MIN (height*scale_factor, p_height));
+ cairo_clip (cr);
+
+ cairo_scale (cr, scale_factor, scale_factor);
+
+#ifdef HAVE_RSVG
+ if (eom_image_is_svg (data->image))
+ {
+ RsvgHandle *svg = eom_image_get_svg (data->image);
+
+ rsvg_handle_render_cairo (svg, cr);
+ } else
+#endif
+ {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = eom_image_get_pixbuf (data->image);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_paint (cr);
+ g_object_unref (pixbuf);
+ }
+}
+
+static GObject *
+eom_print_create_custom_widget (GtkPrintOperation *operation,
+ gpointer user_data)
+{
+ GtkPageSetup *page_setup;
+ EomPrintData *data;
+
+ eom_debug (DEBUG_PRINTING);
+
+ data = (EomPrintData *)user_data;
+
+ page_setup = gtk_print_operation_get_default_page_setup (operation);
+
+ if (page_setup == NULL)
+ page_setup = gtk_page_setup_new ();
+
+ return G_OBJECT (eom_print_image_setup_new (data->image, page_setup));
+}
+
+static void
+eom_print_custom_widget_apply (GtkPrintOperation *operation,
+ GtkWidget *widget,
+ gpointer user_data)
+{
+ EomPrintData *data;
+ gdouble left_margin, top_margin, scale_factor;
+ GtkUnit unit;
+
+ eom_debug (DEBUG_PRINTING);
+
+ data = (EomPrintData *)user_data;
+
+ eom_print_image_setup_get_options (EOM_PRINT_IMAGE_SETUP (widget),
+ &left_margin, &top_margin,
+ &scale_factor, &unit);
+
+ data->left_margin = left_margin;
+ data->top_margin = top_margin;
+ data->scale_factor = scale_factor;
+ data->unit = unit;
+}
+
+static void
+eom_print_end_print (GtkPrintOperation *operation,
+ GtkPrintContext *context,
+ gpointer user_data)
+{
+ EomPrintData *data = (EomPrintData*) user_data;
+
+ eom_debug (DEBUG_PRINTING);
+
+ g_object_unref (data->image);
+ g_slice_free (EomPrintData, data);
+}
+
+GtkPrintOperation *
+eom_print_operation_new (EomImage *image,
+ GtkPrintSettings *print_settings,
+ GtkPageSetup *page_setup)
+{
+ GtkPrintOperation *print;
+ EomPrintData *data;
+
+ eom_debug (DEBUG_PRINTING);
+
+ print = gtk_print_operation_new ();
+
+ data = g_slice_new0 (EomPrintData);
+
+ data->left_margin = 0;
+ data->top_margin = 0;
+ data->scale_factor = 100;
+ data->image = g_object_ref (image);
+ data->unit = GTK_UNIT_INCH;
+
+ gtk_print_operation_set_print_settings (print, print_settings);
+ gtk_print_operation_set_default_page_setup (print,
+ page_setup);
+ gtk_print_operation_set_n_pages (print, 1);
+ gtk_print_operation_set_job_name (print,
+ eom_image_get_caption (image));
+ gtk_print_operation_set_embed_page_setup (print, TRUE);
+
+ g_signal_connect (print, "draw_page",
+ G_CALLBACK (eom_print_draw_page),
+ data);
+ g_signal_connect (print, "create-custom-widget",
+ G_CALLBACK (eom_print_create_custom_widget),
+ data);
+ g_signal_connect (print, "custom-widget-apply",
+ G_CALLBACK (eom_print_custom_widget_apply),
+ data);
+ g_signal_connect (print, "end-print",
+ G_CALLBACK (eom_print_end_print),
+ data);
+ g_signal_connect (print, "update-custom-widget",
+ G_CALLBACK (eom_print_image_setup_update),
+ data);
+
+ gtk_print_operation_set_custom_tab_label (print, _("Image Settings"));
+
+ return print;
+}
+
+static GKeyFile *
+eom_print_get_key_file (void)
+{
+ GKeyFile *key_file;
+ GError *error = NULL;
+ gchar *filename;
+ GFile *file;
+ const gchar *dot_dir = eom_util_dot_dir ();
+
+ filename = g_build_filename (dot_dir, EOM_PRINT_SETTINGS_FILE, NULL);
+
+ file = g_file_new_for_path (filename);
+ key_file = g_key_file_new ();
+
+ if (g_file_query_exists (file, NULL)) {
+ g_key_file_load_from_file (key_file, filename,
+ G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
+ &error);
+ if (error) {
+ g_warning ("Error loading print settings file: %s", error->message);
+ g_error_free (error);
+ g_object_unref (file);
+ g_free (filename);
+ g_key_file_free (key_file);
+ return NULL;
+ }
+ }
+
+ g_object_unref (file);
+ g_free (filename);
+
+ return key_file;
+}
+
+GtkPageSetup *
+eom_print_get_page_setup (void)
+{
+ GtkPageSetup *page_setup;
+ GKeyFile *key_file;
+ GError *error = NULL;
+
+ key_file = eom_print_get_key_file ();
+
+ if (key_file && g_key_file_has_group (key_file, EOM_PAGE_SETUP_GROUP)) {
+ page_setup = gtk_page_setup_new_from_key_file (key_file, EOM_PAGE_SETUP_GROUP, &error);
+ } else {
+ page_setup = gtk_page_setup_new ();
+ }
+
+ if (error) {
+ page_setup = gtk_page_setup_new ();
+
+ g_warning ("Error loading print settings file: %s", error->message);
+ g_error_free (error);
+ }
+
+ if (key_file)
+ g_key_file_free (key_file);
+
+ return page_setup;
+}
+
+static void
+eom_print_save_key_file (GKeyFile *key_file)
+{
+ gchar *filename;
+ gchar *data;
+ GError *error = NULL;
+ const gchar *dot_dir = eom_util_dot_dir ();
+
+ filename = g_build_filename (dot_dir, EOM_PRINT_SETTINGS_FILE, NULL);
+
+ data = g_key_file_to_data (key_file, NULL, NULL);
+
+ g_file_set_contents (filename, data, -1, &error);
+
+ if (error) {
+ g_warning ("Error saving print settings file: %s", error->message);
+ g_error_free (error);
+ }
+
+ g_free (filename);
+ g_free (data);
+}
+
+void
+eom_print_set_page_setup (GtkPageSetup *page_setup)
+{
+ GKeyFile *key_file;
+
+ key_file = eom_print_get_key_file ();
+
+ if (key_file == NULL) {
+ key_file = g_key_file_new ();
+ }
+
+ gtk_page_setup_to_key_file (page_setup, key_file, EOM_PAGE_SETUP_GROUP);
+ eom_print_save_key_file (key_file);
+
+ g_key_file_free (key_file);
+}
+
+GtkPrintSettings *
+eom_print_get_print_settings (void)
+{
+ GtkPrintSettings *print_settings;
+ GError *error = NULL;
+ GKeyFile *key_file;
+
+ key_file = eom_print_get_key_file ();
+
+ if (key_file && g_key_file_has_group (key_file, EOM_PRINT_SETTINGS_GROUP)) {
+ print_settings = gtk_print_settings_new_from_key_file (key_file, EOM_PRINT_SETTINGS_GROUP, &error);
+ } else {
+ print_settings = gtk_print_settings_new ();
+ }
+
+ if (error) {
+ print_settings = gtk_print_settings_new ();
+
+ g_warning ("Error loading print settings file: %s", error->message);
+ g_error_free (error);
+ }
+
+ if (key_file)
+ g_key_file_free (key_file);
+
+ return print_settings;
+}
+
+void
+eom_print_set_print_settings (GtkPrintSettings *print_settings)
+{
+ GKeyFile *key_file;
+
+ key_file = eom_print_get_key_file ();
+
+ if (key_file == NULL) {
+ key_file = g_key_file_new ();
+ }
+
+ gtk_print_settings_to_key_file (print_settings, key_file, EOM_PRINT_SETTINGS_GROUP);
+ eom_print_save_key_file (key_file);
+
+ g_key_file_free (key_file);
+}