summaryrefslogtreecommitdiff
path: root/src/eom-print-image-setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/eom-print-image-setup.c')
-rw-r--r--src/eom-print-image-setup.c1074
1 files changed, 1074 insertions, 0 deletions
diff --git a/src/eom-print-image-setup.c b/src/eom-print-image-setup.c
new file mode 100644
index 0000000..100d7c9
--- /dev/null
+++ b/src/eom-print-image-setup.c
@@ -0,0 +1,1074 @@
+/* Eye Of MATE -- Print Dialog Custom Widget
+ *
+ * Copyright (C) 2006-2007 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <gtk/gtk.h>
+#include <gtk/gtkunixprint.h>
+
+#include <glib/gi18n.h>
+#include <glib/gprintf.h>
+
+#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT
+#include <langinfo.h>
+#endif
+
+#include "eom-print-image-setup.h"
+#include "eom-print-preview.h"
+
+/**
+ * SECTION:
+ * @Title: Printing Custom Widget
+ * @Short_Description: a custom widget to setup image prints.
+ * @Stability_Level: Internal
+ * @See_Also: #EomPrintPreview
+ *
+ * This widget is to be used as the custom widget in a #GtkPrintUnixDialog in
+ * EOM. Through it, you can set the position and scaling of a image
+ * interactively.
+ */
+
+#define EOM_PRINT_IMAGE_SETUP_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EOM_TYPE_PRINT_IMAGE_SETUP, EomPrintImageSetupPrivate))
+
+G_DEFINE_TYPE (EomPrintImageSetup, eom_print_image_setup, GTK_TYPE_TABLE);
+
+struct EomPrintImageSetupPrivate {
+ GtkWidget *left;
+ GtkWidget *right;
+ GtkWidget *top;
+ GtkWidget *bottom;
+
+ GtkWidget *center;
+
+ GtkWidget *width;
+ GtkWidget *height;
+
+ GtkWidget *scaling;
+ GtkWidget *unit;
+
+ GtkUnit current_unit;
+
+ EomImage *image;
+ GtkPageSetup *page_setup;
+
+ GtkWidget *preview;
+};
+
+enum {
+ PROP_0,
+ PROP_IMAGE,
+ PROP_PAGE_SETUP
+};
+
+enum {
+ CENTER_NONE,
+ CENTER_HORIZONTAL,
+ CENTER_VERTICAL,
+ CENTER_BOTH
+};
+
+enum {
+ CHANGE_HORIZ,
+ CHANGE_VERT
+};
+
+enum {
+ UNIT_INCH,
+ UNIT_MM
+};
+
+#define FACTOR_INCH_TO_MM 25.4
+#define FACTOR_INCH_TO_PIXEL 72.
+#define FACTOR_MM_TO_INCH 0.03937007874015748
+#define FACTOR_MM_TO_PIXEL 2.834645669
+
+static void eom_print_image_setup_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void eom_print_image_setup_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void on_left_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
+static void on_right_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
+static void on_top_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
+static void on_bottom_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
+
+static void on_width_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
+static void on_height_value_changed (GtkSpinButton *spinbutton, gpointer user_data);
+
+
+static void
+block_handlers (EomPrintImageSetup *setup)
+{
+ EomPrintImageSetupPrivate *priv = setup->priv;
+
+ g_signal_handlers_block_by_func (priv->left, on_left_value_changed, setup);
+ g_signal_handlers_block_by_func (priv->right, on_right_value_changed, setup);
+ g_signal_handlers_block_by_func (priv->width, on_width_value_changed, setup);
+ g_signal_handlers_block_by_func (priv->top, on_top_value_changed, setup);
+ g_signal_handlers_block_by_func (priv->bottom, on_bottom_value_changed, setup);
+ g_signal_handlers_block_by_func (priv->height, on_height_value_changed, setup);
+}
+
+static void
+unblock_handlers (EomPrintImageSetup *setup)
+{
+ EomPrintImageSetupPrivate *priv = setup->priv;
+
+ g_signal_handlers_unblock_by_func (priv->left, on_left_value_changed, setup);
+ g_signal_handlers_unblock_by_func (priv->right, on_right_value_changed, setup);
+ g_signal_handlers_unblock_by_func (priv->width, on_width_value_changed, setup);
+ g_signal_handlers_unblock_by_func (priv->top, on_top_value_changed, setup);
+ g_signal_handlers_unblock_by_func (priv->bottom, on_bottom_value_changed, setup);
+ g_signal_handlers_unblock_by_func (priv->height, on_height_value_changed, setup);
+}
+
+static gdouble
+get_scale_to_px_factor (EomPrintImageSetup *setup)
+{
+ gdouble factor = 0.;
+
+ switch (setup->priv->current_unit) {
+ case GTK_UNIT_MM:
+ factor = FACTOR_MM_TO_PIXEL;
+ break;
+ case GTK_UNIT_INCH:
+ factor = FACTOR_INCH_TO_PIXEL;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ return factor;
+}
+
+static gdouble
+get_max_percentage (EomPrintImageSetup *setup)
+{
+ EomPrintImageSetupPrivate *priv = setup->priv;
+ gdouble p_width, p_height;
+ gdouble width, height;
+ gint pix_width, pix_height;
+ gdouble perc;
+
+ p_width = gtk_page_setup_get_page_width (priv->page_setup, GTK_UNIT_INCH);
+ p_height = gtk_page_setup_get_page_height (priv->page_setup, GTK_UNIT_INCH);
+
+ eom_image_get_size (priv->image, &pix_width, &pix_height);
+
+ width = (gdouble)pix_width/FACTOR_INCH_TO_PIXEL;
+ height = (gdouble)pix_height/FACTOR_INCH_TO_PIXEL;
+
+ if (p_width > width && p_height > height) {
+ perc = 1.;
+ } else {
+ perc = MIN (p_width/width, p_height/height);
+ }
+
+ return perc;
+}
+
+static void
+center (gdouble page_width,
+ gdouble width,
+ GtkSpinButton *s_left,
+ GtkSpinButton *s_right)
+{
+ gdouble left, right;
+
+ left = (page_width - width)/2;
+ right = page_width - left - width;
+ gtk_spin_button_set_value (s_left, left);
+ gtk_spin_button_set_value (s_right, right);
+}
+
+static void
+on_center_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ EomPrintImageSetup *setup;
+ EomPrintImageSetupPrivate *priv;
+ gint active;
+
+ setup = EOM_PRINT_IMAGE_SETUP (user_data);
+ priv = setup->priv;
+
+ active = gtk_combo_box_get_active (combobox);
+
+ switch (active) {
+ case CENTER_HORIZONTAL:
+ center (gtk_page_setup_get_page_width (priv->page_setup,
+ priv->current_unit),
+ gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->width)),
+ GTK_SPIN_BUTTON (priv->left),
+ GTK_SPIN_BUTTON (priv->right));
+ break;
+ case CENTER_VERTICAL:
+ center (gtk_page_setup_get_page_height (priv->page_setup,
+ priv->current_unit),
+ gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->height)),
+ GTK_SPIN_BUTTON (priv->top),
+ GTK_SPIN_BUTTON (priv->bottom));
+ break;
+ case CENTER_BOTH:
+ center (gtk_page_setup_get_page_width (priv->page_setup,
+ priv->current_unit),
+ gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->width)),
+ GTK_SPIN_BUTTON (priv->left),
+ GTK_SPIN_BUTTON (priv->right));
+ center (gtk_page_setup_get_page_height (priv->page_setup,
+ priv->current_unit),
+ gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->height)),
+ GTK_SPIN_BUTTON (priv->top),
+ GTK_SPIN_BUTTON (priv->bottom));
+ break;
+ case CENTER_NONE:
+ default:
+ break;
+ }
+
+ gtk_combo_box_set_active (combobox, active);
+}
+
+static void
+update_image_pos_ranges (EomPrintImageSetup *setup,
+ gdouble page_width,
+ gdouble page_height,
+ gdouble width,
+ gdouble height)
+{
+ EomPrintImageSetupPrivate *priv;
+
+ priv = setup->priv;
+
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->left),
+ 0, page_width - width);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->right),
+ 0, page_width - width);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->top),
+ 0, page_height - height);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->bottom),
+ 0, page_height - height);
+}
+
+static gboolean
+on_scale_changed (GtkRange *range,
+ gpointer user_data)
+{
+ gdouble scale;
+ gdouble width, height;
+ gint pix_width, pix_height;
+ gdouble left, right, top, bottom;
+ gdouble page_width, page_height;
+ EomPrintImageSetupPrivate *priv;
+ EomPrintImageSetup *setup;
+ gdouble factor;
+ EomImage *image;
+
+ setup = EOM_PRINT_IMAGE_SETUP (user_data);
+ priv = setup->priv;
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_NONE);
+
+ image = priv->image;
+ eom_image_get_size (image, &pix_width, &pix_height);
+
+ factor = get_scale_to_px_factor (setup);
+
+ width = (gdouble)pix_width/factor;
+ height = (gdouble)pix_height/factor;
+
+ left = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->left));
+ top = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->top));
+
+ scale = CLAMP (0.01*gtk_range_get_value (range), 0, get_max_percentage (setup));
+
+ eom_print_preview_set_scale (EOM_PRINT_PREVIEW (priv->preview), scale);
+
+ width *= scale;
+ height *= scale;
+
+ page_width = gtk_page_setup_get_page_width (priv->page_setup, priv->current_unit);
+ page_height = gtk_page_setup_get_page_height (priv->page_setup, priv->current_unit);
+
+ update_image_pos_ranges (setup, page_width, page_height, width, height);
+
+ right = page_width - left - width;
+ bottom = page_height - top - height;
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->width), width);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->height), height);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->right), right);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->bottom), bottom);
+
+ return FALSE;
+}
+
+static gchar *
+on_scale_format_value (GtkScale *scale,
+ gdouble value)
+{
+ return g_strdup_printf ("%i%%", (gint)value);
+}
+
+static void
+position_values_changed (EomPrintImageSetup *setup,
+ GtkWidget *w_changed,
+ GtkWidget *w_to_update,
+ GtkWidget *w_size,
+ gdouble total_size,
+ gint change)
+{
+ EomPrintImageSetupPrivate *priv;
+ gdouble changed, to_update, size;
+ gdouble pos;
+
+ priv = setup->priv;
+ size = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_size));
+ changed = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_changed));
+
+ to_update = total_size - changed - size;
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_to_update), to_update);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_NONE);
+
+ switch (change) {
+ case CHANGE_HORIZ:
+ pos = gtk_spin_button_get_value (GTK_SPIN_BUTTON (setup->priv->left));
+ if (setup->priv->current_unit == GTK_UNIT_MM) {
+ pos *= FACTOR_MM_TO_INCH;
+ }
+ eom_print_preview_set_image_position (EOM_PRINT_PREVIEW (priv->preview), pos, -1);
+ break;
+ case CHANGE_VERT:
+ pos = gtk_spin_button_get_value (GTK_SPIN_BUTTON (setup->priv->top));
+ if (setup->priv->current_unit == GTK_UNIT_MM) {
+ pos *= FACTOR_MM_TO_INCH;
+ }
+ eom_print_preview_set_image_position (EOM_PRINT_PREVIEW (priv->preview), -1, pos);
+ break;
+ }
+}
+
+static void
+on_left_value_changed (GtkSpinButton *spinbutton,
+ gpointer user_data)
+{
+ EomPrintImageSetup *setup;
+ EomPrintImageSetupPrivate *priv;
+
+ setup = EOM_PRINT_IMAGE_SETUP (user_data);
+ priv = setup->priv;
+
+ position_values_changed (setup,
+ priv->left, priv->right, priv->width,
+ gtk_page_setup_get_page_width (priv->page_setup,
+ priv->current_unit),
+ CHANGE_HORIZ);
+}
+
+static void
+on_right_value_changed (GtkSpinButton *spinbutton,
+ gpointer user_data)
+{
+ EomPrintImageSetupPrivate *priv;
+
+ priv = EOM_PRINT_IMAGE_SETUP (user_data)->priv;
+
+ position_values_changed (EOM_PRINT_IMAGE_SETUP (user_data),
+ priv->right, priv->left, priv->width,
+ gtk_page_setup_get_page_width (priv->page_setup,
+ priv->current_unit),
+ CHANGE_HORIZ);
+}
+
+static void
+on_top_value_changed (GtkSpinButton *spinbutton,
+ gpointer user_data)
+{
+ EomPrintImageSetupPrivate *priv;
+
+ priv = EOM_PRINT_IMAGE_SETUP (user_data)->priv;
+
+ position_values_changed (EOM_PRINT_IMAGE_SETUP (user_data),
+ priv->top, priv->bottom, priv->height,
+ gtk_page_setup_get_page_height (priv->page_setup,
+ priv->current_unit),
+ CHANGE_VERT);
+}
+
+static void
+on_bottom_value_changed (GtkSpinButton *spinbutton,
+ gpointer user_data)
+{
+ EomPrintImageSetupPrivate *priv;
+
+ priv = EOM_PRINT_IMAGE_SETUP (user_data)->priv;
+
+ position_values_changed (EOM_PRINT_IMAGE_SETUP (user_data),
+ priv->bottom, priv->top, priv->height,
+ gtk_page_setup_get_page_height (priv->page_setup,
+ priv->current_unit),
+ CHANGE_VERT);
+}
+
+static void
+size_changed (EomPrintImageSetup *setup,
+ GtkWidget *w_size_x,
+ GtkWidget *w_size_y,
+ GtkWidget *w_margin_x_1,
+ GtkWidget *w_margin_x_2,
+ GtkWidget *w_margin_y_1,
+ GtkWidget *w_margin_y_2,
+ gdouble page_size_x,
+ gdouble page_size_y,
+ gint change)
+{
+ EomPrintImageSetupPrivate *priv;
+ gdouble margin_x_1, margin_x_2;
+ gdouble margin_y_1, margin_y_2;
+ gdouble orig_size_x = -1, orig_size_y = -1, scale;
+ gdouble size_x, size_y;
+ gint pix_width, pix_height;
+ gdouble factor;
+
+ priv = setup->priv;
+
+ size_x = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_size_x));
+ margin_x_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_margin_x_1));
+ margin_y_1 = gtk_spin_button_get_value (GTK_SPIN_BUTTON (w_margin_y_1));
+
+ eom_image_get_size (priv->image, &pix_width, &pix_height);
+
+ factor = get_scale_to_px_factor (setup);
+
+ switch (change) {
+ case CHANGE_HORIZ:
+ orig_size_x = (gdouble) pix_width / factor;
+ orig_size_y = (gdouble) pix_height / factor;
+ break;
+ case CHANGE_VERT:
+ orig_size_y = (gdouble) pix_width / factor;
+ orig_size_x = (gdouble) pix_height / factor;
+ break;
+ }
+
+ scale = CLAMP (size_x / orig_size_x, 0, 1);
+
+ size_y = scale * orig_size_y;
+
+ margin_x_2 = page_size_x - margin_x_1 - size_x;
+ margin_y_2 = page_size_y - margin_y_1 - size_y;
+
+ eom_print_preview_set_scale (EOM_PRINT_PREVIEW (priv->preview), scale);
+
+ switch (change) {
+ case CHANGE_HORIZ:
+ update_image_pos_ranges (setup, page_size_x, page_size_y, size_x, size_y);
+ break;
+ case CHANGE_VERT:
+ update_image_pos_ranges (setup, page_size_y, page_size_x, size_y, size_x);
+ break;
+ }
+
+ gtk_range_set_value (GTK_RANGE (priv->scaling), 100*scale);
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_margin_x_2), margin_x_2);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_size_y), size_y);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (w_margin_y_2), margin_y_2);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center), CENTER_NONE);
+}
+
+static void
+on_width_value_changed (GtkSpinButton *spinbutton,
+ gpointer user_data)
+{
+ EomPrintImageSetupPrivate *priv = EOM_PRINT_IMAGE_SETUP (user_data)->priv;
+
+ size_changed (EOM_PRINT_IMAGE_SETUP (user_data),
+ priv->width, priv->height,
+ priv->left, priv->right,
+ priv->top, priv->bottom,
+ gtk_page_setup_get_page_width (priv->page_setup,
+ priv->current_unit),
+ gtk_page_setup_get_page_height (priv->page_setup,
+ priv->current_unit),
+ CHANGE_HORIZ);
+}
+
+static void
+on_height_value_changed (GtkSpinButton *spinbutton,
+ gpointer user_data)
+{
+ EomPrintImageSetupPrivate *priv = EOM_PRINT_IMAGE_SETUP (user_data)->priv;
+
+ size_changed (EOM_PRINT_IMAGE_SETUP (user_data),
+ priv->height, priv->width,
+ priv->top, priv->bottom,
+ priv->left, priv->right,
+ gtk_page_setup_get_page_height (priv->page_setup,
+ priv->current_unit),
+ gtk_page_setup_get_page_width (priv->page_setup,
+ priv->current_unit),
+ CHANGE_VERT);
+}
+
+static void
+change_unit (GtkSpinButton *spinbutton,
+ gdouble factor,
+ gint digits,
+ gdouble step,
+ gdouble page)
+{
+ gdouble value;
+ gdouble range;
+
+ gtk_spin_button_get_range (spinbutton, NULL, &range);
+ range *= factor;
+
+ value = gtk_spin_button_get_value (spinbutton);
+ value *= factor;
+
+ gtk_spin_button_set_range (spinbutton, 0, range);
+ gtk_spin_button_set_value (spinbutton, value);
+ gtk_spin_button_set_digits (spinbutton, digits);
+ gtk_spin_button_set_increments (spinbutton, step, page);
+}
+
+static void
+set_scale_unit (EomPrintImageSetup *setup,
+ GtkUnit unit)
+{
+ EomPrintImageSetupPrivate *priv = setup->priv;
+ gdouble factor;
+ gdouble step, page;
+ gint digits;
+
+ if (G_UNLIKELY (priv->current_unit == unit))
+ return;
+
+ switch (unit) {
+ case GTK_UNIT_MM:
+ factor = FACTOR_INCH_TO_MM;
+ digits = 0;
+ step = 1;
+ page = 10;
+ break;
+ case GTK_UNIT_INCH:
+ factor = FACTOR_MM_TO_INCH;
+ digits = 2;
+ step = 0.01;
+ page = 0.1;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ block_handlers (setup);
+
+ change_unit (GTK_SPIN_BUTTON (priv->width), factor, digits, step, page);
+ change_unit (GTK_SPIN_BUTTON (priv->height), factor, digits, step, page);
+ change_unit (GTK_SPIN_BUTTON (priv->left), factor, digits, step, page);
+ change_unit (GTK_SPIN_BUTTON (priv->right), factor, digits, step, page);
+ change_unit (GTK_SPIN_BUTTON (priv->top), factor, digits, step, page);
+ change_unit (GTK_SPIN_BUTTON (priv->bottom), factor, digits, step, page);
+
+ unblock_handlers (setup);
+
+ priv->current_unit = unit;
+}
+
+static void
+on_unit_changed (GtkComboBox *combobox,
+ gpointer user_data)
+{
+ GtkUnit unit = GTK_UNIT_INCH;
+
+ switch (gtk_combo_box_get_active (combobox)) {
+ case UNIT_INCH:
+ unit = GTK_UNIT_INCH;
+ break;
+ case UNIT_MM:
+ unit = GTK_UNIT_MM;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ set_scale_unit (EOM_PRINT_IMAGE_SETUP (user_data), unit);
+}
+
+static void
+on_preview_image_moved (EomPrintPreview *preview,
+ gpointer user_data)
+{
+ EomPrintImageSetupPrivate *priv = EOM_PRINT_IMAGE_SETUP (user_data)->priv;
+ gdouble x, y;
+
+ eom_print_preview_get_image_position (preview, &x, &y);
+
+ if (priv->current_unit == GTK_UNIT_MM) {
+ x *= FACTOR_INCH_TO_MM;
+ y *= FACTOR_INCH_TO_MM;
+ }
+
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->left), x);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->top), y);
+}
+
+/* Function taken from gtkprintunixdialog.c */
+static GtkWidget *
+wrap_in_frame (const gchar *label,
+ GtkWidget *child)
+{
+ GtkWidget *frame, *alignment, *label_widget;
+ gchar *bold_text;
+
+ label_widget = gtk_label_new ("");
+ gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
+ gtk_widget_show (label_widget);
+
+ bold_text = g_markup_printf_escaped ("<b>%s</b>", label);
+ gtk_label_set_markup (GTK_LABEL (label_widget), bold_text);
+ g_free (bold_text);
+
+ frame = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (frame), label_widget, FALSE, FALSE, 0);
+
+ alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0);
+ gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
+ 0, 0, 12, 0);
+ gtk_box_pack_start (GTK_BOX (frame), alignment, FALSE, FALSE, 0);
+
+ gtk_container_add (GTK_CONTAINER (alignment), child);
+
+ gtk_widget_show (frame);
+ gtk_widget_show (alignment);
+
+ return frame;
+}
+
+static GtkWidget *
+table_attach_spin_button_with_label (GtkWidget *table,
+ const gchar* text_label,
+ gint left, gint top)
+{
+ GtkWidget *label, *spin_button;
+
+ label = gtk_label_new_with_mnemonic (text_label);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ spin_button = gtk_spin_button_new_with_range (0, 100, 0.01);
+ gtk_spin_button_set_digits (GTK_SPIN_BUTTON (spin_button), 2);
+ gtk_entry_set_width_chars (GTK_ENTRY (spin_button), 6);
+ gtk_table_attach (GTK_TABLE (table), label, left, left + 1,
+ top, top + 1, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), spin_button, left + 1, left + 2,
+ top, top + 1, GTK_FILL, GTK_FILL, 0, 0);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), spin_button);
+
+ return spin_button;
+}
+
+static void
+eom_print_image_setup_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EomPrintImageSetup *setup = EOM_PRINT_IMAGE_SETUP (object);
+ EomPrintImageSetupPrivate *priv = setup->priv;
+ GdkPixbuf *pixbuf;
+
+ switch (prop_id) {
+ case PROP_IMAGE:
+ if (priv->image) {
+ g_object_unref (priv->image);
+ }
+ priv->image = EOM_IMAGE (g_value_dup_object (value));
+ if (EOM_IS_IMAGE (priv->image)) {
+ pixbuf = eom_image_get_pixbuf (priv->image);
+ g_object_set (priv->preview, "image",
+ pixbuf, NULL);
+ g_object_unref (pixbuf);
+ }
+ break;
+ case PROP_PAGE_SETUP:
+ priv->page_setup = g_value_get_object (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+eom_print_image_setup_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EomPrintImageSetup *setup = EOM_PRINT_IMAGE_SETUP (object);
+ EomPrintImageSetupPrivate *priv = setup->priv;
+
+ switch (prop_id) {
+ case PROP_IMAGE:
+ g_value_set_object (value, priv->image);
+ break;
+ case PROP_PAGE_SETUP:
+ g_value_set_object (value, priv->page_setup);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+set_initial_values (EomPrintImageSetup *setup)
+{
+ EomPrintImageSetupPrivate *priv;
+ GtkPageSetup *page_setup;
+ EomImage *image;
+ gdouble page_width, page_height;
+ gint pix_width, pix_height;
+ gdouble factor;
+ gdouble width, height;
+ gdouble max_perc;
+
+ priv = setup->priv;
+ page_setup = priv->page_setup;
+ image = priv->image;
+
+ factor = get_scale_to_px_factor (setup);
+
+ eom_image_get_size (image, &pix_width, &pix_height);
+ width = (gdouble)pix_width/factor;
+ height = (gdouble)pix_height/factor;
+
+ max_perc = get_max_percentage (setup);
+
+ width *= max_perc;
+ height *= max_perc;
+
+ gtk_range_set_range (GTK_RANGE (priv->scaling), 1, 100*max_perc);
+ gtk_range_set_increments (GTK_RANGE (priv->scaling), max_perc, 10*max_perc);
+ gtk_range_set_value (GTK_RANGE (priv->scaling), 100*max_perc);
+
+ eom_print_preview_set_scale (EOM_PRINT_PREVIEW (priv->preview), max_perc);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->width), 0, width);
+ gtk_spin_button_set_range (GTK_SPIN_BUTTON (priv->height), 0, height);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->width), width);
+ gtk_spin_button_set_value (GTK_SPIN_BUTTON (priv->height), height);
+
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->center),
+ CENTER_BOTH);
+
+ center (gtk_page_setup_get_page_width (priv->page_setup, priv->current_unit),
+ gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->width)),
+ GTK_SPIN_BUTTON (priv->left), GTK_SPIN_BUTTON (priv->right));
+ center (gtk_page_setup_get_page_height (priv->page_setup, priv->current_unit),
+ gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->height)),
+ GTK_SPIN_BUTTON (priv->top), GTK_SPIN_BUTTON (priv->bottom));
+
+ page_width = gtk_page_setup_get_page_width (page_setup, priv->current_unit);
+ page_height = gtk_page_setup_get_page_height (page_setup, priv->current_unit);
+
+ update_image_pos_ranges (setup, page_width, page_height, width, height);
+
+
+}
+
+static void
+connect_signals (EomPrintImageSetup *setup)
+{
+ EomPrintImageSetupPrivate *priv;
+
+ priv = setup->priv;
+
+ g_signal_connect (G_OBJECT (priv->left), "value-changed",
+ G_CALLBACK (on_left_value_changed), setup);
+ g_signal_connect (G_OBJECT (priv->right), "value-changed",
+ G_CALLBACK (on_right_value_changed), setup);
+ g_signal_connect (G_OBJECT (priv->top), "value-changed",
+ G_CALLBACK (on_top_value_changed), setup);
+ g_signal_connect (G_OBJECT (priv->bottom), "value-changed",
+ G_CALLBACK (on_bottom_value_changed), setup);
+ g_signal_connect (G_OBJECT (priv->width), "value-changed",
+ G_CALLBACK (on_width_value_changed), setup);
+ g_signal_connect (G_OBJECT (priv->height), "value-changed",
+ G_CALLBACK (on_height_value_changed), setup);
+ g_signal_connect (G_OBJECT (priv->scaling), "value-changed",
+ G_CALLBACK (on_scale_changed), setup);
+ g_signal_connect (G_OBJECT (priv->scaling), "format-value",
+ G_CALLBACK (on_scale_format_value), NULL);
+ g_signal_connect (G_OBJECT (priv->preview), "image-moved",
+ G_CALLBACK (on_preview_image_moved), setup);
+}
+
+static void
+eom_print_image_setup_class_init (EomPrintImageSetupClass *class)
+{
+ GObjectClass *object_class = (GObjectClass *)class;
+
+ object_class->set_property = eom_print_image_setup_set_property;
+ object_class->get_property = eom_print_image_setup_get_property;
+
+ g_object_class_install_property (object_class, PROP_IMAGE,
+ g_param_spec_object ("image",
+ _("Image"),
+ _("The image whose printing properties will be set up"),
+ EOM_TYPE_IMAGE,
+ G_PARAM_READWRITE));
+
+ g_object_class_install_property (object_class, PROP_PAGE_SETUP,
+ g_param_spec_object ("page-setup",
+ _("Page Setup"),
+ _("The information for the page where the image will be printed"),
+ GTK_TYPE_PAGE_SETUP,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (class, sizeof (EomPrintImageSetupPrivate));
+}
+
+static void
+eom_print_image_setup_init (EomPrintImageSetup *setup)
+{
+ GtkWidget *frame;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *hscale;
+ GtkWidget *combobox;
+ EomPrintImageSetupPrivate *priv;
+
+#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT
+ gchar *locale_scale = NULL;
+#endif
+
+ priv = setup->priv = EOM_PRINT_IMAGE_SETUP_GET_PRIVATE (setup);
+
+ priv->image = NULL;
+
+ table = gtk_table_new (3, 4, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+ frame = wrap_in_frame (_("Position"), table);
+ gtk_table_attach (GTK_TABLE (setup), frame,
+ 0, 1, 0, 1, GTK_FILL, 0,
+ 0, 0);
+
+ priv->left = table_attach_spin_button_with_label (table, _("_Left:"), 0, 0);
+ priv->right = table_attach_spin_button_with_label (table, _("_Right:"), 0, 1);
+ priv->top = table_attach_spin_button_with_label (table, _("_Top:"), 2, 0);
+ priv->bottom = table_attach_spin_button_with_label (table, _("_Bottom:"), 2, 1);
+
+ label = gtk_label_new_with_mnemonic (_("C_enter:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ combobox = gtk_combo_box_new_text ();
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (combobox),
+ CENTER_NONE, _("None"));
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (combobox),
+ CENTER_HORIZONTAL, _("Horizontal"));
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (combobox),
+ CENTER_VERTICAL, _("Vertical"));
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (combobox),
+ CENTER_BOTH, _("Both"));
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), CENTER_NONE);
+ gtk_table_attach (GTK_TABLE (table), label,
+ 0, 1, 2, 3, GTK_FILL, GTK_FILL,
+ 0, 0);
+ gtk_table_attach (GTK_TABLE (table), combobox,
+ 1, 4, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL,
+ 0, 0);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), combobox);
+ priv->center = combobox;
+ g_signal_connect (G_OBJECT (combobox), "changed",
+ G_CALLBACK (on_center_changed), setup);
+
+ table = gtk_table_new (3, 4, FALSE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+ frame = wrap_in_frame (_("Size"), table);
+ gtk_table_attach (GTK_TABLE (setup), frame,
+ 0, 1, 1, 2, GTK_FILL, 0,
+ 0, 0);
+
+ priv->width = table_attach_spin_button_with_label (table, _("_Width:"),
+ 0, 0);
+ priv->height = table_attach_spin_button_with_label (table, _("_Height:"),
+ 2, 0);
+
+ label = gtk_label_new_with_mnemonic (_("_Scaling:"));
+ hscale = gtk_hscale_new_with_range (1, 100, 1);
+ gtk_scale_set_value_pos (GTK_SCALE (hscale), GTK_POS_RIGHT);
+ gtk_range_set_value (GTK_RANGE (hscale), 100);
+ gtk_table_attach (GTK_TABLE (table), label,
+ 0, 1, 1, 2, GTK_FILL, GTK_FILL,
+ 0, 0);
+ gtk_table_attach (GTK_TABLE (table), hscale,
+ 1, 4, 1, 2, GTK_FILL | GTK_EXPAND, GTK_FILL,
+ 0, 0);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), hscale);
+ priv->scaling = hscale;
+
+ label = gtk_label_new_with_mnemonic (_("_Unit:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+
+ combobox = gtk_combo_box_new_text ();
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (combobox), UNIT_MM,
+ _("Millimeters"));
+ gtk_combo_box_insert_text (GTK_COMBO_BOX (combobox), UNIT_INCH,
+ _("Inches"));
+
+#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT
+ locale_scale = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT);
+ if (locale_scale && locale_scale[0] == 2) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), UNIT_INCH);
+ set_scale_unit (setup, GTK_UNIT_INCH);
+ } else
+#endif
+ {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), UNIT_MM);
+ set_scale_unit (setup, GTK_UNIT_MM);
+ }
+
+ gtk_table_attach (GTK_TABLE (table), label,
+ 0, 1, 2, 3, GTK_FILL, GTK_FILL,
+ 0, 0);
+ gtk_table_attach (GTK_TABLE (table), combobox,
+ 1, 4, 2, 3, GTK_FILL | GTK_EXPAND, GTK_FILL,
+ 0, 0);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), combobox);
+ priv->unit = combobox;
+ g_signal_connect (G_OBJECT (combobox), "changed",
+ G_CALLBACK (on_unit_changed), setup);
+
+ priv->preview = eom_print_preview_new ();
+
+ /* FIXME: This shouldn't be set by hand */
+ gtk_widget_set_size_request (priv->preview, 250, 250);
+
+ frame = wrap_in_frame (_("Preview"), priv->preview);
+ gtk_table_attach (GTK_TABLE (setup), frame,
+ 1, 2, 0, 2, GTK_FILL, GTK_FILL,
+ 0, 0);
+
+ gtk_widget_show_all (GTK_WIDGET (setup));
+}
+
+
+/**
+ * eom_print_image_setup_new:
+ * @image: the #EomImage to print
+ * @page_setup: a #GtkPageSetup specifying the page where
+ * the image will be print
+ *
+ * Creates a new #EomPrintImageSetup widget, to be used as a custom
+ * widget in a #GtkPrintUnixDialog. This widgets allows to set
+ * the image position and scale in a page.
+ *
+ * Returns: a new #EomPrintImageSetup
+ **/
+GtkWidget *
+eom_print_image_setup_new (EomImage *image, GtkPageSetup *page_setup)
+{
+ GtkWidget *setup;
+ GtkWidget *preview;
+
+ setup = g_object_new (EOM_TYPE_PRINT_IMAGE_SETUP,
+ "n-rows", 2,
+ "n-columns", 2,
+ "homogeneous", FALSE,
+ "row-spacing", 18,
+ "column-spacing", 18,
+ "border-width", 12,
+ "image", image,
+ "page-setup", page_setup,
+ NULL);
+
+ set_initial_values (EOM_PRINT_IMAGE_SETUP (setup));
+
+ preview = EOM_PRINT_IMAGE_SETUP (setup)->priv->preview;
+ eom_print_preview_set_from_page_setup (EOM_PRINT_PREVIEW (preview),
+ page_setup);
+
+ connect_signals (EOM_PRINT_IMAGE_SETUP (setup));
+
+ return setup;
+}
+
+/**
+ * eom_print_image_setup_get_options:
+ * @setup: a #EomPrintImageSetup
+ * @left: a pointer where to store the image's left position
+ * @top: a pointer where to store the image's top position
+ * @scale: a pointer where to store the image's scale
+ * @unit: a pointer where to store the #GtkUnit used by the @left and @top values.
+ *
+ * Gets the options set by the #EomPrintImageSetup.
+ **/
+void
+eom_print_image_setup_get_options (EomPrintImageSetup *setup,
+ gdouble *left,
+ gdouble *top,
+ gdouble *scale,
+ GtkUnit *unit)
+{
+ EomPrintImageSetupPrivate *priv;
+
+ g_return_if_fail (EOM_IS_PRINT_IMAGE_SETUP (setup));
+
+ priv = setup->priv;
+
+ *left = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->left));
+ *top = gtk_spin_button_get_value (GTK_SPIN_BUTTON (priv->top));
+ *scale = gtk_range_get_value (GTK_RANGE (priv->scaling));
+ *unit = priv->current_unit;
+}
+
+void
+eom_print_image_setup_update (GtkPrintOperation *operation,
+ GtkWidget *custom_widget,
+ GtkPageSetup *page_setup,
+ GtkPrintSettings *print_settings,
+ gpointer user_data)
+{
+ GtkWidget *preview;
+ gdouble pos_x;
+ gdouble pos_y;
+ EomPrintImageSetup *setup;
+
+ setup = EOM_PRINT_IMAGE_SETUP (custom_widget);
+
+ setup->priv->page_setup = gtk_page_setup_copy (page_setup);
+
+ set_initial_values (EOM_PRINT_IMAGE_SETUP (setup));
+
+ preview = EOM_PRINT_IMAGE_SETUP (setup)->priv->preview;
+ eom_print_preview_set_from_page_setup (EOM_PRINT_PREVIEW (preview),
+ setup->priv->page_setup);
+
+ pos_x = gtk_spin_button_get_value (GTK_SPIN_BUTTON (setup->priv->left));
+ pos_y = gtk_spin_button_get_value (GTK_SPIN_BUTTON (setup->priv->top));
+ if (setup->priv->current_unit == GTK_UNIT_MM) {
+ pos_x *= FACTOR_MM_TO_INCH;
+ pos_y *= FACTOR_MM_TO_INCH;
+ }
+ eom_print_preview_set_image_position (EOM_PRINT_PREVIEW (setup->priv->preview), pos_x, pos_y);
+}