summaryrefslogtreecommitdiff
path: root/src/gutenprintui2/panel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/gutenprintui2/panel.c')
-rw-r--r--src/gutenprintui2/panel.c4962
1 files changed, 4962 insertions, 0 deletions
diff --git a/src/gutenprintui2/panel.c b/src/gutenprintui2/panel.c
new file mode 100644
index 0000000..c8a2ab9
--- /dev/null
+++ b/src/gutenprintui2/panel.c
@@ -0,0 +1,4962 @@
+/*
+ * "$Id: panel.c,v 1.4 2005/06/30 01:42:56 rlk Exp $"
+ *
+ * Main window code for Print plug-in for the GIMP.
+ *
+ * Copyright 1997-2003 Michael Sweet (mike@easysw.com),
+ * Robert Krawitz (rlk@alum.mit.edu), Steve Miller (smiller@rni.net)
+ * and Michael Natterer (mitch@gimp.org)
+ *
+ * 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
+
+#define MAX_PREVIEW_PPI (400)
+#define INCH 72
+#define FINCH ((gdouble) INCH)
+#define ROUNDUP(x, y) (((x) + ((y) - 1)) / (y))
+#define SCALE(x, y) (((x) + (1.0 / (2.0 * (y)))) * (y))
+
+#include <gutenprint/gutenprint-intl-internal.h>
+#include <gutenprintui2/gutenprintui.h>
+#include "gutenprintui-internal.h"
+
+#include <string.h>
+#include <stdio.h>
+
+#define MAXIMUM_PARAMETER_LEVEL STP_PARAMETER_LEVEL_ADVANCED4
+
+/*
+ * Constants for GUI.
+ */
+static int preview_size_vert = 360;
+static int preview_size_horiz = 300;
+static const int minimum_image_percent = 5.0;
+static const int thumbnail_hintw = 128;
+static const int thumbnail_hinth = 128;
+
+#define MOVE_CONSTRAIN 0
+#define MOVE_HORIZONTAL 1
+#define MOVE_VERTICAL 2
+#define MOVE_ANY (MOVE_HORIZONTAL | MOVE_VERTICAL)
+#define MOVE_GRID 4
+
+/*
+ * Main window widgets
+ */
+
+static GtkWidget *main_vbox;
+static GtkWidget *main_hbox;
+static GtkWidget *right_vbox;
+static GtkWidget *notebook;
+
+static GtkWidget *output_color_vbox;
+static GtkWidget *cyan_button;
+static GtkWidget *magenta_button;
+static GtkWidget *yellow_button;
+static GtkWidget *black_button;
+
+static GtkWidget *print_dialog; /* Print dialog window */
+
+static GtkWidget *recenter_button;
+static GtkWidget *recenter_vertical_button;
+static GtkWidget *recenter_horizontal_button;
+
+static GtkWidget *left_entry;
+/*
+static GtkWidget *right_entry;
+*/
+static GtkWidget *right_border_entry;
+static GtkWidget *top_entry;
+/*
+static GtkWidget *bottom_entry;
+*/
+static GtkWidget *bottom_border_entry;
+static GtkWidget *width_entry;
+static GtkWidget *height_entry;
+static GtkWidget *units_hbox;
+static GtkWidget *units_label;
+
+static GtkWidget *custom_size_width;
+static GtkWidget *custom_size_height;
+static GtkWidget *show_all_paper_sizes_button;
+static GtkWidget *auto_paper_size_button;
+
+static GtkWidget *orientation_menu; /* Orientation menu */
+
+static GtkWidget *scaling_percent; /* Scale by percent */
+static GtkWidget *scaling_ppi; /* Scale by pixels-per-inch */
+static GtkWidget *scaling_image; /* Scale to the image */
+static GtkObject *scaling_adjustment; /* Adjustment object for scaling */
+
+static GtkWidget *setup_dialog; /* Setup dialog window */
+static GtkWidget *printer_driver; /* Printer driver widget */
+static GtkWidget *printer_model_label; /* Printer model name */
+static GtkWidget *printer_crawler; /* Scrolled Window for menu */
+static GtkWidget *printer_combo; /* Combo for menu */
+static GtkWidget *manufacturer_clist; /* Manufacturer widget */
+static GtkWidget *manufacturer_crawler; /* Scrolled Window for menu */
+static gint plist_callback_id = -1;
+static GtkWidget *ppd_file; /* PPD file entry */
+static GtkWidget *ppd_box;
+static GtkWidget *ppd_label; /* PPD file entry */
+static GtkWidget *ppd_button; /* PPD file browse button */
+static GtkWidget *ppd_browser; /* File selection dialog for PPDs */
+static GtkWidget *new_printer_dialog; /* New printer dialog window */
+static GtkWidget *new_printer_entry; /* New printer text entry */
+static GtkWidget *file_button; /* PPD file browse button */
+static GtkWidget *file_entry; /* FSD for print files */
+static GtkWidget *file_browser; /* FSD for print files */
+static GtkWidget *standard_cmd_entry; /* FSD for print files */
+static GtkWidget *custom_command_entry; /* FSD for print files */
+static GtkWidget *queue_combo; /* FSD for print files */
+static gint queue_callback_id = -1;
+
+static GtkWidget *adjust_color_button;
+static GtkWidget *about_dialog;
+
+static GtkWidget *page_size_table;
+static GtkWidget *printer_features_table;
+static GtkWidget *color_adjustment_table;
+
+static GtkWidget *copy_count_spin_button;
+
+static gboolean preview_valid = FALSE;
+static gboolean frame_valid = FALSE;
+static gboolean need_exposure = FALSE;
+static gboolean suppress_scaling_adjustment = FALSE;
+static gboolean suppress_scaling_callback = FALSE;
+static gboolean thumbnail_update_pending = FALSE;
+/*
+ * These are semaphores, not true booleans.
+ */
+static gint suppress_preview_update = 0;
+static gint suppress_preview_reset = 0;
+
+static GtkDrawingArea *preview = NULL; /* Preview drawing area widget */
+static GtkDrawingArea *swatch = NULL;
+static gint mouse_x, mouse_y; /* Last mouse position */
+static gint orig_top, orig_left; /* Original mouse position at start */
+static gint buttons_pressed = 0;
+static gint preview_active = 0;
+static gint buttons_mask = 0;
+static gint move_constraint = 0;
+static gint mouse_button = -1; /* Button being dragged with */
+static gint preview_thumbnail_w, preview_thumbnail_h;
+static gint preview_x, preview_y, preview_w, preview_h;
+
+static gint physical_orientation = -2; /* Actual orientation */
+
+static gint paper_width, paper_height; /* Physical width */
+static gint printable_width, printable_height; /* Size of printable area */
+static gint print_width, print_height; /* Printed area of image */
+static gint left, right, top, bottom; /* Imageable region */
+static gint image_width, image_height; /* Image size (possibly rotated) */
+static gint image_true_width, image_true_height; /* Original image */
+static gdouble image_xres, image_yres; /* Original image resolution */
+static gint do_update_thumbnail = 0;
+static gint saveme = 0; /* True if printrc should be saved */
+static gint runme = 0; /* True if print should proceed */
+static gint exit_after_file_ok = 0; /* True if we should exit after file browser complete */
+static gint auto_paper_size = 0; /* True if we're using auto paper size now */
+
+
+
+static void scaling_update (GtkAdjustment *adjustment);
+static void scaling_callback (GtkWidget *widget);
+static void plist_callback (GtkWidget *widget, gpointer data);
+static void queue_callback (GtkWidget *widget, gpointer data);
+static void custom_media_size_callback(GtkWidget *widget, gpointer data);
+static void show_all_paper_sizes_callback(GtkWidget *widget, gpointer data);
+static void auto_paper_size_callback(GtkWidget *widget, gpointer data);
+static void combo_callback (GtkWidget *widget, gpointer data);
+static void output_type_callback (GtkWidget *widget, gpointer data);
+static void unit_callback (GtkWidget *widget, gpointer data);
+static void orientation_callback (GtkWidget *widget, gpointer data);
+static void printandsave_callback (void);
+static void about_callback (void);
+static void print_callback (void);
+static void save_callback (void);
+static void setup_callback (GtkWidget *widget);
+
+static void setup_update (void);
+static void setup_open_callback (void);
+static void setup_ok_callback (void);
+static void setup_cancel_callback (void);
+static void new_printer_open_callback (void);
+static void new_printer_ok_callback (void);
+static void ppd_browse_callback (void);
+static void ppd_ok_callback (void);
+static void file_browse_callback (void);
+static void file_ok_callback (void);
+static void file_cancel_callback (void);
+static void build_printer_driver_clist(void);
+static void print_driver_callback (GtkWidget *widget,
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data);
+static void manufacturer_callback (GtkWidget *widget,
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data);
+static void command_type_callback (GtkWidget *widget, gpointer data);
+
+static void do_preview_thumbnail (void);
+static void invalidate_preview_thumbnail (void);
+static void invalidate_frame (void);
+
+static GtkWidget *color_adjust_dialog;
+
+static void preview_update (void);
+static void preview_expose (void);
+static void preview_button_callback (GtkWidget *widget,
+ GdkEventButton *bevent,
+ gpointer data);
+static void preview_motion_callback (GtkWidget *widget,
+ GdkEventMotion *mevent,
+ gpointer data);
+static void position_callback (GtkWidget *widget);
+static void position_button_callback (GtkWidget *widget,
+ gpointer data);
+static void copy_count_callback (GtkAdjustment *widget,
+ gpointer data);
+static void plist_build_combo(GtkWidget *combo,
+ GtkWidget *label,
+ stp_string_list_t *items,
+ int active,
+ const gchar *cur_item,
+ const gchar *def_value,
+ GCallback callback,
+ gint *callback_id,
+ int (*check_func)(const char *string),
+ gpointer data);
+static void initialize_thumbnail(void);
+static void set_color_defaults (void);
+static void redraw_color_swatch (void);
+static void color_update (GtkAdjustment *adjustment);
+static void dimension_update (GtkAdjustment *adjustment);
+static void set_controls_active (GtkObject *checkbutton, gpointer optno);
+static void update_adjusted_thumbnail (void);
+
+static void set_media_size(const gchar *new_media_size);
+static const stp_printer_t *tmp_printer = NULL;
+
+static option_t *current_options = NULL;
+static int current_option_count = 0;
+
+static unit_t units[] =
+ {
+ { N_("Inch"), N_("Set the base unit of measurement to inches"),
+ 72.0, NULL, "%.2f" },
+ { N_("cm"), N_("Set the base unit of measurement to centimetres"),
+ 72.0 / 2.54, NULL, "%.2f" },
+ { N_("Points"), N_("Set the base unit of measurement to points (1/72\")"),
+ 1.0, NULL, "%.0f" },
+ { N_("mm"), N_("Set the base unit of measurement to millimetres"),
+ 72.0 / 25.4, NULL, "%.1f" },
+ { N_("Pica"), N_("Set the base unit of measurement to picas (1/12\")"),
+ 72.0 / 12.0, NULL, "%.1f" },
+ };
+static const gint unit_count = sizeof(units) / sizeof(unit_t);
+
+static radio_group_t output_types[] =
+ {
+ { N_("Color"), N_("Color output"), "Color", NULL },
+ { N_("Grayscale"),
+ N_("Print in shades of gray using black ink"), "BW", NULL }
+ };
+
+static const gint output_type_count = (sizeof(output_types) /
+ sizeof(radio_group_t));
+
+/*
+ * The order of these entries must match the order in command_t in
+ * gutenprintui.h
+ */
+static radio_group_t command_options[] =
+ {
+ { N_("Standard Command"), N_("Use standard print command"), "Standard", NULL },
+ { N_("Custom Command"), N_("Use custom print command"), "Custom", NULL },
+ { N_("File"), N_("Print to a file"), "File", NULL }
+ };
+
+static const gint command_options_count = (sizeof(command_options) /
+ sizeof(radio_group_t));
+
+static gdouble preview_ppi = 10;
+
+static stp_string_list_t *printer_list = 0;
+static stpui_plist_t *pv;
+static const char *manufacturer = 0;
+
+static gint thumbnail_w, thumbnail_h, thumbnail_bpp;
+static guchar *thumbnail_data;
+static guchar *adjusted_thumbnail_data;
+static guchar *preview_thumbnail_data;
+
+static void
+set_stpui_curve_values(GtkWidget *gcurve, const stp_curve_t *seed)
+{
+ if (stp_curve_get_gamma(seed))
+ {
+ stpui_curve_set_gamma(STPUI_CURVE(gcurve), stp_curve_get_gamma(seed));
+ }
+ else
+ {
+ stp_curve_t *copy = stp_curve_create_copy(seed);
+ const float *fdata;
+ size_t count;
+ stp_curve_resample(copy, 256);
+ fdata = stp_curve_get_float_data(copy, &count);
+ stpui_curve_set_vector(STPUI_CURVE(gcurve), count, fdata);
+ stp_curve_destroy(copy);
+ }
+}
+
+static void
+set_stp_curve_values(GtkWidget *widget, option_t *opt)
+{
+ int i;
+ double lo, hi;
+ gfloat vector[256];
+ GtkWidget *gcurve = GTK_WIDGET(widget);
+ stp_curve_t *curve = stp_curve_create_copy(opt->info.curve.deflt);
+ stpui_curve_get_vector(STPUI_CURVE(gcurve), 256, vector);
+ stp_curve_get_bounds(opt->info.curve.deflt, &lo, &hi);
+ for (i = 0; i < 256; i++)
+ {
+ if (vector[i] > hi)
+ vector[i] = hi;
+ else if (vector[i] < lo)
+ vector[i] = lo;
+ }
+ switch (STPUI_CURVE(gcurve)->curve_type)
+ {
+ case STPUI_CURVE_TYPE_SPLINE:
+ stp_curve_set_interpolation_type(curve, STP_CURVE_TYPE_SPLINE);
+ break;
+ default:
+ stp_curve_set_interpolation_type(curve, STP_CURVE_TYPE_LINEAR);
+ break;
+ }
+ stp_curve_set_float_data(curve, 256, vector);
+ stp_set_curve_parameter(pv->v, opt->fast_desc->name, curve);
+ stp_curve_destroy(curve);
+}
+
+static int
+open_curve_editor(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ if (opt->info.curve.is_visible == FALSE)
+ {
+ GtkWidget *gcurve =
+ GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve);
+ const stp_curve_t *seed =
+ stp_get_curve_parameter(pv->v, opt->fast_desc->name);
+ stp_curve_t *nseed = NULL;
+ if (!seed)
+ seed = opt->info.curve.deflt;
+ if (seed)
+ nseed = stp_curve_create_copy(seed);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), FALSE);
+ gtk_widget_show(GTK_WIDGET(opt->info.curve.dialog));
+ set_stpui_curve_values(gcurve, seed);
+ opt->info.curve.is_visible = TRUE;
+ if (opt->info.curve.current)
+ stp_curve_destroy(opt->info.curve.current);
+ opt->info.curve.current = nseed;
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ }
+/* gtk_window_activate_focus(GTK_WINDOW(opt->info.curve.dialog)); */
+ return 1;
+}
+
+static int
+set_default_curve_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ GtkWidget *gcurve =
+ GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve);
+ const stp_curve_t *seed = opt->info.curve.deflt;
+ set_stpui_curve_values(gcurve, seed);
+ set_stp_curve_values(gcurve, opt);
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ return 1;
+}
+
+static int
+set_previous_curve_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ GtkWidget *gcurve =
+ GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve);
+ const stp_curve_t *seed = opt->info.curve.current;
+ if (!seed)
+ seed = opt->info.curve.deflt;
+ set_stpui_curve_values(gcurve, seed);
+ set_stp_curve_values(gcurve, opt);
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ return 1;
+}
+
+static int
+set_curve_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ GtkWidget *gcurve =
+ GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve);
+ gtk_widget_hide(opt->info.curve.dialog);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), TRUE);
+ opt->info.curve.is_visible = FALSE;
+ set_stp_curve_values(gcurve, opt);
+ if (opt->info.curve.current)
+ stp_curve_destroy(opt->info.curve.current);
+ opt->info.curve.current = NULL;
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ return 1;
+}
+
+static gint
+curve_draw_callback(GtkWidget *widget, GdkEvent *event, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ switch (event->type)
+ {
+ case GDK_BUTTON_RELEASE:
+ set_stp_curve_values(widget, opt);
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ break;
+ default:
+ break;
+ }
+ return 1;
+}
+
+static gint
+curve_type_changed(GtkWidget *widget, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ set_stp_curve_values(widget, opt);
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ return 1;
+}
+
+static int
+cancel_curve_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ if (opt->info.curve.is_visible)
+ {
+ stp_set_curve_parameter(pv->v, opt->fast_desc->name,
+ opt->info.curve.current);
+ stp_curve_destroy(opt->info.curve.current);
+ opt->info.curve.current = NULL;
+ gtk_widget_hide(opt->info.curve.dialog);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), TRUE);
+ opt->info.curve.is_visible = FALSE;
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+ }
+ return 1;
+}
+
+static void
+stpui_create_curve(option_t *opt,
+ GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *text,
+ const stp_curve_t *deflt,
+ gboolean is_optional)
+{
+ double lower, upper;
+ opt->checkbox = gtk_check_button_new();
+ gtk_table_attach(GTK_TABLE(table), opt->checkbox,
+ column, column + 1, row, row + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ if (is_optional)
+ gtk_widget_show(opt->checkbox);
+ else
+ gtk_widget_hide(opt->checkbox);
+
+ opt->info.curve.label = gtk_label_new(text);
+ gtk_misc_set_alignment (GTK_MISC (opt->info.curve.label), 0.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), opt->info.curve.label,
+ column + 1, column + 2, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (opt->info.curve.label);
+
+ opt->info.curve.button = gtk_button_new_with_label(_("Edit Curve..."));
+ g_signal_connect(G_OBJECT(opt->info.curve.button), "clicked",
+ G_CALLBACK(open_curve_editor), opt);
+ gtk_table_attach (GTK_TABLE (table), opt->info.curve.button,
+ column + 2, column + 3, row, row + 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show(opt->info.curve.button);
+
+ opt->info.curve.dialog =
+ stpui_dialog_new(_(opt->fast_desc->text),
+ GTK_WIN_POS_MOUSE, TRUE,
+ _("Set Default"), set_default_curve_callback,
+ opt, NULL, NULL, FALSE, FALSE,
+ _("Restore Previous"), set_previous_curve_callback,
+ opt, NULL, NULL, FALSE, FALSE,
+ _("OK"), set_curve_callback,
+ opt, NULL, NULL, FALSE, FALSE,
+ _("Cancel"), cancel_curve_callback,
+ opt, NULL, NULL, FALSE, FALSE,
+ NULL);
+ opt->info.curve.gamma_curve = stpui_gamma_curve_new();
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(opt->info.curve.dialog)->vbox),
+ opt->info.curve.gamma_curve, TRUE, TRUE, 0);
+ stp_curve_get_bounds(opt->info.curve.deflt, &lower, &upper);
+ stpui_curve_set_range
+ (STPUI_CURVE (STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve),
+ 0.0, 1.0, lower, upper);
+ gtk_widget_set_usize
+ (GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve), 256, 256);
+ gtk_widget_show(opt->info.curve.gamma_curve);
+
+ g_signal_connect
+ (G_OBJECT(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve),
+ "curve-type-changed", G_CALLBACK(curve_type_changed), opt);
+ g_signal_connect
+ (G_OBJECT(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve),
+ "event", G_CALLBACK(curve_draw_callback), opt);
+
+ if (opt->fast_desc->help)
+ {
+ stpui_set_help_data (opt->info.curve.label, opt->fast_desc->help);
+ stpui_set_help_data (opt->info.curve.button, opt->fast_desc->help);
+ stpui_set_help_data (opt->info.curve.gamma_curve, opt->fast_desc->help);
+ }
+}
+
+static int
+checkbox_callback(GtkObject *button, gpointer xopt)
+{
+ option_t *opt = (option_t *)xopt;
+ GtkWidget *checkbox = GTK_WIDGET(opt->info.bool.checkbox);
+ opt->info.bool.current =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox));
+ stp_set_boolean_parameter(pv->v, opt->fast_desc->name,
+ opt->info.bool.current);
+ invalidate_frame();
+ invalidate_preview_thumbnail();
+ if (opt->fast_desc->p_class == STP_PARAMETER_CLASS_OUTPUT)
+ update_adjusted_thumbnail();
+ preview_update();
+ return 1;
+}
+
+static int
+print_mode_is_color(const stp_vars_t *v)
+{
+ const char *printing_mode = stp_get_string_parameter(v, "PrintingMode");
+ if (!printing_mode)
+ {
+ int answer = 1;
+ stp_parameter_t desc;
+ stp_describe_parameter(v, "PrintingMode", &desc);
+ if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST &&
+ strcmp(desc.deflt.str, "BW") == 0)
+ answer = 0;
+ stp_parameter_description_destroy(&desc);
+ return answer;
+ }
+ if (strcmp(printing_mode, "BW") == 0)
+ return 0;
+ else
+ return 1;
+}
+
+static void
+set_current_printer(void)
+{
+ pv = &(stpui_plist[stpui_plist_current]);
+ if (print_mode_is_color(pv->v))
+ stp_set_string_parameter(pv->v, "PrintingMode", "Color");
+ else
+ stp_set_string_parameter(pv->v, "PrintingMode", "BW");
+}
+
+
+static void
+stpui_create_boolean(option_t *opt,
+ GtkTable *table,
+ gint column,
+ gint row,
+ const gchar *text,
+ int deflt,
+ gboolean is_optional)
+{
+ opt->checkbox = gtk_check_button_new();
+ gtk_table_attach(GTK_TABLE(table), opt->checkbox,
+ column, column + 1, row, row + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ if (is_optional)
+ gtk_widget_show(opt->checkbox);
+ else
+ gtk_widget_hide(opt->checkbox);
+
+ opt->info.bool.checkbox =
+ gtk_toggle_button_new_with_label(_(opt->fast_desc->text));
+ gtk_table_attach(GTK_TABLE(table), opt->info.bool.checkbox,
+ column + 1, column + 3, row, row + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show(opt->info.bool.checkbox);
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(opt->info.bool.checkbox),
+ stp_get_boolean_parameter(pv->v, opt->fast_desc->name));
+ g_signal_connect(G_OBJECT(opt->info.bool.checkbox), "toggled",
+ G_CALLBACK(checkbox_callback), opt);
+}
+
+static void
+build_queue_combo(void)
+{
+ plist_build_combo(queue_combo,
+ NULL,
+ stpui_system_print_queues,
+ 1,
+ stpui_plist_get_queue_name(pv),
+ NULL,
+ G_CALLBACK(queue_callback),
+ &queue_callback_id,
+ NULL,
+ NULL);
+}
+
+static void
+build_printer_combo(void)
+{
+ int i;
+ if (printer_list)
+ stp_string_list_destroy(printer_list);
+ printer_list = stp_string_list_create();
+ for (i = 0; i < stpui_plist_count; i++)
+ stp_string_list_add_string(printer_list,
+ stpui_plist[i].name, stpui_plist[i].name);
+ plist_build_combo(printer_combo,
+ NULL,
+ printer_list,
+ 1,
+ stp_string_list_param(printer_list, stpui_plist_current)->name,
+ NULL,
+ G_CALLBACK(plist_callback),
+ &plist_callback_id,
+ NULL,
+ NULL);
+}
+
+static int
+check_page_size(const char *paper_size)
+{
+ const stp_papersize_t *ps = stp_get_papersize_by_name(paper_size);
+ if (ps && (ps->paper_unit == PAPERSIZE_ENGLISH_STANDARD ||
+ ps->paper_unit == PAPERSIZE_METRIC_STANDARD))
+ return 1;
+ else
+ return 0;
+}
+
+static void
+build_page_size_combo(option_t *option)
+{
+ /*
+ * Some printers don't support any "standard" page sizes. If the number
+ * of page sizes is small, just display all of them.
+ */
+ if (stpui_show_all_paper_sizes ||
+ stp_string_list_count(option->info.list.params) < 10)
+ plist_build_combo(option->info.list.combo, option->info.list.label,
+ option->info.list.params, option->is_active,
+ stp_get_string_parameter(pv->v, option->fast_desc->name),
+ option->info.list.default_val,G_CALLBACK(combo_callback),
+ &(option->info.list.callback_id), NULL, option);
+ else
+ plist_build_combo(option->info.list.combo, option->info.list.label,
+ option->info.list.params, option->is_active,
+ stp_get_string_parameter(pv->v, option->fast_desc->name),
+ option->info.list.default_val,G_CALLBACK(combo_callback),
+ &(option->info.list.callback_id),
+ check_page_size, option);
+}
+
+static void
+build_a_combo(option_t *option)
+{
+ const gchar *new_value;
+ stp_parameter_activity_t active;
+ if (option->fast_desc &&
+ option->fast_desc->p_type == STP_PARAMETER_TYPE_STRING_LIST)
+ {
+ const gchar *val = stp_get_string_parameter(pv->v,
+ option->fast_desc->name);
+ if (option->info.list.params == NULL || ! option->is_active ||
+ stp_string_list_count(option->info.list.params) == 0)
+ stp_set_string_parameter(pv->v, option->fast_desc->name, NULL);
+ else if (!val || strlen(val) == 0 ||
+ ! stp_string_list_is_present(option->info.list.params, val))
+ stp_set_string_parameter(pv->v, option->fast_desc->name,
+ option->info.list.default_val);
+ if (strcmp(option->fast_desc->name, "PageSize") == 0)
+ build_page_size_combo(option);
+ else
+ plist_build_combo(option->info.list.combo, option->info.list.label,
+ option->info.list.params,
+ option->is_active,
+ stp_get_string_parameter(pv->v,
+ option->fast_desc->name),
+ option->info.list.default_val, G_CALLBACK(combo_callback),
+ &(option->info.list.callback_id), NULL, option);
+ if (strcmp(option->fast_desc->name, "PageSize") == 0)
+ set_media_size
+ (stp_get_string_parameter(pv->v, option->fast_desc->name));
+ }
+ else
+ plist_build_combo(option->info.list.combo, option->info.list.label,
+ NULL, 0, "", "", G_CALLBACK(combo_callback),
+ &(option->info.list.callback_id), NULL, option);
+ new_value =
+ stpui_combo_get_name(option->info.list.combo, option->info.list.params);
+ active = stp_get_string_parameter_active(pv->v, option->fast_desc->name);
+ stp_set_string_parameter(pv->v, option->fast_desc->name, new_value);
+ stp_set_string_parameter_active(pv->v, option->fast_desc->name, active);
+}
+
+static void
+populate_options(const stp_vars_t *v)
+{
+ stp_parameter_list_t params = stp_get_parameter_list(v);
+ int i;
+ int idx;
+ if (current_options)
+ {
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ if (opt->info.list.combo)
+ {
+ gtk_widget_destroy(opt->info.list.combo);
+ gtk_widget_destroy(opt->info.list.label);
+ if (opt->info.list.params)
+ stp_string_list_destroy(opt->info.list.params);
+ g_free(opt->info.list.default_val);
+ }
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ case STP_PARAMETER_TYPE_DIMENSION:
+ if (opt->info.flt.adjustment)
+ {
+ gtk_widget_destroy
+ (GTK_WIDGET
+ (SCALE_ENTRY_SCALE(opt->info.flt.adjustment)));
+ gtk_widget_destroy
+ (GTK_WIDGET
+ (SCALE_ENTRY_LABEL(opt->info.flt.adjustment)));
+ gtk_widget_destroy
+ (GTK_WIDGET
+ (SCALE_ENTRY_SPINBUTTON(opt->info.flt.adjustment)));
+ }
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ gtk_widget_destroy(GTK_WIDGET(opt->info.curve.label));
+ gtk_widget_destroy(GTK_WIDGET(opt->info.curve.button));
+ gtk_widget_destroy(GTK_WIDGET(opt->info.curve.dialog));
+ if (opt->info.curve.current)
+ stp_curve_destroy(opt->info.curve.current);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ gtk_widget_destroy(GTK_WIDGET(opt->info.bool.checkbox));
+ break;
+ default:
+ break;
+ }
+ if (opt->checkbox)
+ gtk_widget_destroy(GTK_WIDGET(opt->checkbox));
+ }
+ g_free(current_options);
+ }
+ current_option_count = stp_parameter_list_count(params);
+ current_options = g_malloc(sizeof(option_t) * current_option_count);
+
+ for (idx = 0, i = 0; i < current_option_count; i++)
+ {
+ stp_parameter_t desc;
+ const stp_parameter_t *param = stp_parameter_list_param(params, i);
+ if (!param->read_only &&
+ (param->p_class == STP_PARAMETER_CLASS_OUTPUT ||
+ param->p_class == STP_PARAMETER_CLASS_FEATURE ||
+ (param->p_class == STP_PARAMETER_CLASS_CORE &&
+ strcmp(param->name, "PageSize") == 0)))
+ {
+ option_t *opt = &(current_options[idx]);
+ opt->fast_desc = stp_parameter_list_param(params, i);
+ stp_describe_parameter(v, opt->fast_desc->name, &desc);
+ opt->checkbox = NULL;
+ opt->is_active = 0;
+ opt->is_enabled = 0;
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ opt->info.list.callback_id = -1;
+ opt->info.list.default_val = g_strdup(desc.deflt.str);
+ if (desc.bounds.str)
+ opt->info.list.params =
+ stp_string_list_create_copy(desc.bounds.str);
+ else
+ opt->info.list.params = NULL;
+ opt->info.list.combo = NULL;
+ opt->info.list.label = NULL;
+ opt->is_active = desc.is_active;
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ opt->info.flt.adjustment = NULL;
+ opt->info.flt.upper = desc.bounds.dbl.upper;
+ opt->info.flt.lower = desc.bounds.dbl.lower;
+ opt->info.flt.deflt = desc.deflt.dbl;
+ opt->info.flt.scale = 1.0;
+ opt->is_active = desc.is_active;
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ opt->info.flt.adjustment = NULL;
+ opt->info.flt.upper = desc.bounds.dimension.upper;
+ opt->info.flt.lower = desc.bounds.dimension.lower;
+ opt->info.flt.deflt = desc.deflt.dimension;
+ opt->info.flt.scale = 1.0;
+ opt->is_active = desc.is_active;
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ opt->info.curve.label = NULL;
+ opt->info.curve.button = NULL;
+ opt->info.curve.dialog = NULL;
+ opt->info.curve.gamma_curve = NULL;
+ opt->info.curve.current = NULL;
+ opt->info.curve.deflt = desc.deflt.curve;
+ opt->info.curve.is_visible = FALSE;
+ opt->is_active = desc.is_active;
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ opt->info.bool.checkbox = NULL;
+ opt->info.bool.current = 0;
+ opt->info.bool.deflt = desc.deflt.boolean;
+ opt->is_active = desc.is_active;
+ default:
+ break;
+ }
+ idx++;
+ stp_parameter_description_destroy(&desc);
+ }
+ }
+ current_option_count = idx;
+ stp_parameter_list_destroy(params);
+}
+
+static void
+populate_option_table(GtkWidget *table, int p_class)
+{
+ int i, j;
+ int current_pos = 0;
+ int counts[STP_PARAMETER_LEVEL_INVALID][STP_PARAMETER_TYPE_INVALID];
+ int vpos[STP_PARAMETER_LEVEL_INVALID][STP_PARAMETER_TYPE_INVALID];
+ for (i = 0; i < STP_PARAMETER_LEVEL_INVALID; i++)
+ for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++)
+ {
+ vpos[i][j] = 0;
+ counts[i][j] = 0;
+ }
+
+
+ /* First scan the options to figure out where to start */
+ for (i = 0; i < current_option_count; i++)
+ {
+ const stp_parameter_t *desc = current_options[i].fast_desc;
+ /*
+ * Specialize the core parameters (page size is the only one we want)
+ * Yuck.
+ */
+ if (!desc->read_only && desc->p_class == p_class &&
+ (desc->p_class != STP_PARAMETER_CLASS_CORE ||
+ strcmp(desc->name, "PageSize") == 0))
+ {
+ switch (desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ case STP_PARAMETER_TYPE_DIMENSION:
+ case STP_PARAMETER_TYPE_DOUBLE:
+ case STP_PARAMETER_TYPE_CURVE:
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ counts[desc->p_level][desc->p_type]++;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* Now, figure out where we're going to put the options */
+ for (i = 0; i < STP_PARAMETER_LEVEL_INVALID; i++)
+ {
+ int level_count = 0;
+ for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++)
+ level_count += counts[i][j];
+ if (level_count > 0 && current_pos > 0)
+ {
+ GtkWidget *sep = gtk_hseparator_new();
+ gtk_table_attach (GTK_TABLE(table), sep, 0, 4,
+ current_pos, current_pos + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ if (i <= MAXIMUM_PARAMETER_LEVEL)
+ gtk_widget_show(sep);
+ current_pos++;
+ }
+ for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++)
+ {
+ vpos[i][j] = current_pos;
+ current_pos += counts[i][j];
+ }
+ }
+
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ const stp_curve_t *xcurve;
+ const stp_parameter_t *desc = opt->fast_desc;
+ if (!desc->read_only && desc->p_class == p_class &&
+ (desc->p_class != STP_PARAMETER_CLASS_CORE ||
+ strcmp(desc->name, "PageSize") == 0))
+ {
+ gdouble unit_scaler;
+ gdouble minor_increment;
+ gint digits;
+ switch (desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ stpui_create_new_combo(opt, table, 0,
+ vpos[desc->p_level][desc->p_type]++,
+ !(desc->is_mandatory));
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_string_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ stpui_create_scale_entry(opt, GTK_TABLE(table), 0,
+ vpos[desc->p_level][desc->p_type]++,
+ _(desc->text), 200, 0,
+ opt->info.flt.deflt,
+ opt->info.flt.lower,
+ opt->info.flt.upper,
+ .001, .01, 3, TRUE, 0, 0, NULL,
+ !(desc->is_mandatory));
+ stpui_set_adjustment_tooltip(opt->info.flt.adjustment,
+ _(desc->help));
+ g_signal_connect(G_OBJECT(opt->info.flt.adjustment),
+ "value_changed",
+ G_CALLBACK(color_update), opt);
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_float_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ unit_scaler = units[pv->unit].scale;
+ if (unit_scaler > 100)
+ {
+ digits = 3;
+ minor_increment = .001;
+ }
+ else if (unit_scaler > 10)
+ {
+ digits = 2;
+ minor_increment = .01;
+ }
+ else if (unit_scaler > 1)
+ {
+ digits = 1;
+ minor_increment = .1;
+ }
+ else
+ {
+ digits = 0;
+ minor_increment = 1;
+ }
+ stpui_create_scale_entry(opt, GTK_TABLE(table), 0,
+ vpos[desc->p_level][desc->p_type]++,
+ _(desc->text), 200, 0,
+ opt->info.flt.deflt / unit_scaler,
+ opt->info.flt.lower / unit_scaler,
+ opt->info.flt.upper / unit_scaler,
+ minor_increment, minor_increment * 10,
+ digits, TRUE, 0, 0, NULL,
+ !(desc->is_mandatory));
+ stpui_set_adjustment_tooltip(opt->info.flt.adjustment,
+ _(desc->help));
+ g_signal_connect(G_OBJECT(opt->info.flt.adjustment),
+ "value_changed",
+ G_CALLBACK(dimension_update), opt);
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_dimension_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ xcurve = stp_get_curve_parameter(pv->v, opt->fast_desc->name);
+ if (xcurve)
+ opt->info.curve.current = stp_curve_create_copy(xcurve);
+ else
+ opt->info.curve.current = NULL;
+ stpui_create_curve(opt, GTK_TABLE(table), 0,
+ vpos[desc->p_level][desc->p_type]++,
+ _(desc->text), opt->info.curve.deflt,
+ !(desc->is_mandatory));
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_curve_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ opt->info.bool.current =
+ stp_get_boolean_parameter(pv->v, opt->fast_desc->name);
+ stpui_create_boolean(opt, GTK_TABLE(table), 0,
+ vpos[desc->p_level][desc->p_type]++,
+ _(desc->text), opt->info.bool.deflt,
+ !(desc->is_mandatory));
+ if (desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ stp_set_boolean_parameter_active(pv->v, desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_INT:
+ stp_set_int_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_RAW:
+ stp_set_raw_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_FILE:
+ if (strcmp(opt->fast_desc->name, "PPDFile") != 0)
+ stp_set_file_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ default:
+ break;
+ }
+ if (opt->checkbox)
+ g_signal_connect
+ (G_OBJECT(opt->checkbox), "toggled",
+ G_CALLBACK(set_controls_active), opt);
+ }
+ }
+}
+
+static void
+set_options_active(const char *omit)
+{
+ int i;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ const stp_parameter_t *desc = opt->fast_desc;
+ GtkObject *adj;
+ if (omit && strcmp(omit, opt->fast_desc->name) == 0)
+ continue;
+ switch (desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ build_a_combo(opt);
+ break;
+ case STP_PARAMETER_TYPE_DOUBLE:
+ case STP_PARAMETER_TYPE_DIMENSION:
+ adj = opt->info.flt.adjustment;
+ if (adj)
+ {
+ if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_LABEL(adj)));
+ gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_SCALE(adj)));
+ gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_SPINBUTTON(adj)));
+ }
+ else
+ {
+ gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_LABEL(adj)));
+ gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_SCALE(adj)));
+ gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_SPINBUTTON(adj)));
+ }
+ }
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ gtk_widget_show(GTK_WIDGET(opt->info.curve.label));
+ gtk_widget_show(GTK_WIDGET(opt->info.curve.button));
+ }
+ else
+ {
+ gtk_widget_hide(GTK_WIDGET(opt->info.curve.label));
+ gtk_widget_hide(GTK_WIDGET(opt->info.curve.button));
+ gtk_widget_hide(GTK_WIDGET(opt->info.curve.dialog));
+ }
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ gtk_widget_show(GTK_WIDGET(opt->info.bool.checkbox));
+ }
+ else
+ {
+ gtk_widget_hide(GTK_WIDGET(opt->info.bool.checkbox));
+ }
+ break;
+ default:
+ break;
+ }
+ if (opt->checkbox)
+ {
+ if (!(opt->is_active) || desc->p_level > MAXIMUM_PARAMETER_LEVEL)
+ gtk_widget_hide(GTK_WIDGET(opt->checkbox));
+ else if (!(desc->is_mandatory))
+ gtk_widget_show(GTK_WIDGET(opt->checkbox));
+ }
+ }
+}
+
+static void
+color_button_callback(GtkWidget *widget, gpointer data)
+{
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+}
+
+static void
+create_top_level_structure(void)
+{
+ gchar *plug_in_name;
+ /*
+ * Create the main dialog
+ */
+
+ plug_in_name = g_strdup_printf (_("%s -- Print v%s"),
+ stpui_get_image_filename(),
+ VERSION " - " RELEASE_DATE);
+
+ print_dialog =
+ stpui_dialog_new (plug_in_name,
+ GTK_WIN_POS_MOUSE,
+ TRUE,
+
+ _("About"), about_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Print and\nSave Settings"), printandsave_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Save\nSettings"), save_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Print"), print_callback,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Cancel"), gtk_widget_destroy,
+ NULL, (GObject *) 1, NULL, FALSE, TRUE,
+
+ NULL);
+
+ g_free (plug_in_name);
+
+ g_signal_connect (G_OBJECT (print_dialog), "destroy",
+ G_CALLBACK (gtk_main_quit), NULL);
+
+ /*
+ * Top-level containers
+ */
+
+ main_vbox = gtk_vbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (print_dialog)->vbox), main_vbox,
+ TRUE, TRUE, 0);
+ gtk_widget_show (main_vbox);
+
+ main_hbox = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, TRUE, TRUE, 0);
+ gtk_widget_show (main_hbox);
+
+ right_vbox = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_end (GTK_BOX (main_hbox), right_vbox, FALSE, FALSE, 0);
+ gtk_widget_show (right_vbox);
+
+ notebook = gtk_notebook_new ();
+ gtk_box_pack_start (GTK_BOX (right_vbox), notebook, TRUE, TRUE, 0);
+ gtk_widget_show (notebook);
+}
+
+static gint
+drawing_area_resize_callback(GtkWidget *widget, GdkEventConfigure *event)
+{
+ preview_size_vert = event->height - 1;
+ preview_size_horiz = event->width - 1;
+ invalidate_preview_thumbnail();
+ invalidate_frame();
+ preview_update();
+ return 1;
+}
+
+static void
+create_preview (void)
+{
+ GtkWidget *frame;
+ GtkWidget *event_box;
+
+ frame = gtk_frame_new (_("Preview"));
+ gtk_box_pack_start (GTK_BOX (main_hbox), frame, TRUE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ preview = (GtkDrawingArea *) gtk_drawing_area_new ();
+ gtk_drawing_area_size(preview, preview_size_horiz + 1, preview_size_vert +1);
+ g_signal_connect(G_OBJECT(preview), "configure_event",
+ G_CALLBACK(drawing_area_resize_callback), NULL);
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (preview));
+ gtk_container_add (GTK_CONTAINER (frame), event_box);
+ gtk_widget_show (event_box);
+
+ g_signal_connect (G_OBJECT (preview), "expose_event",
+ G_CALLBACK (preview_expose), NULL);
+ g_signal_connect (G_OBJECT (preview), "button_press_event",
+ G_CALLBACK (preview_button_callback), NULL);
+ g_signal_connect (G_OBJECT (preview), "button_release_event",
+ G_CALLBACK (preview_button_callback), NULL);
+ g_signal_connect (G_OBJECT (preview), "motion_notify_event",
+ G_CALLBACK (preview_motion_callback), NULL);
+ gtk_widget_show (GTK_WIDGET (preview));
+
+ stpui_set_help_data
+ (event_box,
+ _("Position the image on the page.\n"
+ "Click and drag with the primary button to position the image.\n"
+ "Click and drag with the second button to move the image with finer precision; "
+ "each unit of motion moves the image one point (1/72\")\n"
+ "Click and drag with the third (middle) button to move the image in units of "
+ "the image size.\n"
+ "Holding down the shift key while clicking and dragging constrains the image to "
+ "only horizontal or vertical motion.\n"
+ "If you click another button while dragging the mouse, the image will return "
+ "to its original position."));
+
+ gtk_widget_set_events (GTK_WIDGET (preview),
+ GDK_EXPOSURE_MASK | GDK_BUTTON_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK);
+}
+
+static GtkWidget *
+create_positioning_entry(GtkWidget *table, int hpos, int vpos,
+ const char *text, const char *help)
+{
+ return stpui_create_entry
+ (table, hpos, vpos, text, help, G_CALLBACK(position_callback));
+}
+
+static GtkWidget *
+create_positioning_button(GtkWidget *box, int invalid,
+ const char *text, const char *help)
+{
+ GtkWidget *button = gtk_button_new_with_label(_(text));
+ gtk_box_pack_start(GTK_BOX(box), button, FALSE, TRUE, 0);
+ gtk_widget_show(button);
+ stpui_set_help_data(button, help);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(position_button_callback),
+ (gpointer) invalid);
+ return button;
+}
+
+static void
+create_paper_size_frame(void)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *media_size_table;
+ GtkWidget *table;
+ int vpos = 0;
+
+ frame = gtk_frame_new (_("Paper Size"));
+ gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ vbox = gtk_vbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_container_add (GTK_CONTAINER (vbox), table);
+ gtk_widget_show (table);
+
+ /*
+ * Media size combo box.
+ */
+
+ page_size_table = gtk_table_new(1, 1, FALSE);
+ gtk_widget_show (page_size_table);
+ gtk_table_attach_defaults(GTK_TABLE(table), page_size_table,
+ 0, 2, vpos, vpos + 1);
+ vpos++;
+ show_all_paper_sizes_button =
+ gtk_check_button_new_with_label(_("Show All Paper Sizes"));
+ gtk_table_attach_defaults
+ (GTK_TABLE(table), show_all_paper_sizes_button, 0, 2, vpos, vpos + 1);
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(show_all_paper_sizes_button),
+ stpui_show_all_paper_sizes);
+ g_signal_connect(G_OBJECT(show_all_paper_sizes_button), "toggled",
+ G_CALLBACK(show_all_paper_sizes_callback), NULL);
+ gtk_widget_show(show_all_paper_sizes_button);
+ vpos++;
+
+ /*
+ * Custom media size entries
+ */
+
+ media_size_table = gtk_table_new (1, 1, FALSE);
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Dimensions:"),
+ 0.0, 0.5, media_size_table, 1, TRUE);
+ gtk_table_set_col_spacings (GTK_TABLE (media_size_table), 4);
+
+ custom_size_width = stpui_create_entry
+ (media_size_table, 0, 3, _("Width:"),
+ _("Width of the paper that you wish to print to"),
+ G_CALLBACK(custom_media_size_callback));
+
+ custom_size_height = stpui_create_entry
+ (media_size_table, 2, 3, _("Height:"),
+ _("Height of the paper that you wish to print to"),
+ G_CALLBACK(custom_media_size_callback));
+
+ vpos++;
+ auto_paper_size_button =
+ gtk_check_button_new_with_label(_("Automatic Paper Size"));
+ gtk_table_attach_defaults
+ (GTK_TABLE(table), auto_paper_size_button, 0, 2, vpos, vpos + 1);
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(auto_paper_size_button), FALSE);
+ g_signal_connect(G_OBJECT(auto_paper_size_button), "toggled",
+ G_CALLBACK(auto_paper_size_callback), NULL);
+}
+
+static void
+create_copy_number_frame(void)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *event_box;
+ GtkAdjustment *adj;
+
+ frame = gtk_frame_new (_("Number of Copies"));
+ gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ vbox = gtk_hbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), vbox);
+ gtk_widget_show (vbox);
+
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (vbox), event_box);
+ stpui_set_help_data(event_box,
+ _("Select the number of copies to print; "
+ "a value between 1 and 100"));
+ gtk_widget_show (event_box);
+
+ /*
+ * Number of Copies Spin Button
+ */
+
+ adj = (GtkAdjustment *) gtk_adjustment_new (1.0f, 1.0f, 100.0f,
+ 1.0f, 5.0f, 0.0f);
+ copy_count_spin_button = gtk_spin_button_new (adj, 0, 0);
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (copy_count_spin_button), FALSE);
+ gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (copy_count_spin_button), TRUE);
+ gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (copy_count_spin_button),
+ GTK_UPDATE_IF_VALID);
+
+ g_signal_connect(G_OBJECT (adj), "value_changed",
+ G_CALLBACK (copy_count_callback),
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (event_box), copy_count_spin_button);
+ gtk_widget_show(copy_count_spin_button);
+}
+
+static void
+create_positioning_frame (void)
+{
+ GtkWidget *frame;
+ GtkWidget *table;
+ GtkWidget *box;
+ GtkWidget *sep;
+
+ frame = gtk_frame_new (_("Image Position"));
+ gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0);
+ gtk_widget_show (frame);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+ gtk_container_add (GTK_CONTAINER (frame), table);
+ gtk_widget_show (table);
+
+ /*
+ * Orientation option menu.
+ */
+
+ orientation_menu =
+ stpui_option_menu_new (FALSE,
+ _("Auto"), orientation_callback,
+ (gpointer) ORIENT_AUTO, NULL, NULL, 0,
+ _("Portrait"), orientation_callback,
+ (gpointer) ORIENT_PORTRAIT, NULL, NULL, 0,
+ _("Landscape"), orientation_callback,
+ (gpointer) ORIENT_LANDSCAPE, NULL, NULL, 0,
+ _("Upside down"), orientation_callback,
+ (gpointer) ORIENT_UPSIDEDOWN, NULL, NULL, 0,
+ _("Seascape"), orientation_callback,
+ (gpointer) ORIENT_SEASCAPE, NULL, NULL, 0,
+ NULL);
+ stpui_set_help_data (orientation_menu,
+ _("Select the orientation: portrait, landscape, "
+ "upside down, or seascape (upside down landscape)"));
+ stpui_table_attach_aligned (GTK_TABLE (table), 0, 0, _("Orientation:"),
+ 1.0, 0.5, orientation_menu, 4, TRUE);
+ sep = gtk_hseparator_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 6, 1, 2);
+ gtk_widget_show (sep);
+
+ /*
+ * Position entries
+ */
+
+ left_entry = create_positioning_entry
+ (table, 0, 2, _("Left:"),
+ _("Distance from the left of the paper to the image"));
+#if 0
+ right_entry = create_positioning_entry
+ (table, 0, 3, _("Right:"),
+ _("Distance from the left of the paper to the right of the image"));
+#endif
+ right_border_entry = create_positioning_entry
+ (table, 0, 4, _("Right:"),
+ _("Distance from the right of the paper to the image"));
+ top_entry = create_positioning_entry
+ (table, 3, 2, _("Top:"),
+ _("Distance from the top of the paper to the image"));
+#if 0
+ bottom_entry = create_positioning_entry
+ (table, 3, 3, _("Bottom:"),
+ _("Distance from the top of the paper to bottom of the image"));
+#endif
+ bottom_border_entry = create_positioning_entry
+ (table, 3, 4, _("Bottom:"),
+ _("Distance from the bottom of the paper to the image"));
+ /*
+ * Center options
+ */
+
+ sep = gtk_hseparator_new ();
+ gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 6, 5, 6);
+ gtk_widget_show (sep);
+
+ box = gtk_hbox_new (TRUE, 4);
+ stpui_table_attach_aligned (GTK_TABLE (table), 0, 7, _("Center:"), 0.5, 0.5,
+ box, 5, TRUE);
+ recenter_horizontal_button = create_positioning_button
+ (box, INVALID_LEFT, _("Horizontal"),
+ _("Center the image horizontally on the paper"));
+ recenter_button = create_positioning_button
+ (box, INVALID_LEFT | INVALID_TOP, _("Both"),
+ _("Center the image on the paper"));
+ recenter_vertical_button = create_positioning_button
+ (box, INVALID_TOP, _("Vertical"),
+ _("Center the image vertically on the paper"));
+}
+
+static void
+create_printer_dialog (void)
+{
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GSList *group;
+ gint i;
+ stp_string_list_t *manufacturer_list = stp_string_list_create();
+
+ setup_dialog = stpui_dialog_new(_("Setup Printer"),
+ GTK_WIN_POS_MOUSE, TRUE,
+ _("OK"), setup_ok_callback,
+ NULL, NULL, NULL, TRUE, FALSE,
+ _("Cancel"), setup_cancel_callback,
+ NULL, (GObject *) 1, NULL, FALSE, TRUE,
+ NULL);
+
+ /*
+ * Top-level table for dialog.
+ */
+
+ table = gtk_table_new (4, 4, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacing (GTK_TABLE (table), 0, 150);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (setup_dialog)->vbox), table,
+ TRUE, TRUE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Printer driver option menu.
+ */
+
+ label = gtk_label_new (_("Printer Make:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 2, 4, 0, 2,
+ GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
+ gtk_widget_show (event_box);
+
+ stpui_set_help_data (event_box, _("Select the make of your printer"));
+
+ manufacturer_crawler = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (manufacturer_crawler),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (event_box), manufacturer_crawler);
+ gtk_widget_show (manufacturer_crawler);
+
+ manufacturer_clist = gtk_clist_new (1);
+ gtk_widget_set_usize (manufacturer_clist, 200, 0);
+ gtk_clist_set_selection_mode(GTK_CLIST(manufacturer_clist),GTK_SELECTION_SINGLE);
+ gtk_container_add (GTK_CONTAINER (manufacturer_crawler), manufacturer_clist);
+ gtk_widget_show (manufacturer_clist);
+
+ g_signal_connect (G_OBJECT (manufacturer_clist), "select_row",
+ G_CALLBACK (manufacturer_callback), NULL);
+
+
+ label = gtk_label_new (_("Printer Model:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), label, 4, 5, 0, 2,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (label);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 5, 7, 0, 2,
+ GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0);
+ gtk_widget_show (event_box);
+
+ stpui_set_help_data (event_box, _("Select your printer model"));
+
+ printer_crawler = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (printer_crawler),
+ GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+ gtk_container_add (GTK_CONTAINER (event_box), printer_crawler);
+ gtk_widget_show (printer_crawler);
+
+ printer_driver = gtk_clist_new (1);
+ gtk_widget_set_usize (printer_driver, 200, 0);
+ gtk_clist_set_selection_mode(GTK_CLIST(printer_driver),GTK_SELECTION_SINGLE);
+ gtk_container_add (GTK_CONTAINER (printer_crawler), printer_driver);
+ gtk_widget_show (printer_driver);
+
+ g_signal_connect (G_OBJECT (printer_driver), "select_row",
+ G_CALLBACK (print_driver_callback), NULL);
+
+
+ for (i = 0; i < stp_printer_model_count (); i ++)
+ {
+ const stp_printer_t *the_printer = stp_get_printer_by_index (i);
+
+ if (strcmp(stp_printer_get_long_name (the_printer), "") != 0 &&
+ strcmp(stp_printer_get_family(the_printer), "raw") != 0)
+ {
+ const gchar *make = stp_printer_get_manufacturer(the_printer);
+ if (! stp_string_list_is_present(manufacturer_list, make))
+ stp_string_list_add_string(manufacturer_list, make, make);
+ }
+ }
+
+ for (i = 0; i < stp_string_list_count(manufacturer_list); i++)
+ {
+ const stp_param_string_t *param =
+ stp_string_list_param(manufacturer_list, i);
+ gchar *xname = g_strdup(param->name);
+ gtk_clist_insert(GTK_CLIST(manufacturer_clist), i, &xname);
+ gtk_clist_set_row_data_full(GTK_CLIST(manufacturer_clist), i, xname,
+ g_free);
+ }
+ stp_string_list_destroy(manufacturer_list);
+ gtk_clist_sort(GTK_CLIST(manufacturer_clist));
+ build_printer_driver_clist();
+
+ /*
+ * PPD file.
+ */
+
+ ppd_label = gtk_label_new (_("PPD File:"));
+ gtk_misc_set_alignment (GTK_MISC (ppd_label), 1.0, 0.5);
+ gtk_table_attach (GTK_TABLE (table), ppd_label, 1, 2, 3, 4,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (ppd_label);
+
+ ppd_box = gtk_hbox_new (FALSE, 8);
+ gtk_table_attach (GTK_TABLE (table), ppd_box, 2, 7, 3, 4,
+ GTK_FILL, GTK_FILL, 0, 0);
+
+ ppd_file = gtk_entry_new ();
+ gtk_box_pack_start (GTK_BOX (ppd_box), ppd_file, TRUE, TRUE, 0);
+ gtk_widget_show (ppd_file);
+
+ stpui_set_help_data(ppd_file,_("Enter the correct PPD filename for your printer"));
+
+ ppd_button = gtk_button_new_with_label (_("Browse"));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (ppd_button)->child), 2, 0);
+ gtk_box_pack_start (GTK_BOX (ppd_box), ppd_button, FALSE, FALSE, 0);
+ gtk_widget_show (ppd_button);
+ gtk_widget_show (ppd_box);
+
+ stpui_set_help_data(ppd_button,
+ _("Choose the correct PPD filename for your printer"));
+ g_signal_connect (G_OBJECT (ppd_button), "clicked",
+ G_CALLBACK (ppd_browse_callback), NULL);
+
+ /*
+ * Print command.
+ */
+
+ group = NULL;
+ for (i = 0; i < command_options_count; i++)
+ group = stpui_create_radio_button(&(command_options[i]), group, table,
+ 0, i > 0 ? i + 5 : i + 4,
+ G_CALLBACK(command_type_callback));
+
+ standard_cmd_entry = gtk_entry_new();
+ gtk_table_attach (GTK_TABLE (table), standard_cmd_entry, 2, 7, 5, 6,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_entry_set_editable(GTK_ENTRY(standard_cmd_entry), FALSE);
+ gtk_widget_set_sensitive(standard_cmd_entry, FALSE);
+ gtk_widget_show (standard_cmd_entry);
+
+ queue_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), queue_combo);
+ gtk_widget_show (queue_combo);
+ gtk_widget_show (event_box);
+ build_queue_combo();
+
+ stpui_set_help_data(event_box,
+ _("Select the name of the output queue (not the type, "
+ "or model, of printer) that you wish to print to"));
+ label = gtk_label_new(_("Printer Queue:"));
+ gtk_widget_show(label);
+ gtk_table_attach (GTK_TABLE (table), label, 2, 3, 4, 5,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_table_attach (GTK_TABLE (table), event_box, 3, 7, 4, 5,
+ GTK_FILL, GTK_FILL, 0, 0);
+
+ custom_command_entry = gtk_entry_new ();
+ gtk_table_attach (GTK_TABLE (table), custom_command_entry, 2, 7, 6, 7,
+ GTK_FILL, GTK_FILL, 0, 0);
+ g_signal_connect(G_OBJECT(custom_command_entry), "activate",
+ G_CALLBACK(setup_callback), NULL);
+ gtk_widget_set_sensitive(custom_command_entry, FALSE);
+ gtk_widget_show (custom_command_entry);
+
+ stpui_set_help_data
+ (custom_command_entry, _("Enter the correct command to print to your printer. "));
+
+ file_entry = gtk_entry_new ();
+ gtk_table_attach (GTK_TABLE (table), file_entry, 2, 6, 7, 8,
+ GTK_FILL, GTK_FILL, 0, 0);
+ g_signal_connect(G_OBJECT(file_entry), "activate",
+ G_CALLBACK(setup_callback), NULL);
+ gtk_widget_show (file_entry);
+
+ gtk_widget_set_sensitive(file_entry, FALSE);
+ stpui_set_help_data
+ (file_entry, _("Enter the file to print to. "));
+
+ file_button = gtk_button_new_with_label (_("Browse"));
+
+ gtk_table_attach (GTK_TABLE (table), file_button, 6, 7, 7, 8,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (file_button);
+
+ stpui_set_help_data(file_button, _("File to print to"));
+ g_signal_connect (G_OBJECT (file_button), "clicked",
+ G_CALLBACK (file_browse_callback), NULL);
+
+ /*
+ * Output file selection dialog.
+ */
+
+ file_browser = gtk_file_selection_new (_("Print To File"));
+
+ g_signal_connect
+ (G_OBJECT (GTK_FILE_SELECTION (file_browser)->ok_button), "clicked",
+ G_CALLBACK (file_ok_callback), NULL);
+ g_signal_connect
+ (G_OBJECT (GTK_FILE_SELECTION (file_browser)->cancel_button), "clicked",
+ G_CALLBACK (file_cancel_callback), NULL);
+
+ /*
+ * PPD file selection dialog.
+ */
+
+ ppd_browser = gtk_file_selection_new (_("PPD File"));
+ gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (ppd_browser));
+
+ g_signal_connect
+ (G_OBJECT (GTK_FILE_SELECTION (ppd_browser)->ok_button), "clicked",
+ G_CALLBACK (ppd_ok_callback), NULL);
+ g_signal_connect_object
+ (G_OBJECT (GTK_FILE_SELECTION (ppd_browser)->cancel_button), "clicked",
+ G_CALLBACK (gtk_widget_hide), G_OBJECT (ppd_browser), G_CONNECT_SWAPPED);
+}
+
+static void
+create_new_printer_dialog (void)
+{
+ GtkWidget *table;
+
+ new_printer_dialog =
+ stpui_dialog_new (_("Define New Printer"),
+ GTK_WIN_POS_MOUSE, FALSE,
+ _("OK"), new_printer_ok_callback,
+ NULL, NULL, NULL, TRUE, FALSE,
+ _("Cancel"), gtk_widget_hide,
+ NULL, (GObject *) 1, NULL, FALSE, TRUE,
+ NULL);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 8);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (new_printer_dialog)->vbox), table,
+ FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ new_printer_entry = gtk_entry_new ();
+ gtk_entry_set_max_length (GTK_ENTRY (new_printer_entry), 127);
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, 0, _("Printer Name:"), 1.0,
+ 0.5, new_printer_entry, 1, TRUE);
+
+ stpui_set_help_data(new_printer_entry,
+ _("Enter the name you wish to give this logical printer"));
+ g_signal_connect (G_OBJECT (new_printer_entry), "activate",
+ G_CALLBACK (new_printer_ok_callback), NULL);
+}
+
+static void
+create_about_dialog (void)
+{
+ GtkWidget *label;
+ about_dialog =
+ stpui_dialog_new (_("About Gutenprint " PLUG_IN_VERSION),
+ GTK_WIN_POS_MOUSE, FALSE,
+ _("OK"), gtk_widget_hide,
+ NULL, (GObject *) 1, NULL, TRUE, TRUE,
+ NULL);
+
+ label = gtk_label_new
+ (_("Gutenprint Version " PLUG_IN_VERSION "\n"
+ "\n"
+ "Copyright (C) 1997-2003 Michael Sweet, Robert Krawitz,\n"
+ "and the rest of the Gutenprint Development Team.\n"
+ "\n"
+ "Please visit our web site at http://gimp-print.sourceforge.net.\n"
+ "\n"
+ "This program is free software; you can redistribute it and/or modify\n"
+ "it under the terms of the GNU General Public License as published by\n"
+ "the Free Software Foundation; either version 2 of the License, or\n"
+ "(at your option) any later version.\n"
+ "\n"
+ "This program is distributed in the hope that it will be useful,\n"
+ "but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "GNU General Public License for more details.\n"
+ "\n"
+ "You should have received a copy of the GNU General Public License\n"
+ "along with this program; if not, write to the Free Software\n"
+ "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 "
+ "USA\n"));
+
+ gtk_misc_set_padding (GTK_MISC (label), 12, 4);
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_dialog)->vbox), label,
+ FALSE, FALSE, 0);
+ gtk_widget_show (label);
+}
+
+static void
+create_printer_settings_frame (void)
+{
+ GtkWidget *table;
+ GtkWidget *sep;
+ GtkWidget *printer_hbox;
+ GtkWidget *button;
+ GtkWidget *event_box;
+ GtkWidget *scrolled_window;
+ gint vpos = 0;
+
+ create_printer_dialog ();
+ create_about_dialog ();
+ create_new_printer_dialog ();
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 4);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table,
+ gtk_label_new (_("Printer Settings")));
+ gtk_widget_show (table);
+
+ /*
+ * Printer option menu.
+ */
+
+ printer_combo = gtk_combo_new ();
+ event_box = gtk_event_box_new ();
+ gtk_container_add (GTK_CONTAINER (event_box), printer_combo);
+ gtk_widget_show (printer_combo);
+
+ stpui_set_help_data(event_box,
+ _("Select the name of the printer (not the type, "
+ "or model, of printer) that you wish to print to"));
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Printer Name:"),
+ 0.0, 0.5, event_box, 1, TRUE);
+ printer_model_label = gtk_label_new ("");
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Printer Model:"),
+ 0.0, 0.0, printer_model_label, 1, TRUE);
+ printer_hbox = gtk_hbox_new (TRUE, 4);
+ gtk_table_attach (GTK_TABLE (table), printer_hbox,
+ 1, 4, vpos, vpos + 1, GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ vpos += 2;
+ gtk_widget_show (printer_hbox);
+
+ /*
+ * Setup printer button
+ */
+
+ button = gtk_button_new_with_label (_("Setup Printer..."));
+ stpui_set_help_data(button,
+ _("Choose the printer model, PPD file, and command "
+ "that is used to print to this printer"));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0);
+ gtk_box_pack_start (GTK_BOX (printer_hbox), button, FALSE, TRUE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (setup_open_callback), NULL);
+
+ /*
+ * New printer button
+ */
+
+ button = gtk_button_new_with_label (_("New Printer..."));
+ stpui_set_help_data (button, _("Define a new logical printer. This can be used to "
+ "name a collection of settings that you wish to "
+ "remember for future use."));
+ gtk_box_pack_start (GTK_BOX (printer_hbox), button, FALSE, TRUE, 0);
+ gtk_widget_show (button);
+
+ g_signal_connect (G_OBJECT (button), "clicked",
+ G_CALLBACK (new_printer_open_callback), NULL);
+
+ sep = gtk_hseparator_new ();
+ gtk_table_attach (GTK_TABLE (table), sep, 0, 5, vpos, vpos + 1,
+ GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (sep);
+ vpos++;
+
+ printer_features_table = gtk_table_new(1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (printer_features_table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (printer_features_table), 0);
+ gtk_widget_show (printer_features_table);
+
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
+ printer_features_table);
+ gtk_table_attach_defaults(GTK_TABLE(table), scrolled_window,
+ 0, 6, vpos, vpos + 1);
+ gtk_widget_show(scrolled_window);
+}
+
+static void
+create_scaling_frame (void)
+{
+ GtkWidget *frame;
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *table;
+ GtkWidget *box;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GtkWidget *sep;
+ GSList *group;
+
+ frame = gtk_frame_new (_("Image Size"));
+ gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0);
+ gtk_widget_show (frame);
+
+ hbox = gtk_hbox_new (FALSE, 2);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 4);
+ gtk_container_add (GTK_CONTAINER (frame), hbox);
+ gtk_widget_show (hbox);
+
+ vbox = gtk_vbox_new (FALSE, 2);
+/* gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); */
+ gtk_container_add (GTK_CONTAINER (hbox), vbox);
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Create the scaling adjustment using percent. It doesn't really matter,
+ * since as soon as we call plist_callback at the end of initialization
+ * everything will be put right.
+ */
+ scaling_adjustment =
+ stpui_scale_entry_new (GTK_TABLE (table), 0, 0, _("Scaling:"), 100, 75,
+ 100.0, minimum_image_percent, 100.0,
+ 1.0, 10.0, 1, TRUE, 0, 0, NULL);
+ stpui_set_adjustment_tooltip(scaling_adjustment,
+ _("Set the scale (size) of the image"));
+ g_signal_connect (G_OBJECT (scaling_adjustment), "value_changed",
+ G_CALLBACK (scaling_update), NULL);
+
+ box = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (vbox), box, TRUE, TRUE, 0);
+ gtk_widget_show (box);
+
+ /*
+ * The scale by percent/ppi toggles
+ */
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (box), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Scale by:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ stpui_set_help_data(event_box,
+ _("Select whether scaling is measured as percent of "
+ "available page size or number of output dots per inch"));
+
+ scaling_percent = gtk_radio_button_new_with_label (NULL, _("Percent"));
+ group = gtk_radio_button_group (GTK_RADIO_BUTTON (scaling_percent));
+ stpui_table_attach_aligned(GTK_TABLE (table), 0, 0, NULL, 0.5, 0.5,
+ scaling_percent, 2, TRUE);
+
+ stpui_set_help_data(scaling_percent, _("Scale the print to the size of the page"));
+ g_signal_connect (G_OBJECT (scaling_percent), "toggled",
+ G_CALLBACK (scaling_callback), NULL);
+
+ scaling_ppi = gtk_radio_button_new_with_label (group, _("PPI"));
+ stpui_table_attach_aligned(GTK_TABLE (table), 2, 0, NULL, 0.5, 0.5,
+ scaling_ppi, 1, TRUE);
+
+ stpui_set_help_data(scaling_ppi,
+ _("Scale the print to the number of dots per inch"));
+ g_signal_connect (G_OBJECT (scaling_ppi), "toggled",
+ G_CALLBACK (scaling_callback), NULL);
+
+ sep = gtk_vseparator_new ();
+ gtk_box_pack_start (GTK_BOX (hbox), sep, FALSE, FALSE, 8);
+ gtk_widget_show (sep);
+
+ /*
+ * The width/height enries
+ */
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 2);
+ gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ width_entry = create_positioning_entry
+ (table, 0, 0, _("Width:"), _("Set the width of the print"));
+ height_entry = create_positioning_entry
+ (table, 0, 1, _("Height:"), _("Set the height of the print"));
+
+ /*
+ * The "image size" button
+ */
+
+ scaling_image = gtk_button_new_with_label (_("Use Original\nImage Size"));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (scaling_image)->child), 2, 2);
+ gtk_box_pack_end (GTK_BOX (hbox), scaling_image, FALSE, FALSE, 0);
+ gtk_widget_show (scaling_image);
+
+ stpui_set_help_data(scaling_image,
+ _("Set the print size to the size of the image"));
+ g_signal_connect (G_OBJECT (scaling_image), "clicked",
+ G_CALLBACK (scaling_callback), NULL);
+}
+
+/*
+ * create_color_adjust_window (void)
+ *
+ * NOTES:
+ * creates the color adjuster popup, allowing the user to adjust brightness,
+ * contrast, saturation, etc.
+ */
+static void
+create_color_adjust_window (void)
+{
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GtkWidget *scrolled_window;
+ gint x, y; /* Window dimensions */
+
+ initialize_thumbnail();
+
+ color_adjust_dialog =
+ stpui_dialog_new(_("Print Color Adjust"),
+ GTK_WIN_POS_MOUSE, TRUE,
+
+ _("Set Defaults"), set_color_defaults,
+ NULL, NULL, NULL, FALSE, FALSE,
+ _("Close"), gtk_widget_hide,
+ NULL, (GObject *) 1, NULL, TRUE, TRUE,
+ NULL);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_container_set_border_width (GTK_CONTAINER (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 0);
+/* gtk_table_set_row_spacing (GTK_TABLE (table), 8, 6); */
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (color_adjust_dialog)->vbox),
+ table, TRUE, TRUE, 0);
+ gtk_widget_show (table);
+
+ /*
+ * Drawing area for color swatch feedback display...
+ */
+
+ event_box = gtk_event_box_new ();
+ gtk_widget_show (GTK_WIDGET (event_box));
+ gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (event_box),
+ 0, 1, 0, 1, 0, 0, 0, 0);
+
+ swatch = (GtkDrawingArea *) gtk_drawing_area_new ();
+ gtk_widget_set_events (GTK_WIDGET (swatch), GDK_EXPOSURE_MASK);
+ gtk_drawing_area_size (swatch, thumbnail_w, thumbnail_h);
+ gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (swatch));
+ gtk_widget_show (GTK_WIDGET (swatch));
+
+ stpui_set_help_data (GTK_WIDGET (event_box), _("Image preview"));
+ g_signal_connect (G_OBJECT (swatch), "expose_event",
+ G_CALLBACK (redraw_color_swatch),
+ NULL);
+
+ event_box = gtk_event_box_new ();
+ gtk_widget_show (GTK_WIDGET (event_box));
+ gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (event_box),
+ 1, 2, 0, 1, 0, 0, 0, 0);
+
+ output_color_vbox = gtk_vbox_new(TRUE, 0);
+ gtk_container_add(GTK_CONTAINER(event_box), output_color_vbox);
+ gtk_widget_show(GTK_WIDGET(output_color_vbox));
+
+ label = gtk_label_new(_("View Output Channels:"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(GTK_WIDGET(label));
+
+ cyan_button = gtk_toggle_button_new_with_label(_("Cyan"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), cyan_button, TRUE, TRUE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cyan_button), TRUE);
+ gtk_widget_show(GTK_WIDGET(cyan_button));
+ g_signal_connect (G_OBJECT (cyan_button), "toggled",
+ G_CALLBACK (color_button_callback), NULL);
+
+ magenta_button = gtk_toggle_button_new_with_label(_("Magenta"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), magenta_button, TRUE, TRUE,0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(magenta_button), TRUE);
+ gtk_widget_show(GTK_WIDGET(magenta_button));
+ g_signal_connect (G_OBJECT (magenta_button), "toggled",
+ G_CALLBACK (color_button_callback), NULL);
+
+ yellow_button = gtk_toggle_button_new_with_label(_("Yellow"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), yellow_button, TRUE, TRUE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(yellow_button), TRUE);
+ gtk_widget_show(GTK_WIDGET(yellow_button));
+ g_signal_connect (G_OBJECT (yellow_button), "toggled",
+ G_CALLBACK (color_button_callback), NULL);
+
+ black_button = gtk_toggle_button_new_with_label(_("Black"));
+ gtk_box_pack_start(GTK_BOX(output_color_vbox), black_button, TRUE, TRUE, 0);
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(black_button), TRUE);
+ gtk_widget_show(GTK_WIDGET(black_button));
+ g_signal_connect (G_OBJECT (black_button), "toggled",
+ G_CALLBACK (color_button_callback), NULL);
+
+ color_adjustment_table = gtk_table_new(1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (color_adjustment_table), 2);
+ gtk_table_set_row_spacings (GTK_TABLE (color_adjustment_table), 0);
+ gtk_container_set_border_width (GTK_CONTAINER (color_adjustment_table), 4);
+ gtk_widget_show (color_adjustment_table);
+
+ scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window),
+ color_adjustment_table);
+ gtk_table_attach_defaults(GTK_TABLE(table), scrolled_window,
+ 0, 2, 1, 2);
+ gtk_widget_show(scrolled_window);
+
+ /* The initial size request does not account for the
+ GtkScrolledWindow. */
+ gtk_window_get_size(GTK_WINDOW(color_adjust_dialog), &x, &y);
+ gtk_window_set_default_size(GTK_WINDOW(color_adjust_dialog), x, y+300);
+}
+
+static void
+create_image_settings_frame (void)
+{
+ GtkWidget *vbox;
+ GtkWidget *hbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GtkWidget *sep;
+ GSList *group;
+ gint i;
+
+ create_color_adjust_window ();
+
+ vbox = gtk_vbox_new (FALSE, 4);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox,
+ gtk_label_new (_("Output")));
+ gtk_widget_show (vbox);
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ /*
+ * Output type toggles.
+ */
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+/* gtk_table_set_row_spacing (GTK_TABLE (table), 2, 4); */
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Output Type:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ stpui_set_help_data(event_box, _("Select the desired output type"));
+
+ group = NULL;
+ for (i = 0; i < output_type_count; i++)
+ group = stpui_create_radio_button(&(output_types[i]), group, table, 0, i,
+ G_CALLBACK(output_type_callback));
+
+ sep = gtk_hseparator_new ();
+ gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0);
+ gtk_widget_show (sep);
+
+ /*
+ * Color adjust button
+ */
+ hbox = gtk_hbox_new (FALSE, 4);
+ gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
+ gtk_widget_show(hbox);
+ label = gtk_label_new("");
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ adjust_color_button = gtk_button_new_with_label (_("Adjust Output..."));
+ gtk_misc_set_padding (GTK_MISC (GTK_BIN (adjust_color_button)->child), 4, 0);
+ gtk_box_pack_start (GTK_BOX (hbox), adjust_color_button, FALSE, FALSE, 0);
+ gtk_widget_show(adjust_color_button);
+ label = gtk_label_new("");
+ gtk_box_pack_end(GTK_BOX(hbox), label, TRUE, TRUE, 0);
+ gtk_widget_show(label);
+
+ stpui_set_help_data(adjust_color_button,
+ _("Adjust color balance, brightness, contrast, "
+ "saturation, and dither algorithm"));
+ g_signal_connect_object (G_OBJECT (adjust_color_button), "clicked",
+ G_CALLBACK (gtk_widget_show),
+ G_OBJECT (color_adjust_dialog),
+ G_CONNECT_SWAPPED);
+}
+
+static void
+create_units_frame (void)
+{
+ GtkWidget *vbox;
+ GtkWidget *table;
+ GtkWidget *label;
+ GtkWidget *event_box;
+ GSList *group;
+ gint i;
+
+ units_hbox = gtk_hbox_new(FALSE, 0);
+ label = gtk_label_new(_("Size Units:"));
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(units_hbox), label, TRUE, TRUE, 0);
+ units_label = gtk_label_new(_(" "));
+ gtk_widget_show(units_label);
+ gtk_box_pack_start(GTK_BOX(units_hbox), units_label, TRUE, TRUE, 0);
+ gtk_widget_show(units_hbox);
+
+ vbox = gtk_vbox_new (FALSE, 4);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
+ gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, units_hbox);
+ gtk_widget_show (vbox);
+
+ /*
+ * The units toggles
+ */
+
+ table = gtk_table_new (1, 1, FALSE);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
+ gtk_widget_show (table);
+
+ event_box = gtk_event_box_new ();
+ gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1,
+ GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0);
+ gtk_widget_show (event_box);
+
+ label = gtk_label_new (_("Units:"));
+ gtk_container_add (GTK_CONTAINER (event_box), label);
+ gtk_widget_show (label);
+
+ stpui_set_help_data(event_box,
+ _("Select the base unit of measurement for printing"));
+
+ group = NULL;
+ for (i = 0; i < unit_count; i++)
+ {
+ unit_t *unit = &(units[i]);
+ unit->checkbox = gtk_radio_button_new_with_label(group, _(unit->name));
+ group = gtk_radio_button_group(GTK_RADIO_BUTTON(unit->checkbox));
+ stpui_table_attach_aligned(GTK_TABLE(table), i / 2, i % 2, NULL, 0.5,
+ 0.5, unit->checkbox, 1, TRUE);
+ stpui_set_help_data(unit->checkbox, _(unit->help));
+ g_signal_connect(G_OBJECT(unit->checkbox), "toggled",
+ G_CALLBACK(unit_callback), (gpointer) i);
+ }
+}
+
+/*
+ * create_main_window()
+ */
+static void
+create_main_window (void)
+{
+ gint x, y; /* Window dimensions */
+
+ set_current_printer();
+ manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
+ /*
+ * Create the various dialog components. Note that we're not
+ * actually initializing the values at this point; that will be done after
+ * the UI is fully created.
+ */
+
+ stpui_help_init();
+
+ create_top_level_structure ();
+
+ create_preview ();
+ create_printer_settings_frame ();
+ create_units_frame();
+ create_paper_size_frame();
+ create_copy_number_frame();
+ create_positioning_frame ();
+ create_scaling_frame ();
+ create_image_settings_frame ();
+
+ /*
+ * Now actually set up the correct values in the dialog
+ */
+
+ do_update_thumbnail = 1;
+ build_printer_combo ();
+ plist_callback (NULL, (gpointer) stpui_plist_current);
+ update_adjusted_thumbnail ();
+
+ /* The initial size request does not account for the
+ GtkScrolledWindow. */
+ gtk_window_get_size(GTK_WINDOW(print_dialog), &x, &y);
+ gtk_window_set_default_size(GTK_WINDOW(print_dialog), x, y+80);
+
+ gtk_widget_show (print_dialog);
+}
+
+static void
+set_entry_value(GtkWidget *entry, double value, int block)
+{
+ gchar s[255];
+ gdouble unit_scaler = units[pv->unit].scale;
+ const gchar *format = units[pv->unit].format;
+
+ g_snprintf(s, sizeof(s), format, value / unit_scaler);
+ if (block)
+ g_signal_handlers_block_matched (G_OBJECT (entry),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+
+ gtk_entry_set_text (GTK_ENTRY (entry), s);
+ if (block)
+ g_signal_handlers_unblock_matched (G_OBJECT (entry),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+}
+
+static void
+reset_preview(void)
+{
+ if (!suppress_preview_reset)
+ {
+ stpui_enable_help();
+ buttons_pressed = preview_active = 0;
+ }
+}
+
+static void
+invalidate_preview_thumbnail (void)
+{
+ preview_valid = FALSE;
+}
+
+static void
+invalidate_frame (void)
+{
+ frame_valid = FALSE;
+}
+
+static void
+compute_scaling_limits(gdouble *min_ppi_scaling, gdouble *max_ppi_scaling)
+{
+ if (auto_paper_size)
+ {
+ *min_ppi_scaling =
+ FINCH * (gdouble) image_width / (gdouble) printable_width;
+ }
+ else
+ {
+ gdouble min_ppi_scaling1 =
+ FINCH * (gdouble) image_width / (gdouble) printable_width;
+ gdouble min_ppi_scaling2 =
+ FINCH * (gdouble) image_height / (gdouble) printable_height;
+
+ if (min_ppi_scaling1 > min_ppi_scaling2)
+ *min_ppi_scaling = min_ppi_scaling1;
+ else
+ *min_ppi_scaling = min_ppi_scaling2;
+ }
+
+ *max_ppi_scaling = *min_ppi_scaling * 100 / minimum_image_percent;
+}
+
+/*
+ * scaling_update() - Update the scaling scale using the slider.
+ */
+static void
+scaling_update (GtkAdjustment *adjustment)
+{
+ reset_preview ();
+
+ if (pv->scaling != adjustment->value)
+ {
+ invalidate_preview_thumbnail ();
+ if (GTK_TOGGLE_BUTTON (scaling_ppi)->active)
+ pv->scaling = -adjustment->value;
+ else
+ pv->scaling = adjustment->value;
+
+ suppress_scaling_adjustment = TRUE;
+ preview_update ();
+ suppress_scaling_adjustment = FALSE;
+ }
+}
+
+/*
+ * scaling_callback() - Update the scaling scale using radio buttons.
+ */
+static void
+scaling_callback (GtkWidget *widget)
+{
+ gdouble max_ppi_scaling;
+ gdouble min_ppi_scaling;
+ gdouble current_scale;
+
+ reset_preview ();
+
+ if (suppress_scaling_callback)
+ return;
+
+ compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling);
+
+ if (widget == scaling_ppi)
+ {
+ if (! GTK_TOGGLE_BUTTON (scaling_ppi)->active)
+ return;
+
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+
+ /*
+ * Compute the correct PPI to create an image of the same size
+ * as the one measured in percent
+ */
+ current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value;
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ min_ppi_scaling / (current_scale / 100);
+ pv->scaling = 0.0;
+ }
+ else if (widget == scaling_percent)
+ {
+ gdouble new_percent;
+
+ if (! GTK_TOGGLE_BUTTON (scaling_percent)->active)
+ return;
+
+ current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value;
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = minimum_image_percent;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0;
+
+ new_percent = 100 * min_ppi_scaling / current_scale;
+
+ if (new_percent > 100)
+ new_percent = 100;
+ if (new_percent < minimum_image_percent)
+ new_percent = minimum_image_percent;
+
+ GTK_ADJUSTMENT (scaling_adjustment)->value = new_percent;
+ pv->scaling = 0.0;
+ }
+ else if (widget == scaling_image)
+ {
+ gdouble yres = image_yres;
+
+ invalidate_preview_thumbnail ();
+
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+
+ if (yres < min_ppi_scaling)
+ yres = min_ppi_scaling;
+ if (yres > max_ppi_scaling)
+ yres = max_ppi_scaling;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->value = yres;
+ pv->scaling = 0.0;
+ }
+
+ if (widget == scaling_ppi || widget == scaling_percent)
+ suppress_preview_update++;
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ if (auto_paper_size)
+ set_media_size(stp_get_string_parameter(pv->v, "PageSize"));
+ if (widget == scaling_ppi || widget == scaling_percent)
+ suppress_preview_update--;
+}
+
+/****************************************************************************
+ *
+ * plist_build_combo
+ *
+ ****************************************************************************/
+static void
+plist_build_combo (GtkWidget *combo, /* I - Combo widget */
+ GtkWidget *label,
+ stp_string_list_t *items, /* I - Menu items */
+ int active,
+ const gchar *cur_item, /* I - Current item */
+ const gchar *def_value, /* I - default item */
+ GCallback callback, /* I - Callback */
+ gint *callback_id, /* IO - Callback ID (init to -1) */
+ int (*check_func)(const char *string),
+ gpointer data)
+{
+ gint i; /* Looping var */
+ GList *list = 0;
+ gint num_items = 0;
+ GtkEntry *entry = GTK_ENTRY (GTK_COMBO (combo)->entry);
+
+ if (check_func && items)
+ {
+ stp_string_list_t *new_items = stp_string_list_create();
+ num_items = stp_string_list_count(items);
+ for (i = 0; i < num_items; i++)
+ {
+ stp_param_string_t *param = stp_string_list_param(items, i);
+ if ((*check_func)(param->name))
+ stp_string_list_add_string(new_items, param->name, param->text);
+ }
+ items = new_items;
+ }
+
+ if (items)
+ num_items = stp_string_list_count(items);
+
+ if (*callback_id != -1)
+ g_signal_handler_disconnect (G_OBJECT (entry), *callback_id);
+ gtk_entry_set_editable (entry, FALSE);
+
+ if (!active || num_items == 0)
+ {
+ list = g_list_append (list, _("Standard"));
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), list);
+ *callback_id = -1;
+ gtk_widget_set_sensitive (combo, FALSE);
+ gtk_widget_hide (combo);
+ if (label)
+ gtk_widget_hide(label);
+ if (check_func && items)
+ stp_string_list_destroy(items);
+ return;
+ }
+
+ for (i = 0; i < num_items; i ++)
+ list = g_list_append(list, g_strdup(stp_string_list_param(items, i)->text));
+
+ gtk_combo_set_popdown_strings (GTK_COMBO (combo), list);
+
+ for (i = 0; i < num_items; i ++)
+ if (strcmp(stp_string_list_param(items, i)->name, cur_item) == 0)
+ break;
+
+ if (i >= num_items && def_value)
+ for (i = 0; i < num_items; i ++)
+ if (strcmp(stp_string_list_param(items, i)->name, def_value) == 0)
+ break;
+
+ if (i >= num_items)
+ i = 0;
+
+ gtk_entry_set_text (entry, stp_string_list_param(items, i)->text);
+
+ gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE);
+ gtk_widget_set_sensitive (combo, TRUE);
+ gtk_widget_show (combo);
+ if (label)
+ gtk_widget_show(label);
+
+ *callback_id = g_signal_connect (G_OBJECT (entry), "changed", callback,
+ data);
+ if (check_func && items)
+ stp_string_list_destroy(items);
+}
+
+void
+stpui_set_image_dimensions(gint width, gint height)
+{
+ image_true_width = width;
+ image_true_height = height;
+}
+
+void
+stpui_set_image_resolution(gdouble xres, gdouble yres)
+{
+ image_xres = xres;
+ image_yres = yres;
+}
+
+gint
+stpui_compute_orientation(void)
+{
+ if (auto_paper_size ||
+ (printable_width >= printable_height &&
+ image_true_width >= image_true_height) ||
+ (printable_height >= printable_width &&
+ image_true_height >= image_true_width))
+ return ORIENT_PORTRAIT;
+ else
+ return ORIENT_LANDSCAPE;
+}
+
+static void
+set_orientation(int orientation)
+{
+ pv->orientation = orientation;
+ if (orientation == ORIENT_AUTO)
+ orientation = stpui_compute_orientation();
+ physical_orientation = orientation;
+ switch (orientation)
+ {
+ case ORIENT_PORTRAIT:
+ case ORIENT_UPSIDEDOWN:
+ image_height = image_true_height;
+ image_width = image_true_width;
+ preview_thumbnail_h = thumbnail_h;
+ preview_thumbnail_w = thumbnail_w;
+ break;
+ case ORIENT_LANDSCAPE:
+ case ORIENT_SEASCAPE:
+ image_height = image_true_width;
+ image_width = image_true_height;
+ preview_thumbnail_h = thumbnail_w;
+ preview_thumbnail_w = thumbnail_h;
+ break;
+ }
+ update_adjusted_thumbnail();
+}
+
+static void
+position_button_callback(GtkWidget *widget, gpointer data)
+{
+ reset_preview();
+ pv->invalid_mask |= (gint) data;
+ preview_update ();
+}
+
+/*
+ * position_callback() - callback for position entry widgets
+ */
+static void
+position_callback (GtkWidget *widget)
+{
+ gdouble new_printed_value = atof (gtk_entry_get_text (GTK_ENTRY (widget)));
+ gint new_value = SCALE(new_printed_value, units[pv->unit].scale);
+
+ reset_preview ();
+ suppress_preview_update++;
+
+ if (widget == top_entry)
+ stp_set_top(pv->v, new_value);
+/*
+ else if (widget == bottom_entry)
+ stp_set_top(pv->v, new_value - print_height);
+*/
+ else if (widget == bottom_border_entry)
+ stp_set_top (pv->v, paper_height - print_height - new_value);
+ else if (widget == left_entry)
+ stp_set_left (pv->v, new_value);
+/*
+ else if (widget == right_entry)
+ stp_set_left(pv->v, new_value - print_width);
+*/
+ else if (widget == right_border_entry)
+ stp_set_left (pv->v, paper_width - print_width - new_value);
+ else if (widget == width_entry || widget == height_entry)
+ {
+ gboolean was_percent = (pv->scaling >= 0);
+ if (pv->scaling >= 0)
+ {
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ scaling_callback (scaling_ppi);
+ }
+ if (widget == width_entry)
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ ((gdouble) image_width) / (new_value / FINCH);
+ else
+ GTK_ADJUSTMENT (scaling_adjustment)->value =
+ ((gdouble) image_height) / (new_value / FINCH);
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ if (was_percent)
+ {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scaling_percent),TRUE);
+ gtk_adjustment_value_changed(GTK_ADJUSTMENT (scaling_adjustment));
+ }
+ }
+
+ suppress_preview_update--;
+ preview_update ();
+}
+
+static void
+set_adjustment_active(option_t *opt, gboolean active, gboolean do_toggle)
+{
+ GtkObject *adj = opt->info.flt.adjustment;
+ if (do_toggle)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active);
+ gtk_widget_set_sensitive
+ (GTK_WIDGET (SCALE_ENTRY_LABEL (adj)), active);
+ gtk_widget_set_sensitive
+ (GTK_WIDGET (SCALE_ENTRY_SCALE (adj)), active);
+ gtk_widget_set_sensitive
+ (GTK_WIDGET (SCALE_ENTRY_SPINBUTTON (adj)), active);
+}
+
+static void
+set_combo_active(option_t *opt, gboolean active, gboolean do_toggle)
+{
+ if (do_toggle)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.list.combo), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.list.label), active);
+}
+
+static void
+set_curve_active(option_t *opt, gboolean active, gboolean do_toggle)
+{
+ if (do_toggle)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.curve.button), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.curve.label), active);
+ if (active)
+ {
+ if (opt->info.curve.is_visible)
+ gtk_widget_show(GTK_WIDGET(opt->info.curve.dialog));
+ }
+ else
+ gtk_widget_hide(GTK_WIDGET(opt->info.curve.dialog));
+}
+
+static void
+set_bool_active(option_t *opt, gboolean active, gboolean do_toggle)
+{
+ if (do_toggle)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active);
+ gtk_widget_set_sensitive(GTK_WIDGET(opt->info.bool.checkbox), active);
+}
+
+static void
+do_color_updates (void)
+{
+ int i;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ if (opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_DOUBLE:
+ if (stp_check_float_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ gtk_adjustment_set_value
+ (GTK_ADJUSTMENT(opt->info.flt.adjustment),
+ stp_get_float_parameter(pv->v, opt->fast_desc->name));
+ if (stp_check_float_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_adjustment_active(opt, TRUE, TRUE);
+ else
+ set_adjustment_active(opt, FALSE, TRUE);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ if (stp_check_dimension_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ gdouble unit_scaler = units[pv->unit].scale;
+ gtk_adjustment_set_value
+ (GTK_ADJUSTMENT(opt->info.flt.adjustment),
+ (stp_get_dimension_parameter(pv->v, opt->fast_desc->name) /
+ unit_scaler));
+ }
+ if (stp_check_dimension_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_adjustment_active(opt, TRUE, TRUE);
+ else
+ set_adjustment_active(opt, FALSE, TRUE);
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ if (stp_check_curve_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_curve_active(opt, TRUE, TRUE);
+ else
+ set_curve_active(opt, FALSE, TRUE);
+ break;
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ if (strcmp(opt->fast_desc->name, "PageSize") == 0)
+ build_page_size_combo(opt);
+ else if (stp_check_string_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ plist_build_combo(opt->info.list.combo, opt->info.list.label,
+ opt->info.list.params, opt->is_active,
+ (stp_get_string_parameter
+ (pv->v, opt->fast_desc->name)),
+ opt->info.list.default_val,
+ G_CALLBACK(combo_callback),
+ &(opt->info.list.callback_id),
+ NULL, opt);
+ if (stp_check_string_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_combo_active(opt, TRUE, TRUE);
+ else
+ set_combo_active(opt, FALSE, TRUE);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ if (stp_check_boolean_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON(opt->info.bool.checkbox),
+ stp_get_boolean_parameter(pv->v, opt->fast_desc->name));
+ if (stp_check_boolean_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE) ||
+ opt->fast_desc->is_mandatory)
+ set_bool_active(opt, TRUE, TRUE);
+ else
+ set_bool_active(opt, FALSE, TRUE);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ update_adjusted_thumbnail ();
+}
+
+static void
+update_options(void)
+{
+ gtk_widget_hide(page_size_table);
+ gtk_widget_hide(printer_features_table);
+ gtk_widget_hide(color_adjustment_table);
+ populate_options(pv->v);
+ populate_option_table(page_size_table, STP_PARAMETER_CLASS_CORE);
+ populate_option_table(printer_features_table, STP_PARAMETER_CLASS_FEATURE);
+ populate_option_table(color_adjustment_table, STP_PARAMETER_CLASS_OUTPUT);
+ gtk_widget_show(page_size_table);
+ gtk_widget_show(printer_features_table);
+ gtk_widget_show(color_adjustment_table);
+ set_options_active(NULL);
+}
+
+static void
+update_standard_print_command(void)
+{
+ char *label_text =
+ stpui_build_standard_print_command(pv, stp_get_printer(pv->v));
+ gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), label_text);
+ g_free(label_text);
+}
+
+static void
+do_all_updates(void)
+{
+ gint i;
+ suppress_preview_update++;
+ set_orientation(pv->orientation);
+ invalidate_preview_thumbnail ();
+ preview_update ();
+ update_standard_print_command();
+
+ if (pv->scaling < 0)
+ {
+ gdouble tmp = -pv->scaling;
+ gdouble max_ppi_scaling;
+ gdouble min_ppi_scaling;
+
+ compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling);
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = tmp;
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ }
+ else
+ {
+ gdouble tmp = pv->scaling;
+
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent), TRUE);
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = minimum_image_percent;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = tmp;
+ g_signal_emit_by_name (G_OBJECT(scaling_adjustment), "changed");
+ g_signal_emit_by_name (G_OBJECT(scaling_adjustment), "value_changed");
+ }
+
+ for (i = 0; i < output_type_count; i++)
+ {
+ if (stp_get_string_parameter(pv->v, "PrintingMode") &&
+ strcmp(output_types[i].value,
+ stp_get_string_parameter(pv->v, "PrintingMode")) == 0)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(output_types[i].button),
+ TRUE);
+ }
+
+ /*
+ * Now get option parameters.
+ */
+
+ update_options();
+ do_color_updates ();
+
+ gtk_option_menu_set_history (GTK_OPTION_MENU (orientation_menu),
+ pv->orientation + 1);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(units[pv->unit].checkbox),
+ TRUE);
+ gtk_label_set_text(GTK_LABEL(units_label), units[pv->unit].name);
+ suppress_preview_update--;
+ preview_update ();
+}
+
+static void
+copy_count_callback(GtkAdjustment *adjustment, gpointer data)
+{
+ gint copy_count = (gint) adjustment->value;
+ stpui_plist_set_copy_count(pv, copy_count);
+ update_standard_print_command();
+}
+
+static void
+auto_paper_size_callback(GtkWidget *widget, gpointer data)
+{
+ auto_paper_size =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_paper_size_button));
+ pv->auto_size_roll_feed_paper = auto_paper_size;
+ set_orientation(pv->orientation);
+ do_all_updates();
+}
+
+static void
+setup_auto_paper_size(void)
+{
+ const stp_papersize_t *ps =
+ stp_get_papersize_by_name(stp_get_string_parameter(pv->v, "PageSize"));
+ if (ps->height == 0 && ps->width != 0) /* Implies roll feed */
+ {
+ g_signal_handlers_block_matched (G_OBJECT(auto_paper_size_button),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auto_paper_size_button),
+ pv->auto_size_roll_feed_paper);
+ gtk_widget_show(auto_paper_size_button);
+ g_signal_handlers_unblock_matched (G_OBJECT(auto_paper_size_button),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ NULL);
+ }
+ else
+ {
+ gtk_widget_hide(auto_paper_size_button);
+ auto_paper_size = 0;
+ }
+}
+
+static void
+queue_callback (GtkWidget *widget,
+ gpointer data)
+{
+ int i;
+ int count = stp_string_list_count(stpui_system_print_queues);
+ const gchar *result =
+ gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(queue_combo)->entry));
+ for (i = 0; i < count; i++)
+ {
+ const stp_param_string_t *s =
+ stp_string_list_param(stpui_system_print_queues, i);
+ if (!strcmp(result, s->text))
+ {
+ stpui_plist_set_queue_name(pv, s->name);
+ do_all_updates();
+ return;
+ }
+ }
+}
+
+static void
+setup_callback (GtkWidget *widget)
+{
+ const gchar *new_value = gtk_entry_get_text (GTK_ENTRY (widget));
+
+ if (widget == custom_command_entry)
+ stpui_plist_set_custom_command(pv, new_value);
+ else if (widget == file_entry)
+ {
+ stpui_plist_set_output_filename(pv, new_value);
+ gtk_file_selection_set_filename
+ (GTK_FILE_SELECTION (file_browser),
+ gtk_entry_get_text (GTK_ENTRY (file_entry)));
+ }
+}
+
+/*
+ * plist_callback() - Update the current system printer.
+ */
+static void
+plist_callback (GtkWidget *widget,
+ gpointer data)
+{
+ gint i;
+ char *tmp;
+ stp_parameter_t desc;
+
+ suppress_preview_update++;
+ invalidate_frame ();
+ invalidate_preview_thumbnail ();
+ reset_preview ();
+
+ if (widget)
+ {
+ const gchar *result =
+ gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(printer_combo)->entry));
+
+ for (i = 0; i < stpui_plist_count; i++)
+ {
+ if (! strcmp (result, stp_string_list_param(printer_list, i)->text))
+ {
+ stpui_plist_current = i;
+ break;
+ }
+ }
+ }
+ else
+ {
+ stpui_plist_current = (gint) data;
+ }
+
+ set_current_printer();
+ build_queue_combo();
+ manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
+ build_printer_driver_clist();
+
+ if (strcmp(stp_get_driver(pv->v), "") != 0)
+ tmp_printer = stp_get_printer(pv->v);
+
+ stp_describe_parameter(pv->v, "PrintingMode", &desc);
+ if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST)
+ {
+ if (!stp_string_list_is_present(desc.bounds.str, "Color"))
+ {
+ gtk_widget_set_sensitive (output_types[1].button, TRUE);
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON (output_types[0].button)) == TRUE)
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (output_types[1].button), TRUE);
+ gtk_widget_set_sensitive (output_types[0].button, FALSE);
+ }
+ else if (!stp_string_list_is_present(desc.bounds.str, "BW"))
+ {
+ gtk_widget_set_sensitive (output_types[0].button, TRUE);
+ if (gtk_toggle_button_get_active
+ (GTK_TOGGLE_BUTTON (output_types[1].button)) == TRUE)
+ gtk_toggle_button_set_active
+ (GTK_TOGGLE_BUTTON (output_types[0].button), TRUE);
+ gtk_widget_set_sensitive (output_types[1].button, FALSE);
+ }
+ else
+ {
+ gtk_widget_set_sensitive (output_types[0].button, TRUE);
+ gtk_widget_set_sensitive (output_types[1].button, TRUE);
+ }
+ }
+ stp_parameter_description_destroy(&desc);
+ gtk_entry_set_text(GTK_ENTRY(file_entry),
+ stpui_plist_get_output_filename(pv));
+ tmp = stpui_build_standard_print_command(pv, stp_get_printer(pv->v));
+ gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), tmp);
+ stp_free(tmp);
+ gtk_entry_set_text(GTK_ENTRY(custom_command_entry),
+ stpui_plist_get_custom_command(pv));
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(copy_count_spin_button),
+ (gfloat) stpui_plist_get_copy_count(pv));
+ do_all_updates();
+
+ setup_update ();
+ do_all_updates();
+ suppress_preview_update--;
+ update_adjusted_thumbnail();
+ preview_update ();
+}
+
+static void
+show_all_paper_sizes_callback(GtkWidget *widget, gpointer data)
+{
+ int i;
+ stpui_show_all_paper_sizes =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *option = &(current_options[i]);
+ if (option->fast_desc &&
+ strcmp(option->fast_desc->name, "PageSize") == 0)
+ {
+ build_a_combo(option);
+ break;
+ }
+ }
+}
+
+static void
+custom_media_size_callback(GtkWidget *widget,
+ gpointer data)
+{
+ gint width_limit, height_limit;
+ gint min_width_limit, min_height_limit;
+ gdouble new_printed_value = atof(gtk_entry_get_text(GTK_ENTRY(widget)));
+ gint new_value = SCALE(new_printed_value, units[pv->unit].scale);
+ invalidate_frame ();
+ invalidate_preview_thumbnail ();
+ reset_preview ();
+
+ stp_get_size_limit(pv->v, &width_limit, &height_limit,
+ &min_width_limit, &min_height_limit);
+ if (widget == custom_size_width)
+ {
+ if (new_value < min_width_limit)
+ new_value = min_width_limit;
+ else if (new_value > width_limit)
+ new_value = width_limit;
+ stp_set_page_width (pv->v, new_value);
+ }
+ else
+ {
+ if (new_value < min_height_limit)
+ new_value = min_height_limit;
+ else if (new_value > height_limit)
+ new_value = height_limit;
+ stp_set_page_height (pv->v, new_value);
+ }
+ set_entry_value (widget, new_value, 0);
+ preview_update ();
+}
+
+
+/*
+ * media_size_callback() - Update the current media size.
+ */
+static void
+set_media_size(const gchar *new_media_size)
+{
+ static int setting_media_size = 0;
+ const stp_papersize_t *pap = stp_get_papersize_by_name (new_media_size);
+
+ if (setting_media_size)
+ return;
+ setting_media_size++;
+
+ if (pap)
+ {
+ gint size;
+ int old_width = stp_get_page_width(pv->v);
+ int old_height = stp_get_page_height(pv->v);
+ int need_preview_update = 0;
+
+ if (! stpui_show_all_paper_sizes &&
+ (pap->paper_unit == PAPERSIZE_METRIC_EXTENDED ||
+ pap->paper_unit == PAPERSIZE_ENGLISH_EXTENDED))
+ {
+ int i;
+ stp_parameter_t desc;
+ stp_describe_parameter(pv->v, "PageSize", &desc);
+ stp_set_string_parameter(pv->v, "PageSize", desc.deflt.str);
+ pap = stp_get_papersize_by_name(desc.deflt.str);
+ stp_parameter_description_destroy(&desc);
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *option = &(current_options[i]);
+ if (option->fast_desc &&
+ strcmp(option->fast_desc->name, "PageSize") == 0)
+ {
+ build_a_combo(option);
+ break;
+ }
+ }
+ }
+
+ if (pap->width == 0)
+ {
+ int max_w, max_h, min_w, min_h;
+ stp_get_size_limit(pv->v, &max_w, &max_h, &min_w, &min_h);
+ size = old_width;
+ if (size < min_w)
+ size = min_w;
+ else if (size > max_w)
+ size = max_w;
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_width), TRUE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_width), TRUE);
+ }
+ else
+ {
+ size = pap->width;
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_width), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_width), FALSE);
+ }
+ if (size != old_width)
+ {
+ need_preview_update = 1;
+ set_entry_value (custom_size_width, size, 0);
+ stp_set_page_width (pv->v, size);
+ }
+
+ setup_auto_paper_size();
+ if (pap->height == 0)
+ {
+ int max_w, max_h, min_w, min_h;
+ stp_get_size_limit(pv->v, &max_w, &max_h, &min_w, &min_h);
+ if (auto_paper_size)
+ {
+ int l, r, b, t;
+ stp_set_page_height(pv->v, 0);
+ old_height = 0;
+ stp_get_imageable_area(pv->v, &l, &r, &b, &t);
+ gtk_widget_set_sensitive(GTK_WIDGET(custom_size_height), FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(custom_size_height), FALSE);
+ size = print_height;
+ }
+ else
+ {
+ gtk_widget_set_sensitive (GTK_WIDGET (custom_size_height), TRUE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_height), TRUE);
+ size = old_height;
+ }
+ if (size < min_h)
+ size = min_h;
+ else if (size > max_h)
+ size = max_h;
+ }
+ else
+ {
+ size = pap->height;
+ gtk_widget_set_sensitive(GTK_WIDGET (custom_size_height), FALSE);
+ gtk_entry_set_editable (GTK_ENTRY (custom_size_height), FALSE);
+ }
+ if (size != old_height)
+ {
+ need_preview_update = 1;
+ set_entry_value (custom_size_height, size, 0);
+ stp_set_page_height (pv->v, size);
+ }
+ if (need_preview_update)
+ {
+ invalidate_preview_thumbnail();
+ invalidate_frame();
+ preview_update();
+ }
+ }
+ setting_media_size--;
+}
+
+static gboolean
+refresh_all_options(gpointer data)
+{
+ do_all_updates();
+ do_all_updates(); /* Update twice to pick up cascading changes */
+ return FALSE;
+}
+
+static void
+combo_callback(GtkWidget *widget, gpointer data)
+{
+ option_t *option = (option_t *)data;
+ const gchar *new_value =
+ stpui_combo_get_name(option->info.list.combo, option->info.list.params);
+ const gchar *value =
+ stp_get_string_parameter(pv->v, option->fast_desc->name);
+ if (value && new_value)
+ {
+ reset_preview();
+ if (!value || strcmp(value, new_value) != 0)
+ {
+ invalidate_frame();
+ invalidate_preview_thumbnail();
+ stp_set_string_parameter(pv->v, option->fast_desc->name, new_value);
+ if (strcmp(option->fast_desc->name, "PageSize") == 0)
+ set_media_size(new_value);
+ g_idle_add(refresh_all_options, NULL);
+ if (option->fast_desc->p_class == STP_PARAMETER_CLASS_OUTPUT)
+ update_adjusted_thumbnail();
+ preview_update();
+ }
+ }
+}
+
+/*
+ * orientation_callback() - Update the current media size.
+ */
+static void
+orientation_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (pv->orientation != (gint) data)
+ {
+ invalidate_preview_thumbnail ();
+ set_orientation((gint) data);
+ preview_update ();
+ }
+}
+
+/*
+ * output_type_callback() - Update the current output type.
+ */
+static void
+output_type_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ {
+ if (strcmp((const char *) data, "BW") == 0)
+ gtk_widget_hide(output_color_vbox);
+ else
+ gtk_widget_show(output_color_vbox);
+ stp_set_string_parameter(pv->v, "PrintingMode", (const char *) data);
+ invalidate_preview_thumbnail ();
+ update_adjusted_thumbnail ();
+ set_options_active(NULL);
+ preview_update ();
+ do_all_updates();
+ }
+}
+
+static void
+command_type_callback(GtkWidget *widget, gpointer data)
+{
+ if (strcmp((const char *) data, "Standard") == 0)
+ {
+ gtk_widget_set_sensitive(standard_cmd_entry, TRUE);
+ gtk_widget_set_sensitive(queue_combo, TRUE);
+ gtk_widget_set_sensitive(file_entry, FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(file_entry), FALSE);
+ gtk_widget_set_sensitive(custom_command_entry, FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), FALSE);
+ gtk_widget_hide(GTK_WIDGET(file_browser));
+ gtk_widget_set_sensitive(file_button, FALSE);
+ gtk_widget_set_sensitive(copy_count_spin_button, TRUE);
+ stpui_plist_set_command_type(pv, COMMAND_TYPE_DEFAULT);
+ }
+ else if (strcmp((const char *) data, "Custom") == 0)
+ {
+ gtk_widget_set_sensitive(standard_cmd_entry, FALSE);
+ gtk_widget_set_sensitive(queue_combo, FALSE);
+ gtk_widget_set_sensitive(file_entry, FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(file_entry), FALSE);
+ gtk_widget_set_sensitive(custom_command_entry, TRUE);
+ gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), TRUE);
+ gtk_widget_hide(GTK_WIDGET(file_browser));
+ gtk_widget_set_sensitive(file_button, FALSE);
+ gtk_widget_set_sensitive(copy_count_spin_button, FALSE);
+ stpui_plist_set_command_type(pv, COMMAND_TYPE_CUSTOM);
+ }
+ else if (strcmp((const char *) data, "File") == 0)
+ {
+ gtk_widget_set_sensitive(standard_cmd_entry, FALSE);
+ gtk_widget_set_sensitive(queue_combo, FALSE);
+ gtk_widget_set_sensitive(file_entry, TRUE);
+ gtk_entry_set_editable(GTK_ENTRY(file_entry), TRUE);
+ gtk_widget_set_sensitive(custom_command_entry, FALSE);
+ gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), FALSE);
+ gtk_widget_set_sensitive(file_button, TRUE);
+ gtk_widget_set_sensitive(copy_count_spin_button, FALSE);
+ stpui_plist_set_command_type(pv, COMMAND_TYPE_FILE);
+ }
+}
+
+static void
+set_all_entry_values(void)
+{
+ set_entry_value (top_entry, (stp_get_top (pv->v)), 1);
+ set_entry_value (left_entry, (stp_get_left (pv->v)), 1);
+/*
+ set_entry_value (bottom_entry, (top + stp_get_top(pv->v) + print_height), 1);
+*/
+ set_entry_value (bottom_border_entry,
+ (paper_height - (stp_get_top (pv->v) + print_height)), 1);
+/*
+ set_entry_value (right_entry, (stp_get_left(pv->v) + print_width), 1);
+*/
+ set_entry_value (right_border_entry,
+ (paper_width - (stp_get_left (pv->v) + print_width)), 1);
+ set_entry_value (width_entry, print_width, 1);
+ set_entry_value (height_entry, print_height, 1);
+ set_entry_value (custom_size_width, stp_get_page_width (pv->v), 1);
+ set_entry_value (custom_size_height, stp_get_page_height (pv->v), 1);
+}
+
+/*
+ * unit_callback() - Update the current unit.
+ */
+static void
+unit_callback (GtkWidget *widget,
+ gpointer data)
+{
+ reset_preview ();
+
+ if (GTK_TOGGLE_BUTTON (widget)->active)
+ {
+ pv->unit = (gint) data;
+ gtk_label_set_text(GTK_LABEL(units_label), units[pv->unit].name);
+ set_all_entry_values();
+ update_options();
+ do_color_updates();
+ }
+}
+
+static void
+destroy_dialogs (void)
+{
+ int i;
+ gtk_widget_destroy (color_adjust_dialog);
+ gtk_widget_destroy (setup_dialog);
+ gtk_widget_destroy (print_dialog);
+ gtk_widget_destroy (new_printer_dialog);
+ gtk_widget_destroy (about_dialog);
+ for (i = 0; i < current_option_count; i++)
+ {
+ if (current_options[i].fast_desc->p_type == STP_PARAMETER_TYPE_CURVE &&
+ current_options[i].info.curve.dialog)
+ gtk_widget_destroy(current_options[i].info.curve.dialog);
+ }
+}
+
+static void
+dialogs_set_sensitive (gboolean sensitive)
+{
+ int i;
+ gtk_widget_set_sensitive (color_adjust_dialog, sensitive);
+ gtk_widget_set_sensitive (setup_dialog, sensitive);
+ gtk_widget_set_sensitive (print_dialog, sensitive);
+ gtk_widget_set_sensitive (new_printer_dialog, sensitive);
+ gtk_widget_set_sensitive (about_dialog, sensitive);
+ for (i = 0; i < current_option_count; i++)
+ {
+ if (current_options[i].fast_desc->p_type == STP_PARAMETER_TYPE_CURVE &&
+ current_options[i].info.curve.dialog)
+ gtk_widget_set_sensitive(current_options[i].info.curve.dialog,
+ sensitive);
+ }
+}
+
+/*
+ * 'print_callback()' - Start the print.
+ */
+static void
+print_callback (void)
+{
+ if (stpui_plist_get_command_type(pv) == COMMAND_TYPE_FILE &&
+ strlen(stpui_plist_get_output_filename(pv)) == 0)
+ {
+ dialogs_set_sensitive (FALSE);
+ exit_after_file_ok = 1;
+ gtk_widget_show (file_browser);
+ }
+ else
+ {
+ runme = TRUE;
+ destroy_dialogs ();
+ }
+}
+
+/*
+ * printandsave_callback() -
+ */
+static void
+printandsave_callback (void)
+{
+ saveme = TRUE;
+ print_callback();
+}
+
+static void
+about_callback (void)
+{
+ gtk_widget_show (about_dialog);
+}
+
+/*
+ * save_callback() - save settings, don't destroy dialog
+ */
+static void
+save_callback (void)
+{
+ reset_preview ();
+ stpui_printrc_save ();
+}
+
+/*
+ * setup_update() - update widgets in the setup dialog
+ */
+static void
+setup_update (void)
+{
+ GtkAdjustment *adjustment;
+ gint idx = 0;
+ gint i;
+ gchar *tmp;
+ const char *ppd_file_name = stp_get_file_parameter(pv->v, "PPDFile");
+
+ for (i = 0; i < GTK_CLIST(manufacturer_clist)->rows; i++)
+ {
+ (void) gtk_clist_get_text(GTK_CLIST(manufacturer_clist), i, 0, &tmp);
+ if (tmp && strcmp(manufacturer, tmp) == 0)
+ {
+ idx = i;
+ break;
+ }
+ }
+ gtk_clist_select_row(GTK_CLIST(manufacturer_clist), idx, 0);
+
+ idx = stp_get_printer_index_by_driver (stp_get_driver (pv->v));
+
+ idx = gtk_clist_find_row_from_data(GTK_CLIST(printer_driver),
+ (gpointer) idx);
+/*
+ if (idx >= 0)
+ idx = 0;
+*/
+ gtk_clist_select_row (GTK_CLIST (printer_driver), idx, 0);
+ gtk_label_set_text (GTK_LABEL (printer_model_label),
+ gettext (stp_printer_get_long_name (tmp_printer)));
+
+ if (ppd_file_name)
+ gtk_entry_set_text (GTK_ENTRY (ppd_file), ppd_file_name);
+ else
+ gtk_entry_set_text (GTK_ENTRY (ppd_file), "");
+
+ if (stp_parameter_find_in_settings(pv->v, "PPDFile"))
+ {
+ gtk_widget_show (ppd_box);
+ gtk_widget_show (ppd_label);
+ }
+ else
+ {
+ gtk_widget_hide (ppd_box);
+ gtk_widget_hide (ppd_label);
+ }
+ gtk_entry_set_text (GTK_ENTRY (custom_command_entry),
+ stpui_plist_get_custom_command (pv));
+
+ adjustment = GTK_CLIST (printer_driver)->vadjustment;
+ gtk_adjustment_set_value
+ (adjustment,
+ adjustment->lower + idx * (adjustment->upper - adjustment->lower) /
+ GTK_CLIST (printer_driver)->rows);
+
+ i = stpui_plist_get_command_type(pv);
+ if (i >= 0 && i < command_options_count)
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(command_options[i].button),
+ TRUE);
+}
+
+/*
+ * setup_open_callback() -
+ */
+static void
+setup_open_callback (void)
+{
+ static gboolean first_time = TRUE;
+ manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
+ build_printer_driver_clist();
+
+ reset_preview ();
+ setup_update ();
+
+/* gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, FALSE); */
+ gtk_widget_show (setup_dialog);
+
+ if (first_time)
+ {
+ /* Make sure the driver scroller gets positioned correctly. */
+ setup_update ();
+ first_time = FALSE;
+ }
+}
+
+/*
+ * new_printer_open_callback() -
+ */
+static void
+new_printer_open_callback (void)
+{
+ reset_preview ();
+ gtk_entry_set_text (GTK_ENTRY (new_printer_entry), "");
+ gtk_widget_show (new_printer_dialog);
+}
+
+static void
+set_printer(void)
+{
+ manufacturer = stp_printer_get_manufacturer(tmp_printer);
+ build_printer_driver_clist();
+ build_queue_combo();
+ stp_set_driver (pv->v, stp_printer_get_driver (tmp_printer));
+ stpui_plist_set_custom_command
+ (pv, gtk_entry_get_text (GTK_ENTRY (custom_command_entry)));
+ stpui_plist_set_output_filename
+ (pv, gtk_entry_get_text (GTK_ENTRY (file_entry)));
+ stp_set_file_parameter (pv->v, "PPDFile",
+ gtk_entry_get_text (GTK_ENTRY (ppd_file)));
+ gtk_label_set_text (GTK_LABEL (printer_model_label),
+ gettext (stp_printer_get_long_name (tmp_printer)));
+
+ plist_callback (NULL, (gpointer) stpui_plist_current);
+}
+
+/*
+ * setup_ok_callback() -
+ */
+static void
+setup_ok_callback (void)
+{
+ gtk_widget_hide(ppd_browser);
+ gtk_widget_hide(file_browser);
+ gtk_widget_hide(setup_dialog);
+ set_printer();
+ gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, TRUE);
+}
+
+/*
+ * setup_cancel_callback() -
+ */
+static void
+setup_cancel_callback (void)
+{
+ gtk_widget_hide(ppd_browser);
+ gtk_widget_hide(file_browser);
+ gtk_widget_hide(setup_dialog);
+ manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
+ build_printer_driver_clist();
+ setup_update();
+ gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, TRUE);
+}
+
+/*
+ * setup_ok_callback() -
+ */
+static void
+new_printer_ok_callback (void)
+{
+ const gchar *data = gtk_entry_get_text (GTK_ENTRY (new_printer_entry));
+ stpui_plist_t key;
+
+ if (strlen(data))
+ {
+ memset(&key, 0, sizeof(key));
+ stpui_printer_initialize (&key);
+ stpui_plist_copy(&key, pv);
+ stpui_plist_set_name(&key, data);
+
+ if (stpui_plist_add (&key, 1))
+ {
+ stp_vars_destroy(key.v);
+ g_free(key.name);
+ stpui_plist_current = stpui_plist_count - 1;
+ set_current_printer();
+ build_printer_combo ();
+ set_printer();
+ }
+ }
+
+ gtk_widget_hide (new_printer_dialog);
+}
+
+static void
+pop_ppd_box(void)
+{
+ const stp_vars_t *v = stp_printer_get_defaults(tmp_printer);
+ if (stp_parameter_find_in_settings(v, "PPDFile"))
+ {
+ gtk_widget_show (ppd_label);
+ gtk_widget_show (ppd_box);
+ }
+ else
+ {
+ gtk_widget_hide (ppd_label);
+ gtk_widget_hide (ppd_box);
+ }
+}
+
+static void
+build_printer_driver_clist(void)
+{
+ int i;
+ int current_idx = 0;
+ gtk_clist_clear(GTK_CLIST(printer_driver));
+ for (i = 0; i < stp_printer_model_count (); i ++)
+ {
+ const stp_printer_t *the_printer = stp_get_printer_by_index (i);
+
+ if (strcmp(manufacturer, stp_printer_get_manufacturer(the_printer)) == 0)
+ {
+ gchar *tmp=g_strdup(gettext(stp_printer_get_long_name(the_printer)));
+ /*
+ * FIXME Somehow if the raw printer comes before any of the
+ * "real" printers in the list of printers created in module.c,
+ * this code barfs on any of those printers added later. For
+ * example, try listing olympus_LTX_stpi_module_data after
+ * raw_LTX_stpi_module_data.
+ */
+
+ gtk_clist_insert (GTK_CLIST (printer_driver), current_idx, &tmp);
+ gtk_clist_set_row_data (GTK_CLIST (printer_driver), current_idx,
+ (gpointer) i);
+ g_free(tmp);
+ current_idx++;
+ }
+ }
+}
+
+static void
+manufacturer_callback(GtkWidget *widget, /* I - Driver list */
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data)
+{
+ static int calling_manufacturer_callback = 0;
+ gchar *text;
+ if (calling_manufacturer_callback)
+ return;
+ calling_manufacturer_callback++;
+ if (gtk_clist_get_text(GTK_CLIST(widget), row, column, &text))
+ manufacturer = text;
+ build_printer_driver_clist();
+ setup_update();
+ calling_manufacturer_callback--;
+}
+
+/*
+ * print_driver_callback() - Update the current printer driver.
+ */
+static void
+print_driver_callback (GtkWidget *widget, /* I - Driver list */
+ gint row,
+ gint column,
+ GdkEventButton *event,
+ gpointer data) /* I - Data */
+{
+ char *tmp;
+ static int calling_print_driver_callback = 0;
+ if (calling_print_driver_callback)
+ return;
+ calling_print_driver_callback++;
+ invalidate_frame ();
+ invalidate_preview_thumbnail ();
+ reset_preview ();
+ data = gtk_clist_get_row_data (GTK_CLIST (widget), row);
+ tmp_printer = stp_get_printer_by_index ((gint) data);
+ tmp = stpui_build_standard_print_command(pv, tmp_printer);
+ gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), tmp);
+ g_free(tmp);
+
+ pop_ppd_box();
+ calling_print_driver_callback--;
+}
+
+/*
+ * ppd_browse_callback() -
+ */
+static void
+ppd_browse_callback (void)
+{
+ reset_preview ();
+ gtk_file_selection_set_filename (GTK_FILE_SELECTION (ppd_browser),
+ gtk_entry_get_text (GTK_ENTRY (ppd_file)));
+ gtk_widget_show (ppd_browser);
+}
+
+/*
+ * ppd_ok_callback() -
+ */
+static void
+ppd_ok_callback (void)
+{
+ reset_preview ();
+ gtk_widget_hide (ppd_browser);
+ gtk_entry_set_text
+ (GTK_ENTRY (ppd_file),
+ gtk_file_selection_get_filename (GTK_FILE_SELECTION (ppd_browser)));
+}
+
+/*
+ * ppd_browse_callback() -
+ */
+static void
+file_browse_callback (void)
+{
+ reset_preview ();
+ gtk_file_selection_set_filename (GTK_FILE_SELECTION (file_browser),
+ gtk_entry_get_text (GTK_ENTRY (file_entry)));
+ gtk_widget_show (file_browser);
+}
+
+/*
+ * file_ok_callback() - print to file and go away
+ */
+static void
+file_ok_callback (void)
+{
+ const char *filename =
+ gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_browser));
+ gtk_widget_hide (file_browser);
+ gtk_entry_set_text(GTK_ENTRY(file_entry), filename);
+ stpui_plist_set_output_filename(pv, filename);
+ if (exit_after_file_ok)
+ {
+ runme = TRUE;
+ destroy_dialogs ();
+ }
+}
+
+/*
+ * file_cancel_callback() -
+ */
+static void
+file_cancel_callback (void)
+{
+ exit_after_file_ok = 0;
+ gtk_widget_hide (file_browser);
+ dialogs_set_sensitive (TRUE);
+}
+
+static void
+fill_buffer_writefunc(void *priv, const char *buffer, size_t bytes)
+{
+ int mask = 0;
+ int i;
+ int pixels = bytes / 4;
+ priv_t *p = (priv_t *) priv;
+ unsigned char *where = p->base_addr + p->offset;
+ const unsigned char *xbuffer = (const unsigned char *)buffer;
+
+ if (p->bpp == 1)
+ {
+ memcpy(where, buffer, bytes);
+ p->offset += bytes;
+ }
+ else
+ {
+ if (bytes + p->offset > p->limit)
+ bytes = p->limit - p->offset;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cyan_button)))
+ mask |= 1;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(magenta_button)))
+ mask |= 2;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(yellow_button)))
+ mask |= 4;
+ if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(black_button)))
+ mask |= 8;
+
+ memset(where, 0xff, pixels * 3);
+ for (i = 0; i < pixels; i++)
+ {
+ if (mask & 8)
+ {
+ where[0] -= xbuffer[3];
+ where[1] -= xbuffer[3];
+ where[2] -= xbuffer[3];
+ }
+ if (mask & 1)
+ {
+ if (where[0] < xbuffer[0])
+ where[0] = 0;
+ else
+ where[0] -= xbuffer[0];
+ }
+ if (mask & 2)
+ {
+ if (where[1] < xbuffer[1])
+ where[1] = 0;
+ else
+ where[1] -= xbuffer[1];
+ }
+ if (mask & 4)
+ {
+ if (where[2] < xbuffer[2])
+ where[2] = 0;
+ else
+ where[2] -= xbuffer[2];
+ }
+ where += 3;
+ xbuffer += 4;
+ }
+ p->offset += pixels * 3;
+ }
+}
+
+/*
+ * update_adjusted_thumbnail()
+ */
+
+static void
+redraw_color_swatch (void)
+{
+ static GdkGC *gc = NULL;
+ static GdkColormap *cmap;
+
+ if (adjusted_thumbnail_data && swatch && swatch->widget.window)
+ {
+ if (gc == NULL)
+ {
+ gc = gdk_gc_new (swatch->widget.window);
+ cmap = gtk_widget_get_colormap (GTK_WIDGET(swatch));
+ }
+
+ if (!print_mode_is_color(pv->v))
+ gdk_draw_gray_image(swatch->widget.window, gc, 0, 0,
+ thumbnail_w, thumbnail_h, GDK_RGB_DITHER_NORMAL,
+ adjusted_thumbnail_data, thumbnail_w);
+ else
+ gdk_draw_rgb_image(swatch->widget.window, gc, 0, 0,
+ thumbnail_w, thumbnail_h, GDK_RGB_DITHER_NORMAL,
+ adjusted_thumbnail_data, 3 * thumbnail_w);
+ }
+}
+
+static void
+initialize_thumbnail(void)
+{
+ int i;
+ if (stpui_get_thumbnail_func())
+ {
+ const guchar *internal_thumbnail_data;
+ /*
+ * Fetch a thumbnail of the image we're to print from the Gimp.
+ */
+
+ thumbnail_w = thumbnail_hintw;
+ thumbnail_h = thumbnail_hinth;
+ internal_thumbnail_data =
+ (stpui_get_thumbnail_func()) (stpui_get_thumbnail_data(), &thumbnail_w,
+ &thumbnail_h, &thumbnail_bpp, 0);
+ if (adjusted_thumbnail_data)
+ g_free(adjusted_thumbnail_data);
+ if (preview_thumbnail_data)
+ g_free(preview_thumbnail_data);
+ if (thumbnail_data)
+ g_free(thumbnail_data);
+
+ if (internal_thumbnail_data)
+ {
+ /*
+ * thumbnail_w and thumbnail_h have now been adjusted to the actual
+ * thumbnail dimensions. Now initialize a color-adjusted version of
+ * the thumbnail.
+ */
+
+ adjusted_thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h);
+ preview_thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h);
+ thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h);
+
+ switch (thumbnail_bpp)
+ {
+ case 1:
+ for (i = 0; i < thumbnail_w * thumbnail_h; i++)
+ {
+ gint val = internal_thumbnail_data[i];
+ thumbnail_data[(3 * i) + 0] = val;
+ thumbnail_data[(3 * i) + 1] = val;
+ thumbnail_data[(3 * i) + 2] = val;
+ }
+ break;
+ case 3:
+ memcpy(thumbnail_data, internal_thumbnail_data,
+ 3 * thumbnail_w * thumbnail_h);
+ break;
+ case 2:
+ for (i = 0; i < thumbnail_w * thumbnail_h; i++)
+ {
+ gint val = internal_thumbnail_data[2 * i];
+ gint alpha = internal_thumbnail_data[(2 * i) + 1];
+ thumbnail_data[(3 * i) +0] = val * alpha / 255 + 255 - alpha;
+ thumbnail_data[(3 * i) +1] = val * alpha / 255 + 255 - alpha;
+ thumbnail_data[(3 * i) +2] = val * alpha / 255 + 255 - alpha;
+ }
+ break;
+ case 4:
+ for (i = 0; i < thumbnail_w * thumbnail_h; i++)
+ {
+ gint r = internal_thumbnail_data[(4 * i)];
+ gint g = internal_thumbnail_data[(4 * i) + 1];
+ gint b = internal_thumbnail_data[(4 * i) + 2];
+ gint alpha = internal_thumbnail_data[(4 * i) + 3];
+ thumbnail_data[(3 * i) + 0] = r * alpha / 255 + 255 - alpha;
+ thumbnail_data[(3 * i) + 1] = g * alpha / 255 + 255 - alpha;
+ thumbnail_data[(3 * i) + 2] = b * alpha / 255 + 255 - alpha;
+ }
+ break;
+ default:
+ break;
+ /* Whatever */
+ }
+ thumbnail_bpp = 3;
+ }
+ else
+ {
+ thumbnail_h = 0;
+ thumbnail_w = 0;
+ }
+ }
+ else
+ {
+ thumbnail_h = 0;
+ thumbnail_w = 0;
+ }
+}
+
+static int
+compute_thumbnail(const stp_vars_t *v)
+{
+ priv_t priv;
+ int answer = 1;
+ stp_image_t *im = stpui_image_thumbnail_new(thumbnail_data, thumbnail_w,
+ thumbnail_h, thumbnail_bpp);
+ stp_vars_t *nv = stp_vars_create_copy(v);
+ stp_set_driver(nv, "raw-data-8");
+ stp_set_top(nv, 0);
+ stp_set_left(nv, 0);
+ stp_set_width(nv, thumbnail_w);
+ stp_set_height(nv, thumbnail_h);
+ stp_set_outfunc(nv, fill_buffer_writefunc);
+ stp_set_outdata(nv, &priv);
+ stp_set_errfunc(nv, stpui_get_errfunc());
+ stp_set_errdata(nv, stpui_get_errdata());
+ if (!print_mode_is_color(nv))
+ {
+ priv.bpp = 1;
+ stp_set_string_parameter(nv, "InkType", "RGBGray");
+ }
+ else
+ {
+ priv.bpp = 4;
+ stp_set_string_parameter(nv, "InkType", "CMYK");
+ }
+ stp_set_page_height(nv, thumbnail_h);
+ stp_set_page_width(nv, thumbnail_w);
+ stp_set_float_parameter(nv, "Density", 1.0);
+ stp_set_float_parameter(nv, "InkLimit", 0);
+ stp_set_string_parameter(nv, "InputImageType", "RGB");
+
+ priv.base_addr = adjusted_thumbnail_data;
+ priv.offset = 0;
+ priv.limit = thumbnail_bpp * thumbnail_h * thumbnail_w;
+
+ if (stp_verify(nv) != 1 || stp_print(nv, im) != 1)
+ {
+ answer = 0;
+ fprintf(stderr, "Could not print thumbnail!\n");
+ }
+ stp_vars_destroy(nv);
+ return answer;
+}
+
+static void
+set_thumbnail_orientation(void)
+{
+ gint x, y;
+ gint preview_limit = (thumbnail_h * thumbnail_w) - 1;
+ gint bpp;
+ if (!print_mode_is_color(pv->v))
+ bpp = 1;
+ else
+ bpp = 3;
+ switch (physical_orientation)
+ {
+ case ORIENT_PORTRAIT:
+ memcpy(preview_thumbnail_data, adjusted_thumbnail_data,
+ bpp * thumbnail_h * thumbnail_w);
+ break;
+ case ORIENT_SEASCAPE:
+ for (x = 0; x < thumbnail_w; x++)
+ for (y = 0; y < thumbnail_h; y++)
+ memcpy((preview_thumbnail_data +
+ bpp * (preview_limit - (x * thumbnail_h + y))),
+ (adjusted_thumbnail_data +
+ bpp * ((thumbnail_h - y - 1) * thumbnail_w + x)), bpp);
+ break;
+
+ case ORIENT_UPSIDEDOWN:
+ for (x = 0; x < thumbnail_h * thumbnail_w; x++)
+ memcpy((preview_thumbnail_data + bpp * (preview_limit - x)),
+ adjusted_thumbnail_data + bpp * x, bpp);
+ break;
+ case ORIENT_LANDSCAPE:
+ for (x = 0; x < thumbnail_w; x++)
+ for (y = 0; y < thumbnail_h; y++)
+ memcpy((preview_thumbnail_data + bpp * (x * thumbnail_h + y)),
+ (adjusted_thumbnail_data +
+ bpp * ((thumbnail_h - y - 1) * thumbnail_w + x)), bpp);
+ break;
+ }
+}
+
+static void
+update_adjusted_thumbnail (void)
+{
+ if (thumbnail_data && adjusted_thumbnail_data && do_update_thumbnail &&
+ suppress_preview_update == 0)
+ {
+ if (compute_thumbnail(pv->v))
+ {
+ set_thumbnail_orientation();
+ redraw_color_swatch ();
+ preview_update ();
+ }
+ }
+}
+
+static void
+draw_arrow (GdkWindow *w,
+ GdkGC *gc,
+ gint paper_left,
+ gint paper_top)
+{
+ gint u = preview_ppi/2;
+ gint ox = paper_left + preview_ppi * paper_width / INCH / 2;
+ gint oy = paper_top + preview_ppi * paper_height / INCH / 2;
+
+ oy -= preview_ppi * paper_height / INCH / 4;
+ if (oy < paper_top + u)
+ oy = paper_top + u;
+ gdk_draw_line (w, gc, ox, oy - u, ox - u, oy);
+ gdk_draw_line (w, gc, ox, oy - u, ox + u, oy);
+ gdk_draw_line (w, gc, ox, oy - u, ox, oy + u);
+}
+
+static void
+create_valid_preview(guchar **preview_data)
+{
+ if (adjusted_thumbnail_data)
+ {
+ gint bpp = (print_mode_is_color(pv->v)) ? 3 : 1;
+ gint v_denominator = preview_h > 1 ? preview_h - 1 : 1;
+ gint v_numerator = (preview_thumbnail_h - 1) % v_denominator;
+ gint v_whole = (preview_thumbnail_h - 1) / v_denominator;
+ gint h_denominator = preview_w > 1 ? preview_w - 1 : 1;
+ gint h_numerator = (preview_thumbnail_w - 1) % h_denominator;
+ gint h_whole = (preview_thumbnail_w - 1) / h_denominator;
+ gint adjusted_preview_width = bpp * preview_w;
+ gint adjusted_thumbnail_width = bpp * preview_thumbnail_w;
+ gint v_cur = 0;
+ gint v_last = -1;
+ gint v_error = v_denominator / 2;
+ gint y;
+ gint i;
+
+ if (*preview_data)
+ g_free (*preview_data);
+ *preview_data = g_malloc (bpp * preview_h * preview_w);
+
+ for (y = 0; y < preview_h; y++)
+ {
+ guchar *outbuf = *preview_data + adjusted_preview_width * y;
+
+ if (v_cur == v_last)
+ memcpy (outbuf, outbuf-adjusted_preview_width,
+ adjusted_preview_width);
+ else
+ {
+ guchar *inbuf = preview_thumbnail_data - bpp
+ + adjusted_thumbnail_width * v_cur;
+
+ gint h_cur = 0;
+ gint h_last = -1;
+ gint h_error = h_denominator / 2;
+ gint x;
+
+ v_last = v_cur;
+ for (x = 0; x < preview_w; x++)
+ {
+ if (h_cur == h_last)
+ {
+ for (i = 0; i < bpp; i++)
+ outbuf[i] = outbuf[i - bpp];
+ }
+ else
+ {
+ inbuf += bpp * (h_cur - h_last);
+ h_last = h_cur;
+ for (i = 0; i < bpp; i++)
+ outbuf[i] = inbuf[i];
+ }
+ outbuf += bpp;
+ h_cur += h_whole;
+ h_error += h_numerator;
+ if (h_error >= h_denominator)
+ {
+ h_error -= h_denominator;
+ h_cur++;
+ }
+ }
+ }
+ v_cur += v_whole;
+ v_error += v_numerator;
+ if (v_error >= v_denominator)
+ {
+ v_error -= v_denominator;
+ v_cur++;
+ }
+ }
+ preview_valid = TRUE;
+ }
+}
+
+/*
+ * preview_update_callback() -
+ */
+static void
+do_preview_thumbnail (void)
+{
+ static GdkGC *gc = NULL;
+ static GdkGC *gcinv = NULL;
+ static GdkGC *gcset = NULL;
+ static guchar *preview_data = NULL;
+ gint opx = preview_x;
+ gint opy = preview_y;
+ gint oph = preview_h;
+ gint opw = preview_w;
+ gint paper_display_left, paper_display_top;
+ gint printable_display_left, printable_display_top;
+ gint paper_display_width, paper_display_height;
+ gint printable_display_width, printable_display_height;
+ int l_bottom = stp_get_top(pv->v) + stp_get_height(pv->v);
+ int l_right = stp_get_left(pv->v) + stp_get_width(pv->v);
+
+ preview_ppi = preview_size_horiz * FINCH / (gdouble) paper_width;
+
+ if (preview_ppi > preview_size_vert * FINCH / (gdouble) paper_height)
+ preview_ppi = preview_size_vert * FINCH / (gdouble) paper_height;
+ if (preview_ppi > MAX_PREVIEW_PPI)
+ preview_ppi = MAX_PREVIEW_PPI;
+
+ if (preview == NULL || preview->widget.window == NULL)
+ return;
+ /*
+ * Center the page on the preview
+ */
+ paper_display_width = MAX(3, ROUNDUP(preview_ppi * paper_width, INCH));
+ paper_display_height = MAX(3, ROUNDUP(preview_ppi * paper_height, INCH));
+
+ paper_display_left = (preview_size_horiz - paper_display_width) / 2;
+ paper_display_top = (preview_size_vert - paper_display_height) / 2;
+
+ printable_display_width =
+ MAX(3, ROUNDUP(preview_ppi * printable_width, INCH));
+ printable_display_height =
+ MAX(3, ROUNDUP(preview_ppi * printable_height, INCH));
+
+ printable_display_left = paper_display_left + preview_ppi * left / INCH;
+ printable_display_top = paper_display_top + preview_ppi * top / INCH ;
+
+ preview_x =
+ 1 + paper_display_left + preview_ppi * stp_get_left (pv->v) / INCH;
+ preview_y =
+ 1 + paper_display_top + preview_ppi * stp_get_top (pv->v) / INCH;
+
+ if (!preview_valid)
+ {
+ gint preview_r = 1 + paper_display_left + preview_ppi * l_right / INCH;
+ gint preview_b = 1 + paper_display_top + preview_ppi * l_bottom / INCH;
+ preview_w = preview_r - preview_x;
+ preview_h = preview_b - preview_y;
+ if (preview_w >= printable_display_width)
+ preview_w = printable_display_width - 1;
+ if (preview_h >= printable_display_height)
+ preview_h = printable_display_height - 1;
+ }
+
+ if (preview_w + preview_x > printable_display_left + printable_display_width)
+ preview_x--;
+ if (preview_h + preview_y > printable_display_top + printable_display_height)
+ preview_y--;
+
+ if (gc == NULL)
+ {
+ gc = gdk_gc_new (preview->widget.window);
+ gcinv = gdk_gc_new (preview->widget.window);
+ gdk_gc_set_function (gcinv, GDK_INVERT);
+ gcset = gdk_gc_new (preview->widget.window);
+ gdk_gc_set_function (gcset, GDK_SET);
+ }
+
+ if (!preview_valid)
+ create_valid_preview(&preview_data);
+
+ if (printable_display_left < paper_display_left)
+ printable_display_left = paper_display_left;
+ if (printable_display_top < paper_display_top)
+ printable_display_top = paper_display_top;
+ if (printable_display_left + printable_display_width >
+ paper_display_left + paper_display_width)
+ printable_display_width =
+ paper_display_width - (paper_display_left - printable_display_left);
+ if (printable_display_top + printable_display_height >
+ paper_display_top + paper_display_height)
+ printable_display_height =
+ paper_display_height - (paper_display_top - printable_display_top);
+ if (need_exposure)
+ {
+ if (!frame_valid)
+ {
+ gdk_window_clear (preview->widget.window);
+ frame_valid = TRUE;
+ }
+ /* draw paper frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ paper_display_left, paper_display_top,
+ paper_display_width, paper_display_height);
+
+ /* draw printable frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ printable_display_left, printable_display_top,
+ printable_display_width, printable_display_height);
+ need_exposure = FALSE;
+ }
+ else if (!frame_valid)
+ {
+ gdk_window_clear (preview->widget.window);
+ /* draw paper frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ paper_display_left, paper_display_top,
+ paper_display_width, paper_display_height);
+
+ /* draw printable frame */
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ printable_display_left, printable_display_top,
+ printable_display_width, printable_display_height);
+ frame_valid = TRUE;
+ }
+ else
+ {
+ if (opx + opw <= preview_x || opy + oph <= preview_y ||
+ preview_x + preview_w <= opx || preview_y + preview_h <= opy)
+ {
+ gdk_window_clear_area (preview->widget.window, opx, opy, opw, oph);
+ }
+ else
+ {
+ if (opx < preview_x)
+ gdk_window_clear_area (preview->widget.window,
+ opx, opy, preview_x - opx, oph);
+ if (opy < preview_y)
+ gdk_window_clear_area (preview->widget.window,
+ opx, opy, opw, preview_y - opy);
+ if (opx + opw > preview_x + preview_w)
+ gdk_window_clear_area (preview->widget.window,
+ preview_x + preview_w, opy,
+ (opx + opw) - (preview_x + preview_w), oph);
+ if (opy + oph > preview_y + preview_h)
+ gdk_window_clear_area (preview->widget.window,
+ opx, preview_y + preview_h,
+ opw, (opy + oph) - (preview_y + preview_h));
+ }
+ }
+
+ draw_arrow (preview->widget.window, gcset, paper_display_left,
+ paper_display_top);
+
+ if (!preview_valid)
+ gdk_draw_rectangle (preview->widget.window, gc, 1,
+ preview_x, preview_y, preview_w, preview_h);
+ else if (!print_mode_is_color(pv->v))
+ gdk_draw_gray_image (preview->widget.window, gc,
+ preview_x, preview_y, preview_w, preview_h,
+ GDK_RGB_DITHER_NORMAL, preview_data, preview_w);
+ else
+ gdk_draw_rgb_image (preview->widget.window, gc,
+ preview_x, preview_y, preview_w, preview_h,
+ GDK_RGB_DITHER_NORMAL, preview_data, 3 * preview_w);
+
+ /* If we're printing full bleed, redisplay the paper frame */
+ if (preview_x <= paper_display_left || opx <= paper_display_left ||
+ preview_y <= paper_display_top || opy <= paper_display_top ||
+ preview_x + preview_w >= paper_display_left + paper_display_width ||
+ opx + opw >= paper_display_left + paper_display_width ||
+ preview_y + preview_h >= paper_display_top + paper_display_height ||
+ opy + oph >= paper_display_top + paper_display_height)
+ gdk_draw_rectangle (preview->widget.window, gc, 0,
+ paper_display_left, paper_display_top,
+ paper_display_width, paper_display_height);
+
+
+ /* draw orientation arrow pointing to top-of-paper */
+ draw_arrow (preview->widget.window, gcinv, paper_display_left,
+ paper_display_top);
+ gdk_flush();
+}
+
+static gboolean
+idle_preview_thumbnail(gpointer data)
+{
+ set_orientation(pv->orientation);
+ do_preview_thumbnail();
+ thumbnail_update_pending = FALSE;
+ return FALSE;
+}
+
+static void
+preview_expose (void)
+{
+ need_exposure = TRUE;
+ preview_update ();
+}
+
+static void
+preview_update (void)
+{
+ gdouble max_ppi_scaling; /* Maximum PPI for current page size */
+ gdouble min_ppi_scaling; /* Minimum PPI for current page size */
+
+ suppress_preview_update++;
+ stp_get_media_size(pv->v, &paper_width, &paper_height);
+
+ stp_get_imageable_area(pv->v, &left, &right, &bottom, &top);
+
+ printable_width = right - left;
+ printable_height = bottom - top;
+
+ if (pv->scaling < 0)
+ {
+ gdouble twidth;
+
+ compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling);
+
+ if (pv->scaling < 0 && pv->scaling > -min_ppi_scaling)
+ pv->scaling = -min_ppi_scaling;
+
+ twidth = (FINCH * (gdouble) image_width / -pv->scaling);
+ print_width = twidth + .5;
+ print_height = (twidth * (gdouble) image_height / image_width) + .5;
+ GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling;
+ GTK_ADJUSTMENT (scaling_adjustment)->value = -pv->scaling;
+
+ if (!suppress_scaling_adjustment)
+ {
+ suppress_preview_reset++;
+ gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ suppress_scaling_callback = TRUE;
+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE);
+ suppress_scaling_callback = FALSE;
+ gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment));
+ suppress_preview_reset--;
+ }
+ }
+ else if (auto_paper_size)
+ {
+ gdouble twidth = printable_width * pv->scaling / 100;
+
+ print_width = twidth + .5;
+ print_height =
+ (twidth * (gdouble) image_height / (gdouble) image_width) + .5;
+ }
+ else
+ {
+ /* we do pv->scaling % of height or width, whatever is less */
+ /* this is relative to printable size */
+ if (image_width * printable_height > printable_width * image_height)
+ /* if image_width/image_height > printable_width/printable_height */
+ /* i.e. if image is wider relative to its height than the width
+ of the printable area relative to its height */
+ {
+ gdouble twidth = printable_width * pv->scaling / 100;
+
+ print_width = twidth + .5;
+ print_height =
+ (twidth * (gdouble) image_height / (gdouble) image_width) + .5;
+ }
+ else
+ {
+ gdouble theight = printable_height * pv->scaling /100;
+
+ print_height = theight + .5;
+ print_width =
+ (theight * (gdouble) image_width / (gdouble) image_height) + .5;
+ }
+ }
+
+ if (auto_paper_size)
+ set_media_size(stp_get_string_parameter(pv->v, "PageSize"));
+
+ stp_set_width(pv->v, print_width);
+ stp_set_height(pv->v, print_height);
+
+ if (pv->invalid_mask & INVALID_LEFT)
+ stp_set_left (pv->v, (paper_width - print_width) / 2);
+
+ if (stp_get_left(pv->v) < left)
+ stp_set_left(pv->v, left);
+
+ if (stp_get_left (pv->v) > right - print_width)
+ stp_set_left (pv->v, right - print_width);
+
+ if (pv->invalid_mask & INVALID_TOP)
+ stp_set_top (pv->v, ((paper_height - print_height) / 2));
+ if (stp_get_top(pv->v) < top)
+ stp_set_top(pv->v, top);
+
+ if (stp_get_top (pv->v) > bottom - print_height)
+ stp_set_top (pv->v, bottom - print_height);
+
+ pv->invalid_mask = 0;
+
+ set_all_entry_values();
+ suppress_preview_update--;
+
+ /* draw image */
+ if (! suppress_preview_update && !thumbnail_update_pending)
+ {
+ thumbnail_update_pending = TRUE;
+ g_idle_add(idle_preview_thumbnail, NULL);
+ }
+}
+
+/*
+ * preview_button_callback() -
+ */
+static void
+preview_button_callback (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ if (event->type == GDK_BUTTON_PRESS)
+ {
+ if (preview_active == 0)
+ {
+ mouse_x = event->x;
+ mouse_y = event->y;
+ orig_left = stp_get_left (pv->v);
+ orig_top = stp_get_top (pv->v);
+ mouse_button = event->button;
+ buttons_mask = 1 << event->button;
+ buttons_pressed++;
+ preview_active = 1;
+ stpui_disable_help();
+ move_constraint =
+ (event->state & GDK_SHIFT_MASK) ? MOVE_CONSTRAIN : MOVE_ANY;
+ if (event->state & GDK_CONTROL_MASK)
+ move_constraint |= MOVE_GRID;
+ }
+ else if ((buttons_mask & (1 << event->button)) == 0)
+ {
+ if (preview_active == 1)
+ {
+ stpui_enable_help();
+ preview_active = -1;
+ stp_set_left (pv->v, orig_left);
+ stp_set_top (pv->v, orig_top);
+ preview_update ();
+ }
+ buttons_mask |= 1 << event->button;
+ buttons_pressed++;
+ }
+ }
+ else if (event->type == GDK_BUTTON_RELEASE)
+ {
+ buttons_pressed--;
+ buttons_mask &= ~(1 << event->button);
+ if (buttons_pressed == 0)
+ {
+ stpui_enable_help ();
+ preview_active = 0;
+ }
+ }
+}
+
+/*
+ * preview_motion_callback() -
+ */
+static void
+preview_motion_callback (GtkWidget *widget,
+ GdkEventMotion *event,
+ gpointer data)
+{
+
+ gint old_top = stp_get_top (pv->v);
+ gint old_left = stp_get_left (pv->v);
+ gint new_top = old_top;
+ gint new_left = old_left;
+ gint steps;
+ if (preview_active != 1 || event->type != GDK_MOTION_NOTIFY)
+ return;
+ if (move_constraint == MOVE_CONSTRAIN)
+ {
+ int dx = abs(event->x - mouse_x);
+ int dy = abs(event->y - mouse_y);
+ if (dx > dy && dx > 3)
+ move_constraint = MOVE_HORIZONTAL;
+ else if (dy > dx && dy > 3)
+ move_constraint = MOVE_VERTICAL;
+ else
+ return;
+ }
+
+ switch (mouse_button)
+ {
+ case 1:
+ if (move_constraint & MOVE_VERTICAL)
+ new_top = orig_top + INCH * (event->y - mouse_y) / preview_ppi;
+ if (move_constraint & MOVE_HORIZONTAL)
+ new_left = orig_left + INCH * (event->x - mouse_x) / preview_ppi;
+ break;
+ case 3:
+ if (move_constraint & MOVE_VERTICAL)
+ new_top = orig_top + event->y - mouse_y;
+ if (move_constraint & MOVE_HORIZONTAL)
+ new_left = orig_left + event->x - mouse_x;
+ break;
+ case 2:
+ if (move_constraint & MOVE_HORIZONTAL)
+ {
+ gint increment_width =
+ ((move_constraint & MOVE_GRID) && pv->scaling > 0) ?
+ printable_width * pv->scaling / 100 : print_width;
+ gint x_threshold = MAX (1, (preview_ppi * increment_width) / INCH);
+ if (event->x > mouse_x)
+ steps = MIN((event->x - mouse_x) / x_threshold,
+ ((right - orig_left) / increment_width) - 1);
+ else
+ steps = -(MIN((mouse_x - event->x) / x_threshold,
+ (orig_left - left) / increment_width));
+ new_left = orig_left + steps * increment_width;
+ }
+ if (move_constraint & MOVE_VERTICAL)
+ {
+ gint increment_height =
+ ((move_constraint & MOVE_GRID) && pv->scaling > 0) ?
+ printable_height * pv->scaling / 100 : print_height;
+ gint y_threshold = MAX (1, (preview_ppi * increment_height) / INCH);
+ if (event->y > mouse_y)
+ steps = MIN((event->y - mouse_y) / y_threshold,
+ ((bottom - orig_top) / increment_height) - 1);
+ else
+ steps = -(MIN((mouse_y - event->y) / y_threshold,
+ (orig_top - top) / increment_height));
+ new_top = orig_top + steps * increment_height;
+ }
+ break;
+ }
+
+ if (new_top < top)
+ new_top = top;
+ if (new_top > bottom - print_height)
+ new_top = bottom - print_height;
+ if (new_left < left)
+ new_left = left;
+ if (new_left > right - print_width)
+ new_left = right - print_width;
+
+ if (new_top != old_top || new_left != old_left)
+ {
+ stp_set_top (pv->v, new_top);
+ stp_set_left (pv->v, new_left);
+ preview_update ();
+ }
+}
+
+static void
+color_update (GtkAdjustment *adjustment)
+{
+ int i;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ if (opt->fast_desc->p_type == STP_PARAMETER_TYPE_DOUBLE &&
+ opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL &&
+ opt->info.flt.adjustment &&
+ adjustment == GTK_ADJUSTMENT(opt->info.flt.adjustment))
+ {
+ invalidate_preview_thumbnail ();
+ if (stp_get_float_parameter(pv->v, opt->fast_desc->name) !=
+ adjustment->value)
+ {
+ stp_set_float_parameter(pv->v, opt->fast_desc->name,
+ adjustment->value);
+ update_adjusted_thumbnail();
+ }
+ }
+ }
+}
+
+static void
+dimension_update (GtkAdjustment *adjustment)
+{
+ int i;
+ gdouble unit_scaler = units[pv->unit].scale;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ if (opt->fast_desc->p_type == STP_PARAMETER_TYPE_DIMENSION &&
+ opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL &&
+ opt->info.flt.adjustment &&
+ adjustment == GTK_ADJUSTMENT(opt->info.flt.adjustment))
+ {
+ invalidate_preview_thumbnail ();
+ if (stp_get_dimension_parameter(pv->v, opt->fast_desc->name) !=
+ adjustment->value * unit_scaler)
+ {
+ stp_set_dimension_parameter(pv->v, opt->fast_desc->name,
+ adjustment->value * unit_scaler);
+ update_adjusted_thumbnail();
+ }
+ }
+ }
+}
+
+static void
+set_controls_active (GtkObject *checkbutton, gpointer xopt)
+{
+ option_t *opt = (option_t *) xopt;
+ stp_parameter_t desc;
+ gboolean setting =
+ gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton));
+ if (setting && opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL)
+ {
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_DOUBLE:
+ set_adjustment_active(opt, TRUE, FALSE);
+ if (! stp_check_float_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_float_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.dbl);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_float_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ set_adjustment_active(opt, TRUE, FALSE);
+ if (! stp_check_dimension_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_dimension_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.dimension);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ set_curve_active(opt, TRUE, FALSE);
+ if (! stp_check_curve_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_curve_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.curve);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_curve_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ set_combo_active(opt, TRUE, FALSE);
+ if (! stp_check_string_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_string_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.str);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_string_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ set_bool_active(opt, TRUE, FALSE);
+ if (! stp_check_boolean_parameter(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE))
+ {
+ stp_describe_parameter(pv->v, opt->fast_desc->name, &desc);
+ stp_set_boolean_parameter(pv->v, opt->fast_desc->name,
+ desc.deflt.boolean);
+ stp_parameter_description_destroy(&desc);
+ }
+ stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_ACTIVE);
+ break;
+ default:
+ break;
+ }
+ }
+ else
+ {
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_DOUBLE:
+ set_adjustment_active(opt, FALSE, FALSE);
+ stp_set_float_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ set_adjustment_active(opt, FALSE, FALSE);
+ stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_CURVE:
+ set_curve_active(opt, FALSE, FALSE);
+ stp_set_curve_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ set_combo_active(opt, FALSE, FALSE);
+ stp_set_string_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN: /* ??? */
+ set_bool_active(opt, FALSE, FALSE);
+ stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name,
+ STP_PARAMETER_INACTIVE);
+ break;
+ default:
+ break;
+ }
+ }
+ invalidate_preview_thumbnail();
+ update_adjusted_thumbnail();
+}
+
+static void
+set_color_defaults (void)
+{
+ int i;
+ for (i = 0; i < current_option_count; i++)
+ {
+ option_t *opt = &(current_options[i]);
+ if (opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL &&
+ opt->fast_desc->p_class == STP_PARAMETER_CLASS_OUTPUT &&
+ opt->is_active && !opt->fast_desc->read_only)
+ {
+ stp_parameter_activity_t active;
+ gdouble unit_scaler;
+ switch (opt->fast_desc->p_type)
+ {
+ case STP_PARAMETER_TYPE_DOUBLE:
+ active =
+ stp_get_float_parameter_active(pv->v, opt->fast_desc->name);
+ stp_set_float_parameter(pv->v, opt->fast_desc->name,
+ opt->info.flt.deflt);
+ stp_set_float_parameter_active(pv->v, opt->fast_desc->name,
+ active);
+ break;
+ case STP_PARAMETER_TYPE_DIMENSION:
+ unit_scaler = units[pv->unit].scale;
+ active =
+ stp_get_dimension_parameter_active(pv->v,
+ opt->fast_desc->name);
+ stp_set_dimension_parameter(pv->v, opt->fast_desc->name,
+ opt->info.flt.deflt * unit_scaler);
+ stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name,
+ active);
+ break;
+ case STP_PARAMETER_TYPE_BOOLEAN:
+ active =
+ stp_get_boolean_parameter_active(pv->v, opt->fast_desc->name);
+ stp_set_boolean_parameter(pv->v, opt->fast_desc->name,
+ opt->info.bool.deflt);
+ stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name,
+ active);
+ break;
+ case STP_PARAMETER_TYPE_STRING_LIST:
+ active =
+ stp_get_string_parameter_active(pv->v, opt->fast_desc->name);
+ stp_set_string_parameter(pv->v, opt->fast_desc->name,
+ opt->info.list.default_val);
+ stp_set_string_parameter_active(pv->v, opt->fast_desc->name,
+ active);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ do_color_updates ();
+}
+
+gint
+stpui_do_print_dialog(void)
+{
+ /*
+ * Get printrc options...
+ */
+ stpui_printrc_load ();
+
+ /*
+ * Print dialog window...
+ */
+ create_main_window();
+
+ gtk_main ();
+ gdk_flush ();
+
+ /*
+ * Set printrc options...
+ */
+ if (saveme)
+ stpui_printrc_save ();
+
+ /*
+ * Return ok/cancel...
+ */
+ return (runme);
+}