#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 <gimp-print/gimp-print-intl-internal.h>
#include <gimp-print-ui2/gimp-print-ui.h>
#include "gimp-print-ui-internal.h"
#include <string.h>
#include <stdio.h>
#define MAXIMUM_PARAMETER_LEVEL STP_PARAMETER_LEVEL_ADVANCED4
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
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;
static GtkWidget *recenter_button;
static GtkWidget *recenter_vertical_button;
static GtkWidget *recenter_horizontal_button;
static GtkWidget *left_entry;
static GtkWidget *right_border_entry;
static GtkWidget *top_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;
static GtkWidget *scaling_percent;
static GtkWidget *scaling_ppi;
static GtkWidget *scaling_image;
static GtkObject *scaling_adjustment;
static GtkWidget *setup_dialog;
static GtkWidget *printer_driver;
static GtkWidget *printer_model_label;
static GtkWidget *printer_crawler;
static GtkWidget *printer_combo;
static GtkWidget *manufacturer_clist;
static GtkWidget *manufacturer_crawler;
static gint plist_callback_id = -1;
static GtkWidget *ppd_file;
static GtkWidget *ppd_box;
static GtkWidget *ppd_label;
static GtkWidget *ppd_button;
static GtkWidget *ppd_browser;
static GtkWidget *new_printer_dialog;
static GtkWidget *new_printer_entry;
static GtkWidget *file_button;
static GtkWidget *file_entry;
static GtkWidget *file_browser;
static GtkWidget *standard_cmd_entry;
static GtkWidget *custom_command_entry;
static GtkWidget *queue_combo;
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 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;
static gint suppress_preview_update = 0;
static gint suppress_preview_reset = 0;
static GtkDrawingArea *preview = NULL;
static GtkDrawingArea *swatch = NULL;
static gint mouse_x, mouse_y;
static gint orig_top, orig_left;
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;
static gint preview_thumbnail_w, preview_thumbnail_h;
static gint preview_x, preview_y, preview_w, preview_h;
static gint physical_orientation = -2;
static gint paper_width, paper_height;
static gint printable_width, printable_height;
static gint print_width, print_height;
static gint left, right, top, bottom;
static gint image_width, image_height;
static gint image_true_width, image_true_height;
static gdouble image_xres, image_yres;
static gint do_update_thumbnail = 0;
static gint saveme = 0;
static gint runme = 0;
static gint exit_after_file_ok = 0;
static gint auto_paper_size = 0;
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 plist_build_combo(GtkWidget *combo,
GtkWidget *label,
stp_string_list_t *items,
int active,
const gchar *cur_item,
const gchar *def_value,
GtkSignalFunc 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));
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, (float *) 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();
}
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,
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,
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)
{
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, 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, 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, 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, "", "", 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;
}
for (i = 0; i < current_option_count; i++)
{
const stp_parameter_t *desc = current_options[i].fast_desc;
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;
}
}
}
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;
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);
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);
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++;
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"),
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"),
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_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_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);
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"));
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);
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);
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_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);
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,
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);
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_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 Gimp-Print " PLUG_IN_VERSION),
GTK_WIN_POS_MOUSE, FALSE,
_("OK"), gtk_widget_hide,
NULL, (GObject *) 1, NULL, TRUE, TRUE,
NULL);
label = gtk_label_new
(_("Gimp-Print Version " PLUG_IN_VERSION "\n"
"\n"
"Copyright (C) 1997-2003 Michael Sweet, Robert Krawitz,\n"
"and the rest of the Gimp-Print 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_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);
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);
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_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);
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);
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);
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"));
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);
}
static void
create_color_adjust_window (void)
{
GtkWidget *table;
GtkWidget *label;
GtkWidget *event_box;
GtkWidget *scrolled_window;
gint x, y;
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_box_pack_start (GTK_BOX (GTK_DIALOG (color_adjust_dialog)->vbox),
table, TRUE, TRUE, 0);
gtk_widget_show (table);
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);
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);
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);
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,
output_type_callback);
sep = gtk_hseparator_new ();
gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0);
gtk_widget_show (sep);
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);
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);
}
}
static void
create_main_window (void)
{
gint x, y;
set_current_printer();
manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v));
stpui_help_init();
create_top_level_structure ();
create_preview ();
create_printer_settings_frame ();
create_units_frame();
create_paper_size_frame();
create_positioning_frame ();
create_scaling_frame ();
create_image_settings_frame ();
do_update_thumbnail = 1;
build_printer_combo ();
plist_callback (NULL, (gpointer) stpui_plist_current);
update_adjusted_thumbnail ();
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;
}
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;
}
}
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;
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--;
}
static void
plist_build_combo (GtkWidget *combo,
GtkWidget *label,
stp_string_list_t *items,
int active,
const gchar *cur_item,
const gchar *def_value,
GtkSignalFunc callback,
gint *callback_id,
int (*check_func)(const char *string),
gpointer data)
{
gint i;
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 ();
}
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_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_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, 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
do_all_updates(void)
{
gint i;
char *label_text =
stpui_build_standard_print_command(pv, stp_get_printer(pv->v));
suppress_preview_update++;
set_orientation(pv->orientation);
invalidate_preview_thumbnail ();
preview_update ();
gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), label_text);
g_free(label_text);
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);
}
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
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)
{
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)
{
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)));
}
}
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));
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 ();
}
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();
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();
}
}
}
static void
orientation_callback (GtkWidget *widget,
gpointer data)
{
reset_preview ();
if (pv->orientation != (gint) data)
{
invalidate_preview_thumbnail ();
set_orientation((gint) data);
preview_update ();
}
}
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);
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);
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);
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_border_entry,
(paper_height - (stp_get_top (pv->v) + print_height)), 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);
}
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);
}
}
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 ();
}
}
static void
printandsave_callback (void)
{
saveme = TRUE;
print_callback();
}
static void
about_callback (void)
{
gtk_widget_show (about_dialog);
}
static void
save_callback (void)
{
reset_preview ();
stpui_printrc_save ();
}
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);
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);
}
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_show (setup_dialog);
if (first_time)
{
setup_update ();
first_time = FALSE;
}
}
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);
}
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);
}
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);
}
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)));
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,
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--;
}
static void
print_driver_callback (GtkWidget *widget,
gint row,
gint column,
GdkEventButton *event,
gpointer 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--;
}
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);
}
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)));
}
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);
}
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 ();
}
}
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;
}
}
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;
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)
{
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;
}
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;
}
}
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;
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;
}
gdk_draw_rectangle (preview->widget.window, gc, 0,
paper_display_left, paper_display_top,
paper_display_width, paper_display_height);
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);
gdk_draw_rectangle (preview->widget.window, gc, 0,
paper_display_left, paper_display_top,
paper_display_width, paper_display_height);
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 (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_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;
gdouble min_ppi_scaling;
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
{
if (image_width * printable_height > printable_width * image_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--;
if (! suppress_preview_update && !thumbnail_update_pending)
{
thumbnail_update_pending = TRUE;
g_idle_add(idle_preview_thumbnail, NULL);
}
}
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;
}
}
}
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)
{
stpui_printrc_load ();
create_main_window();
gtk_main ();
gdk_flush ();
if (saveme)
stpui_printrc_save ();
return (runme);
}