1/* 2 * "$Id: panel.c,v 1.19 2010/07/10 18:32:35 rlk Exp $" 3 * 4 * Main window code for Print plug-in for the GIMP. 5 * 6 * Copyright 1997-2003 Michael Sweet (mike@easysw.com), 7 * Robert Krawitz (rlk@alum.mit.edu), Steve Miller (smiller@rni.net) 8 * and Michael Natterer (mitch@gimp.org) 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by the Free 12 * Software Foundation; either version 2 of the License, or (at your option) 13 * any later version. 14 * 15 * This program is distributed in the hope that it will be useful, but 16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18 * for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 23 */ 24 25#ifdef HAVE_CONFIG_H 26#include <config.h> 27#endif 28 29#define MAX_PREVIEW_PPI (400) 30#define INCH 72 31#define FINCH ((gdouble) INCH) 32#define ROUNDUP(x, y) (((x) + ((y) - 1)) / (y)) 33#define SCALE(x, y) (((x) + (1.0 / (2.0 * (y)))) * (y)) 34 35#include <gutenprint/gutenprint-intl-internal.h> 36#include <gutenprintui2/gutenprintui.h> 37#include "gutenprintui-internal.h" 38 39#include <string.h> 40#include <stdio.h> 41 42#define MAXIMUM_PARAMETER_LEVEL STP_PARAMETER_LEVEL_ADVANCED4 43 44/* 45 * Constants for GUI. 46 */ 47static int preview_size_vert = 360; 48static int preview_size_horiz = 300; 49static gdouble minimum_image_percent = 5.0; 50static const int thumbnail_hintw = 128; 51static const int thumbnail_hinth = 128; 52 53#define MOVE_CONSTRAIN 0 54#define MOVE_HORIZONTAL 1 55#define MOVE_VERTICAL 2 56#define MOVE_ANY (MOVE_HORIZONTAL | MOVE_VERTICAL) 57#define MOVE_GRID 4 58 59/* 60 * Main window widgets 61 */ 62 63static GtkWidget *main_vbox; 64static GtkWidget *main_hbox; 65static GtkWidget *right_vbox; 66static GtkWidget *notebook; 67 68static GtkWidget *output_color_vbox; 69static GtkWidget *cyan_button; 70static GtkWidget *magenta_button; 71static GtkWidget *yellow_button; 72static GtkWidget *black_button; 73static GtkWidget *red_button; 74static GtkWidget *green_button; 75static GtkWidget *blue_button; 76 77static GtkWidget *print_dialog; /* Print dialog window */ 78 79static GtkWidget *recenter_button; 80static GtkWidget *recenter_vertical_button; 81static GtkWidget *recenter_horizontal_button; 82 83static GtkWidget *left_entry; 84/* 85static GtkWidget *right_entry; 86*/ 87static GtkWidget *right_border_entry; 88static GtkWidget *top_entry; 89/* 90static GtkWidget *bottom_entry; 91*/ 92static GtkWidget *bottom_border_entry; 93static GtkWidget *width_entry; 94static GtkWidget *height_entry; 95static GtkWidget *units_hbox; 96static GtkWidget *units_label; 97 98static GtkWidget *custom_size_width; 99static GtkWidget *custom_size_height; 100static GtkWidget *show_all_paper_sizes_button; 101static GtkWidget *auto_paper_size_button; 102 103static GtkWidget *orientation_menu; /* Orientation menu */ 104 105static GtkWidget *scaling_percent; /* Scale by percent */ 106static GtkWidget *scaling_ppi; /* Scale by pixels-per-inch */ 107static GtkWidget *scaling_image; /* Scale to the image */ 108static GtkObject *scaling_adjustment; /* Adjustment object for scaling */ 109 110static GtkWidget *setup_dialog; /* Setup dialog window */ 111static GtkWidget *printer_driver; /* Printer driver widget */ 112static GtkWidget *printer_model_label; /* Printer model name */ 113static GtkWidget *printer_crawler; /* Scrolled Window for menu */ 114static GtkWidget *printer_combo; /* Combo for menu */ 115static GtkWidget *manufacturer_clist; /* Manufacturer widget */ 116static GtkWidget *manufacturer_crawler; /* Scrolled Window for menu */ 117static gint plist_callback_id = -1; 118static GtkWidget *ppd_file; /* PPD file entry */ 119static GtkWidget *ppd_box; 120static GtkWidget *ppd_label; /* PPD file entry */ 121static GtkWidget *ppd_button; /* PPD file browse button */ 122static GtkWidget *ppd_browser; /* File selection dialog for PPDs */ 123static GtkWidget *ppd_model_label; /* PPD file entry */ 124static GtkWidget *ppd_model; /* PPD file entry */ 125static GtkWidget *new_printer_dialog; /* New printer dialog window */ 126static GtkWidget *new_printer_entry; /* New printer text entry */ 127static GtkWidget *file_button; /* PPD file browse button */ 128static GtkWidget *file_entry; /* FSD for print files */ 129static GtkWidget *file_browser; /* FSD for print files */ 130static GtkWidget *standard_cmd_entry; /* FSD for print files */ 131static GtkWidget *custom_command_entry; /* FSD for print files */ 132static GtkWidget *queue_combo; /* FSD for print files */ 133static gint queue_callback_id = -1; 134 135static GtkWidget *adjust_color_button; 136static GtkWidget *about_dialog; 137 138static GtkWidget *page_size_table; 139static GtkWidget *printer_features_table; 140static GtkWidget *color_adjustment_table; 141 142static GtkWidget *copy_count_spin_button; 143 144static gboolean preview_valid = FALSE; 145static gboolean frame_valid = FALSE; 146static gboolean need_exposure = FALSE; 147static gboolean suppress_scaling_adjustment = FALSE; 148static gboolean suppress_scaling_callback = FALSE; 149static gboolean thumbnail_update_pending = FALSE; 150static gboolean thumbnail_needs_rebuild = FALSE; 151/* 152 * These are semaphores, not true booleans. 153 */ 154static gint suppress_preview_update = 0; 155static gint suppress_preview_reset = 0; 156 157static GtkDrawingArea *preview = NULL; /* Preview drawing area widget */ 158static GtkDrawingArea *swatch = NULL; 159static gint mouse_x, mouse_y; /* Last mouse position */ 160static gint orig_top, orig_left; /* Original mouse position at start */ 161static gint buttons_pressed = 0; 162static gint preview_active = 0; 163static gint buttons_mask = 0; 164static gint move_constraint = 0; 165static gint mouse_button = -1; /* Button being dragged with */ 166static gint preview_thumbnail_w, preview_thumbnail_h; 167static gint preview_x, preview_y, preview_w, preview_h; 168 169static gint physical_orientation = -2; /* Actual orientation */ 170 171static gint paper_width, paper_height; /* Physical width */ 172static gint printable_width, printable_height; /* Size of printable area */ 173static gint print_width, print_height; /* Printed area of image */ 174static gint left, right, top, bottom; /* Imageable region */ 175static gint image_width, image_height; /* Image size (possibly rotated) */ 176static gint image_true_width, image_true_height; /* Original image */ 177static gdouble image_xres, image_yres; /* Original image resolution */ 178static gint do_update_thumbnail = 0; 179static gint saveme = 0; /* True if printrc should be saved */ 180static gint runme = 0; /* True if print should proceed */ 181static gint exit_after_file_ok = 0; /* True if we should exit after file browser complete */ 182static gint auto_paper_size = 0; /* True if we're using auto paper size now */ 183 184 185 186static void scaling_update (GtkAdjustment *adjustment); 187static void scaling_callback (GtkWidget *widget); 188static void plist_callback (GtkWidget *widget, gpointer data); 189static void queue_callback (GtkWidget *widget, gpointer data); 190static void custom_media_size_callback(GtkWidget *widget, gpointer data); 191static void show_all_paper_sizes_callback(GtkWidget *widget, gpointer data); 192static void auto_paper_size_callback(GtkWidget *widget, gpointer data); 193static void combo_callback (GtkWidget *widget, gpointer data); 194static void output_type_callback (GtkWidget *widget, gpointer data); 195static void unit_callback (GtkWidget *widget, gpointer data); 196static void orientation_callback (GtkWidget *widget, gpointer data); 197static void ppd_file_callback (GtkWidget *widget, gpointer data); 198static void printandsave_callback (void); 199static void about_callback (void); 200static void print_callback (void); 201static void save_callback (void); 202static void setup_callback (GtkWidget *widget); 203 204static void setup_update (void); 205static void setup_open_callback (void); 206static void setup_ok_callback (void); 207static void setup_cancel_callback (void); 208static void new_printer_open_callback (void); 209static void new_printer_ok_callback (void); 210static void ppd_browse_callback (void); 211static void ppd_ok_callback (void); 212static void file_browse_callback (void); 213static void file_ok_callback (void); 214static void file_cancel_callback (void); 215static void build_printer_driver_clist(void); 216static void print_driver_callback (GtkWidget *widget, 217 gint row, 218 gint column, 219 GdkEventButton *event, 220 gpointer data); 221static void manufacturer_callback (GtkWidget *widget, 222 gint row, 223 gint column, 224 GdkEventButton *event, 225 gpointer data); 226static void command_type_callback (GtkWidget *widget, gpointer data); 227 228static void do_preview_thumbnail (void); 229static void invalidate_preview_thumbnail (void); 230static void invalidate_frame (void); 231 232static GtkWidget *color_adjust_dialog; 233 234static void preview_update (void); 235static void preview_expose (void); 236static void preview_button_callback (GtkWidget *widget, 237 GdkEventButton *bevent, 238 gpointer data); 239static void preview_motion_callback (GtkWidget *widget, 240 GdkEventMotion *mevent, 241 gpointer data); 242static void position_callback (GtkWidget *widget); 243static void position_button_callback (GtkWidget *widget, 244 gpointer data); 245static void copy_count_callback (GtkAdjustment *widget, 246 gpointer data); 247static void plist_build_combo(GtkWidget *combo, 248 GtkWidget *label, 249 stp_string_list_t *items, 250 int active, 251 const gchar *cur_item, 252 const gchar *def_value, 253 GCallback callback, 254 gint *callback_id, 255 int (*check_func)(const char *string), 256 gpointer data); 257static void initialize_thumbnail(void); 258static void reset_callback (GtkObject *widget, gpointer data); 259static void set_color_defaults (void); 260static void set_printer_defaults (void); 261static void redraw_color_swatch (void); 262static void color_update (GtkAdjustment *adjustment); 263static void dimension_update (GtkAdjustment *adjustment); 264static void integer_update (GtkAdjustment *adjustment); 265static void set_controls_active (GtkObject *checkbutton, gpointer optno); 266static void update_adjusted_thumbnail (gboolean regenerate_image); 267 268static void set_media_size(const gchar *new_media_size); 269static const stp_printer_t *tmp_printer = NULL; 270 271static option_t *current_options = NULL; 272static int current_option_count = 0; 273 274static unit_t units[] = 275 { 276 { N_("Inch"), N_("Set the base unit of measurement to inches"), 277 72.0, NULL, "%.2f" }, 278 { N_("cm"), N_("Set the base unit of measurement to centimetres"), 279 72.0 / 2.54, NULL, "%.2f" }, 280 { N_("Points"), N_("Set the base unit of measurement to points (1/72\")"), 281 1.0, NULL, "%.0f" }, 282 { N_("mm"), N_("Set the base unit of measurement to millimetres"), 283 72.0 / 25.4, NULL, "%.1f" }, 284 { N_("Pica"), N_("Set the base unit of measurement to picas (1/12\")"), 285 72.0 / 12.0, NULL, "%.1f" }, 286 }; 287static const gint unit_count = sizeof(units) / sizeof(unit_t); 288 289static radio_group_t output_types[] = 290 { 291 { N_("Color"), N_("Color output"), "Color", NULL }, 292 { N_("Grayscale"), 293 N_("Print in shades of gray using black ink"), "BW", NULL } 294 }; 295 296static const gint output_type_count = (sizeof(output_types) / 297 sizeof(radio_group_t)); 298 299/* 300 * The order of these entries must match the order in command_t in 301 * gutenprintui.h 302 */ 303static radio_group_t command_options[] = 304 { 305 { N_("Standard Command"), N_("Use standard print command"), "Standard", NULL }, 306 { N_("Custom Command"), N_("Use custom print command"), "Custom", NULL }, 307 { N_("File"), N_("Print to a file"), "File", NULL } 308 }; 309 310static const gint command_options_count = (sizeof(command_options) / 311 sizeof(radio_group_t)); 312 313static gdouble preview_ppi = 10; 314 315static stp_string_list_t *printer_list = 0; 316static stpui_plist_t *pv; 317static const char *manufacturer = 0; 318 319static gint thumbnail_w, thumbnail_h, thumbnail_bpp; 320static guchar *thumbnail_data; 321static guchar *adjusted_thumbnail_data; 322static guchar *preview_thumbnail_data; 323 324static void 325set_stpui_curve_values(GtkWidget *gcurve, const stp_curve_t *seed) 326{ 327 if (stp_curve_get_gamma(seed)) 328 { 329 stpui_curve_set_gamma(STPUI_CURVE(gcurve), stp_curve_get_gamma(seed)); 330 } 331 else 332 { 333 stp_curve_t *copy = stp_curve_create_copy(seed); 334 const float *fdata; 335 size_t count; 336 stp_curve_resample(copy, 256); 337 fdata = stp_curve_get_float_data(copy, &count); 338 stpui_curve_set_vector(STPUI_CURVE(gcurve), count, fdata); 339 stp_curve_destroy(copy); 340 } 341} 342 343static void 344set_stp_curve_values(GtkWidget *widget, option_t *opt) 345{ 346 int i; 347 double lo, hi; 348 gfloat vector[256]; 349 GtkWidget *gcurve = GTK_WIDGET(widget); 350 stp_curve_t *curve = stp_curve_create_copy(opt->info.curve.deflt); 351 stpui_curve_get_vector(STPUI_CURVE(gcurve), 256, vector); 352 stp_curve_get_bounds(opt->info.curve.deflt, &lo, &hi); 353 for (i = 0; i < 256; i++) 354 { 355 if (vector[i] > hi) 356 vector[i] = hi; 357 else if (vector[i] < lo) 358 vector[i] = lo; 359 } 360 switch (STPUI_CURVE(gcurve)->curve_type) 361 { 362 case STPUI_CURVE_TYPE_SPLINE: 363 stp_curve_set_interpolation_type(curve, STP_CURVE_TYPE_SPLINE); 364 break; 365 default: 366 stp_curve_set_interpolation_type(curve, STP_CURVE_TYPE_LINEAR); 367 break; 368 } 369 stp_curve_set_float_data(curve, 256, vector); 370 stp_set_curve_parameter(pv->v, opt->fast_desc->name, curve); 371 stp_curve_destroy(curve); 372} 373 374static int 375open_curve_editor(GtkObject *button, gpointer xopt) 376{ 377 option_t *opt = (option_t *)xopt; 378 if (opt->info.curve.is_visible == FALSE) 379 { 380 GtkWidget *gcurve = 381 GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve); 382 const stp_curve_t *seed = 383 stp_get_curve_parameter(pv->v, opt->fast_desc->name); 384 stp_curve_t *nseed = NULL; 385 if (!seed) 386 seed = opt->info.curve.deflt; 387 if (seed) 388 nseed = stp_curve_create_copy(seed); 389 gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), FALSE); 390 gtk_widget_show(GTK_WIDGET(opt->info.curve.dialog)); 391 set_stpui_curve_values(gcurve, seed); 392 opt->info.curve.is_visible = TRUE; 393 if (opt->info.curve.current) 394 stp_curve_destroy(opt->info.curve.current); 395 opt->info.curve.current = nseed; 396 invalidate_preview_thumbnail(); 397 update_adjusted_thumbnail(FALSE); 398 } 399/* gtk_window_activate_focus(GTK_WINDOW(opt->info.curve.dialog)); */ 400 return 1; 401} 402 403static int 404set_default_curve_callback(GtkObject *button, gpointer xopt) 405{ 406 option_t *opt = (option_t *)xopt; 407 GtkWidget *gcurve = 408 GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve); 409 const stp_curve_t *seed = opt->info.curve.deflt; 410 set_stpui_curve_values(gcurve, seed); 411 set_stp_curve_values(gcurve, opt); 412 invalidate_preview_thumbnail(); 413 update_adjusted_thumbnail(TRUE); 414 return 1; 415} 416 417static int 418set_previous_curve_callback(GtkObject *button, gpointer xopt) 419{ 420 option_t *opt = (option_t *)xopt; 421 GtkWidget *gcurve = 422 GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve); 423 const stp_curve_t *seed = opt->info.curve.current; 424 if (!seed) 425 seed = opt->info.curve.deflt; 426 set_stpui_curve_values(gcurve, seed); 427 set_stp_curve_values(gcurve, opt); 428 invalidate_preview_thumbnail(); 429 update_adjusted_thumbnail(TRUE); 430 return 1; 431} 432 433static int 434set_curve_callback(GtkObject *button, gpointer xopt) 435{ 436 option_t *opt = (option_t *)xopt; 437 GtkWidget *gcurve = 438 GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve); 439 gtk_widget_hide(opt->info.curve.dialog); 440 gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), TRUE); 441 opt->info.curve.is_visible = FALSE; 442 set_stp_curve_values(gcurve, opt); 443 if (opt->info.curve.current) 444 stp_curve_destroy(opt->info.curve.current); 445 opt->info.curve.current = NULL; 446 invalidate_preview_thumbnail(); 447 update_adjusted_thumbnail(TRUE); 448 return 1; 449} 450 451static gint 452curve_draw_callback(GtkWidget *widget, GdkEvent *event, gpointer xopt) 453{ 454 option_t *opt = (option_t *)xopt; 455 switch (event->type) 456 { 457 case GDK_BUTTON_RELEASE: 458 set_stp_curve_values(widget, opt); 459 invalidate_preview_thumbnail(); 460 update_adjusted_thumbnail(TRUE); 461 break; 462 default: 463 break; 464 } 465 return 1; 466} 467 468static gint 469curve_type_changed(GtkWidget *widget, gpointer xopt) 470{ 471 option_t *opt = (option_t *)xopt; 472 set_stp_curve_values(widget, opt); 473 invalidate_preview_thumbnail(); 474 update_adjusted_thumbnail(TRUE); 475 return 1; 476} 477 478static int 479cancel_curve_callback(GtkObject *button, gpointer xopt) 480{ 481 option_t *opt = (option_t *)xopt; 482 if (opt->info.curve.is_visible) 483 { 484 stp_set_curve_parameter(pv->v, opt->fast_desc->name, 485 opt->info.curve.current); 486 stp_curve_destroy(opt->info.curve.current); 487 opt->info.curve.current = NULL; 488 gtk_widget_hide(opt->info.curve.dialog); 489 gtk_widget_set_sensitive(GTK_WIDGET(opt->checkbox), TRUE); 490 opt->info.curve.is_visible = FALSE; 491 invalidate_preview_thumbnail(); 492 update_adjusted_thumbnail(TRUE); 493 } 494 return 1; 495} 496 497static void 498stpui_create_curve(option_t *opt, 499 GtkTable *table, 500 gint column, 501 gint row, 502 const gchar *text, 503 const stp_curve_t *deflt, 504 gboolean is_optional) 505{ 506 double lower, upper; 507 opt->checkbox = gtk_check_button_new(); 508 gtk_table_attach(GTK_TABLE(table), opt->checkbox, 509 column, column + 1, row, row + 1, 510 GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0); 511 if (is_optional) 512 gtk_widget_show(opt->checkbox); 513 else 514 gtk_widget_hide(opt->checkbox); 515 516 opt->info.curve.label = gtk_label_new(text); 517 gtk_misc_set_alignment (GTK_MISC (opt->info.curve.label), 0.0, 0.5); 518 gtk_table_attach (GTK_TABLE (table), opt->info.curve.label, 519 column + 1, column + 2, row, row + 1, 520 GTK_FILL, GTK_FILL, 0, 0); 521 gtk_widget_show (opt->info.curve.label); 522 523 opt->info.curve.button = gtk_button_new_with_label(_("Edit Curve...")); 524 g_signal_connect(G_OBJECT(opt->info.curve.button), "clicked", 525 G_CALLBACK(open_curve_editor), opt); 526 gtk_table_attach (GTK_TABLE (table), opt->info.curve.button, 527 column + 2, column + 3, row, row + 1, 528 GTK_FILL, GTK_FILL, 0, 0); 529 gtk_widget_show(opt->info.curve.button); 530 531 opt->info.curve.dialog = 532 stpui_dialog_new(gettext(opt->fast_desc->text), 533 GTK_WIN_POS_MOUSE, TRUE, 534 _("Set Default"), set_default_curve_callback, 535 opt, NULL, NULL, FALSE, FALSE, 536 _("Restore Previous"), set_previous_curve_callback, 537 opt, NULL, NULL, FALSE, FALSE, 538 _("OK"), set_curve_callback, 539 opt, NULL, NULL, FALSE, FALSE, 540 _("Cancel"), cancel_curve_callback, 541 opt, NULL, NULL, FALSE, FALSE, 542 NULL); 543 opt->info.curve.gamma_curve = stpui_gamma_curve_new(); 544 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(opt->info.curve.dialog)->vbox), 545 opt->info.curve.gamma_curve, TRUE, TRUE, 0); 546 stp_curve_get_bounds(opt->info.curve.deflt, &lower, &upper); 547 stpui_curve_set_range 548 (STPUI_CURVE (STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve), 549 0.0, 1.0, lower, upper); 550 gtk_widget_set_usize 551 (GTK_WIDGET(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve), 256, 256); 552 gtk_widget_show(opt->info.curve.gamma_curve); 553 554 g_signal_connect 555 (G_OBJECT(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve), 556 "curve-type-changed", G_CALLBACK(curve_type_changed), opt); 557 g_signal_connect 558 (G_OBJECT(STPUI_GAMMA_CURVE(opt->info.curve.gamma_curve)->curve), 559 "event", G_CALLBACK(curve_draw_callback), opt); 560 561 if (opt->fast_desc->help) 562 { 563 stpui_set_help_data (opt->info.curve.label, opt->fast_desc->help); 564 stpui_set_help_data (opt->info.curve.button, opt->fast_desc->help); 565 stpui_set_help_data (opt->info.curve.gamma_curve, opt->fast_desc->help); 566 } 567} 568 569static int 570open_file_browser(GtkObject *button, gpointer xopt) 571{ 572 option_t *opt = (option_t *)xopt; 573 GtkWidget *browser = opt->info.file.f_browser; 574 GtkWidget *entry = opt->info.file.f_entry; 575 gtk_file_selection_set_filename (GTK_FILE_SELECTION (browser), 576 gtk_entry_get_text (GTK_ENTRY (entry))); 577 gtk_widget_show(opt->info.file.f_browser); 578 return 1; 579} 580 581static void 582file_entry_callback(GtkWidget *widget, gpointer xopt) 583{ 584 const gchar *name = gtk_entry_get_text(GTK_ENTRY(widget)); 585 if (name && pv && pv->v) 586 { 587 option_t *opt = (option_t *)xopt; 588 stp_set_file_parameter(pv->v, opt->fast_desc->name, name); 589 } 590} 591 592static int 593file_browser_ok_callback(GtkObject *browser_ok, gpointer xopt) 594{ 595 option_t *opt = (option_t *)xopt; 596 GtkWidget *entry = opt->info.file.f_entry; 597 GtkWidget *browser = opt->info.file.f_browser; 598 gtk_widget_hide(opt->info.file.f_browser); 599 gtk_entry_set_text 600 (GTK_ENTRY (entry), 601 gtk_file_selection_get_filename (GTK_FILE_SELECTION (browser))); 602 file_entry_callback(entry, xopt); 603 return 1; 604} 605 606static void 607stpui_create_file_browser(option_t *opt, 608 GtkTable *table, 609 gint column, 610 gint row, 611 const gchar *text, 612 gboolean is_optional) 613{ 614 opt->checkbox = gtk_check_button_new(); 615 gtk_table_attach(GTK_TABLE(table), opt->checkbox, 616 column, column + 1, row, row + 1, 617 GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0); 618 if (is_optional) 619 gtk_widget_show(opt->checkbox); 620 else 621 gtk_widget_hide(opt->checkbox); 622 623 opt->info.file.f_label = gtk_label_new(text); 624 gtk_misc_set_alignment (GTK_MISC (opt->info.file.f_label), 0.0, 0.5); 625 gtk_table_attach (GTK_TABLE (table), opt->info.file.f_label, 626 column + 1, column + 2, row, row + 1, 627 GTK_FILL, GTK_FILL, 0, 0); 628 gtk_widget_show (opt->info.file.f_label); 629 630 opt->info.file.f_entry = gtk_entry_new(); 631 gtk_table_attach (GTK_TABLE (table), opt->info.file.f_entry, 632 column + 2, column + 3, row, row + 1, 633 GTK_FILL, GTK_FILL, 0, 0); 634 g_signal_connect(G_OBJECT(opt->info.file.f_entry), "activate", 635 G_CALLBACK(file_entry_callback), opt); 636 if (stp_get_file_parameter(pv->v, opt->fast_desc->name)) 637 gtk_entry_set_text 638 (GTK_ENTRY (opt->info.file.f_entry), 639 stp_get_file_parameter(pv->v, opt->fast_desc->name)); 640 gtk_widget_show (opt->info.file.f_entry); 641 642 opt->info.file.f_button = gtk_button_new_with_label(_("Select File...")); 643 g_signal_connect(G_OBJECT(opt->info.file.f_button), "clicked", 644 G_CALLBACK(open_file_browser), opt); 645 gtk_table_attach (GTK_TABLE (table), opt->info.file.f_button, 646 column + 3, column + 4, row, row + 1, 647 GTK_FILL, GTK_FILL, 0, 0); 648 gtk_widget_show(opt->info.file.f_button); 649 650 opt->info.file.f_browser = 651 gtk_file_selection_new(gettext(opt->fast_desc->text)); 652 653 g_signal_connect 654 (G_OBJECT (GTK_FILE_SELECTION (opt->info.file.f_browser)->ok_button), "clicked", 655 G_CALLBACK (file_browser_ok_callback), opt); 656 g_signal_connect_object 657 (G_OBJECT (GTK_FILE_SELECTION (opt->info.file.f_browser)->cancel_button), "clicked", 658 G_CALLBACK (gtk_widget_hide), G_OBJECT (opt->info.file.f_browser), G_CONNECT_SWAPPED); 659 660 if (opt->fast_desc->help) 661 { 662 stpui_set_help_data (opt->info.file.f_label, opt->fast_desc->help); 663 stpui_set_help_data (opt->info.file.f_button, opt->fast_desc->help); 664 stpui_set_help_data (opt->info.file.f_entry, opt->fast_desc->help); 665 stpui_set_help_data (opt->info.file.f_browser, opt->fast_desc->help); 666 } 667} 668 669static int 670checkbox_callback(GtkObject *button, gpointer xopt) 671{ 672 option_t *opt = (option_t *)xopt; 673 GtkWidget *checkbox = GTK_WIDGET(opt->info.bool.checkbox); 674 opt->info.bool.current = 675 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox)); 676 stp_set_boolean_parameter(pv->v, opt->fast_desc->name, 677 opt->info.bool.current); 678 invalidate_frame(); 679 invalidate_preview_thumbnail(); 680 update_adjusted_thumbnail(TRUE); 681 preview_update(); 682 return 1; 683} 684 685static int 686print_mode_is_color(const stp_vars_t *v) 687{ 688 const char *printing_mode = stp_get_string_parameter(v, "PrintingMode"); 689 if (!printing_mode) 690 { 691 int answer = 1; 692 stp_parameter_t desc; 693 stp_describe_parameter(v, "PrintingMode", &desc); 694 if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST && 695 strcmp(desc.deflt.str, "BW") == 0) 696 answer = 0; 697 stp_parameter_description_destroy(&desc); 698 return answer; 699 } 700 if (strcmp(printing_mode, "BW") == 0) 701 return 0; 702 else 703 return 1; 704} 705 706static void 707set_current_printer(void) 708{ 709 pv = &(stpui_plist[stpui_plist_current]); 710 if (print_mode_is_color(pv->v)) 711 stp_set_string_parameter(pv->v, "PrintingMode", "Color"); 712 else 713 stp_set_string_parameter(pv->v, "PrintingMode", "BW"); 714} 715 716 717static void 718stpui_create_boolean(option_t *opt, 719 GtkTable *table, 720 gint column, 721 gint row, 722 const gchar *text, 723 int deflt, 724 gboolean is_optional) 725{ 726 opt->checkbox = gtk_check_button_new(); 727 gtk_table_attach(GTK_TABLE(table), opt->checkbox, 728 column, column + 1, row, row + 1, 729 GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0); 730 if (is_optional) 731 gtk_widget_show(opt->checkbox); 732 else 733 gtk_widget_hide(opt->checkbox); 734 735 opt->info.bool.checkbox = 736 gtk_toggle_button_new_with_label(gettext(opt->fast_desc->text)); 737 gtk_table_attach(GTK_TABLE(table), opt->info.bool.checkbox, 738 column + 1, column + 3, row, row + 1, 739 GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0); 740 gtk_widget_show(opt->info.bool.checkbox); 741 gtk_toggle_button_set_active 742 (GTK_TOGGLE_BUTTON(opt->info.bool.checkbox), 743 stp_get_boolean_parameter(pv->v, opt->fast_desc->name)); 744 g_signal_connect(G_OBJECT(opt->info.bool.checkbox), "toggled", 745 G_CALLBACK(checkbox_callback), opt); 746} 747 748static void 749build_queue_combo(void) 750{ 751 plist_build_combo(queue_combo, 752 NULL, 753 stpui_system_print_queues, 754 1, 755 stpui_plist_get_queue_name(pv), 756 NULL, 757 G_CALLBACK(queue_callback), 758 &queue_callback_id, 759 NULL, 760 NULL); 761} 762 763static void 764build_printer_combo(void) 765{ 766 int i; 767 if (printer_list) 768 stp_string_list_destroy(printer_list); 769 printer_list = stp_string_list_create(); 770 for (i = 0; i < stpui_plist_count; i++) 771 stp_string_list_add_string(printer_list, 772 stpui_plist[i].name, stpui_plist[i].name); 773 plist_build_combo(printer_combo, 774 NULL, 775 printer_list, 776 1, 777 stp_string_list_param(printer_list, stpui_plist_current)->name, 778 NULL, 779 G_CALLBACK(plist_callback), 780 &plist_callback_id, 781 NULL, 782 NULL); 783} 784 785static int 786check_page_size(const char *paper_size) 787{ 788 const stp_papersize_t *ps = stp_get_papersize_by_name(paper_size); 789 if (ps && (ps->paper_unit == PAPERSIZE_ENGLISH_STANDARD || 790 ps->paper_unit == PAPERSIZE_METRIC_STANDARD)) 791 return 1; 792 else 793 return 0; 794} 795 796static void 797build_page_size_combo(option_t *option) 798{ 799 /* 800 * Some printers don't support any "standard" page sizes. If the number 801 * of page sizes is small, just display all of them. 802 */ 803 if (stpui_show_all_paper_sizes || 804 stp_string_list_count(option->info.list.params) < 10) 805 plist_build_combo(option->info.list.combo, option->info.list.label, 806 option->info.list.params, option->is_active, 807 stp_get_string_parameter(pv->v, option->fast_desc->name), 808 option->info.list.default_val,G_CALLBACK(combo_callback), 809 &(option->info.list.callback_id), NULL, option); 810 else 811 plist_build_combo(option->info.list.combo, option->info.list.label, 812 option->info.list.params, option->is_active, 813 stp_get_string_parameter(pv->v, option->fast_desc->name), 814 option->info.list.default_val,G_CALLBACK(combo_callback), 815 &(option->info.list.callback_id), 816 check_page_size, option); 817} 818 819static void 820build_a_combo(option_t *option) 821{ 822 const gchar *new_value; 823 stp_parameter_activity_t active; 824 if (option->fast_desc && 825 option->fast_desc->p_type == STP_PARAMETER_TYPE_STRING_LIST) 826 { 827 const gchar *val = stp_get_string_parameter(pv->v, 828 option->fast_desc->name); 829 if (option->info.list.params == NULL || ! option->is_active || 830 stp_string_list_count(option->info.list.params) == 0) 831 stp_set_string_parameter(pv->v, option->fast_desc->name, NULL); 832 else if (!val || strlen(val) == 0 || 833 ! stp_string_list_is_present(option->info.list.params, val)) 834 stp_set_string_parameter(pv->v, option->fast_desc->name, 835 option->info.list.default_val); 836 if (strcmp(option->fast_desc->name, "PageSize") == 0) 837 build_page_size_combo(option); 838 else 839 plist_build_combo(option->info.list.combo, option->info.list.label, 840 option->info.list.params, 841 option->is_active, 842 stp_get_string_parameter(pv->v, 843 option->fast_desc->name), 844 option->info.list.default_val, G_CALLBACK(combo_callback), 845 &(option->info.list.callback_id), NULL, option); 846 if (strcmp(option->fast_desc->name, "PageSize") == 0) 847 set_media_size 848 (stp_get_string_parameter(pv->v, option->fast_desc->name)); 849 } 850 else 851 plist_build_combo(option->info.list.combo, option->info.list.label, 852 NULL, 0, "", "", G_CALLBACK(combo_callback), 853 &(option->info.list.callback_id), NULL, option); 854 new_value = 855 stpui_combo_get_name(option->info.list.combo, option->info.list.params); 856 active = stp_get_string_parameter_active(pv->v, option->fast_desc->name); 857 stp_set_string_parameter(pv->v, option->fast_desc->name, new_value); 858 stp_set_string_parameter_active(pv->v, option->fast_desc->name, active); 859} 860 861static void 862populate_options(const stp_vars_t *v) 863{ 864 stp_parameter_list_t params = stp_get_parameter_list(v); 865 int i; 866 int idx; 867 if (current_options) 868 { 869 for (i = 0; i < current_option_count; i++) 870 { 871 option_t *opt = &(current_options[i]); 872 switch (opt->fast_desc->p_type) 873 { 874 case STP_PARAMETER_TYPE_STRING_LIST: 875 if (opt->info.list.combo) 876 { 877 gtk_widget_destroy(opt->info.list.combo); 878 gtk_widget_destroy(opt->info.list.label); 879 if (opt->info.list.params) 880 stp_string_list_destroy(opt->info.list.params); 881 g_free(opt->info.list.default_val); 882 } 883 break; 884 case STP_PARAMETER_TYPE_DOUBLE: 885 case STP_PARAMETER_TYPE_DIMENSION: 886 case STP_PARAMETER_TYPE_INT: 887 if (opt->info.flt.adjustment) 888 { 889 gtk_widget_destroy 890 (GTK_WIDGET 891 (SCALE_ENTRY_SCALE(opt->info.flt.adjustment))); 892 gtk_widget_destroy 893 (GTK_WIDGET 894 (SCALE_ENTRY_LABEL(opt->info.flt.adjustment))); 895 gtk_widget_destroy 896 (GTK_WIDGET 897 (SCALE_ENTRY_SPINBUTTON(opt->info.flt.adjustment))); 898 } 899 break; 900 case STP_PARAMETER_TYPE_CURVE: 901 gtk_widget_destroy(GTK_WIDGET(opt->info.curve.label)); 902 gtk_widget_destroy(GTK_WIDGET(opt->info.curve.button)); 903 gtk_widget_destroy(GTK_WIDGET(opt->info.curve.dialog)); 904 if (opt->info.curve.current) 905 stp_curve_destroy(opt->info.curve.current); 906 break; 907 case STP_PARAMETER_TYPE_BOOLEAN: 908 gtk_widget_destroy(GTK_WIDGET(opt->info.bool.checkbox)); 909 break; 910 case STP_PARAMETER_TYPE_FILE: 911 gtk_widget_destroy(GTK_WIDGET(opt->info.file.f_label)); 912 gtk_widget_destroy(GTK_WIDGET(opt->info.file.f_button)); 913 gtk_widget_destroy(GTK_WIDGET(opt->info.file.f_entry)); 914 gtk_widget_destroy(GTK_WIDGET(opt->info.file.f_browser)); 915 break; 916 default: 917 break; 918 } 919 if (opt->checkbox) 920 gtk_widget_destroy(GTK_WIDGET(opt->checkbox)); 921 if (opt->reset_btn) 922 gtk_widget_destroy(GTK_WIDGET(opt->reset_btn)); 923 } 924 g_free(current_options); 925 } 926 current_option_count = stp_parameter_list_count(params); 927 current_options = g_malloc(sizeof(option_t) * current_option_count); 928 929 for (idx = 0, i = 0; i < current_option_count; i++) 930 { 931 stp_parameter_t desc; 932 const stp_parameter_t *param = stp_parameter_list_param(params, i); 933 if (!param->read_only && 934 (param->p_class == STP_PARAMETER_CLASS_OUTPUT || 935 param->p_class == STP_PARAMETER_CLASS_FEATURE || 936 (param->p_class == STP_PARAMETER_CLASS_CORE && 937 strcmp(param->name, "PageSize") == 0))) 938 { 939 option_t *opt = &(current_options[idx]); 940 opt->fast_desc = stp_parameter_list_param(params, i); 941 stp_describe_parameter(v, opt->fast_desc->name, &desc); 942 opt->checkbox = NULL; 943 opt->reset_btn = NULL; 944 opt->is_active = 0; 945 opt->is_enabled = 0; 946 switch (opt->fast_desc->p_type) 947 { 948 case STP_PARAMETER_TYPE_STRING_LIST: 949 opt->info.list.callback_id = -1; 950 opt->info.list.default_val = g_strdup(desc.deflt.str); 951 if (desc.bounds.str) 952 opt->info.list.params = 953 stp_string_list_create_copy(desc.bounds.str); 954 else 955 opt->info.list.params = NULL; 956 opt->info.list.combo = NULL; 957 opt->info.list.label = NULL; 958 opt->is_active = desc.is_active; 959 break; 960 case STP_PARAMETER_TYPE_DOUBLE: 961 opt->info.flt.adjustment = NULL; 962 opt->info.flt.upper = desc.bounds.dbl.upper; 963 opt->info.flt.lower = desc.bounds.dbl.lower; 964 opt->info.flt.deflt = desc.deflt.dbl; 965 opt->info.flt.scale = 1.0; 966 opt->is_active = desc.is_active; 967 break; 968 case STP_PARAMETER_TYPE_DIMENSION: 969 opt->info.flt.adjustment = NULL; 970 opt->info.flt.upper = desc.bounds.dimension.upper; 971 opt->info.flt.lower = desc.bounds.dimension.lower; 972 opt->info.flt.deflt = desc.deflt.dimension; 973 opt->info.flt.scale = 1.0; 974 opt->is_active = desc.is_active; 975 break; 976 case STP_PARAMETER_TYPE_INT: 977 opt->info.flt.adjustment = NULL; 978 opt->info.flt.upper = desc.bounds.integer.upper; 979 opt->info.flt.lower = desc.bounds.integer.lower; 980 opt->info.flt.deflt = desc.deflt.dimension; 981 opt->info.flt.scale = 1.0; 982 opt->is_active = desc.is_active; 983 break; 984 case STP_PARAMETER_TYPE_CURVE: 985 opt->info.curve.label = NULL; 986 opt->info.curve.button = NULL; 987 opt->info.curve.dialog = NULL; 988 opt->info.curve.gamma_curve = NULL; 989 opt->info.curve.current = NULL; 990 opt->info.curve.deflt = desc.deflt.curve; 991 opt->info.curve.is_visible = FALSE; 992 opt->is_active = desc.is_active; 993 break; 994 case STP_PARAMETER_TYPE_BOOLEAN: 995 opt->info.bool.checkbox = NULL; 996 opt->info.bool.current = 0; 997 opt->info.bool.deflt = desc.deflt.boolean; 998 opt->is_active = desc.is_active; 999 break; 1000 case STP_PARAMETER_TYPE_FILE: 1001 opt->info.file.f_label = NULL; 1002 opt->info.file.f_button = NULL; 1003 opt->info.file.f_entry = NULL; 1004 opt->info.file.f_browser = NULL; 1005 opt->info.file.f_is_visible = FALSE; 1006 opt->is_active = desc.is_active; 1007 break; 1008 default: 1009 break; 1010 } 1011 idx++; 1012 stp_parameter_description_destroy(&desc); 1013 } 1014 } 1015 current_option_count = idx; 1016 stp_parameter_list_destroy(params); 1017} 1018 1019static void 1020destroy_something(GtkWidget *widget, gpointer data) 1021{ 1022 gtk_widget_destroy(widget); 1023} 1024 1025static void 1026add_reset_button(option_t *opt, GtkWidget *table, gint column, gint row) 1027{ 1028 GtkWidget *button = gtk_button_new_with_label(_("Reset")); 1029 gtk_table_attach(GTK_TABLE(table), button, column, column + 1, 1030 row, row + 1, GTK_FILL, GTK_FILL, 0, 0); 1031 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(reset_callback), opt); 1032 opt->reset_btn = button; 1033 gtk_widget_show(button); 1034} 1035 1036static void 1037populate_option_table(GtkWidget *table, int p_class) 1038{ 1039 int i, j; 1040 int current_pos = 0; 1041 GtkWidget *previous_sep = NULL; 1042 int counts[STP_PARAMETER_LEVEL_INVALID][STP_PARAMETER_TYPE_INVALID]; 1043 int vpos[STP_PARAMETER_LEVEL_INVALID][STP_PARAMETER_TYPE_INVALID]; 1044 for (i = 0; i < STP_PARAMETER_LEVEL_INVALID; i++) 1045 for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++) 1046 { 1047 vpos[i][j] = 0; 1048 counts[i][j] = 0; 1049 } 1050 1051 1052 gtk_container_foreach(GTK_CONTAINER(table), destroy_something, NULL); 1053 1054 /* First scan the options to figure out where to start */ 1055 for (i = 0; i < current_option_count; i++) 1056 { 1057 const stp_parameter_t *desc = current_options[i].fast_desc; 1058 /* 1059 * Specialize the core parameters (page size is the only one we want) 1060 * Yuck. 1061 */ 1062 if (!desc->read_only && desc->p_class == p_class && 1063 (desc->p_class != STP_PARAMETER_CLASS_CORE || 1064 strcmp(desc->name, "PageSize") == 0)) 1065 { 1066 switch (desc->p_type) 1067 { 1068 case STP_PARAMETER_TYPE_STRING_LIST: 1069 case STP_PARAMETER_TYPE_DIMENSION: 1070 case STP_PARAMETER_TYPE_INT: 1071 case STP_PARAMETER_TYPE_DOUBLE: 1072 case STP_PARAMETER_TYPE_CURVE: 1073 case STP_PARAMETER_TYPE_BOOLEAN: 1074 case STP_PARAMETER_TYPE_FILE: 1075 counts[desc->p_level][desc->p_type]++; 1076 break; 1077 default: 1078 break; 1079 } 1080 } 1081 } 1082 1083 /* Now, figure out where we're going to put the options */ 1084 for (i = 0; i <= MAXIMUM_PARAMETER_LEVEL + 1; i++) 1085 { 1086 int level_count = 0; 1087 if (i <= MAXIMUM_PARAMETER_LEVEL) 1088 for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++) 1089 level_count += counts[i][j]; 1090 if (level_count > 0 && current_pos > 0) 1091 { 1092 GtkWidget *sep = gtk_hseparator_new(); 1093 gtk_table_attach (GTK_TABLE(table), sep, 0, 4, 1094 current_pos, current_pos + 1, 1095 GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0); 1096 if (previous_sep) 1097 gtk_widget_show(previous_sep); 1098 previous_sep = sep; 1099 current_pos++; 1100 } 1101 if (i <= MAXIMUM_PARAMETER_LEVEL) 1102 for (j = 0; j < STP_PARAMETER_TYPE_INVALID; j++) 1103 { 1104 vpos[i][j] = current_pos; 1105 current_pos += counts[i][j]; 1106 } 1107 } 1108 1109 for (i = 0; i < current_option_count; i++) 1110 { 1111 option_t *opt = &(current_options[i]); 1112 const stp_curve_t *xcurve; 1113 const stp_parameter_t *desc = opt->fast_desc; 1114 if (!desc->read_only && desc->p_class == p_class && 1115 (desc->p_class != STP_PARAMETER_CLASS_CORE || 1116 strcmp(desc->name, "PageSize") == 0)) 1117 { 1118 gdouble unit_scaler; 1119 gdouble minor_increment; 1120 gint digits; 1121 if (p_class == STP_PARAMETER_CLASS_OUTPUT) 1122 opt->reset_all = FALSE; 1123 else 1124 opt->reset_all = TRUE; 1125 switch (desc->p_type) 1126 { 1127 case STP_PARAMETER_TYPE_STRING_LIST: 1128 add_reset_button(opt, table, 4, vpos[desc->p_level][desc->p_type]); 1129 stpui_create_new_combo(opt, table, 0, 1130 vpos[desc->p_level][desc->p_type]++, 1131 !(desc->is_mandatory)); 1132 if (desc->p_level > MAXIMUM_PARAMETER_LEVEL) 1133 stp_set_string_parameter_active(pv->v, desc->name, 1134 STP_PARAMETER_INACTIVE); 1135 break; 1136 case STP_PARAMETER_TYPE_DOUBLE: 1137 add_reset_button(opt, table, 4, vpos[desc->p_level][desc->p_type]); 1138 stpui_create_scale_entry(opt, GTK_TABLE(table), 0, 1139 vpos[desc->p_level][desc->p_type]++, 1140 gettext(desc->text), 200, 0, 1141 opt->info.flt.deflt, 1142 opt->info.flt.lower, 1143 opt->info.flt.upper, 1144 .001, .01, 3, TRUE, 0, 0, NULL, 1145 !(desc->is_mandatory)); 1146 stpui_set_adjustment_tooltip(opt->info.flt.adjustment, 1147 gettext(desc->help)); 1148 g_signal_connect(G_OBJECT(opt->info.flt.adjustment), 1149 "value_changed", 1150 G_CALLBACK(color_update), opt); 1151 if (desc->p_level > MAXIMUM_PARAMETER_LEVEL) 1152 stp_set_float_parameter_active(pv->v, desc->name, 1153 STP_PARAMETER_INACTIVE); 1154 break; 1155 case STP_PARAMETER_TYPE_DIMENSION: 1156 unit_scaler = units[pv->unit].scale; 1157 if (unit_scaler > 100) 1158 { 1159 digits = 3; 1160 minor_increment = .001; 1161 } 1162 else if (unit_scaler > 10) 1163 { 1164 digits = 2; 1165 minor_increment = .01; 1166 } 1167 else if (unit_scaler > 1) 1168 { 1169 digits = 1; 1170 minor_increment = .1; 1171 } 1172 else 1173 { 1174 digits = 0; 1175 minor_increment = 1; 1176 } 1177 add_reset_button(opt, table, 4, vpos[desc->p_level][desc->p_type]); 1178 stpui_create_scale_entry(opt, GTK_TABLE(table), 0, 1179 vpos[desc->p_level][desc->p_type]++, 1180 gettext(desc->text), 200, 0, 1181 opt->info.flt.deflt / unit_scaler, 1182 opt->info.flt.lower / unit_scaler, 1183 opt->info.flt.upper / unit_scaler, 1184 minor_increment, minor_increment * 10, 1185 digits, TRUE, 0, 0, NULL, 1186 !(desc->is_mandatory)); 1187 stpui_set_adjustment_tooltip(opt->info.flt.adjustment, 1188 gettext(desc->help)); 1189 g_signal_connect(G_OBJECT(opt->info.flt.adjustment), 1190 "value_changed", 1191 G_CALLBACK(dimension_update), opt); 1192 if (desc->p_level > MAXIMUM_PARAMETER_LEVEL) 1193 stp_set_dimension_parameter_active(pv->v, desc->name, 1194 STP_PARAMETER_INACTIVE); 1195 break; 1196 case STP_PARAMETER_TYPE_INT: 1197 add_reset_button(opt, table, 4, vpos[desc->p_level][desc->p_type]); 1198 stpui_create_scale_entry(opt, GTK_TABLE(table), 0, 1199 vpos[desc->p_level][desc->p_type]++, 1200 gettext(desc->text), 200, 0, 1201 opt->info.flt.deflt, 1202 opt->info.flt.lower, 1203 opt->info.flt.upper, 1204 1, 10, 0, TRUE, 0, 0, NULL, 1205 !(desc->is_mandatory)); 1206 stpui_set_adjustment_tooltip(opt->info.flt.adjustment, 1207 gettext(desc->help)); 1208 g_signal_connect(G_OBJECT(opt->info.flt.adjustment), 1209 "value_changed", 1210 G_CALLBACK(integer_update), opt); 1211 if (desc->p_level > MAXIMUM_PARAMETER_LEVEL) 1212 stp_set_int_parameter_active(pv->v, desc->name, 1213 STP_PARAMETER_INACTIVE); 1214 break; 1215 case STP_PARAMETER_TYPE_CURVE: 1216 xcurve = stp_get_curve_parameter(pv->v, opt->fast_desc->name); 1217 if (xcurve) 1218 opt->info.curve.current = stp_curve_create_copy(xcurve); 1219 else 1220 opt->info.curve.current = NULL; 1221 add_reset_button(opt, table, 4, vpos[desc->p_level][desc->p_type]); 1222 stpui_create_curve(opt, GTK_TABLE(table), 0, 1223 vpos[desc->p_level][desc->p_type]++, 1224 gettext(desc->text), opt->info.curve.deflt, 1225 !(desc->is_mandatory)); 1226 if (desc->p_level > MAXIMUM_PARAMETER_LEVEL) 1227 stp_set_curve_parameter_active(pv->v, desc->name, 1228 STP_PARAMETER_INACTIVE); 1229 break; 1230 case STP_PARAMETER_TYPE_BOOLEAN: 1231 opt->info.bool.current = 1232 stp_get_boolean_parameter(pv->v, opt->fast_desc->name); 1233 add_reset_button(opt, table, 4, vpos[desc->p_level][desc->p_type]); 1234 stpui_create_boolean(opt, GTK_TABLE(table), 0, 1235 vpos[desc->p_level][desc->p_type]++, 1236 gettext(desc->text), opt->info.bool.deflt, 1237 !(desc->is_mandatory)); 1238 if (desc->p_level > MAXIMUM_PARAMETER_LEVEL) 1239 stp_set_boolean_parameter_active(pv->v, desc->name, 1240 STP_PARAMETER_INACTIVE); 1241 break; 1242 case STP_PARAMETER_TYPE_RAW: 1243 stp_set_raw_parameter_active(pv->v, opt->fast_desc->name, 1244 STP_PARAMETER_INACTIVE); 1245 break; 1246 case STP_PARAMETER_TYPE_FILE: 1247 if (strcmp(opt->fast_desc->name, "PPDFile") != 0) 1248 { 1249 add_reset_button(opt, table, 4, vpos[desc->p_level][desc->p_type]); 1250 stpui_create_file_browser(opt, GTK_TABLE(table), 0, 1251 vpos[desc->p_level][desc->p_type]++, 1252 gettext(desc->text), 1253 !(desc->is_mandatory)); 1254 } 1255 if (desc->p_level > MAXIMUM_PARAMETER_LEVEL) 1256 stp_set_file_parameter_active(pv->v, desc->name, 1257 STP_PARAMETER_INACTIVE); 1258 break; 1259 default: 1260 break; 1261 } 1262 if (opt->checkbox) 1263 g_signal_connect 1264 (G_OBJECT(opt->checkbox), "toggled", 1265 G_CALLBACK(set_controls_active), opt); 1266 } 1267 } 1268} 1269 1270static void 1271set_options_active(const char *omit) 1272{ 1273 int i; 1274 for (i = 0; i < current_option_count; i++) 1275 { 1276 option_t *opt = &(current_options[i]); 1277 const stp_parameter_t *desc = opt->fast_desc; 1278 GtkObject *adj; 1279 if (omit && strcmp(omit, opt->fast_desc->name) == 0) 1280 continue; 1281 switch (desc->p_type) 1282 { 1283 case STP_PARAMETER_TYPE_STRING_LIST: 1284 build_a_combo(opt); 1285 break; 1286 case STP_PARAMETER_TYPE_DOUBLE: 1287 case STP_PARAMETER_TYPE_DIMENSION: 1288 case STP_PARAMETER_TYPE_INT: 1289 adj = opt->info.flt.adjustment; 1290 if (adj) 1291 { 1292 if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL) 1293 { 1294 gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_LABEL(adj))); 1295 gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_SCALE(adj))); 1296 gtk_widget_show(GTK_WIDGET(SCALE_ENTRY_SPINBUTTON(adj))); 1297 } 1298 else 1299 { 1300 gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_LABEL(adj))); 1301 gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_SCALE(adj))); 1302 gtk_widget_hide(GTK_WIDGET(SCALE_ENTRY_SPINBUTTON(adj))); 1303 } 1304 } 1305 break; 1306 case STP_PARAMETER_TYPE_CURVE: 1307 if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL) 1308 { 1309 gtk_widget_show(GTK_WIDGET(opt->info.curve.label)); 1310 gtk_widget_show(GTK_WIDGET(opt->info.curve.button)); 1311 } 1312 else 1313 { 1314 gtk_widget_hide(GTK_WIDGET(opt->info.curve.label)); 1315 gtk_widget_hide(GTK_WIDGET(opt->info.curve.button)); 1316 gtk_widget_hide(GTK_WIDGET(opt->info.curve.dialog)); 1317 } 1318 case STP_PARAMETER_TYPE_BOOLEAN: 1319 if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL) 1320 { 1321 gtk_widget_show(GTK_WIDGET(opt->info.bool.checkbox)); 1322 } 1323 else 1324 { 1325 gtk_widget_hide(GTK_WIDGET(opt->info.bool.checkbox)); 1326 } 1327 break; 1328 case STP_PARAMETER_TYPE_FILE: 1329 if (opt->is_active && desc->p_level <= MAXIMUM_PARAMETER_LEVEL) 1330 { 1331 gtk_widget_show(GTK_WIDGET(opt->info.file.f_label)); 1332 gtk_widget_show(GTK_WIDGET(opt->info.file.f_button)); 1333 gtk_widget_show(GTK_WIDGET(opt->info.file.f_entry)); 1334 } 1335 else 1336 { 1337 gtk_widget_hide(GTK_WIDGET(opt->info.file.f_label)); 1338 gtk_widget_hide(GTK_WIDGET(opt->info.file.f_button)); 1339 gtk_widget_hide(GTK_WIDGET(opt->info.file.f_entry)); 1340 gtk_widget_hide(GTK_WIDGET(opt->info.file.f_browser)); 1341 } 1342 break; 1343 default: 1344 break; 1345 } 1346 if (!(opt->is_active) || desc->p_level > MAXIMUM_PARAMETER_LEVEL) 1347 { 1348 if (opt->checkbox) 1349 gtk_widget_hide(GTK_WIDGET(opt->checkbox)); 1350 if (opt->reset_btn) 1351 gtk_widget_hide(GTK_WIDGET(opt->reset_btn)); 1352 } 1353 else 1354 { 1355 if (opt->checkbox) 1356 { 1357 if (!desc->is_mandatory) 1358 gtk_widget_show(GTK_WIDGET(opt->checkbox)); 1359 else 1360 gtk_widget_hide(GTK_WIDGET(opt->checkbox)); 1361 } 1362 if (opt->reset_btn) 1363 gtk_widget_show(GTK_WIDGET(opt->reset_btn)); 1364 } 1365 } 1366} 1367 1368static void 1369color_button_callback(GtkWidget *widget, gpointer data) 1370{ 1371 invalidate_preview_thumbnail(); 1372 update_adjusted_thumbnail(TRUE); 1373} 1374 1375static void 1376create_top_level_structure(void) 1377{ 1378 gchar *plug_in_name; 1379 /* 1380 * Create the main dialog 1381 */ 1382 1383 plug_in_name = g_strdup_printf (_("%s -- Print v%s"), 1384 stpui_get_image_filename(), 1385 VERSION " - " RELEASE_DATE); 1386 1387 print_dialog = 1388 stpui_dialog_new (plug_in_name, 1389 GTK_WIN_POS_MOUSE, 1390 TRUE, 1391 1392 _("About"), about_callback, 1393 NULL, NULL, NULL, FALSE, FALSE, 1394 _("Print and\nSave Settings"), printandsave_callback, 1395 NULL, NULL, NULL, FALSE, FALSE, 1396 _("Save\nSettings"), save_callback, 1397 NULL, NULL, NULL, FALSE, FALSE, 1398 _("Print"), print_callback, 1399 NULL, NULL, NULL, FALSE, FALSE, 1400 _("Cancel"), gtk_widget_destroy, 1401 NULL, (GObject *) 1, NULL, FALSE, TRUE, 1402 1403 NULL); 1404 1405 g_free (plug_in_name); 1406 1407 g_signal_connect (G_OBJECT (print_dialog), "destroy", 1408 G_CALLBACK (gtk_main_quit), NULL); 1409 1410 /* 1411 * Top-level containers 1412 */ 1413 1414 main_vbox = gtk_vbox_new (FALSE, 2); 1415 gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 6); 1416 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (print_dialog)->vbox), main_vbox, 1417 TRUE, TRUE, 0); 1418 gtk_widget_show (main_vbox); 1419 1420 main_hbox = gtk_hbox_new (FALSE, 4); 1421 gtk_box_pack_start (GTK_BOX (main_vbox), main_hbox, TRUE, TRUE, 0); 1422 gtk_widget_show (main_hbox); 1423 1424 right_vbox = gtk_vbox_new (FALSE, 2); 1425 gtk_box_pack_end (GTK_BOX (main_hbox), right_vbox, FALSE, FALSE, 0); 1426 gtk_widget_show (right_vbox); 1427 1428 notebook = gtk_notebook_new (); 1429 gtk_box_pack_start (GTK_BOX (right_vbox), notebook, TRUE, TRUE, 0); 1430 gtk_widget_show (notebook); 1431} 1432 1433static gint 1434drawing_area_resize_callback(GtkWidget *widget, GdkEventConfigure *event) 1435{ 1436 preview_size_vert = event->height - 1; 1437 preview_size_horiz = event->width - 1; 1438 invalidate_preview_thumbnail(); 1439 invalidate_frame(); 1440 preview_update(); 1441 return 1; 1442} 1443 1444static void 1445create_preview (void) 1446{ 1447 GtkWidget *frame; 1448 GtkWidget *event_box; 1449 1450 frame = gtk_frame_new (_("Preview")); 1451 gtk_box_pack_start (GTK_BOX (main_hbox), frame, TRUE, TRUE, 0); 1452 gtk_widget_show (frame); 1453 1454 preview = (GtkDrawingArea *) gtk_drawing_area_new (); 1455 gtk_drawing_area_size(preview, preview_size_horiz + 1, preview_size_vert +1); 1456 g_signal_connect(G_OBJECT(preview), "configure_event", 1457 G_CALLBACK(drawing_area_resize_callback), NULL); 1458 event_box = gtk_event_box_new (); 1459 gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (preview)); 1460 gtk_container_add (GTK_CONTAINER (frame), event_box); 1461 gtk_widget_show (event_box); 1462 1463 g_signal_connect (G_OBJECT (preview), "expose_event", 1464 G_CALLBACK (preview_expose), NULL); 1465 g_signal_connect (G_OBJECT (preview), "button_press_event", 1466 G_CALLBACK (preview_button_callback), NULL); 1467 g_signal_connect (G_OBJECT (preview), "button_release_event", 1468 G_CALLBACK (preview_button_callback), NULL); 1469 g_signal_connect (G_OBJECT (preview), "motion_notify_event", 1470 G_CALLBACK (preview_motion_callback), NULL); 1471 gtk_widget_show (GTK_WIDGET (preview)); 1472 1473 stpui_set_help_data 1474 (event_box, 1475 _("Position the image on the page.\n" 1476 "Click and drag with the primary button to position the image.\n" 1477 "Click and drag with the second button to move the image with finer precision; " 1478 "each unit of motion moves the image one point (1/72\")\n" 1479 "Click and drag with the third (middle) button to move the image in units of " 1480 "the image size.\n" 1481 "Holding down the shift key while clicking and dragging constrains the image to " 1482 "only horizontal or vertical motion.\n" 1483 "If you click another button while dragging the mouse, the image will return " 1484 "to its original position.")); 1485 1486 gtk_widget_set_events (GTK_WIDGET (preview), 1487 GDK_EXPOSURE_MASK | GDK_BUTTON_MOTION_MASK | 1488 GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK); 1489} 1490 1491static GtkWidget * 1492create_positioning_entry(GtkWidget *table, int hpos, int vpos, 1493 const char *text, const char *help) 1494{ 1495 return stpui_create_entry 1496 (table, hpos, vpos, text, help, G_CALLBACK(position_callback)); 1497} 1498 1499static GtkWidget * 1500create_positioning_button(GtkWidget *box, int invalid, 1501 const char *text, const char *help) 1502{ 1503 GtkWidget *button = gtk_button_new_with_label(gettext(text)); 1504 gtk_box_pack_start(GTK_BOX(box), button, FALSE, TRUE, 0); 1505 gtk_widget_show(button); 1506 stpui_set_help_data(button, help); 1507 g_signal_connect(G_OBJECT(button), "clicked", 1508 G_CALLBACK(position_button_callback), 1509 (gpointer) invalid); 1510 return button; 1511} 1512 1513static void 1514create_paper_size_frame(void) 1515{ 1516 GtkWidget *frame; 1517 GtkWidget *vbox; 1518 GtkWidget *media_size_table; 1519 GtkWidget *table; 1520 int vpos = 0; 1521 1522 frame = gtk_frame_new (_("Paper Size")); 1523 gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0); 1524 gtk_widget_show (frame); 1525 1526 vbox = gtk_vbox_new (FALSE, 2); 1527 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); 1528 gtk_container_add (GTK_CONTAINER (frame), vbox); 1529 gtk_widget_show (vbox); 1530 1531 table = gtk_table_new (1, 1, FALSE); 1532 gtk_container_add (GTK_CONTAINER (vbox), table); 1533 gtk_widget_show (table); 1534 1535 /* 1536 * Media size combo box. 1537 */ 1538 1539 page_size_table = gtk_table_new(1, 1, FALSE); 1540 gtk_widget_show (page_size_table); 1541 gtk_table_attach_defaults(GTK_TABLE(table), page_size_table, 1542 0, 2, vpos, vpos + 1); 1543 vpos++; 1544 show_all_paper_sizes_button = 1545 gtk_check_button_new_with_label(_("Show All Paper Sizes")); 1546 gtk_table_attach_defaults 1547 (GTK_TABLE(table), show_all_paper_sizes_button, 0, 2, vpos, vpos + 1); 1548 gtk_toggle_button_set_active 1549 (GTK_TOGGLE_BUTTON(show_all_paper_sizes_button), 1550 stpui_show_all_paper_sizes); 1551 g_signal_connect(G_OBJECT(show_all_paper_sizes_button), "toggled", 1552 G_CALLBACK(show_all_paper_sizes_callback), NULL); 1553 gtk_widget_show(show_all_paper_sizes_button); 1554 vpos++; 1555 1556 /* 1557 * Custom media size entries 1558 */ 1559 1560 media_size_table = gtk_table_new (1, 1, FALSE); 1561 stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Dimensions:"), 1562 0.0, 0.5, media_size_table, 1, TRUE); 1563 gtk_table_set_col_spacings (GTK_TABLE (media_size_table), 4); 1564 1565 custom_size_width = stpui_create_entry 1566 (media_size_table, 0, 3, _("Width:"), 1567 _("Width of the paper that you wish to print to"), 1568 G_CALLBACK(custom_media_size_callback)); 1569 1570 custom_size_height = stpui_create_entry 1571 (media_size_table, 2, 3, _("Height:"), 1572 _("Height of the paper that you wish to print to"), 1573 G_CALLBACK(custom_media_size_callback)); 1574 1575 vpos++; 1576 auto_paper_size_button = 1577 gtk_check_button_new_with_label(_("Automatic Paper Size")); 1578 gtk_table_attach_defaults 1579 (GTK_TABLE(table), auto_paper_size_button, 0, 2, vpos, vpos + 1); 1580 gtk_toggle_button_set_active 1581 (GTK_TOGGLE_BUTTON(auto_paper_size_button), FALSE); 1582 g_signal_connect(G_OBJECT(auto_paper_size_button), "toggled", 1583 G_CALLBACK(auto_paper_size_callback), NULL); 1584} 1585 1586static void 1587create_copy_number_frame(void) 1588{ 1589 GtkWidget *frame; 1590 GtkWidget *vbox; 1591 GtkWidget *event_box; 1592 GtkAdjustment *adj; 1593 1594 frame = gtk_frame_new (_("Number of Copies")); 1595 gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0); 1596 gtk_widget_show (frame); 1597 1598 vbox = gtk_hbox_new (FALSE, 2); 1599 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); 1600 gtk_container_add (GTK_CONTAINER (frame), vbox); 1601 gtk_widget_show (vbox); 1602 1603 event_box = gtk_event_box_new (); 1604 gtk_container_add (GTK_CONTAINER (vbox), event_box); 1605 stpui_set_help_data(event_box, 1606 _("Select the number of copies to print; " 1607 "a value between 1 and 100")); 1608 gtk_widget_show (event_box); 1609 1610 /* 1611 * Number of Copies Spin Button 1612 */ 1613 1614 adj = (GtkAdjustment *) gtk_adjustment_new (1.0f, 1.0f, 100.0f, 1615 1.0f, 5.0f, 0.0f); 1616 copy_count_spin_button = gtk_spin_button_new (adj, 0, 0); 1617 gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (copy_count_spin_button), FALSE); 1618 gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (copy_count_spin_button), TRUE); 1619 gtk_spin_button_set_update_policy (GTK_SPIN_BUTTON (copy_count_spin_button), 1620 GTK_UPDATE_IF_VALID); 1621 1622 g_signal_connect(G_OBJECT (adj), "value_changed", 1623 G_CALLBACK (copy_count_callback), 1624 NULL); 1625 1626 gtk_container_add (GTK_CONTAINER (event_box), copy_count_spin_button); 1627 gtk_widget_show(copy_count_spin_button); 1628} 1629 1630static void 1631create_positioning_frame (void) 1632{ 1633 GtkWidget *frame; 1634 GtkWidget *table; 1635 GtkWidget *box; 1636 GtkWidget *sep; 1637 1638 frame = gtk_frame_new (_("Image Position")); 1639 gtk_box_pack_start (GTK_BOX (right_vbox), frame, FALSE, TRUE, 0); 1640 gtk_widget_show (frame); 1641 1642 table = gtk_table_new (1, 1, FALSE); 1643 gtk_table_set_col_spacings (GTK_TABLE (table), 2); 1644 gtk_table_set_row_spacings (GTK_TABLE (table), 2); 1645 gtk_container_set_border_width (GTK_CONTAINER (table), 4); 1646 gtk_container_add (GTK_CONTAINER (frame), table); 1647 gtk_widget_show (table); 1648 1649 /* 1650 * Orientation option menu. 1651 */ 1652 1653 orientation_menu = 1654 stpui_option_menu_new (FALSE, 1655 _("Auto"), orientation_callback, 1656 (gpointer) ORIENT_AUTO, NULL, NULL, 0, 1657 _("Portrait"), orientation_callback, 1658 (gpointer) ORIENT_PORTRAIT, NULL, NULL, 0, 1659 _("Landscape"), orientation_callback, 1660 (gpointer) ORIENT_LANDSCAPE, NULL, NULL, 0, 1661 _("Upside down"), orientation_callback, 1662 (gpointer) ORIENT_UPSIDEDOWN, NULL, NULL, 0, 1663 _("Seascape"), orientation_callback, 1664 (gpointer) ORIENT_SEASCAPE, NULL, NULL, 0, 1665 NULL); 1666 stpui_set_help_data (orientation_menu, 1667 _("Select the orientation: portrait, landscape, " 1668 "upside down, or seascape (upside down landscape)")); 1669 stpui_table_attach_aligned (GTK_TABLE (table), 0, 0, _("Orientation:"), 1670 1.0, 0.5, orientation_menu, 4, TRUE); 1671 sep = gtk_hseparator_new (); 1672 gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 6, 1, 2); 1673 gtk_widget_show (sep); 1674 1675 /* 1676 * Position entries 1677 */ 1678 1679 left_entry = create_positioning_entry 1680 (table, 0, 2, _("Left:"), 1681 _("Distance from the left of the paper to the image")); 1682#if 0 1683 right_entry = create_positioning_entry 1684 (table, 0, 3, _("Right:"), 1685 _("Distance from the left of the paper to the right of the image")); 1686#endif 1687 right_border_entry = create_positioning_entry 1688 (table, 0, 4, _("Right:"), 1689 _("Distance from the right of the paper to the image")); 1690 top_entry = create_positioning_entry 1691 (table, 3, 2, _("Top:"), 1692 _("Distance from the top of the paper to the image")); 1693#if 0 1694 bottom_entry = create_positioning_entry 1695 (table, 3, 3, _("Bottom:"), 1696 _("Distance from the top of the paper to bottom of the image")); 1697#endif 1698 bottom_border_entry = create_positioning_entry 1699 (table, 3, 4, _("Bottom:"), 1700 _("Distance from the bottom of the paper to the image")); 1701 /* 1702 * Center options 1703 */ 1704 1705 sep = gtk_hseparator_new (); 1706 gtk_table_attach_defaults (GTK_TABLE (table), sep, 0, 6, 5, 6); 1707 gtk_widget_show (sep); 1708 1709 box = gtk_hbox_new (TRUE, 4); 1710 stpui_table_attach_aligned (GTK_TABLE (table), 0, 7, _("Center:"), 0.5, 0.5, 1711 box, 5, TRUE); 1712 recenter_horizontal_button = create_positioning_button 1713 (box, INVALID_LEFT, _("Horizontal"), 1714 _("Center the image horizontally on the paper")); 1715 recenter_button = create_positioning_button 1716 (box, INVALID_LEFT | INVALID_TOP, _("Both"), 1717 _("Center the image on the paper")); 1718 recenter_vertical_button = create_positioning_button 1719 (box, INVALID_TOP, _("Vertical"), 1720 _("Center the image vertically on the paper")); 1721} 1722 1723static void 1724create_printer_dialog (void) 1725{ 1726 GtkWidget *table; 1727 GtkWidget *label; 1728 GtkWidget *event_box; 1729 GSList *group; 1730 gint i; 1731 stp_string_list_t *manufacturer_list = stp_string_list_create(); 1732 1733 setup_dialog = stpui_dialog_new(_("Setup Printer"), 1734 GTK_WIN_POS_MOUSE, TRUE, 1735 _("OK"), setup_ok_callback, 1736 NULL, NULL, NULL, TRUE, FALSE, 1737 _("Cancel"), setup_cancel_callback, 1738 NULL, (GObject *) 1, NULL, FALSE, TRUE, 1739 NULL); 1740 1741 /* 1742 * Top-level table for dialog. 1743 */ 1744 1745 table = gtk_table_new (4, 4, FALSE); 1746 gtk_container_set_border_width (GTK_CONTAINER (table), 6); 1747 gtk_table_set_col_spacings (GTK_TABLE (table), 4); 1748 gtk_table_set_row_spacing (GTK_TABLE (table), 0, 150); 1749 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (setup_dialog)->vbox), table, 1750 TRUE, TRUE, 0); 1751 gtk_widget_show (table); 1752 1753 /* 1754 * Printer driver option menu. 1755 */ 1756 1757 label = gtk_label_new (_("Printer Make:")); 1758 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 1759 gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 2, 1760 GTK_FILL, GTK_FILL, 0, 0); 1761 gtk_widget_show (label); 1762 1763 event_box = gtk_event_box_new (); 1764 gtk_table_attach (GTK_TABLE (table), event_box, 2, 4, 0, 2, 1765 GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0); 1766 gtk_widget_show (event_box); 1767 1768 stpui_set_help_data (event_box, _("Select the make of your printer")); 1769 1770 manufacturer_crawler = gtk_scrolled_window_new (NULL, NULL); 1771 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (manufacturer_crawler), 1772 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 1773 gtk_container_add (GTK_CONTAINER (event_box), manufacturer_crawler); 1774 gtk_widget_show (manufacturer_crawler); 1775 1776 manufacturer_clist = gtk_clist_new (1); 1777 gtk_widget_set_usize (manufacturer_clist, 200, 0); 1778 gtk_clist_set_selection_mode(GTK_CLIST(manufacturer_clist),GTK_SELECTION_SINGLE); 1779 gtk_container_add (GTK_CONTAINER (manufacturer_crawler), manufacturer_clist); 1780 gtk_widget_show (manufacturer_clist); 1781 1782 g_signal_connect (G_OBJECT (manufacturer_clist), "select_row", 1783 G_CALLBACK (manufacturer_callback), NULL); 1784 1785 1786 label = gtk_label_new (_("Printer Model:")); 1787 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 1788 gtk_table_attach (GTK_TABLE (table), label, 4, 5, 0, 2, 1789 GTK_FILL, GTK_FILL, 0, 0); 1790 gtk_widget_show (label); 1791 1792 event_box = gtk_event_box_new (); 1793 gtk_table_attach (GTK_TABLE (table), event_box, 5, 7, 0, 2, 1794 GTK_FILL | GTK_EXPAND, GTK_FILL | GTK_EXPAND, 0, 0); 1795 gtk_widget_show (event_box); 1796 1797 stpui_set_help_data (event_box, _("Select your printer model")); 1798 1799 printer_crawler = gtk_scrolled_window_new (NULL, NULL); 1800 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (printer_crawler), 1801 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); 1802 gtk_container_add (GTK_CONTAINER (event_box), printer_crawler); 1803 gtk_widget_show (printer_crawler); 1804 1805 printer_driver = gtk_clist_new (1); 1806 gtk_widget_set_usize (printer_driver, 200, 0); 1807 gtk_clist_set_selection_mode(GTK_CLIST(printer_driver),GTK_SELECTION_SINGLE); 1808 gtk_container_add (GTK_CONTAINER (printer_crawler), printer_driver); 1809 gtk_widget_show (printer_driver); 1810 1811 g_signal_connect (G_OBJECT (printer_driver), "select_row", 1812 G_CALLBACK (print_driver_callback), NULL); 1813 1814 1815 for (i = 0; i < stp_printer_model_count (); i ++) 1816 { 1817 const stp_printer_t *the_printer = stp_get_printer_by_index (i); 1818 1819 if (strcmp(stp_printer_get_long_name (the_printer), "") != 0 && 1820 strcmp(stp_printer_get_family(the_printer), "raw") != 0) 1821 { 1822 const gchar *make = stp_printer_get_manufacturer(the_printer); 1823 if (! stp_string_list_is_present(manufacturer_list, make)) 1824 stp_string_list_add_string(manufacturer_list, make, make); 1825 } 1826 } 1827 1828 for (i = 0; i < stp_string_list_count(manufacturer_list); i++) 1829 { 1830 const stp_param_string_t *param = 1831 stp_string_list_param(manufacturer_list, i); 1832 gchar *xname = g_strdup(param->name); 1833 gtk_clist_insert(GTK_CLIST(manufacturer_clist), i, &xname); 1834 gtk_clist_set_row_data_full(GTK_CLIST(manufacturer_clist), i, xname, 1835 g_free); 1836 } 1837 stp_string_list_destroy(manufacturer_list); 1838 gtk_clist_sort(GTK_CLIST(manufacturer_clist)); 1839 build_printer_driver_clist(); 1840 1841 /* 1842 * PPD file. 1843 */ 1844 1845 ppd_label = gtk_label_new (_("PPD File:")); 1846 gtk_misc_set_alignment (GTK_MISC (ppd_label), 1.0, 0.5); 1847 gtk_table_attach (GTK_TABLE (table), ppd_label, 1, 2, 3, 4, 1848 GTK_FILL, GTK_FILL, 0, 0); 1849 gtk_widget_show (ppd_label); 1850 1851 ppd_box = gtk_hbox_new (FALSE, 8); 1852 gtk_table_attach (GTK_TABLE (table), ppd_box, 2, 7, 3, 4, 1853 GTK_FILL, GTK_FILL, 0, 0); 1854 1855 ppd_file = gtk_entry_new (); 1856 g_signal_connect(G_OBJECT(ppd_file), "activate", 1857 G_CALLBACK(ppd_file_callback), NULL); 1858 gtk_box_pack_start (GTK_BOX (ppd_box), ppd_file, TRUE, TRUE, 0); 1859 gtk_widget_show (ppd_file); 1860 1861 stpui_set_help_data(ppd_file,_("Enter the correct PPD filename for your printer")); 1862 1863 ppd_button = gtk_button_new_with_label (_("Browse")); 1864 gtk_misc_set_padding (GTK_MISC (GTK_BIN (ppd_button)->child), 2, 0); 1865 gtk_box_pack_start (GTK_BOX (ppd_box), ppd_button, FALSE, FALSE, 0); 1866 gtk_widget_show (ppd_button); 1867 gtk_widget_show (ppd_box); 1868 1869 stpui_set_help_data(ppd_button, 1870 _("Choose the correct PPD filename for your printer")); 1871 g_signal_connect (G_OBJECT (ppd_button), "clicked", 1872 G_CALLBACK (ppd_browse_callback), NULL); 1873 1874 ppd_model_label = gtk_label_new (_("Printer Model:")); 1875 gtk_misc_set_alignment (GTK_MISC (ppd_model_label), 1.0, 0.5); 1876 gtk_table_attach (GTK_TABLE (table), ppd_model_label, 1, 2, 4, 5, 1877 GTK_FILL, GTK_FILL, 0, 0); 1878 gtk_widget_show (ppd_model_label); 1879 1880 ppd_model = gtk_label_new (""); 1881 gtk_misc_set_alignment (GTK_MISC (ppd_model), 0.0, 0.5); 1882 gtk_table_attach (GTK_TABLE (table), ppd_model, 2, 7, 4, 5, 1883 GTK_FILL, GTK_FILL, 0, 0); 1884 gtk_widget_show (ppd_model); 1885 1886 1887 /* 1888 * Print command. 1889 */ 1890 1891 group = NULL; 1892 for (i = 0; i < command_options_count; i++) 1893 group = stpui_create_radio_button(&(command_options[i]), group, table, 1894 0, i > 0 ? i + 6 : i + 5, 1895 G_CALLBACK(command_type_callback)); 1896 1897 standard_cmd_entry = gtk_entry_new(); 1898 gtk_table_attach (GTK_TABLE (table), standard_cmd_entry, 2, 7, 6, 7, 1899 GTK_FILL, GTK_FILL, 0, 0); 1900 gtk_entry_set_editable(GTK_ENTRY(standard_cmd_entry), FALSE); 1901 gtk_widget_set_sensitive(standard_cmd_entry, FALSE); 1902 gtk_widget_show (standard_cmd_entry); 1903 1904 queue_combo = gtk_combo_new (); 1905 event_box = gtk_event_box_new (); 1906 gtk_container_add (GTK_CONTAINER (event_box), queue_combo); 1907 gtk_widget_show (queue_combo); 1908 gtk_widget_show (event_box); 1909 build_queue_combo(); 1910 1911 stpui_set_help_data(event_box, 1912 _("Select the name of the output queue (not the type, " 1913 "or model, of printer) that you wish to print to")); 1914 label = gtk_label_new(_("Printer Queue:")); 1915 gtk_widget_show(label); 1916 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 5, 6, 1917 GTK_FILL, GTK_FILL, 0, 0); 1918 gtk_table_attach (GTK_TABLE (table), event_box, 3, 7, 5, 6, 1919 GTK_FILL, GTK_FILL, 0, 0); 1920 1921 custom_command_entry = gtk_entry_new (); 1922 gtk_table_attach (GTK_TABLE (table), custom_command_entry, 2, 7, 7, 8, 1923 GTK_FILL, GTK_FILL, 0, 0); 1924 g_signal_connect(G_OBJECT(custom_command_entry), "activate", 1925 G_CALLBACK(setup_callback), NULL); 1926 gtk_widget_set_sensitive(custom_command_entry, FALSE); 1927 gtk_widget_show (custom_command_entry); 1928 1929 stpui_set_help_data 1930 (custom_command_entry, _("Enter the correct command to print to your printer. ")); 1931 1932 file_entry = gtk_entry_new (); 1933 gtk_table_attach (GTK_TABLE (table), file_entry, 2, 6, 8, 9, 1934 GTK_FILL, GTK_FILL, 0, 0); 1935 g_signal_connect(G_OBJECT(file_entry), "activate", 1936 G_CALLBACK(setup_callback), NULL); 1937 gtk_widget_show (file_entry); 1938 1939 gtk_widget_set_sensitive(file_entry, FALSE); 1940 stpui_set_help_data 1941 (file_entry, _("Enter the file to print to. ")); 1942 1943 file_button = gtk_button_new_with_label (_("Browse")); 1944 1945 gtk_table_attach (GTK_TABLE (table), file_button, 6, 7, 8, 9, 1946 GTK_FILL, GTK_FILL, 0, 0); 1947 gtk_widget_show (file_button); 1948 1949 stpui_set_help_data(file_button, _("File to print to")); 1950 g_signal_connect (G_OBJECT (file_button), "clicked", 1951 G_CALLBACK (file_browse_callback), NULL); 1952 1953 /* 1954 * Output file selection dialog. 1955 */ 1956 1957 file_browser = gtk_file_selection_new (_("Print To File")); 1958 1959 g_signal_connect 1960 (G_OBJECT (GTK_FILE_SELECTION (file_browser)->ok_button), "clicked", 1961 G_CALLBACK (file_ok_callback), NULL); 1962 g_signal_connect 1963 (G_OBJECT (GTK_FILE_SELECTION (file_browser)->cancel_button), "clicked", 1964 G_CALLBACK (file_cancel_callback), NULL); 1965 1966 /* 1967 * PPD file selection dialog. 1968 */ 1969 1970 ppd_browser = gtk_file_selection_new (_("PPD File")); 1971 gtk_file_selection_hide_fileop_buttons (GTK_FILE_SELECTION (ppd_browser)); 1972 1973 g_signal_connect 1974 (G_OBJECT (GTK_FILE_SELECTION (ppd_browser)->ok_button), "clicked", 1975 G_CALLBACK (ppd_ok_callback), NULL); 1976 g_signal_connect_object 1977 (G_OBJECT (GTK_FILE_SELECTION (ppd_browser)->cancel_button), "clicked", 1978 G_CALLBACK (gtk_widget_hide), G_OBJECT (ppd_browser), G_CONNECT_SWAPPED); 1979} 1980 1981static void 1982create_new_printer_dialog (void) 1983{ 1984 GtkWidget *table; 1985 1986 new_printer_dialog = 1987 stpui_dialog_new (_("Define New Printer"), 1988 GTK_WIN_POS_MOUSE, FALSE, 1989 _("OK"), new_printer_ok_callback, 1990 NULL, NULL, NULL, TRUE, FALSE, 1991 _("Cancel"), gtk_widget_hide, 1992 NULL, (GObject *) 1, NULL, FALSE, TRUE, 1993 NULL); 1994 1995 table = gtk_table_new (1, 1, FALSE); 1996 gtk_container_set_border_width (GTK_CONTAINER (table), 6); 1997 gtk_table_set_col_spacings (GTK_TABLE (table), 4); 1998 gtk_table_set_row_spacings (GTK_TABLE (table), 8); 1999 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (new_printer_dialog)->vbox), table, 2000 FALSE, FALSE, 0); 2001 gtk_widget_show (table); 2002 2003 new_printer_entry = gtk_entry_new (); 2004 gtk_entry_set_max_length (GTK_ENTRY (new_printer_entry), 127); 2005 stpui_table_attach_aligned(GTK_TABLE (table), 0, 0, _("Printer Name:"), 1.0, 2006 0.5, new_printer_entry, 1, TRUE); 2007 2008 stpui_set_help_data(new_printer_entry, 2009 _("Enter the name you wish to give this logical printer")); 2010 g_signal_connect (G_OBJECT (new_printer_entry), "activate", 2011 G_CALLBACK (new_printer_ok_callback), NULL); 2012} 2013 2014static void 2015create_about_dialog (void) 2016{ 2017 GtkWidget *label; 2018 about_dialog = 2019 stpui_dialog_new (_("About Gutenprint " PLUG_IN_VERSION), 2020 GTK_WIN_POS_MOUSE, FALSE, 2021 _("OK"), gtk_widget_hide, 2022 NULL, (GObject *) 1, NULL, TRUE, TRUE, 2023 NULL); 2024 2025 label = gtk_label_new 2026 (_("Gutenprint Version " PLUG_IN_VERSION "\n" 2027 "\n" 2028 "Copyright (C) 1997-2003 Michael Sweet, Robert Krawitz,\n" 2029 "and the rest of the Gutenprint Development Team.\n" 2030 "\n" 2031 "Please visit our web site at http://gimp-print.sourceforge.net.\n" 2032 "\n" 2033 "This program is free software; you can redistribute it and/or modify\n" 2034 "it under the terms of the GNU General Public License as published by\n" 2035 "the Free Software Foundation; either version 2 of the License, or\n" 2036 "(at your option) any later version.\n" 2037 "\n" 2038 "This program is distributed in the hope that it will be useful,\n" 2039 "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" 2040 "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" 2041 "GNU General Public License for more details.\n" 2042 "\n" 2043 "You should have received a copy of the GNU General Public License\n" 2044 "along with this program; if not, write to the Free Software\n" 2045 "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 " 2046 "USA\n")); 2047 2048 gtk_misc_set_padding (GTK_MISC (label), 12, 4); 2049 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (about_dialog)->vbox), label, 2050 FALSE, FALSE, 0); 2051 gtk_widget_show (label); 2052} 2053 2054static void 2055create_printer_settings_frame (void) 2056{ 2057 GtkWidget *table; 2058 GtkWidget *sep; 2059 GtkWidget *printer_hbox; 2060 GtkWidget *button; 2061 GtkWidget *event_box; 2062 GtkWidget *scrolled_window; 2063 gint vpos = 0; 2064 2065 create_printer_dialog (); 2066 create_about_dialog (); 2067 create_new_printer_dialog (); 2068 2069 table = gtk_table_new (1, 1, FALSE); 2070 gtk_table_set_col_spacings (GTK_TABLE (table), 2); 2071 gtk_table_set_row_spacings (GTK_TABLE (table), 2); 2072 gtk_container_set_border_width (GTK_CONTAINER (table), 4); 2073 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), table, 2074 gtk_label_new (_("Printer Settings"))); 2075 gtk_widget_show (table); 2076 2077 /* 2078 * Printer option menu. 2079 */ 2080 2081 printer_combo = gtk_combo_new (); 2082 event_box = gtk_event_box_new (); 2083 gtk_container_add (GTK_CONTAINER (event_box), printer_combo); 2084 gtk_widget_show (printer_combo); 2085 2086 stpui_set_help_data(event_box, 2087 _("Select the name of the printer (not the type, " 2088 "or model, of printer) that you wish to print to")); 2089 stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Printer Name:"), 2090 0.0, 0.5, event_box, 1, TRUE); 2091 printer_model_label = gtk_label_new (""); 2092 stpui_table_attach_aligned(GTK_TABLE (table), 0, vpos++, _("Printer Model:"), 2093 0.0, 0.0, printer_model_label, 1, TRUE); 2094 printer_hbox = gtk_hbox_new (TRUE, 4); 2095 gtk_table_attach (GTK_TABLE (table), printer_hbox, 2096 1, 4, vpos, vpos + 1, GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0); 2097 vpos += 2; 2098 gtk_widget_show (printer_hbox); 2099 2100 /* 2101 * Setup printer button 2102 */ 2103 2104 button = gtk_button_new_with_label (_("Setup Printer...")); 2105 stpui_set_help_data(button, 2106 _("Choose the printer model, PPD file, and command " 2107 "that is used to print to this printer")); 2108 gtk_misc_set_padding (GTK_MISC (GTK_BIN (button)->child), 2, 0); 2109 gtk_box_pack_start (GTK_BOX (printer_hbox), button, FALSE, TRUE, 0); 2110 gtk_widget_show (button); 2111 2112 g_signal_connect (G_OBJECT (button), "clicked", 2113 G_CALLBACK (setup_open_callback), NULL); 2114 2115 /* 2116 * New printer button 2117 */ 2118 2119 button = gtk_button_new_with_label (_("New Printer...")); 2120 stpui_set_help_data (button, _("Define a new logical printer. This can be used to " 2121 "name a collection of settings that you wish to " 2122 "remember for future use.")); 2123 gtk_box_pack_start (GTK_BOX (printer_hbox), button, FALSE, TRUE, 0); 2124 gtk_widget_show (button); 2125 2126 g_signal_connect (G_OBJECT (button), "clicked", 2127 G_CALLBACK (new_printer_open_callback), NULL); 2128 2129 sep = gtk_hseparator_new (); 2130 gtk_table_attach (GTK_TABLE (table), sep, 0, 5, vpos, vpos + 1, 2131 GTK_EXPAND|GTK_FILL, GTK_FILL, 0, 0); 2132 gtk_widget_show (sep); 2133 vpos++; 2134 2135 printer_features_table = gtk_table_new(1, 1, FALSE); 2136 gtk_table_set_col_spacings (GTK_TABLE (printer_features_table), 2); 2137 gtk_table_set_row_spacings (GTK_TABLE (printer_features_table), 0); 2138 gtk_widget_show (printer_features_table); 2139 2140 scrolled_window = gtk_scrolled_window_new(NULL, NULL); 2141 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), 2142 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); 2143 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), 2144 printer_features_table); 2145 gtk_table_attach_defaults(GTK_TABLE(table), scrolled_window, 2146 0, 6, vpos, vpos + 1); 2147 gtk_widget_show(scrolled_window); 2148 vpos++; 2149 2150 button = gtk_button_new_with_label (_("Set Printer Option Defaults")); 2151 stpui_set_help_data (button, _("Set all printer options to their defaults")); 2152 gtk_table_attach(GTK_TABLE(table), button, 0, 6, vpos, vpos + 1, 2153 GTK_EXPAND|GTK_FILL, GTK_SHRINK|GTK_FILL, 0, 0); 2154 gtk_widget_show (button); 2155 2156 g_signal_connect (G_OBJECT (button), "clicked", 2157 G_CALLBACK (set_printer_defaults), NULL); 2158 2159} 2160 2161static void 2162create_scaling_frame (void) 2163{ 2164 GtkWidget *frame; 2165 GtkWidget *vbox; 2166 GtkWidget *hbox; 2167 GtkWidget *table; 2168 GtkWidget *box; 2169 GtkWidget *label; 2170 GtkWidget *event_box; 2171 GtkWidget *sep; 2172 GSList *group; 2173 2174 frame = gtk_frame_new (_("Image Size")); 2175 gtk_box_pack_start (GTK_BOX (main_vbox), frame, FALSE, FALSE, 0); 2176 gtk_widget_show (frame); 2177 2178 hbox = gtk_hbox_new (FALSE, 2); 2179 gtk_container_set_border_width (GTK_CONTAINER (hbox), 4); 2180 gtk_container_add (GTK_CONTAINER (frame), hbox); 2181 gtk_widget_show (hbox); 2182 2183 vbox = gtk_vbox_new (FALSE, 2); 2184/* gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); */ 2185 gtk_container_add (GTK_CONTAINER (hbox), vbox); 2186 gtk_widget_show (vbox); 2187 2188 table = gtk_table_new (1, 1, FALSE); 2189 gtk_table_set_col_spacings (GTK_TABLE (table), 4); 2190 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); 2191 gtk_widget_show (table); 2192 2193 /* 2194 * Create the scaling adjustment using percent. It doesn't really matter, 2195 * since as soon as we call plist_callback at the end of initialization 2196 * everything will be put right. 2197 */ 2198 scaling_adjustment = 2199 stpui_scale_entry_new (GTK_TABLE (table), 0, 0, _("Scaling:"), 100, 75, 2200 100.0, minimum_image_percent, 100.0, 2201 1.0, 10.0, 1, TRUE, 0, 0, NULL); 2202 stpui_set_adjustment_tooltip(scaling_adjustment, 2203 _("Set the scale (size) of the image")); 2204 g_signal_connect (G_OBJECT (scaling_adjustment), "value_changed", 2205 G_CALLBACK (scaling_update), NULL); 2206 2207 box = gtk_hbox_new (FALSE, 4); 2208 gtk_box_pack_start (GTK_BOX (vbox), box, TRUE, TRUE, 0); 2209 gtk_widget_show (box); 2210 2211 /* 2212 * The scale by percent/ppi toggles 2213 */ 2214 2215 table = gtk_table_new (1, 1, FALSE); 2216 gtk_table_set_col_spacings (GTK_TABLE (table), 4); 2217 gtk_box_pack_start (GTK_BOX (box), table, FALSE, FALSE, 0); 2218 gtk_widget_show (table); 2219 2220 event_box = gtk_event_box_new (); 2221 gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1, 2222 GTK_FILL, GTK_FILL, 0, 0); 2223 gtk_widget_show (event_box); 2224 2225 label = gtk_label_new (_("Scale by:")); 2226 gtk_container_add (GTK_CONTAINER (event_box), label); 2227 gtk_widget_show (label); 2228 2229 stpui_set_help_data(event_box, 2230 _("Select whether scaling is measured as percent of " 2231 "available page size or number of output dots per inch")); 2232 2233 scaling_percent = gtk_radio_button_new_with_label (NULL, _("Percent")); 2234 group = gtk_radio_button_group (GTK_RADIO_BUTTON (scaling_percent)); 2235 stpui_table_attach_aligned(GTK_TABLE (table), 0, 0, NULL, 0.5, 0.5, 2236 scaling_percent, 2, TRUE); 2237 2238 stpui_set_help_data(scaling_percent, _("Scale the print to the size of the page")); 2239 g_signal_connect (G_OBJECT (scaling_percent), "toggled", 2240 G_CALLBACK (scaling_callback), NULL); 2241 2242 scaling_ppi = gtk_radio_button_new_with_label (group, _("PPI")); 2243 stpui_table_attach_aligned(GTK_TABLE (table), 2, 0, NULL, 0.5, 0.5, 2244 scaling_ppi, 1, TRUE); 2245 2246 stpui_set_help_data(scaling_ppi, 2247 _("Scale the print to the number of dots per inch")); 2248 g_signal_connect (G_OBJECT (scaling_ppi), "toggled", 2249 G_CALLBACK (scaling_callback), NULL); 2250 2251 sep = gtk_vseparator_new (); 2252 gtk_box_pack_start (GTK_BOX (hbox), sep, FALSE, FALSE, 8); 2253 gtk_widget_show (sep); 2254 2255 /* 2256 * The width/height enries 2257 */ 2258 2259 table = gtk_table_new (1, 1, FALSE); 2260 gtk_table_set_col_spacings (GTK_TABLE (table), 2); 2261 gtk_box_pack_start (GTK_BOX (hbox), table, FALSE, FALSE, 0); 2262 gtk_widget_show (table); 2263 2264 width_entry = create_positioning_entry 2265 (table, 0, 0, _("Width:"), _("Set the width of the print")); 2266 height_entry = create_positioning_entry 2267 (table, 0, 1, _("Height:"), _("Set the height of the print")); 2268 2269 /* 2270 * The "image size" button 2271 */ 2272 2273 scaling_image = gtk_button_new_with_label (_("Use Original\nImage Size")); 2274 gtk_misc_set_padding (GTK_MISC (GTK_BIN (scaling_image)->child), 2, 2); 2275 gtk_box_pack_end (GTK_BOX (hbox), scaling_image, FALSE, FALSE, 0); 2276 gtk_widget_show (scaling_image); 2277 2278 stpui_set_help_data(scaling_image, 2279 _("Set the print size to the size of the image")); 2280 g_signal_connect (G_OBJECT (scaling_image), "clicked", 2281 G_CALLBACK (scaling_callback), NULL); 2282} 2283 2284/* 2285 * create_color_adjust_window (void) 2286 * 2287 * NOTES: 2288 * creates the color adjuster popup, allowing the user to adjust brightness, 2289 * contrast, saturation, etc. 2290 */ 2291static void 2292create_color_adjust_window (void) 2293{ 2294 GtkWidget *table; 2295 GtkWidget *label; 2296 GtkWidget *event_box; 2297 GtkWidget *scrolled_window; 2298 gint x, y; /* Window dimensions */ 2299 2300 initialize_thumbnail(); 2301 2302 color_adjust_dialog = 2303 stpui_dialog_new(_("Print Color Adjust"), 2304 GTK_WIN_POS_MOUSE, TRUE, 2305 2306 _("Set Defaults"), set_color_defaults, 2307 NULL, NULL, NULL, FALSE, FALSE, 2308 _("Close"), gtk_widget_hide, 2309 NULL, (GObject *) 1, NULL, TRUE, TRUE, 2310 NULL); 2311 2312 table = gtk_table_new (1, 1, FALSE); 2313 gtk_container_set_border_width (GTK_CONTAINER (table), 6); 2314 gtk_table_set_col_spacings (GTK_TABLE (table), 4); 2315 gtk_table_set_row_spacings (GTK_TABLE (table), 0); 2316/* gtk_table_set_row_spacing (GTK_TABLE (table), 8, 6); */ 2317 2318 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (color_adjust_dialog)->vbox), 2319 table, TRUE, TRUE, 0); 2320 gtk_widget_show (table); 2321 2322 /* 2323 * Drawing area for color swatch feedback display... 2324 */ 2325 2326 event_box = gtk_event_box_new (); 2327 gtk_widget_show (GTK_WIDGET (event_box)); 2328 gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (event_box), 2329 0, 1, 0, 1, 0, 0, 0, 0); 2330 2331 swatch = (GtkDrawingArea *) gtk_drawing_area_new (); 2332 gtk_widget_set_events (GTK_WIDGET (swatch), GDK_EXPOSURE_MASK); 2333 gtk_drawing_area_size (swatch, thumbnail_w, thumbnail_h); 2334 gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (swatch)); 2335 gtk_widget_show (GTK_WIDGET (swatch)); 2336 2337 stpui_set_help_data (GTK_WIDGET (event_box), _("Image preview")); 2338 g_signal_connect (G_OBJECT (swatch), "expose_event", 2339 G_CALLBACK (redraw_color_swatch), 2340 NULL); 2341 2342 event_box = gtk_event_box_new (); 2343 gtk_widget_show (GTK_WIDGET (event_box)); 2344 gtk_table_attach (GTK_TABLE (table), GTK_WIDGET (event_box), 2345 1, 2, 0, 1, 0, 0, 0, 0); 2346 2347 output_color_vbox = gtk_vbox_new(TRUE, 0); 2348 gtk_container_add(GTK_CONTAINER(event_box), output_color_vbox); 2349 gtk_widget_show(GTK_WIDGET(output_color_vbox)); 2350 2351 label = gtk_label_new(_("View Output Channels:")); 2352 gtk_box_pack_start(GTK_BOX(output_color_vbox), label, TRUE, TRUE, 0); 2353 gtk_widget_show(GTK_WIDGET(label)); 2354 2355 cyan_button = gtk_toggle_button_new_with_label(_("Cyan")); 2356 gtk_box_pack_start(GTK_BOX(output_color_vbox), cyan_button, TRUE, TRUE, 0); 2357 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cyan_button), TRUE); 2358 gtk_widget_show(GTK_WIDGET(cyan_button)); 2359 g_signal_connect (G_OBJECT (cyan_button), "toggled", 2360 G_CALLBACK (color_button_callback), NULL); 2361 2362 magenta_button = gtk_toggle_button_new_with_label(_("Magenta")); 2363 gtk_box_pack_start(GTK_BOX(output_color_vbox), magenta_button, TRUE, TRUE,0); 2364 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(magenta_button), TRUE); 2365 gtk_widget_show(GTK_WIDGET(magenta_button)); 2366 g_signal_connect (G_OBJECT (magenta_button), "toggled", 2367 G_CALLBACK (color_button_callback), NULL); 2368 2369 yellow_button = gtk_toggle_button_new_with_label(_("Yellow")); 2370 gtk_box_pack_start(GTK_BOX(output_color_vbox), yellow_button, TRUE, TRUE, 0); 2371 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(yellow_button), TRUE); 2372 gtk_widget_show(GTK_WIDGET(yellow_button)); 2373 g_signal_connect (G_OBJECT (yellow_button), "toggled", 2374 G_CALLBACK (color_button_callback), NULL); 2375 2376 black_button = gtk_toggle_button_new_with_label(_("Black")); 2377 gtk_box_pack_start(GTK_BOX(output_color_vbox), black_button, TRUE, TRUE, 0); 2378 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(black_button), TRUE); 2379 gtk_widget_show(GTK_WIDGET(black_button)); 2380 g_signal_connect (G_OBJECT (black_button), "toggled", 2381 G_CALLBACK (color_button_callback), NULL); 2382 2383 red_button = gtk_toggle_button_new_with_label(_("Red")); 2384 gtk_box_pack_start(GTK_BOX(output_color_vbox), red_button, TRUE, TRUE, 0); 2385 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(red_button), TRUE); 2386 gtk_widget_show(GTK_WIDGET(red_button)); 2387 g_signal_connect (G_OBJECT (red_button), "toggled", 2388 G_CALLBACK (color_button_callback), NULL); 2389 2390 green_button = gtk_toggle_button_new_with_label(_("Green")); 2391 gtk_box_pack_start(GTK_BOX(output_color_vbox), green_button, TRUE, TRUE,0); 2392 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(green_button), TRUE); 2393 gtk_widget_show(GTK_WIDGET(green_button)); 2394 g_signal_connect (G_OBJECT (green_button), "toggled", 2395 G_CALLBACK (color_button_callback), NULL); 2396 2397 blue_button = gtk_toggle_button_new_with_label(_("Blue")); 2398 gtk_box_pack_start(GTK_BOX(output_color_vbox), blue_button, TRUE, TRUE, 0); 2399 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(blue_button), TRUE); 2400 gtk_widget_show(GTK_WIDGET(blue_button)); 2401 g_signal_connect (G_OBJECT (blue_button), "toggled", 2402 G_CALLBACK (color_button_callback), NULL); 2403 2404 color_adjustment_table = gtk_table_new(1, 1, FALSE); 2405 gtk_table_set_col_spacings (GTK_TABLE (color_adjustment_table), 2); 2406 gtk_table_set_row_spacings (GTK_TABLE (color_adjustment_table), 0); 2407 gtk_container_set_border_width (GTK_CONTAINER (color_adjustment_table), 4); 2408 gtk_widget_show (color_adjustment_table); 2409 2410 scrolled_window = gtk_scrolled_window_new(NULL, NULL); 2411 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), 2412 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); 2413 gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), 2414 color_adjustment_table); 2415 gtk_table_attach_defaults(GTK_TABLE(table), scrolled_window, 2416 0, 2, 1, 2); 2417 gtk_widget_show(scrolled_window); 2418 2419 /* The initial size request does not account for the 2420 GtkScrolledWindow. */ 2421 gtk_window_get_size(GTK_WINDOW(color_adjust_dialog), &x, &y); 2422 gtk_window_set_default_size(GTK_WINDOW(color_adjust_dialog), x, y+300); 2423} 2424 2425static void 2426create_image_settings_frame (void) 2427{ 2428 GtkWidget *vbox; 2429 GtkWidget *hbox; 2430 GtkWidget *table; 2431 GtkWidget *label; 2432 GtkWidget *event_box; 2433 GtkWidget *sep; 2434 GSList *group; 2435 gint i; 2436 2437 create_color_adjust_window (); 2438 2439 vbox = gtk_vbox_new (FALSE, 4); 2440 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); 2441 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, 2442 gtk_label_new (_("Output"))); 2443 gtk_widget_show (vbox); 2444 2445 table = gtk_table_new (1, 1, FALSE); 2446 gtk_table_set_col_spacings (GTK_TABLE (table), 4); 2447 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); 2448 gtk_widget_show (table); 2449 2450 event_box = gtk_event_box_new (); 2451 gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1, 2452 GTK_FILL, GTK_FILL, 0, 0); 2453 gtk_widget_show (event_box); 2454 2455 /* 2456 * Output type toggles. 2457 */ 2458 2459 table = gtk_table_new (1, 1, FALSE); 2460 gtk_table_set_col_spacings (GTK_TABLE (table), 4); 2461/* gtk_table_set_row_spacing (GTK_TABLE (table), 2, 4); */ 2462 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); 2463 gtk_widget_show (table); 2464 2465 event_box = gtk_event_box_new (); 2466 gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1, 2467 GTK_FILL, GTK_FILL, 0, 0); 2468 gtk_widget_show (event_box); 2469 2470 label = gtk_label_new (_("Output Type:")); 2471 gtk_container_add (GTK_CONTAINER (event_box), label); 2472 gtk_widget_show (label); 2473 2474 stpui_set_help_data(event_box, _("Select the desired output type")); 2475 2476 group = NULL; 2477 for (i = 0; i < output_type_count; i++) 2478 group = stpui_create_radio_button(&(output_types[i]), group, table, 0, i, 2479 G_CALLBACK(output_type_callback)); 2480 2481 sep = gtk_hseparator_new (); 2482 gtk_box_pack_start (GTK_BOX (vbox), sep, FALSE, FALSE, 0); 2483 gtk_widget_show (sep); 2484 2485 /* 2486 * Color adjust button 2487 */ 2488 hbox = gtk_hbox_new (FALSE, 4); 2489 gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0); 2490 gtk_widget_show(hbox); 2491 label = gtk_label_new(""); 2492 gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, TRUE, 0); 2493 gtk_widget_show(label); 2494 2495 adjust_color_button = gtk_button_new_with_label (_("Adjust Output...")); 2496 gtk_misc_set_padding (GTK_MISC (GTK_BIN (adjust_color_button)->child), 4, 0); 2497 gtk_box_pack_start (GTK_BOX (hbox), adjust_color_button, FALSE, FALSE, 0); 2498 gtk_widget_show(adjust_color_button); 2499 label = gtk_label_new(""); 2500 gtk_box_pack_end(GTK_BOX(hbox), label, TRUE, TRUE, 0); 2501 gtk_widget_show(label); 2502 2503 stpui_set_help_data(adjust_color_button, 2504 _("Adjust color balance, brightness, contrast, " 2505 "saturation, and dither algorithm")); 2506 g_signal_connect_object (G_OBJECT (adjust_color_button), "clicked", 2507 G_CALLBACK (gtk_widget_show), 2508 G_OBJECT (color_adjust_dialog), 2509 G_CONNECT_SWAPPED); 2510} 2511 2512static void 2513create_units_frame (void) 2514{ 2515 GtkWidget *vbox; 2516 GtkWidget *table; 2517 GtkWidget *label; 2518 GtkWidget *event_box; 2519 GSList *group; 2520 gint i; 2521 2522 units_hbox = gtk_hbox_new(FALSE, 0); 2523 label = gtk_label_new(_("Size Units:")); 2524 gtk_widget_show(label); 2525 gtk_box_pack_start(GTK_BOX(units_hbox), label, TRUE, TRUE, 0); 2526 units_label = gtk_label_new(_(" ")); 2527 gtk_widget_show(units_label); 2528 gtk_box_pack_start(GTK_BOX(units_hbox), units_label, TRUE, TRUE, 0); 2529 gtk_widget_show(units_hbox); 2530 2531 vbox = gtk_vbox_new (FALSE, 4); 2532 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4); 2533 gtk_notebook_append_page (GTK_NOTEBOOK (notebook), vbox, units_hbox); 2534 gtk_widget_show (vbox); 2535 2536 /* 2537 * The units toggles 2538 */ 2539 2540 table = gtk_table_new (1, 1, FALSE); 2541 gtk_table_set_col_spacings (GTK_TABLE (table), 4); 2542 gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0); 2543 gtk_widget_show (table); 2544 2545 event_box = gtk_event_box_new (); 2546 gtk_table_attach (GTK_TABLE (table), event_box, 0, 1, 0, 1, 2547 GTK_SHRINK | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 0); 2548 gtk_widget_show (event_box); 2549 2550 label = gtk_label_new (_("Units:")); 2551 gtk_container_add (GTK_CONTAINER (event_box), label); 2552 gtk_widget_show (label); 2553 2554 stpui_set_help_data(event_box, 2555 _("Select the base unit of measurement for printing")); 2556 2557 group = NULL; 2558 for (i = 0; i < unit_count; i++) 2559 { 2560 unit_t *unit = &(units[i]); 2561 unit->checkbox = gtk_radio_button_new_with_label(group, gettext(unit->name)); 2562 group = gtk_radio_button_group(GTK_RADIO_BUTTON(unit->checkbox)); 2563 stpui_table_attach_aligned(GTK_TABLE(table), i / 2, i % 2, NULL, 0.5, 2564 0.5, unit->checkbox, 1, TRUE); 2565 stpui_set_help_data(unit->checkbox, gettext(unit->help)); 2566 g_signal_connect(G_OBJECT(unit->checkbox), "toggled", 2567 G_CALLBACK(unit_callback), (gpointer) i); 2568 } 2569} 2570 2571/* 2572 * create_main_window() 2573 */ 2574static void 2575create_main_window (void) 2576{ 2577 gint x, y; /* Window dimensions */ 2578 2579 set_current_printer(); 2580 manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v)); 2581 /* 2582 * Create the various dialog components. Note that we're not 2583 * actually initializing the values at this point; that will be done after 2584 * the UI is fully created. 2585 */ 2586 2587 stpui_help_init(); 2588 2589 create_top_level_structure (); 2590 2591 create_preview (); 2592 create_printer_settings_frame (); 2593 create_units_frame(); 2594 create_paper_size_frame(); 2595 create_copy_number_frame(); 2596 create_positioning_frame (); 2597 create_scaling_frame (); 2598 create_image_settings_frame (); 2599 2600 /* 2601 * Now actually set up the correct values in the dialog 2602 */ 2603 2604 do_update_thumbnail = 1; 2605 build_printer_combo (); 2606 plist_callback (NULL, (gpointer) stpui_plist_current); 2607 update_adjusted_thumbnail (TRUE); 2608 2609 /* The initial size request does not account for the 2610 GtkScrolledWindow. */ 2611 gtk_window_get_size(GTK_WINDOW(print_dialog), &x, &y); 2612 gtk_window_set_default_size(GTK_WINDOW(print_dialog), x, y+80); 2613 2614 gtk_widget_show (print_dialog); 2615} 2616 2617static void 2618set_entry_value(GtkWidget *entry, double value, int block) 2619{ 2620 gchar s[255]; 2621 gdouble unit_scaler = units[pv->unit].scale; 2622 const gchar *format = units[pv->unit].format; 2623 2624 g_snprintf(s, sizeof(s), format, value / unit_scaler); 2625 if (block) 2626 g_signal_handlers_block_matched (G_OBJECT (entry), 2627 G_SIGNAL_MATCH_DATA, 2628 0, 2629 0, 2630 NULL, 2631 NULL, 2632 NULL); 2633 2634 gtk_entry_set_text (GTK_ENTRY (entry), s); 2635 if (block) 2636 g_signal_handlers_unblock_matched (G_OBJECT (entry), 2637 G_SIGNAL_MATCH_DATA, 2638 0, 2639 0, 2640 NULL, 2641 NULL, 2642 NULL); 2643} 2644 2645static void 2646reset_preview(void) 2647{ 2648 if (!suppress_preview_reset) 2649 { 2650 stpui_enable_help(); 2651 buttons_pressed = preview_active = 0; 2652 } 2653} 2654 2655static void 2656invalidate_preview_thumbnail (void) 2657{ 2658 preview_valid = FALSE; 2659} 2660 2661static void 2662invalidate_frame (void) 2663{ 2664 frame_valid = FALSE; 2665} 2666 2667static void 2668compute_scaling_limits(gdouble *min_ppi_scaling, gdouble *max_ppi_scaling) 2669{ 2670 if (auto_paper_size) 2671 { 2672 *min_ppi_scaling = 2673 FINCH * (gdouble) image_width / (gdouble) printable_width; 2674 } 2675 else 2676 { 2677 gdouble min_ppi_scaling1 = 2678 FINCH * (gdouble) image_width / (gdouble) printable_width; 2679 gdouble min_ppi_scaling2 = 2680 FINCH * (gdouble) image_height / (gdouble) printable_height; 2681 2682 if (min_ppi_scaling1 > min_ppi_scaling2) 2683 *min_ppi_scaling = min_ppi_scaling1; 2684 else 2685 *min_ppi_scaling = min_ppi_scaling2; 2686 } 2687 2688 *max_ppi_scaling = *min_ppi_scaling * 100 / minimum_image_percent; 2689 if (*max_ppi_scaling < image_xres) 2690 *max_ppi_scaling = image_xres; 2691 if (*max_ppi_scaling < image_yres) 2692 *max_ppi_scaling = image_yres; 2693 minimum_image_percent = *min_ppi_scaling * 100 / *max_ppi_scaling; 2694} 2695 2696/* 2697 * scaling_update() - Update the scaling scale using the slider. 2698 */ 2699static void 2700scaling_update (GtkAdjustment *adjustment) 2701{ 2702 reset_preview (); 2703 2704 if (pv->scaling != adjustment->value) 2705 { 2706 invalidate_preview_thumbnail (); 2707 if (GTK_TOGGLE_BUTTON (scaling_ppi)->active) 2708 pv->scaling = -adjustment->value; 2709 else 2710 pv->scaling = adjustment->value; 2711 2712 suppress_scaling_adjustment = TRUE; 2713 preview_update (); 2714 suppress_scaling_adjustment = FALSE; 2715 } 2716} 2717 2718/* 2719 * scaling_callback() - Update the scaling scale using radio buttons. 2720 */ 2721static void 2722scaling_callback (GtkWidget *widget) 2723{ 2724 gdouble max_ppi_scaling; 2725 gdouble min_ppi_scaling; 2726 gdouble current_scale; 2727 2728 reset_preview (); 2729 2730 if (suppress_scaling_callback) 2731 return; 2732 2733 compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling); 2734 2735 if (widget == scaling_ppi) 2736 { 2737 if (! GTK_TOGGLE_BUTTON (scaling_ppi)->active) 2738 return; 2739 2740 GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling; 2741 GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling; 2742 2743 /* 2744 * Compute the correct PPI to create an image of the same size 2745 * as the one measured in percent 2746 */ 2747 current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value; 2748 GTK_ADJUSTMENT (scaling_adjustment)->value = 2749 min_ppi_scaling / (current_scale / 100); 2750 pv->scaling = 0.0; 2751 } 2752 else if (widget == scaling_percent) 2753 { 2754 gdouble new_percent; 2755 2756 if (! GTK_TOGGLE_BUTTON (scaling_percent)->active) 2757 return; 2758 2759 current_scale = GTK_ADJUSTMENT (scaling_adjustment)->value; 2760 GTK_ADJUSTMENT (scaling_adjustment)->lower = minimum_image_percent; 2761 GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0; 2762 2763 new_percent = 100 * min_ppi_scaling / current_scale; 2764 2765 if (new_percent > 100) 2766 new_percent = 100; 2767 if (new_percent < minimum_image_percent) 2768 new_percent = minimum_image_percent; 2769 2770 GTK_ADJUSTMENT (scaling_adjustment)->value = new_percent; 2771 pv->scaling = 0.0; 2772 } 2773 else if (widget == scaling_image) 2774 { 2775 gdouble yres = image_yres; 2776 2777 invalidate_preview_thumbnail (); 2778 2779 GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling; 2780 GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling; 2781 2782 if (yres < min_ppi_scaling) 2783 yres = min_ppi_scaling; 2784 if (yres > max_ppi_scaling) 2785 yres = max_ppi_scaling; 2786 2787 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE); 2788 GTK_ADJUSTMENT (scaling_adjustment)->value = yres; 2789 pv->scaling = 0.0; 2790 } 2791 2792 if (widget == scaling_ppi || widget == scaling_percent) 2793 suppress_preview_update++; 2794 gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment)); 2795 gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment)); 2796 if (auto_paper_size) 2797 set_media_size(stp_get_string_parameter(pv->v, "PageSize")); 2798 if (widget == scaling_ppi || widget == scaling_percent) 2799 suppress_preview_update--; 2800} 2801 2802/**************************************************************************** 2803 * 2804 * plist_build_combo 2805 * 2806 ****************************************************************************/ 2807static void 2808plist_build_combo (GtkWidget *combo, /* I - Combo widget */ 2809 GtkWidget *label, 2810 stp_string_list_t *items, /* I - Menu items */ 2811 int active, 2812 const gchar *cur_item, /* I - Current item */ 2813 const gchar *def_value, /* I - default item */ 2814 GCallback callback, /* I - Callback */ 2815 gint *callback_id, /* IO - Callback ID (init to -1) */ 2816 int (*check_func)(const char *string), 2817 gpointer data) 2818{ 2819 gint i; /* Looping var */ 2820 GList *list = 0; 2821 gint num_items = 0; 2822 GtkEntry *entry = GTK_ENTRY (GTK_COMBO (combo)->entry); 2823 2824 if (check_func && items) 2825 { 2826 stp_string_list_t *new_items = stp_string_list_create(); 2827 num_items = stp_string_list_count(items); 2828 for (i = 0; i < num_items; i++) 2829 { 2830 stp_param_string_t *param = stp_string_list_param(items, i); 2831 if ((*check_func)(param->name)) 2832 stp_string_list_add_string(new_items, param->name, param->text); 2833 } 2834 items = new_items; 2835 } 2836 2837 if (items) 2838 num_items = stp_string_list_count(items); 2839 2840 if (*callback_id != -1) 2841 g_signal_handler_disconnect (G_OBJECT (entry), *callback_id); 2842 gtk_entry_set_editable (entry, FALSE); 2843 2844 if (!active || num_items == 0) 2845 { 2846 list = g_list_append (list, _("Standard")); 2847 gtk_combo_set_popdown_strings (GTK_COMBO (combo), list); 2848 *callback_id = -1; 2849 gtk_widget_set_sensitive (combo, FALSE); 2850 gtk_widget_hide (combo); 2851 if (label) 2852 gtk_widget_hide(label); 2853 if (check_func && items) 2854 stp_string_list_destroy(items); 2855 return; 2856 } 2857 2858 for (i = 0; i < num_items; i ++) 2859 list = g_list_append(list, g_strdup(stp_string_list_param(items, i)->text)); 2860 2861 gtk_combo_set_popdown_strings (GTK_COMBO (combo), list); 2862 2863 if (cur_item) 2864 for (i = 0; i < num_items; i ++) 2865 if (strcmp(stp_string_list_param(items, i)->name, cur_item) == 0) 2866 break; 2867 2868 if (i >= num_items && def_value) 2869 for (i = 0; i < num_items; i ++) 2870 if (strcmp(stp_string_list_param(items, i)->name, def_value) == 0) 2871 break; 2872 2873 if (i >= num_items) 2874 i = 0; 2875 2876 gtk_entry_set_text (entry, stp_string_list_param(items, i)->text); 2877 2878 gtk_combo_set_value_in_list (GTK_COMBO (combo), TRUE, FALSE); 2879 gtk_widget_set_sensitive (combo, TRUE); 2880 gtk_widget_show (combo); 2881 if (label) 2882 gtk_widget_show(label); 2883 2884 *callback_id = g_signal_connect (G_OBJECT (entry), "changed", callback, 2885 data); 2886 if (check_func && items) 2887 stp_string_list_destroy(items); 2888} 2889 2890void 2891stpui_set_image_dimensions(gint width, gint height) 2892{ 2893 image_true_width = width; 2894 image_true_height = height; 2895} 2896 2897void 2898stpui_set_image_resolution(gdouble xres, gdouble yres) 2899{ 2900 image_xres = xres; 2901 image_yres = yres; 2902} 2903 2904gint 2905stpui_compute_orientation(void) 2906{ 2907 if (auto_paper_size || 2908 (printable_width >= printable_height && 2909 image_true_width >= image_true_height) || 2910 (printable_height >= printable_width && 2911 image_true_height >= image_true_width)) 2912 return ORIENT_PORTRAIT; 2913 else 2914 return ORIENT_LANDSCAPE; 2915} 2916 2917static void 2918compute_printable_region(void) 2919{ 2920 stp_get_media_size(pv->v, &paper_width, &paper_height); 2921 stp_get_imageable_area(pv->v, &left, &right, &bottom, &top); 2922 printable_width = right - left; 2923 printable_height = bottom - top; 2924} 2925 2926static void 2927set_orientation(int orientation) 2928{ 2929 compute_printable_region(); 2930 pv->orientation = orientation; 2931 if (orientation == ORIENT_AUTO) 2932 orientation = stpui_compute_orientation(); 2933 physical_orientation = orientation; 2934 switch (orientation) 2935 { 2936 case ORIENT_PORTRAIT: 2937 case ORIENT_UPSIDEDOWN: 2938 image_height = image_true_height; 2939 image_width = image_true_width; 2940 preview_thumbnail_h = thumbnail_h; 2941 preview_thumbnail_w = thumbnail_w; 2942 break; 2943 case ORIENT_LANDSCAPE: 2944 case ORIENT_SEASCAPE: 2945 image_height = image_true_width; 2946 image_width = image_true_height; 2947 preview_thumbnail_h = thumbnail_w; 2948 preview_thumbnail_w = thumbnail_h; 2949 break; 2950 } 2951 update_adjusted_thumbnail(FALSE); 2952} 2953 2954static void 2955position_button_callback(GtkWidget *widget, gpointer data) 2956{ 2957 reset_preview(); 2958 pv->invalid_mask |= (gint) data; 2959 preview_update (); 2960} 2961 2962/* 2963 * position_callback() - callback for position entry widgets 2964 */ 2965static void 2966position_callback (GtkWidget *widget) 2967{ 2968 gdouble new_printed_value = atof (gtk_entry_get_text (GTK_ENTRY (widget))); 2969 gint new_value = SCALE(new_printed_value, units[pv->unit].scale); 2970 2971 reset_preview (); 2972 suppress_preview_update++; 2973 2974 if (widget == top_entry) 2975 stp_set_top(pv->v, new_value); 2976/* 2977 else if (widget == bottom_entry) 2978 stp_set_top(pv->v, new_value - print_height); 2979*/ 2980 else if (widget == bottom_border_entry) 2981 stp_set_top (pv->v, paper_height - print_height - new_value); 2982 else if (widget == left_entry) 2983 stp_set_left (pv->v, new_value); 2984/* 2985 else if (widget == right_entry) 2986 stp_set_left(pv->v, new_value - print_width); 2987*/ 2988 else if (widget == right_border_entry) 2989 stp_set_left (pv->v, paper_width - print_width - new_value); 2990 else if (widget == width_entry || widget == height_entry) 2991 { 2992 gboolean was_percent = (pv->scaling >= 0); 2993 if (pv->scaling >= 0) 2994 { 2995 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE); 2996 scaling_callback (scaling_ppi); 2997 } 2998 if (widget == width_entry) 2999 GTK_ADJUSTMENT (scaling_adjustment)->value = 3000 ((gdouble) image_width) / (new_value / FINCH); 3001 else 3002 GTK_ADJUSTMENT (scaling_adjustment)->value = 3003 ((gdouble) image_height) / (new_value / FINCH); 3004 gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment)); 3005 if (was_percent) 3006 { 3007 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(scaling_percent),TRUE); 3008 gtk_adjustment_value_changed(GTK_ADJUSTMENT (scaling_adjustment)); 3009 } 3010 } 3011 3012 suppress_preview_update--; 3013 preview_update (); 3014} 3015 3016static void 3017set_adjustment_active(option_t *opt, gboolean active, gboolean do_toggle) 3018{ 3019 GtkObject *adj = opt->info.flt.adjustment; 3020 if (do_toggle) 3021 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active); 3022 gtk_widget_set_sensitive (GTK_WIDGET (SCALE_ENTRY_LABEL (adj)), active); 3023 gtk_widget_set_sensitive (GTK_WIDGET (SCALE_ENTRY_SCALE (adj)), active); 3024 gtk_widget_set_sensitive (GTK_WIDGET (SCALE_ENTRY_SPINBUTTON (adj)), active); 3025 gtk_widget_set_sensitive (GTK_WIDGET (opt->reset_btn), active); 3026} 3027 3028static void 3029set_combo_active(option_t *opt, gboolean active, gboolean do_toggle) 3030{ 3031 if (do_toggle) 3032 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active); 3033 gtk_widget_set_sensitive(GTK_WIDGET(opt->info.list.combo), active); 3034 gtk_widget_set_sensitive(GTK_WIDGET(opt->info.list.label), active); 3035 gtk_widget_set_sensitive (GTK_WIDGET (opt->reset_btn), active); 3036} 3037 3038static void 3039set_curve_active(option_t *opt, gboolean active, gboolean do_toggle) 3040{ 3041 if (do_toggle) 3042 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active); 3043 gtk_widget_set_sensitive(GTK_WIDGET(opt->info.curve.button), active); 3044 gtk_widget_set_sensitive(GTK_WIDGET(opt->info.curve.label), active); 3045 if (active) 3046 { 3047 if (opt->info.curve.is_visible) 3048 gtk_widget_show(GTK_WIDGET(opt->info.curve.dialog)); 3049 } 3050 else 3051 gtk_widget_hide(GTK_WIDGET(opt->info.curve.dialog)); 3052 gtk_widget_set_sensitive (GTK_WIDGET (opt->reset_btn), active); 3053} 3054 3055static void 3056set_bool_active(option_t *opt, gboolean active, gboolean do_toggle) 3057{ 3058 if (do_toggle) 3059 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active); 3060 gtk_widget_set_sensitive(GTK_WIDGET(opt->info.bool.checkbox), active); 3061 gtk_widget_set_sensitive (GTK_WIDGET (opt->reset_btn), active); 3062} 3063 3064static void 3065set_file_active(option_t *opt, gboolean active, gboolean do_toggle) 3066{ 3067 if (do_toggle) 3068 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(opt->checkbox), active); 3069 gtk_widget_set_sensitive(GTK_WIDGET(opt->info.file.f_label), active); 3070 gtk_widget_set_sensitive(GTK_WIDGET(opt->info.file.f_button), active); 3071 gtk_widget_set_sensitive(GTK_WIDGET(opt->info.file.f_entry), active); 3072 if (active) 3073 { 3074 if (opt->info.file.f_is_visible) 3075 gtk_widget_show(GTK_WIDGET(opt->info.file.f_browser)); 3076 } 3077 else 3078 gtk_widget_hide(GTK_WIDGET(opt->info.file.f_browser)); 3079 gtk_widget_set_sensitive (GTK_WIDGET (opt->reset_btn), active); 3080} 3081 3082static void 3083do_color_updates (void) 3084{ 3085 int i; 3086 for (i = 0; i < current_option_count; i++) 3087 { 3088 option_t *opt = &(current_options[i]); 3089 if (opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL) 3090 { 3091 switch (opt->fast_desc->p_type) 3092 { 3093 case STP_PARAMETER_TYPE_DOUBLE: 3094 if (stp_check_float_parameter(pv->v, opt->fast_desc->name, 3095 STP_PARAMETER_INACTIVE)) 3096 gtk_adjustment_set_value 3097 (GTK_ADJUSTMENT(opt->info.flt.adjustment), 3098 stp_get_float_parameter(pv->v, opt->fast_desc->name)); 3099 if (stp_check_float_parameter(pv->v, opt->fast_desc->name, 3100 STP_PARAMETER_ACTIVE) || 3101 opt->fast_desc->is_mandatory) 3102 set_adjustment_active(opt, TRUE, TRUE); 3103 else 3104 set_adjustment_active(opt, FALSE, TRUE); 3105 break; 3106 case STP_PARAMETER_TYPE_DIMENSION: 3107 if (stp_check_dimension_parameter(pv->v, opt->fast_desc->name, 3108 STP_PARAMETER_INACTIVE)) 3109 { 3110 gdouble unit_scaler = units[pv->unit].scale; 3111 gtk_adjustment_set_value 3112 (GTK_ADJUSTMENT(opt->info.flt.adjustment), 3113 (stp_get_dimension_parameter(pv->v, opt->fast_desc->name) / 3114 unit_scaler)); 3115 } 3116 if (stp_check_dimension_parameter(pv->v, opt->fast_desc->name, 3117 STP_PARAMETER_ACTIVE) || 3118 opt->fast_desc->is_mandatory) 3119 set_adjustment_active(opt, TRUE, TRUE); 3120 else 3121 set_adjustment_active(opt, FALSE, TRUE); 3122 break; 3123 case STP_PARAMETER_TYPE_INT: 3124 if (stp_check_int_parameter(pv->v, opt->fast_desc->name, 3125 STP_PARAMETER_INACTIVE)) 3126 { 3127 gtk_adjustment_set_value 3128 (GTK_ADJUSTMENT(opt->info.flt.adjustment), 3129 (stp_get_int_parameter(pv->v, opt->fast_desc->name))); 3130 } 3131 if (stp_check_int_parameter(pv->v, opt->fast_desc->name, 3132 STP_PARAMETER_ACTIVE) || 3133 opt->fast_desc->is_mandatory) 3134 set_adjustment_active(opt, TRUE, TRUE); 3135 else 3136 set_adjustment_active(opt, FALSE, TRUE); 3137 break; 3138 case STP_PARAMETER_TYPE_CURVE: 3139 if (stp_check_curve_parameter(pv->v, opt->fast_desc->name, 3140 STP_PARAMETER_ACTIVE) || 3141 opt->fast_desc->is_mandatory) 3142 set_curve_active(opt, TRUE, TRUE); 3143 else 3144 set_curve_active(opt, FALSE, TRUE); 3145 break; 3146 case STP_PARAMETER_TYPE_STRING_LIST: 3147 if (strcmp(opt->fast_desc->name, "PageSize") == 0) 3148 build_page_size_combo(opt); 3149 else if (stp_check_string_parameter(pv->v, opt->fast_desc->name, 3150 STP_PARAMETER_INACTIVE)) 3151 plist_build_combo(opt->info.list.combo, opt->info.list.label, 3152 opt->info.list.params, opt->is_active, 3153 (stp_get_string_parameter 3154 (pv->v, opt->fast_desc->name)), 3155 opt->info.list.default_val, 3156 G_CALLBACK(combo_callback), 3157 &(opt->info.list.callback_id), 3158 NULL, opt); 3159 if (stp_check_string_parameter(pv->v, opt->fast_desc->name, 3160 STP_PARAMETER_ACTIVE) || 3161 opt->fast_desc->is_mandatory) 3162 set_combo_active(opt, TRUE, TRUE); 3163 else 3164 set_combo_active(opt, FALSE, TRUE); 3165 break; 3166 case STP_PARAMETER_TYPE_BOOLEAN: 3167 if (stp_check_boolean_parameter(pv->v, opt->fast_desc->name, 3168 STP_PARAMETER_INACTIVE)) 3169 gtk_toggle_button_set_active 3170 (GTK_TOGGLE_BUTTON(opt->info.bool.checkbox), 3171 stp_get_boolean_parameter(pv->v, opt->fast_desc->name)); 3172 if (stp_check_boolean_parameter(pv->v, opt->fast_desc->name, 3173 STP_PARAMETER_ACTIVE) || 3174 opt->fast_desc->is_mandatory) 3175 set_bool_active(opt, TRUE, TRUE); 3176 else 3177 set_bool_active(opt, FALSE, TRUE); 3178 break; 3179 case STP_PARAMETER_TYPE_FILE: 3180 if (stp_check_file_parameter(pv->v, opt->fast_desc->name, 3181 STP_PARAMETER_ACTIVE) || 3182 opt->fast_desc->is_mandatory) 3183 set_file_active(opt, TRUE, TRUE); 3184 else 3185 set_file_active(opt, FALSE, TRUE); 3186 break; 3187 default: 3188 break; 3189 } 3190 } 3191 } 3192 update_adjusted_thumbnail (TRUE); 3193} 3194 3195static void 3196update_options(void) 3197{ 3198 gtk_widget_hide(page_size_table); 3199 gtk_widget_hide(printer_features_table); 3200 gtk_widget_hide(color_adjustment_table); 3201 populate_options(pv->v); 3202 populate_option_table(page_size_table, STP_PARAMETER_CLASS_CORE); 3203 populate_option_table(printer_features_table, STP_PARAMETER_CLASS_FEATURE); 3204 populate_option_table(color_adjustment_table, STP_PARAMETER_CLASS_OUTPUT); 3205 gtk_widget_show(page_size_table); 3206 gtk_widget_show(printer_features_table); 3207 gtk_widget_show(color_adjustment_table); 3208 set_options_active(NULL); 3209} 3210 3211static void 3212update_standard_print_command(void) 3213{ 3214 char *label_text = 3215 stpui_build_standard_print_command(pv, stp_get_printer(pv->v)); 3216 gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), label_text); 3217 g_free(label_text); 3218} 3219 3220static void 3221set_color_options(void) 3222{ 3223 stp_parameter_t desc; 3224 stp_describe_parameter(pv->v, "PrintingMode", &desc); 3225 if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST) 3226 { 3227 if (!stp_string_list_is_present(desc.bounds.str, "Color")) 3228 { 3229 gtk_widget_set_sensitive (output_types[1].button, TRUE); 3230 if (gtk_toggle_button_get_active 3231 (GTK_TOGGLE_BUTTON (output_types[0].button)) == TRUE) 3232 gtk_toggle_button_set_active 3233 (GTK_TOGGLE_BUTTON (output_types[1].button), TRUE); 3234 gtk_widget_set_sensitive (output_types[0].button, FALSE); 3235 } 3236 else if (!stp_string_list_is_present(desc.bounds.str, "BW")) 3237 { 3238 gtk_widget_set_sensitive (output_types[0].button, TRUE); 3239 if (gtk_toggle_button_get_active 3240 (GTK_TOGGLE_BUTTON (output_types[1].button)) == TRUE) 3241 gtk_toggle_button_set_active 3242 (GTK_TOGGLE_BUTTON (output_types[0].button), TRUE); 3243 gtk_widget_set_sensitive (output_types[1].button, FALSE); 3244 } 3245 else 3246 { 3247 gtk_widget_set_sensitive (output_types[0].button, TRUE); 3248 gtk_widget_set_sensitive (output_types[1].button, TRUE); 3249 } 3250 } 3251 stp_parameter_description_destroy(&desc); 3252} 3253 3254static void 3255do_all_updates(void) 3256{ 3257 gint i; 3258 suppress_preview_update++; 3259 set_orientation(pv->orientation); 3260 invalidate_preview_thumbnail (); 3261 preview_update (); 3262 update_standard_print_command(); 3263 3264 if (pv->scaling < 0) 3265 { 3266 gdouble tmp = -pv->scaling; 3267 gdouble max_ppi_scaling; 3268 gdouble min_ppi_scaling; 3269 3270 compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling); 3271 3272 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE); 3273 GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling; 3274 GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling; 3275 GTK_ADJUSTMENT (scaling_adjustment)->value = tmp; 3276 gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment)); 3277 gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment)); 3278 } 3279 else 3280 { 3281 gdouble tmp = pv->scaling; 3282 3283 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_percent), TRUE); 3284 GTK_ADJUSTMENT (scaling_adjustment)->lower = minimum_image_percent; 3285 GTK_ADJUSTMENT (scaling_adjustment)->upper = 100.0; 3286 GTK_ADJUSTMENT (scaling_adjustment)->value = tmp; 3287 g_signal_emit_by_name (G_OBJECT(scaling_adjustment), "changed"); 3288 g_signal_emit_by_name (G_OBJECT(scaling_adjustment), "value_changed"); 3289 } 3290 3291 set_color_options(); 3292 for (i = 0; i < output_type_count; i++) 3293 { 3294 if (stp_get_string_parameter(pv->v, "PrintingMode") && 3295 strcmp(output_types[i].value, 3296 stp_get_string_parameter(pv->v, "PrintingMode")) == 0) 3297 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(output_types[i].button), 3298 TRUE); 3299 } 3300 3301 /* 3302 * Now get option parameters. 3303 */ 3304 3305 update_options(); 3306 do_color_updates (); 3307 3308 gtk_option_menu_set_history (GTK_OPTION_MENU (orientation_menu), 3309 pv->orientation + 1); 3310 3311 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(units[pv->unit].checkbox), 3312 TRUE); 3313 gtk_label_set_text(GTK_LABEL(units_label), units[pv->unit].name); 3314 suppress_preview_update--; 3315 preview_update (); 3316} 3317 3318static void 3319copy_count_callback(GtkAdjustment *adjustment, gpointer data) 3320{ 3321 gint copy_count = (gint) adjustment->value; 3322 stpui_plist_set_copy_count(pv, copy_count); 3323 update_standard_print_command(); 3324} 3325 3326static void 3327auto_paper_size_callback(GtkWidget *widget, gpointer data) 3328{ 3329 auto_paper_size = 3330 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(auto_paper_size_button)); 3331 pv->auto_size_roll_feed_paper = auto_paper_size; 3332 set_orientation(pv->orientation); 3333 do_all_updates(); 3334} 3335 3336static void 3337setup_auto_paper_size(void) 3338{ 3339 const stp_papersize_t *ps = 3340 stp_get_papersize_by_name(stp_get_string_parameter(pv->v, "PageSize")); 3341 if (ps->height == 0 && ps->width != 0) /* Implies roll feed */ 3342 { 3343 g_signal_handlers_block_matched (G_OBJECT(auto_paper_size_button), 3344 G_SIGNAL_MATCH_DATA, 3345 0, 3346 0, 3347 NULL, 3348 NULL, 3349 NULL); 3350 3351 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(auto_paper_size_button), 3352 pv->auto_size_roll_feed_paper); 3353 gtk_widget_show(auto_paper_size_button); 3354 g_signal_handlers_unblock_matched (G_OBJECT(auto_paper_size_button), 3355 G_SIGNAL_MATCH_DATA, 3356 0, 3357 0, 3358 NULL, 3359 NULL, 3360 NULL); 3361 } 3362 else 3363 { 3364 gtk_widget_hide(auto_paper_size_button); 3365 auto_paper_size = 0; 3366 } 3367} 3368 3369static void 3370queue_callback (GtkWidget *widget, 3371 gpointer data) 3372{ 3373 int i; 3374 int count = stp_string_list_count(stpui_system_print_queues); 3375 const gchar *result = 3376 gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(queue_combo)->entry)); 3377 for (i = 0; i < count; i++) 3378 { 3379 const stp_param_string_t *s = 3380 stp_string_list_param(stpui_system_print_queues, i); 3381 if (!strcmp(result, s->text)) 3382 { 3383 stpui_plist_set_queue_name(pv, s->name); 3384 do_all_updates(); 3385 return; 3386 } 3387 } 3388} 3389 3390static void 3391setup_callback (GtkWidget *widget) 3392{ 3393 const gchar *new_value = gtk_entry_get_text (GTK_ENTRY (widget)); 3394 3395 if (widget == custom_command_entry) 3396 stpui_plist_set_custom_command(pv, new_value); 3397 else if (widget == file_entry) 3398 { 3399 stpui_plist_set_output_filename(pv, new_value); 3400 gtk_file_selection_set_filename 3401 (GTK_FILE_SELECTION (file_browser), 3402 gtk_entry_get_text (GTK_ENTRY (file_entry))); 3403 } 3404} 3405 3406/* 3407 * plist_callback() - Update the current system printer. 3408 */ 3409static void 3410plist_callback (GtkWidget *widget, 3411 gpointer data) 3412{ 3413 gint i; 3414 char *tmp; 3415 3416 suppress_preview_update++; 3417 invalidate_frame (); 3418 invalidate_preview_thumbnail (); 3419 reset_preview (); 3420 3421 if (widget) 3422 { 3423 const gchar *result = 3424 gtk_entry_get_text(GTK_ENTRY(GTK_COMBO(printer_combo)->entry)); 3425 3426 for (i = 0; i < stpui_plist_count; i++) 3427 { 3428 if (! strcmp (result, stp_string_list_param(printer_list, i)->text)) 3429 { 3430 stpui_plist_current = i; 3431 break; 3432 } 3433 } 3434 } 3435 else 3436 { 3437 stpui_plist_current = (gint) data; 3438 } 3439 3440 set_current_printer(); 3441 build_queue_combo(); 3442 manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v)); 3443 build_printer_driver_clist(); 3444 3445 if (strcmp(stp_get_driver(pv->v), "") != 0) 3446 tmp_printer = stp_get_printer(pv->v); 3447 3448 gtk_entry_set_text(GTK_ENTRY(file_entry), 3449 stpui_plist_get_output_filename(pv)); 3450 tmp = stpui_build_standard_print_command(pv, stp_get_printer(pv->v)); 3451 gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), tmp); 3452 stp_free(tmp); 3453 gtk_entry_set_text(GTK_ENTRY(custom_command_entry), 3454 stpui_plist_get_custom_command(pv)); 3455 gtk_spin_button_set_value(GTK_SPIN_BUTTON(copy_count_spin_button), 3456 (gfloat) stpui_plist_get_copy_count(pv)); 3457 do_all_updates(); 3458 3459 setup_update (); 3460 do_all_updates(); 3461 suppress_preview_update--; 3462 update_adjusted_thumbnail(TRUE); 3463 preview_update (); 3464} 3465 3466static void 3467show_all_paper_sizes_callback(GtkWidget *widget, gpointer data) 3468{ 3469 int i; 3470 stpui_show_all_paper_sizes = 3471 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); 3472 for (i = 0; i < current_option_count; i++) 3473 { 3474 option_t *option = &(current_options[i]); 3475 if (option->fast_desc && 3476 strcmp(option->fast_desc->name, "PageSize") == 0) 3477 { 3478 build_a_combo(option); 3479 break; 3480 } 3481 } 3482} 3483 3484static void 3485custom_media_size_callback(GtkWidget *widget, 3486 gpointer data) 3487{ 3488 gint width_limit, height_limit; 3489 gint min_width_limit, min_height_limit; 3490 gdouble new_printed_value = atof(gtk_entry_get_text(GTK_ENTRY(widget))); 3491 gint new_value = SCALE(new_printed_value, units[pv->unit].scale); 3492 invalidate_frame (); 3493 invalidate_preview_thumbnail (); 3494 reset_preview (); 3495 3496 stp_get_size_limit(pv->v, &width_limit, &height_limit, 3497 &min_width_limit, &min_height_limit); 3498 if (widget == custom_size_width) 3499 { 3500 if (new_value < min_width_limit) 3501 new_value = min_width_limit; 3502 else if (new_value > width_limit) 3503 new_value = width_limit; 3504 stp_set_page_width (pv->v, new_value); 3505 } 3506 else 3507 { 3508 if (new_value < min_height_limit) 3509 new_value = min_height_limit; 3510 else if (new_value > height_limit) 3511 new_value = height_limit; 3512 stp_set_page_height (pv->v, new_value); 3513 } 3514 set_entry_value (widget, new_value, 0); 3515 preview_update (); 3516} 3517 3518 3519/* 3520 * media_size_callback() - Update the current media size. 3521 */ 3522static void 3523set_media_size(const gchar *new_media_size) 3524{ 3525 static int setting_media_size = 0; 3526 const stp_papersize_t *pap = stp_get_papersize_by_name (new_media_size); 3527 3528 if (setting_media_size) 3529 return; 3530 setting_media_size++; 3531 3532 if (pap) 3533 { 3534 gint size; 3535 int old_width = stp_get_page_width(pv->v); 3536 int old_height = stp_get_page_height(pv->v); 3537 int need_preview_update = 0; 3538 3539 if (! stpui_show_all_paper_sizes && 3540 (pap->paper_unit == PAPERSIZE_METRIC_EXTENDED || 3541 pap->paper_unit == PAPERSIZE_ENGLISH_EXTENDED)) 3542 { 3543 int i; 3544 stp_parameter_t desc; 3545 stp_describe_parameter(pv->v, "PageSize", &desc); 3546 stp_set_string_parameter(pv->v, "PageSize", desc.deflt.str); 3547 pap = stp_get_papersize_by_name(desc.deflt.str); 3548 stp_parameter_description_destroy(&desc); 3549 for (i = 0; i < current_option_count; i++) 3550 { 3551 option_t *option = &(current_options[i]); 3552 if (option->fast_desc && 3553 strcmp(option->fast_desc->name, "PageSize") == 0) 3554 { 3555 build_a_combo(option); 3556 break; 3557 } 3558 } 3559 } 3560 3561 if (pap->width == 0) 3562 { 3563 int max_w, max_h, min_w, min_h; 3564 stp_get_size_limit(pv->v, &max_w, &max_h, &min_w, &min_h); 3565 size = old_width; 3566 if (size < min_w) 3567 size = min_w; 3568 else if (size > max_w) 3569 size = max_w; 3570 gtk_widget_set_sensitive (GTK_WIDGET (custom_size_width), TRUE); 3571 gtk_entry_set_editable (GTK_ENTRY (custom_size_width), TRUE); 3572 } 3573 else 3574 { 3575 size = pap->width; 3576 gtk_widget_set_sensitive (GTK_WIDGET (custom_size_width), FALSE); 3577 gtk_entry_set_editable (GTK_ENTRY (custom_size_width), FALSE); 3578 } 3579 if (size != old_width) 3580 { 3581 need_preview_update = 1; 3582 set_entry_value (custom_size_width, size, 0); 3583 stp_set_page_width (pv->v, size); 3584 } 3585 3586 setup_auto_paper_size(); 3587 if (pap->height == 0) 3588 { 3589 int max_w, max_h, min_w, min_h; 3590 stp_get_size_limit(pv->v, &max_w, &max_h, &min_w, &min_h); 3591 if (auto_paper_size) 3592 { 3593 int l, r, b, t; 3594 stp_set_page_height(pv->v, 0); 3595 old_height = 0; 3596 stp_get_imageable_area(pv->v, &l, &r, &b, &t); 3597 gtk_widget_set_sensitive(GTK_WIDGET(custom_size_height), FALSE); 3598 gtk_entry_set_editable(GTK_ENTRY(custom_size_height), FALSE); 3599 size = print_height; 3600 } 3601 else 3602 { 3603 gtk_widget_set_sensitive (GTK_WIDGET (custom_size_height), TRUE); 3604 gtk_entry_set_editable (GTK_ENTRY (custom_size_height), TRUE); 3605 size = old_height; 3606 } 3607 if (size < min_h) 3608 size = min_h; 3609 else if (size > max_h) 3610 size = max_h; 3611 } 3612 else 3613 { 3614 size = pap->height; 3615 gtk_widget_set_sensitive(GTK_WIDGET (custom_size_height), FALSE); 3616 gtk_entry_set_editable (GTK_ENTRY (custom_size_height), FALSE); 3617 } 3618 if (size != old_height) 3619 { 3620 need_preview_update = 1; 3621 set_entry_value (custom_size_height, size, 0); 3622 stp_set_page_height (pv->v, size); 3623 } 3624 if (need_preview_update) 3625 { 3626 invalidate_preview_thumbnail(); 3627 invalidate_frame(); 3628 preview_update(); 3629 } 3630 } 3631 setting_media_size--; 3632} 3633 3634static gboolean 3635refresh_all_options(gpointer data) 3636{ 3637 do_all_updates(); 3638 do_all_updates(); /* Update twice to pick up cascading changes */ 3639 return FALSE; 3640} 3641 3642static void 3643combo_callback(GtkWidget *widget, gpointer data) 3644{ 3645 option_t *option = (option_t *)data; 3646 const gchar *new_value = 3647 stpui_combo_get_name(option->info.list.combo, option->info.list.params); 3648 const gchar *value = 3649 stp_get_string_parameter(pv->v, option->fast_desc->name); 3650 if (value && new_value) 3651 { 3652 reset_preview(); 3653 if (!value || strcmp(value, new_value) != 0) 3654 { 3655 invalidate_frame(); 3656 invalidate_preview_thumbnail(); 3657 stp_set_string_parameter(pv->v, option->fast_desc->name, new_value); 3658 if (strcmp(option->fast_desc->name, "PageSize") == 0) 3659 set_media_size(new_value); 3660 g_idle_add(refresh_all_options, NULL); 3661 if (option->fast_desc->p_class == STP_PARAMETER_CLASS_OUTPUT) 3662 update_adjusted_thumbnail(TRUE); 3663 preview_update(); 3664 } 3665 } 3666} 3667 3668/* 3669 * orientation_callback() - Update the current media size. 3670 */ 3671static void 3672orientation_callback (GtkWidget *widget, 3673 gpointer data) 3674{ 3675 reset_preview (); 3676 3677 if (pv->orientation != (gint) data) 3678 { 3679 invalidate_preview_thumbnail (); 3680 set_orientation((gint) data); 3681 update_adjusted_thumbnail(TRUE); 3682 preview_update (); 3683 } 3684} 3685 3686/* 3687 * output_type_callback() - Update the current output type. 3688 */ 3689static void 3690output_type_callback (GtkWidget *widget, 3691 gpointer data) 3692{ 3693 reset_preview (); 3694 3695 if (GTK_TOGGLE_BUTTON (widget)->active) 3696 { 3697 if (strcmp((const char *) data, "BW") == 0) 3698 gtk_widget_hide(output_color_vbox); 3699 else 3700 gtk_widget_show(output_color_vbox); 3701 stp_set_string_parameter(pv->v, "PrintingMode", (const char *) data); 3702 invalidate_preview_thumbnail (); 3703 update_adjusted_thumbnail (TRUE); 3704 set_options_active(NULL); 3705 preview_update (); 3706 do_all_updates(); 3707 } 3708} 3709 3710static void 3711command_type_callback(GtkWidget *widget, gpointer data) 3712{ 3713 if (strcmp((const char *) data, "Standard") == 0) 3714 { 3715 gtk_widget_set_sensitive(standard_cmd_entry, TRUE); 3716 gtk_widget_set_sensitive(queue_combo, TRUE); 3717 gtk_widget_set_sensitive(file_entry, FALSE); 3718 gtk_entry_set_editable(GTK_ENTRY(file_entry), FALSE); 3719 gtk_widget_set_sensitive(custom_command_entry, FALSE); 3720 gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), FALSE); 3721 gtk_widget_hide(GTK_WIDGET(file_browser)); 3722 gtk_widget_set_sensitive(file_button, FALSE); 3723 gtk_widget_set_sensitive(copy_count_spin_button, TRUE); 3724 stpui_plist_set_command_type(pv, COMMAND_TYPE_DEFAULT); 3725 } 3726 else if (strcmp((const char *) data, "Custom") == 0) 3727 { 3728 gtk_widget_set_sensitive(standard_cmd_entry, FALSE); 3729 gtk_widget_set_sensitive(queue_combo, FALSE); 3730 gtk_widget_set_sensitive(file_entry, FALSE); 3731 gtk_entry_set_editable(GTK_ENTRY(file_entry), FALSE); 3732 gtk_widget_set_sensitive(custom_command_entry, TRUE); 3733 gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), TRUE); 3734 gtk_widget_hide(GTK_WIDGET(file_browser)); 3735 gtk_widget_set_sensitive(file_button, FALSE); 3736 gtk_widget_set_sensitive(copy_count_spin_button, FALSE); 3737 stpui_plist_set_command_type(pv, COMMAND_TYPE_CUSTOM); 3738 } 3739 else if (strcmp((const char *) data, "File") == 0) 3740 { 3741 gtk_widget_set_sensitive(standard_cmd_entry, FALSE); 3742 gtk_widget_set_sensitive(queue_combo, FALSE); 3743 gtk_widget_set_sensitive(file_entry, TRUE); 3744 gtk_entry_set_editable(GTK_ENTRY(file_entry), TRUE); 3745 gtk_widget_set_sensitive(custom_command_entry, FALSE); 3746 gtk_entry_set_editable(GTK_ENTRY(custom_command_entry), FALSE); 3747 gtk_widget_set_sensitive(file_button, TRUE); 3748 gtk_widget_set_sensitive(copy_count_spin_button, FALSE); 3749 stpui_plist_set_command_type(pv, COMMAND_TYPE_FILE); 3750 } 3751} 3752 3753static void 3754set_all_entry_values(void) 3755{ 3756 set_entry_value (top_entry, (stp_get_top (pv->v)), 1); 3757 set_entry_value (left_entry, (stp_get_left (pv->v)), 1); 3758/* 3759 set_entry_value (bottom_entry, (top + stp_get_top(pv->v) + print_height), 1); 3760*/ 3761 set_entry_value (bottom_border_entry, 3762 (paper_height - (stp_get_top (pv->v) + print_height)), 1); 3763/* 3764 set_entry_value (right_entry, (stp_get_left(pv->v) + print_width), 1); 3765*/ 3766 set_entry_value (right_border_entry, 3767 (paper_width - (stp_get_left (pv->v) + print_width)), 1); 3768 set_entry_value (width_entry, print_width, 1); 3769 set_entry_value (height_entry, print_height, 1); 3770 set_entry_value (custom_size_width, stp_get_page_width (pv->v), 1); 3771 set_entry_value (custom_size_height, stp_get_page_height (pv->v), 1); 3772} 3773 3774/* 3775 * unit_callback() - Update the current unit. 3776 */ 3777static void 3778unit_callback (GtkWidget *widget, 3779 gpointer data) 3780{ 3781 reset_preview (); 3782 3783 if (GTK_TOGGLE_BUTTON (widget)->active) 3784 { 3785 pv->unit = (gint) data; 3786 gtk_label_set_text(GTK_LABEL(units_label), units[pv->unit].name); 3787 set_all_entry_values(); 3788 update_options(); 3789 do_color_updates(); 3790 } 3791} 3792 3793static void 3794destroy_dialogs (void) 3795{ 3796 int i; 3797 gtk_widget_destroy (color_adjust_dialog); 3798 gtk_widget_destroy (setup_dialog); 3799 gtk_widget_destroy (print_dialog); 3800 gtk_widget_destroy (new_printer_dialog); 3801 gtk_widget_destroy (about_dialog); 3802 for (i = 0; i < current_option_count; i++) 3803 { 3804 if (current_options[i].fast_desc->p_type == STP_PARAMETER_TYPE_CURVE && 3805 current_options[i].info.curve.dialog) 3806 gtk_widget_destroy(current_options[i].info.curve.dialog); 3807 } 3808} 3809 3810static void 3811dialogs_set_sensitive (gboolean sensitive) 3812{ 3813 int i; 3814 gtk_widget_set_sensitive (color_adjust_dialog, sensitive); 3815 gtk_widget_set_sensitive (setup_dialog, sensitive); 3816 gtk_widget_set_sensitive (print_dialog, sensitive); 3817 gtk_widget_set_sensitive (new_printer_dialog, sensitive); 3818 gtk_widget_set_sensitive (about_dialog, sensitive); 3819 for (i = 0; i < current_option_count; i++) 3820 { 3821 if (current_options[i].fast_desc->p_type == STP_PARAMETER_TYPE_CURVE && 3822 current_options[i].info.curve.dialog) 3823 gtk_widget_set_sensitive(current_options[i].info.curve.dialog, 3824 sensitive); 3825 } 3826} 3827 3828/* 3829 * 'print_callback()' - Start the print. 3830 */ 3831static void 3832print_callback (void) 3833{ 3834 if (stpui_plist_get_command_type(pv) == COMMAND_TYPE_FILE && 3835 strlen(stpui_plist_get_output_filename(pv)) == 0) 3836 { 3837 dialogs_set_sensitive (FALSE); 3838 exit_after_file_ok = 1; 3839 gtk_widget_show (file_browser); 3840 } 3841 else 3842 { 3843 runme = TRUE; 3844 destroy_dialogs (); 3845 } 3846} 3847 3848/* 3849 * printandsave_callback() - 3850 */ 3851static void 3852printandsave_callback (void) 3853{ 3854 saveme = TRUE; 3855 print_callback(); 3856} 3857 3858static void 3859about_callback (void) 3860{ 3861 gtk_widget_show (about_dialog); 3862} 3863 3864/* 3865 * save_callback() - save settings, don't destroy dialog 3866 */ 3867static void 3868save_callback (void) 3869{ 3870 reset_preview (); 3871 stpui_printrc_save (); 3872} 3873 3874/* 3875 * setup_update() - update widgets in the setup dialog 3876 */ 3877static void 3878setup_update (void) 3879{ 3880 GtkAdjustment *adjustment; 3881 gint idx = 0; 3882 gint i; 3883 gchar *tmp; 3884 stp_parameter_t desc; 3885 const char *ppd_file_name = stp_get_file_parameter(pv->v, "PPDFile"); 3886 3887 for (i = 0; i < GTK_CLIST(manufacturer_clist)->rows; i++) 3888 { 3889 (void) gtk_clist_get_text(GTK_CLIST(manufacturer_clist), i, 0, &tmp); 3890 if (tmp && strcmp(manufacturer, tmp) == 0) 3891 { 3892 idx = i; 3893 break; 3894 } 3895 } 3896 gtk_clist_select_row(GTK_CLIST(manufacturer_clist), idx, 0); 3897 3898 idx = stp_get_printer_index_by_driver (stp_get_driver (pv->v)); 3899 3900 idx = gtk_clist_find_row_from_data(GTK_CLIST(printer_driver), 3901 (gpointer) idx); 3902/* 3903 if (idx >= 0) 3904 idx = 0; 3905*/ 3906 gtk_clist_select_row (GTK_CLIST (printer_driver), idx, 0); 3907 stp_describe_parameter(pv->v, "ModelName", &desc); 3908 if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST && desc.is_active && 3909 desc.deflt.str) 3910 { 3911 const char *extra_printer_model = desc.deflt.str; 3912 char *label_text = 3913 g_malloc(strlen(gettext (stp_printer_get_long_name (tmp_printer))) + 3914 2 + /* " (" */ 3915 strlen(extra_printer_model) + 3916 2); /* ")" + null terminator */ 3917 strcpy(label_text, extra_printer_model); 3918 strcat(label_text, " ("); 3919 strcat(label_text, gettext (stp_printer_get_long_name (tmp_printer))); 3920 strcat(label_text, ")"); 3921 gtk_label_set_text (GTK_LABEL (printer_model_label), label_text); 3922 g_free(label_text); 3923 } 3924 else 3925 { 3926 gtk_label_set_text (GTK_LABEL (printer_model_label), 3927 gettext (stp_printer_get_long_name (tmp_printer))); 3928 } 3929 stp_parameter_description_destroy(&desc); 3930 3931 if (ppd_file_name) 3932 gtk_entry_set_text (GTK_ENTRY (ppd_file), ppd_file_name); 3933 else 3934 gtk_entry_set_text (GTK_ENTRY (ppd_file), ""); 3935 ppd_file_callback(ppd_file, NULL); 3936 3937 if (stp_parameter_find_in_settings(pv->v, "PPDFile")) 3938 { 3939 gtk_widget_show (ppd_box); 3940 gtk_widget_show (ppd_label); 3941 gtk_widget_show (ppd_model_label); 3942 gtk_widget_show (ppd_model); 3943 } 3944 else 3945 { 3946 gtk_widget_hide (ppd_box); 3947 gtk_widget_hide (ppd_label); 3948 gtk_widget_hide (ppd_model_label); 3949 gtk_widget_hide (ppd_model); 3950 } 3951 gtk_entry_set_text (GTK_ENTRY (custom_command_entry), 3952 stpui_plist_get_custom_command (pv)); 3953 3954 adjustment = GTK_CLIST (printer_driver)->vadjustment; 3955 gtk_adjustment_set_value 3956 (adjustment, 3957 adjustment->lower + idx * (adjustment->upper - adjustment->lower) / 3958 GTK_CLIST (printer_driver)->rows); 3959 3960 i = stpui_plist_get_command_type(pv); 3961 if (i >= 0 && i < command_options_count) 3962 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(command_options[i].button), 3963 TRUE); 3964} 3965 3966static void 3967ppd_file_callback(GtkWidget *widget, gpointer data) 3968{ 3969 const gchar *name = gtk_entry_get_text(GTK_ENTRY(widget)); 3970 if (name && pv && pv->v) 3971 { 3972 stp_parameter_t desc; 3973 stp_vars_t *v = stp_vars_create_copy(pv->v); 3974 stp_set_file_parameter(v, "PPDFile", name); 3975 stp_describe_parameter(v, "ModelName", &desc); 3976 if (desc.p_type == STP_PARAMETER_TYPE_STRING_LIST && desc.is_active) 3977 gtk_label_set_text(GTK_LABEL(ppd_model), desc.deflt.str); 3978 else 3979 gtk_label_set_text(GTK_LABEL(ppd_model), ""); 3980 stp_parameter_description_destroy(&desc); 3981 stp_vars_destroy(v); 3982 } 3983 else 3984 gtk_label_set_text(GTK_LABEL(ppd_model), ""); 3985} 3986 3987/* 3988 * setup_open_callback() - 3989 */ 3990static void 3991setup_open_callback (void) 3992{ 3993 static gboolean first_time = TRUE; 3994 manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v)); 3995 build_printer_driver_clist(); 3996 3997 reset_preview (); 3998 setup_update (); 3999 4000/* gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, FALSE); */ 4001 gtk_widget_show (setup_dialog); 4002 4003 if (first_time) 4004 { 4005 /* Make sure the driver scroller gets positioned correctly. */ 4006 setup_update (); 4007 first_time = FALSE; 4008 } 4009} 4010 4011/* 4012 * new_printer_open_callback() - 4013 */ 4014static void 4015new_printer_open_callback (void) 4016{ 4017 reset_preview (); 4018 gtk_entry_set_text (GTK_ENTRY (new_printer_entry), ""); 4019 gtk_widget_show (new_printer_dialog); 4020} 4021 4022static void 4023set_printer(void) 4024{ 4025 manufacturer = stp_printer_get_manufacturer(tmp_printer); 4026 build_printer_driver_clist(); 4027 build_queue_combo(); 4028 stp_set_driver (pv->v, stp_printer_get_driver (tmp_printer)); 4029 stpui_plist_set_custom_command 4030 (pv, gtk_entry_get_text (GTK_ENTRY (custom_command_entry))); 4031 stpui_plist_set_output_filename 4032 (pv, gtk_entry_get_text (GTK_ENTRY (file_entry))); 4033 stp_set_file_parameter (pv->v, "PPDFile", 4034 gtk_entry_get_text (GTK_ENTRY (ppd_file))); 4035 gtk_label_set_text (GTK_LABEL (printer_model_label), 4036 gettext (stp_printer_get_long_name (tmp_printer))); 4037 4038 plist_callback (NULL, (gpointer) stpui_plist_current); 4039} 4040 4041/* 4042 * setup_ok_callback() - 4043 */ 4044static void 4045setup_ok_callback (void) 4046{ 4047 gtk_widget_hide(ppd_browser); 4048 gtk_widget_hide(file_browser); 4049 gtk_widget_hide(setup_dialog); 4050 set_printer(); 4051 gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, TRUE); 4052} 4053 4054/* 4055 * setup_cancel_callback() - 4056 */ 4057static void 4058setup_cancel_callback (void) 4059{ 4060 gtk_widget_hide(ppd_browser); 4061 gtk_widget_hide(file_browser); 4062 gtk_widget_hide(setup_dialog); 4063 manufacturer = stp_printer_get_manufacturer(stp_get_printer(pv->v)); 4064 build_printer_driver_clist(); 4065 setup_update(); 4066 gtk_widget_set_sensitive(GTK_DIALOG(print_dialog)->action_area, TRUE); 4067} 4068 4069/* 4070 * setup_ok_callback() - 4071 */ 4072static void 4073new_printer_ok_callback (void) 4074{ 4075 const gchar *data = gtk_entry_get_text (GTK_ENTRY (new_printer_entry)); 4076 stpui_plist_t key; 4077 4078 if (strlen(data)) 4079 { 4080 memset(&key, 0, sizeof(key)); 4081 stpui_printer_initialize (&key); 4082 stpui_plist_copy(&key, pv); 4083 stpui_plist_set_name(&key, data); 4084 4085 if (stpui_plist_add (&key, 1)) 4086 { 4087 stp_vars_destroy(key.v); 4088 g_free(key.name); 4089 stpui_plist_current = stpui_plist_count - 1; 4090 set_current_printer(); 4091 build_printer_combo (); 4092 set_printer(); 4093 } 4094 } 4095 4096 gtk_widget_hide (new_printer_dialog); 4097} 4098 4099static void 4100pop_ppd_box(void) 4101{ 4102 const stp_vars_t *v = stp_printer_get_defaults(tmp_printer); 4103 if (stp_parameter_find_in_settings(v, "PPDFile")) 4104 { 4105 gtk_widget_show (ppd_label); 4106 gtk_widget_show (ppd_box); 4107 gtk_widget_show (ppd_model_label); 4108 gtk_widget_show (ppd_model); 4109 } 4110 else 4111 { 4112 gtk_widget_hide (ppd_label); 4113 gtk_widget_hide (ppd_box); 4114 gtk_widget_hide (ppd_model_label); 4115 gtk_widget_hide (ppd_model); 4116 } 4117} 4118 4119static void 4120build_printer_driver_clist(void) 4121{ 4122 int i; 4123 int current_idx = 0; 4124 gtk_clist_clear(GTK_CLIST(printer_driver)); 4125 for (i = 0; i < stp_printer_model_count (); i ++) 4126 { 4127 const stp_printer_t *the_printer = stp_get_printer_by_index (i); 4128 4129 if (strcmp(manufacturer, stp_printer_get_manufacturer(the_printer)) == 0) 4130 { 4131 gchar *tmp=g_strdup(gettext(stp_printer_get_long_name(the_printer))); 4132 /* 4133 * FIXME Somehow if the raw printer comes before any of the 4134 * "real" printers in the list of printers created in module.c, 4135 * this code barfs on any of those printers added later. For 4136 * example, try listing olympus_LTX_stpi_module_data after 4137 * raw_LTX_stpi_module_data. 4138 */ 4139 4140 gtk_clist_insert (GTK_CLIST (printer_driver), current_idx, &tmp); 4141 gtk_clist_set_row_data (GTK_CLIST (printer_driver), current_idx, 4142 (gpointer) i); 4143 g_free(tmp); 4144 current_idx++; 4145 } 4146 } 4147} 4148 4149static void 4150manufacturer_callback(GtkWidget *widget, /* I - Driver list */ 4151 gint row, 4152 gint column, 4153 GdkEventButton *event, 4154 gpointer data) 4155{ 4156 static int calling_manufacturer_callback = 0; 4157 gchar *text; 4158 if (calling_manufacturer_callback) 4159 return; 4160 calling_manufacturer_callback++; 4161 if (gtk_clist_get_text(GTK_CLIST(widget), row, column, &text)) 4162 manufacturer = text; 4163 build_printer_driver_clist(); 4164 setup_update(); 4165 calling_manufacturer_callback--; 4166} 4167 4168/* 4169 * print_driver_callback() - Update the current printer driver. 4170 */ 4171static void 4172print_driver_callback (GtkWidget *widget, /* I - Driver list */ 4173 gint row, 4174 gint column, 4175 GdkEventButton *event, 4176 gpointer data) /* I - Data */ 4177{ 4178 char *tmp; 4179 static int calling_print_driver_callback = 0; 4180 if (calling_print_driver_callback) 4181 return; 4182 calling_print_driver_callback++; 4183 invalidate_frame (); 4184 invalidate_preview_thumbnail (); 4185 reset_preview (); 4186 data = gtk_clist_get_row_data (GTK_CLIST (widget), row); 4187 tmp_printer = stp_get_printer_by_index ((gint) data); 4188 tmp = stpui_build_standard_print_command(pv, tmp_printer); 4189 gtk_entry_set_text(GTK_ENTRY(standard_cmd_entry), tmp); 4190 g_free(tmp); 4191 4192 pop_ppd_box(); 4193 calling_print_driver_callback--; 4194} 4195 4196/* 4197 * ppd_browse_callback() - 4198 */ 4199static void 4200ppd_browse_callback (void) 4201{ 4202 reset_preview (); 4203 gtk_file_selection_set_filename (GTK_FILE_SELECTION (ppd_browser), 4204 gtk_entry_get_text (GTK_ENTRY (ppd_file))); 4205 gtk_widget_show (ppd_browser); 4206} 4207 4208/* 4209 * ppd_ok_callback() - 4210 */ 4211static void 4212ppd_ok_callback (void) 4213{ 4214 reset_preview (); 4215 gtk_widget_hide (ppd_browser); 4216 gtk_entry_set_text 4217 (GTK_ENTRY (ppd_file), 4218 gtk_file_selection_get_filename (GTK_FILE_SELECTION (ppd_browser))); 4219 ppd_file_callback(ppd_file, NULL); 4220 update_options(); 4221} 4222 4223/* 4224 * ppd_browse_callback() - 4225 */ 4226static void 4227file_browse_callback (void) 4228{ 4229 reset_preview (); 4230 gtk_file_selection_set_filename (GTK_FILE_SELECTION (file_browser), 4231 gtk_entry_get_text (GTK_ENTRY (file_entry))); 4232 gtk_widget_show (file_browser); 4233} 4234 4235/* 4236 * file_ok_callback() - print to file and go away 4237 */ 4238static void 4239file_ok_callback (void) 4240{ 4241 const char *filename = 4242 gtk_file_selection_get_filename(GTK_FILE_SELECTION(file_browser)); 4243 gtk_widget_hide (file_browser); 4244 gtk_entry_set_text(GTK_ENTRY(file_entry), filename); 4245 stpui_plist_set_output_filename(pv, filename); 4246 if (exit_after_file_ok) 4247 { 4248 runme = TRUE; 4249 destroy_dialogs (); 4250 } 4251} 4252 4253/* 4254 * file_cancel_callback() - 4255 */ 4256static void 4257file_cancel_callback (void) 4258{ 4259 exit_after_file_ok = 0; 4260 gtk_widget_hide (file_browser); 4261 dialogs_set_sensitive (TRUE); 4262} 4263 4264static void 4265fill_buffer_writefunc(void *priv, const char *buffer, size_t bytes) 4266{ 4267 int mask = 0; 4268 int i; 4269 4270 priv_t *p = (priv_t *) priv; 4271 unsigned char *where = p->base_addr + p->offset; 4272 const unsigned char *xbuffer = (const unsigned char *)buffer; 4273 4274 if (strcmp(p->output_type, "Whitescale") == 0) 4275 { 4276 memcpy(where, xbuffer, bytes); 4277 p->offset += bytes; 4278 } 4279 else if (strcmp(p->output_type, "Grayscale") == 0) 4280 { 4281 for (i = 0; i < bytes; i++) 4282 where[i] = ~xbuffer[i]; 4283 p->offset += bytes; 4284 } 4285 else if (strcmp(p->output_type, "RGB") == 0) 4286 { 4287 int pixels = bytes / 3; 4288 if (bytes + p->offset > p->limit) 4289 bytes = p->limit - p->offset; 4290 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(red_button))) 4291 mask |= 1; 4292 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(green_button))) 4293 mask |= 2; 4294 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(blue_button))) 4295 mask |= 4; 4296 4297 memset(where, 0, pixels * 3); 4298 for (i = 0; i < pixels; i++) 4299 { 4300 if (mask & 1) 4301 where[0] = xbuffer[0]; 4302 if (mask & 2) 4303 where[1] = xbuffer[1]; 4304 if (mask & 4) 4305 where[2] = xbuffer[2]; 4306 where += 3; 4307 xbuffer += 3; 4308 } 4309 p->offset += pixels * 3; 4310 } 4311 else if (strcmp(p->output_type, "CMY") == 0) 4312 { 4313 int pixels = bytes / 3; 4314 if (bytes + p->offset > p->limit) 4315 bytes = p->limit - p->offset; 4316 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cyan_button))) 4317 mask |= 1; 4318 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(magenta_button))) 4319 mask |= 2; 4320 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(yellow_button))) 4321 mask |= 4; 4322 4323 memset(where, 0xff, pixels * 3); 4324 for (i = 0; i < pixels; i++) 4325 { 4326 if (mask & 1) 4327 where[0] = ~xbuffer[0]; 4328 if (mask & 2) 4329 where[1] = ~xbuffer[1]; 4330 if (mask & 4) 4331 where[2] = ~xbuffer[2]; 4332 where += 3; 4333 xbuffer += 3; 4334 } 4335 p->offset += pixels * 3; 4336 } 4337 else 4338 { 4339 int pixels = bytes / 4; 4340 if (bytes + p->offset > p->limit) 4341 bytes = p->limit - p->offset; 4342 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cyan_button))) 4343 mask |= 1; 4344 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(magenta_button))) 4345 mask |= 2; 4346 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(yellow_button))) 4347 mask |= 4; 4348 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(black_button))) 4349 mask |= 8; 4350 4351 memset(where, 0xff, pixels * 3); 4352 for (i = 0; i < pixels; i++) 4353 { 4354 if (mask & 8) 4355 { 4356 where[0] -= xbuffer[3]; 4357 where[1] -= xbuffer[3]; 4358 where[2] -= xbuffer[3]; 4359 } 4360 if (mask & 1) 4361 { 4362 if (where[0] < xbuffer[0]) 4363 where[0] = 0; 4364 else 4365 where[0] -= xbuffer[0]; 4366 } 4367 if (mask & 2) 4368 { 4369 if (where[1] < xbuffer[1]) 4370 where[1] = 0; 4371 else 4372 where[1] -= xbuffer[1]; 4373 } 4374 if (mask & 4) 4375 { 4376 if (where[2] < xbuffer[2]) 4377 where[2] = 0; 4378 else 4379 where[2] -= xbuffer[2]; 4380 } 4381 where += 3; 4382 xbuffer += 4; 4383 } 4384 p->offset += pixels * 3; 4385 } 4386} 4387 4388/* 4389 * update_adjusted_thumbnail() 4390 */ 4391 4392static void 4393redraw_color_swatch (void) 4394{ 4395 static GdkGC *gc = NULL; 4396 static GdkColormap *cmap; 4397 4398 if (adjusted_thumbnail_data && swatch && swatch->widget.window) 4399 { 4400 if (gc == NULL) 4401 { 4402 gc = gdk_gc_new (swatch->widget.window); 4403 cmap = gtk_widget_get_colormap (GTK_WIDGET(swatch)); 4404 } 4405 4406 if (!print_mode_is_color(pv->v)) 4407 gdk_draw_gray_image(swatch->widget.window, gc, 0, 0, 4408 thumbnail_w, thumbnail_h, GDK_RGB_DITHER_NORMAL, 4409 adjusted_thumbnail_data, thumbnail_w); 4410 else 4411 gdk_draw_rgb_image(swatch->widget.window, gc, 0, 0, 4412 thumbnail_w, thumbnail_h, GDK_RGB_DITHER_NORMAL, 4413 adjusted_thumbnail_data, 3 * thumbnail_w); 4414 } 4415} 4416 4417static void 4418initialize_thumbnail(void) 4419{ 4420 int i; 4421 if (stpui_get_thumbnail_func()) 4422 { 4423 const guchar *internal_thumbnail_data; 4424 /* 4425 * Fetch a thumbnail of the image we're to print from the Gimp. 4426 */ 4427 4428 thumbnail_w = thumbnail_hintw; 4429 thumbnail_h = thumbnail_hinth; 4430 internal_thumbnail_data = 4431 (stpui_get_thumbnail_func()) (stpui_get_thumbnail_data(), &thumbnail_w, 4432 &thumbnail_h, &thumbnail_bpp, 0); 4433 if (adjusted_thumbnail_data) 4434 g_free(adjusted_thumbnail_data); 4435 if (preview_thumbnail_data) 4436 g_free(preview_thumbnail_data); 4437 if (thumbnail_data) 4438 g_free(thumbnail_data); 4439 4440 if (internal_thumbnail_data) 4441 { 4442 /* 4443 * thumbnail_w and thumbnail_h have now been adjusted to the actual 4444 * thumbnail dimensions. Now initialize a color-adjusted version of 4445 * the thumbnail. 4446 */ 4447 4448 adjusted_thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h); 4449 preview_thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h); 4450 thumbnail_data = g_malloc (3 * thumbnail_w * thumbnail_h); 4451 4452 switch (thumbnail_bpp) 4453 { 4454 case 1: 4455 for (i = 0; i < thumbnail_w * thumbnail_h; i++) 4456 { 4457 gint val = internal_thumbnail_data[i]; 4458 thumbnail_data[(3 * i) + 0] = val; 4459 thumbnail_data[(3 * i) + 1] = val; 4460 thumbnail_data[(3 * i) + 2] = val; 4461 } 4462 break; 4463 case 3: 4464 memcpy(thumbnail_data, internal_thumbnail_data, 4465 3 * thumbnail_w * thumbnail_h); 4466 break; 4467 case 2: 4468 for (i = 0; i < thumbnail_w * thumbnail_h; i++) 4469 { 4470 gint val = internal_thumbnail_data[2 * i]; 4471 gint alpha = internal_thumbnail_data[(2 * i) + 1]; 4472 thumbnail_data[(3 * i) +0] = val * alpha / 255 + 255 - alpha; 4473 thumbnail_data[(3 * i) +1] = val * alpha / 255 + 255 - alpha; 4474 thumbnail_data[(3 * i) +2] = val * alpha / 255 + 255 - alpha; 4475 } 4476 break; 4477 case 4: 4478 for (i = 0; i < thumbnail_w * thumbnail_h; i++) 4479 { 4480 gint r = internal_thumbnail_data[(4 * i)]; 4481 gint g = internal_thumbnail_data[(4 * i) + 1]; 4482 gint b = internal_thumbnail_data[(4 * i) + 2]; 4483 gint alpha = internal_thumbnail_data[(4 * i) + 3]; 4484 thumbnail_data[(3 * i) + 0] = r * alpha / 255 + 255 - alpha; 4485 thumbnail_data[(3 * i) + 1] = g * alpha / 255 + 255 - alpha; 4486 thumbnail_data[(3 * i) + 2] = b * alpha / 255 + 255 - alpha; 4487 } 4488 break; 4489 default: 4490 break; 4491 /* Whatever */ 4492 } 4493 thumbnail_bpp = 3; 4494 } 4495 else 4496 { 4497 thumbnail_h = 0; 4498 thumbnail_w = 0; 4499 } 4500 } 4501 else 4502 { 4503 thumbnail_h = 0; 4504 thumbnail_w = 0; 4505 } 4506} 4507 4508static int 4509compute_thumbnail(const stp_vars_t *v) 4510{ 4511 priv_t priv; 4512 int answer = 1; 4513 stp_image_t *im = stpui_image_thumbnail_new(thumbnail_data, thumbnail_w, 4514 thumbnail_h, thumbnail_bpp); 4515 stp_vars_t *nv = stp_vars_create_copy(v); 4516 const char *output_type = stp_describe_output(nv); 4517 stp_set_top(nv, 0); 4518 stp_set_left(nv, 0); 4519 stp_set_width(nv, thumbnail_w); 4520 stp_set_height(nv, thumbnail_h); 4521 stp_set_outfunc(nv, fill_buffer_writefunc); 4522 stp_set_outdata(nv, &priv); 4523 stp_set_errfunc(nv, stpui_get_errfunc()); 4524 stp_set_errdata(nv, stpui_get_errdata()); 4525 if (strcmp(output_type, "Whitescale") == 0) 4526 { 4527 gtk_widget_hide(output_color_vbox); 4528 priv.bpp = 1; 4529 priv.output_type = "Whitescale"; 4530 stp_set_string_parameter(nv, "InkType", "RGBGray"); 4531 } 4532 else if (strcmp(output_type, "Grayscale") == 0) 4533 { 4534 gtk_widget_hide(output_color_vbox); 4535 priv.bpp = 1; 4536 priv.output_type = "Grayscale"; 4537 stp_set_string_parameter(nv, "InkType", "CMYGray"); 4538 } 4539 else if (strcmp(output_type, "CMY") == 0) 4540 { 4541 gtk_widget_hide(black_button); 4542 gtk_widget_hide(red_button); 4543 gtk_widget_hide(green_button); 4544 gtk_widget_hide(blue_button); 4545 gtk_widget_show(cyan_button); 4546 gtk_widget_show(magenta_button); 4547 gtk_widget_show(yellow_button); 4548 gtk_widget_show(output_color_vbox); 4549 priv.bpp = 3; 4550 priv.output_type = "CMY"; 4551 stp_set_string_parameter(nv, "InkType", "CMY"); 4552 } 4553 else if (strcmp(output_type, "RGB") == 0) 4554 { 4555 gtk_widget_hide(cyan_button); 4556 gtk_widget_hide(magenta_button); 4557 gtk_widget_hide(yellow_button); 4558 gtk_widget_hide(black_button); 4559 gtk_widget_show(red_button); 4560 gtk_widget_show(green_button); 4561 gtk_widget_show(blue_button); 4562 gtk_widget_show(output_color_vbox); 4563 priv.bpp = 3; 4564 priv.output_type = "RGB"; 4565 stp_set_string_parameter(nv, "InkType", "RGB"); 4566 } 4567 else 4568 { 4569 gtk_widget_hide(red_button); 4570 gtk_widget_hide(green_button); 4571 gtk_widget_hide(blue_button); 4572 gtk_widget_show(cyan_button); 4573 gtk_widget_show(magenta_button); 4574 gtk_widget_show(yellow_button); 4575 gtk_widget_show(black_button); 4576 gtk_widget_show(output_color_vbox); 4577 priv.bpp = 4; 4578 priv.output_type = "CMYK"; 4579 stp_set_string_parameter(nv, "InkType", "CMYK"); 4580 } 4581 stp_set_page_height(nv, thumbnail_h); 4582 stp_set_page_width(nv, thumbnail_w); 4583 stp_set_driver(nv, "raw-data-8"); 4584 stp_set_float_parameter(nv, "Density", 1.0); 4585 stp_set_float_parameter(nv, "InkLimit", 0); 4586 stp_set_string_parameter(nv, "InputImageType", "RGB"); 4587 stp_clear_file_parameter(nv, "LUTDumpFile"); 4588 4589 priv.base_addr = adjusted_thumbnail_data; 4590 priv.offset = 0; 4591 priv.limit = thumbnail_bpp * thumbnail_h * thumbnail_w; 4592 4593 if (stp_verify(nv) != 1 || stp_print(nv, im) != 1) 4594 { 4595 answer = 0; 4596 fprintf(stderr, "Could not print thumbnail!\n"); 4597 } 4598 stp_vars_destroy(nv); 4599 thumbnail_needs_rebuild = FALSE; 4600 return answer; 4601} 4602 4603static void 4604set_thumbnail_orientation(void) 4605{ 4606 gint x, y; 4607 gint preview_limit = (thumbnail_h * thumbnail_w) - 1; 4608 gint bpp; 4609 if (!print_mode_is_color(pv->v)) 4610 bpp = 1; 4611 else 4612 bpp = 3; 4613 switch (physical_orientation) 4614 { 4615 case ORIENT_PORTRAIT: 4616 memcpy(preview_thumbnail_data, adjusted_thumbnail_data, 4617 bpp * thumbnail_h * thumbnail_w); 4618 break; 4619 case ORIENT_SEASCAPE: 4620 for (x = 0; x < thumbnail_w; x++) 4621 for (y = 0; y < thumbnail_h; y++) 4622 memcpy((preview_thumbnail_data + 4623 bpp * (preview_limit - (x * thumbnail_h + y))), 4624 (adjusted_thumbnail_data + 4625 bpp * ((thumbnail_h - y - 1) * thumbnail_w + x)), bpp); 4626 break; 4627 4628 case ORIENT_UPSIDEDOWN: 4629 for (x = 0; x < thumbnail_h * thumbnail_w; x++) 4630 memcpy((preview_thumbnail_data + bpp * (preview_limit - x)), 4631 adjusted_thumbnail_data + bpp * x, bpp); 4632 break; 4633 case ORIENT_LANDSCAPE: 4634 for (x = 0; x < thumbnail_w; x++) 4635 for (y = 0; y < thumbnail_h; y++) 4636 memcpy((preview_thumbnail_data + bpp * (x * thumbnail_h + y)), 4637 (adjusted_thumbnail_data + 4638 bpp * ((thumbnail_h - y - 1) * thumbnail_w + x)), bpp); 4639 break; 4640 } 4641} 4642 4643static void 4644draw_arrow (GdkWindow *w, 4645 GdkGC *gc, 4646 gint paper_left, 4647 gint paper_top) 4648{ 4649 gint u = preview_ppi/2; 4650 gint ox = paper_left + preview_ppi * paper_width / INCH / 2; 4651 gint oy = paper_top + preview_ppi * paper_height / INCH / 2; 4652 4653 oy -= preview_ppi * paper_height / INCH / 4; 4654 if (oy < paper_top + u) 4655 oy = paper_top + u; 4656 gdk_draw_line (w, gc, ox, oy - u, ox - u, oy); 4657 gdk_draw_line (w, gc, ox, oy - u, ox + u, oy); 4658 gdk_draw_line (w, gc, ox, oy - u, ox, oy + u); 4659} 4660 4661static void 4662create_valid_preview(guchar **preview_data) 4663{ 4664 if (adjusted_thumbnail_data) 4665 { 4666 gint bpp = (print_mode_is_color(pv->v)) ? 3 : 1; 4667 gint v_denominator = preview_h > 1 ? preview_h - 1 : 1; 4668 gint v_numerator = (preview_thumbnail_h - 1) % v_denominator; 4669 gint v_whole = (preview_thumbnail_h - 1) / v_denominator; 4670 gint h_denominator = preview_w > 1 ? preview_w - 1 : 1; 4671 gint h_numerator = (preview_thumbnail_w - 1) % h_denominator; 4672 gint h_whole = (preview_thumbnail_w - 1) / h_denominator; 4673 gint adjusted_preview_width = bpp * preview_w; 4674 gint adjusted_thumbnail_width = bpp * preview_thumbnail_w; 4675 gint v_cur = 0; 4676 gint v_last = -1; 4677 gint v_error = v_denominator / 2; 4678 gint y; 4679 gint i; 4680 4681 if (*preview_data) 4682 g_free (*preview_data); 4683 *preview_data = g_malloc (bpp * preview_h * preview_w); 4684 4685 for (y = 0; y < preview_h; y++) 4686 { 4687 guchar *outbuf = *preview_data + adjusted_preview_width * y; 4688 4689 if (v_cur == v_last) 4690 memcpy (outbuf, outbuf-adjusted_preview_width, 4691 adjusted_preview_width); 4692 else 4693 { 4694 guchar *inbuf = preview_thumbnail_data - bpp 4695 + adjusted_thumbnail_width * v_cur; 4696 4697 gint h_cur = 0; 4698 gint h_last = -1; 4699 gint h_error = h_denominator / 2; 4700 gint x; 4701 4702 v_last = v_cur; 4703 for (x = 0; x < preview_w; x++) 4704 { 4705 if (h_cur == h_last) 4706 { 4707 for (i = 0; i < bpp; i++) 4708 outbuf[i] = outbuf[i - bpp]; 4709 } 4710 else 4711 { 4712 inbuf += bpp * (h_cur - h_last); 4713 h_last = h_cur; 4714 for (i = 0; i < bpp; i++) 4715 outbuf[i] = inbuf[i]; 4716 } 4717 outbuf += bpp; 4718 h_cur += h_whole; 4719 h_error += h_numerator; 4720 if (h_error >= h_denominator) 4721 { 4722 h_error -= h_denominator; 4723 h_cur++; 4724 } 4725 } 4726 } 4727 v_cur += v_whole; 4728 v_error += v_numerator; 4729 if (v_error >= v_denominator) 4730 { 4731 v_error -= v_denominator; 4732 v_cur++; 4733 } 4734 } 4735 preview_valid = TRUE; 4736 } 4737} 4738 4739/* 4740 * preview_update_callback() - 4741 */ 4742static void 4743do_preview_thumbnail (void) 4744{ 4745 static GdkGC *gc = NULL; 4746 static GdkGC *gcinv = NULL; 4747 static GdkGC *gcset = NULL; 4748 static guchar *preview_data = NULL; 4749 gint opx = preview_x; 4750 gint opy = preview_y; 4751 gint oph = preview_h; 4752 gint opw = preview_w; 4753 gint paper_display_left, paper_display_top; 4754 gint printable_display_left, printable_display_top; 4755 gint paper_display_width, paper_display_height; 4756 gint printable_display_width, printable_display_height; 4757 int l_bottom = stp_get_top(pv->v) + stp_get_height(pv->v); 4758 int l_right = stp_get_left(pv->v) + stp_get_width(pv->v); 4759 4760 preview_ppi = preview_size_horiz * FINCH / (gdouble) paper_width; 4761 4762 if (preview_ppi > preview_size_vert * FINCH / (gdouble) paper_height) 4763 preview_ppi = preview_size_vert * FINCH / (gdouble) paper_height; 4764 if (preview_ppi > MAX_PREVIEW_PPI) 4765 preview_ppi = MAX_PREVIEW_PPI; 4766 4767 if (preview == NULL || preview->widget.window == NULL) 4768 return; 4769 /* 4770 * Center the page on the preview 4771 */ 4772 paper_display_width = MAX(3, ROUNDUP(preview_ppi * paper_width, INCH)); 4773 paper_display_height = MAX(3, ROUNDUP(preview_ppi * paper_height, INCH)); 4774 4775 paper_display_left = (preview_size_horiz - paper_display_width) / 2; 4776 paper_display_top = (preview_size_vert - paper_display_height) / 2; 4777 4778 printable_display_width = 4779 MAX(3, ROUNDUP(preview_ppi * printable_width, INCH)); 4780 printable_display_height = 4781 MAX(3, ROUNDUP(preview_ppi * printable_height, INCH)); 4782 4783 printable_display_left = paper_display_left + preview_ppi * left / INCH; 4784 printable_display_top = paper_display_top + preview_ppi * top / INCH ; 4785 4786 preview_x = 4787 1 + paper_display_left + preview_ppi * stp_get_left (pv->v) / INCH; 4788 preview_y = 4789 1 + paper_display_top + preview_ppi * stp_get_top (pv->v) / INCH; 4790 4791 if (!preview_valid) 4792 { 4793 gint preview_r = 1 + paper_display_left + preview_ppi * l_right / INCH; 4794 gint preview_b = 1 + paper_display_top + preview_ppi * l_bottom / INCH; 4795 preview_w = preview_r - preview_x; 4796 preview_h = preview_b - preview_y; 4797 if (preview_w >= printable_display_width) 4798 preview_w = printable_display_width - 1; 4799 if (preview_h >= printable_display_height) 4800 preview_h = printable_display_height - 1; 4801 } 4802 4803 if (preview_w + preview_x > printable_display_left + printable_display_width) 4804 preview_x--; 4805 if (preview_h + preview_y > printable_display_top + printable_display_height) 4806 preview_y--; 4807 4808 if (gc == NULL) 4809 { 4810 gc = gdk_gc_new (preview->widget.window); 4811 gcinv = gdk_gc_new (preview->widget.window); 4812 gdk_gc_set_function (gcinv, GDK_INVERT); 4813 gcset = gdk_gc_new (preview->widget.window); 4814 gdk_gc_set_function (gcset, GDK_SET); 4815 } 4816 4817 if (!preview_valid) 4818 create_valid_preview(&preview_data); 4819 4820 if (printable_display_left < paper_display_left) 4821 printable_display_left = paper_display_left; 4822 if (printable_display_top < paper_display_top) 4823 printable_display_top = paper_display_top; 4824 if (printable_display_left + printable_display_width > 4825 paper_display_left + paper_display_width) 4826 printable_display_width = 4827 paper_display_width - (paper_display_left - printable_display_left); 4828 if (printable_display_top + printable_display_height > 4829 paper_display_top + paper_display_height) 4830 printable_display_height = 4831 paper_display_height - (paper_display_top - printable_display_top); 4832 if (need_exposure) 4833 { 4834 if (!frame_valid) 4835 { 4836 gdk_window_clear (preview->widget.window); 4837 frame_valid = TRUE; 4838 } 4839 /* draw paper frame */ 4840 gdk_draw_rectangle (preview->widget.window, gc, 0, 4841 paper_display_left, paper_display_top, 4842 paper_display_width, paper_display_height); 4843 4844 /* draw printable frame */ 4845 gdk_draw_rectangle (preview->widget.window, gc, 0, 4846 printable_display_left, printable_display_top, 4847 printable_display_width, printable_display_height); 4848 need_exposure = FALSE; 4849 } 4850 else if (!frame_valid) 4851 { 4852 gdk_window_clear (preview->widget.window); 4853 /* draw paper frame */ 4854 gdk_draw_rectangle (preview->widget.window, gc, 0, 4855 paper_display_left, paper_display_top, 4856 paper_display_width, paper_display_height); 4857 4858 /* draw printable frame */ 4859 gdk_draw_rectangle (preview->widget.window, gc, 0, 4860 printable_display_left, printable_display_top, 4861 printable_display_width, printable_display_height); 4862 frame_valid = TRUE; 4863 } 4864 else 4865 { 4866 if (opx + opw <= preview_x || opy + oph <= preview_y || 4867 preview_x + preview_w <= opx || preview_y + preview_h <= opy) 4868 { 4869 gdk_window_clear_area (preview->widget.window, opx, opy, opw, oph); 4870 } 4871 else 4872 { 4873 if (opx < preview_x) 4874 gdk_window_clear_area (preview->widget.window, 4875 opx, opy, preview_x - opx, oph); 4876 if (opy < preview_y) 4877 gdk_window_clear_area (preview->widget.window, 4878 opx, opy, opw, preview_y - opy); 4879 if (opx + opw > preview_x + preview_w) 4880 gdk_window_clear_area (preview->widget.window, 4881 preview_x + preview_w, opy, 4882 (opx + opw) - (preview_x + preview_w), oph); 4883 if (opy + oph > preview_y + preview_h) 4884 gdk_window_clear_area (preview->widget.window, 4885 opx, preview_y + preview_h, 4886 opw, (opy + oph) - (preview_y + preview_h)); 4887 } 4888 } 4889 4890 draw_arrow (preview->widget.window, gcset, paper_display_left, 4891 paper_display_top); 4892 4893 if (!preview_valid) 4894 gdk_draw_rectangle (preview->widget.window, gc, 1, 4895 preview_x, preview_y, preview_w, preview_h); 4896 else if (!print_mode_is_color(pv->v)) 4897 gdk_draw_gray_image (preview->widget.window, gc, 4898 preview_x, preview_y, preview_w, preview_h, 4899 GDK_RGB_DITHER_NORMAL, preview_data, preview_w); 4900 else 4901 gdk_draw_rgb_image (preview->widget.window, gc, 4902 preview_x, preview_y, preview_w, preview_h, 4903 GDK_RGB_DITHER_NORMAL, preview_data, 3 * preview_w); 4904 4905 /* If we're printing full bleed, redisplay the paper frame */ 4906 if (preview_x <= paper_display_left || opx <= paper_display_left || 4907 preview_y <= paper_display_top || opy <= paper_display_top || 4908 preview_x + preview_w >= paper_display_left + paper_display_width || 4909 opx + opw >= paper_display_left + paper_display_width || 4910 preview_y + preview_h >= paper_display_top + paper_display_height || 4911 opy + oph >= paper_display_top + paper_display_height) 4912 gdk_draw_rectangle (preview->widget.window, gc, 0, 4913 paper_display_left, paper_display_top, 4914 paper_display_width, paper_display_height); 4915 4916 4917 /* draw orientation arrow pointing to top-of-paper */ 4918 draw_arrow (preview->widget.window, gcinv, paper_display_left, 4919 paper_display_top); 4920 gdk_flush(); 4921} 4922 4923static gboolean 4924idle_preview_thumbnail(gpointer data) 4925{ 4926 if (thumbnail_data && adjusted_thumbnail_data && do_update_thumbnail) 4927 { 4928 thumbnail_update_pending = TRUE; 4929 set_orientation(pv->orientation); 4930 if (thumbnail_needs_rebuild && compute_thumbnail(pv->v)) 4931 { 4932 set_thumbnail_orientation(); 4933 redraw_color_swatch (); 4934 } 4935 do_preview_thumbnail(); 4936 } 4937 thumbnail_update_pending = FALSE; 4938 return FALSE; 4939} 4940 4941static void 4942update_adjusted_thumbnail (gboolean regenerate_image) 4943{ 4944 if (regenerate_image) 4945 thumbnail_needs_rebuild = TRUE; 4946 preview_update (); 4947} 4948 4949static void 4950preview_expose (void) 4951{ 4952 need_exposure = TRUE; 4953 preview_update (); 4954} 4955 4956static void 4957preview_update (void) 4958{ 4959 gdouble max_ppi_scaling; /* Maximum PPI for current page size */ 4960 gdouble min_ppi_scaling; /* Minimum PPI for current page size */ 4961 4962 suppress_preview_update++; 4963 compute_printable_region(); 4964 4965 if (pv->scaling < 0) 4966 { 4967 gdouble twidth; 4968 4969 compute_scaling_limits(&min_ppi_scaling, &max_ppi_scaling); 4970 4971 if (pv->scaling < 0 && pv->scaling > -min_ppi_scaling) 4972 pv->scaling = -min_ppi_scaling; 4973 4974 twidth = (FINCH * (gdouble) image_width / -pv->scaling); 4975 print_width = twidth + .5; 4976 print_height = (twidth * (gdouble) image_height / image_width) + .5; 4977 GTK_ADJUSTMENT (scaling_adjustment)->lower = min_ppi_scaling; 4978 GTK_ADJUSTMENT (scaling_adjustment)->upper = max_ppi_scaling; 4979 GTK_ADJUSTMENT (scaling_adjustment)->value = -pv->scaling; 4980 4981 if (!suppress_scaling_adjustment) 4982 { 4983 suppress_preview_reset++; 4984 gtk_adjustment_changed (GTK_ADJUSTMENT (scaling_adjustment)); 4985 suppress_scaling_callback = TRUE; 4986 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (scaling_ppi), TRUE); 4987 suppress_scaling_callback = FALSE; 4988 gtk_adjustment_value_changed (GTK_ADJUSTMENT (scaling_adjustment)); 4989 suppress_preview_reset--; 4990 } 4991 } 4992 else if (auto_paper_size) 4993 { 4994 gdouble twidth = printable_width * pv->scaling / 100; 4995 4996 print_width = twidth + .5; 4997 print_height = 4998 (twidth * (gdouble) image_height / (gdouble) image_width) + .5; 4999 } 5000 else 5001 { 5002 /* we do pv->scaling % of height or width, whatever is less */ 5003 /* this is relative to printable size */ 5004 if (image_width * printable_height > printable_width * image_height) 5005 /* if image_width/image_height > printable_width/printable_height */ 5006 /* i.e. if image is wider relative to its height than the width 5007 of the printable area relative to its height */ 5008 { 5009 gdouble twidth = printable_width * pv->scaling / 100; 5010 5011 print_width = twidth + .5; 5012 print_height = 5013 (twidth * (gdouble) image_height / (gdouble) image_width) + .5; 5014 } 5015 else 5016 { 5017 gdouble theight = printable_height * pv->scaling /100; 5018 5019 print_height = theight + .5; 5020 print_width = 5021 (theight * (gdouble) image_width / (gdouble) image_height) + .5; 5022 } 5023 } 5024 5025 if (auto_paper_size) 5026 set_media_size(stp_get_string_parameter(pv->v, "PageSize")); 5027 5028 stp_set_width(pv->v, print_width); 5029 stp_set_height(pv->v, print_height); 5030 5031 if (pv->invalid_mask & INVALID_LEFT) 5032 stp_set_left (pv->v, (paper_width - print_width) / 2); 5033 5034 if (stp_get_left(pv->v) < left) 5035 stp_set_left(pv->v, left); 5036 5037 if (stp_get_left (pv->v) > right - print_width) 5038 stp_set_left (pv->v, right - print_width); 5039 5040 if (pv->invalid_mask & INVALID_TOP) 5041 stp_set_top (pv->v, ((paper_height - print_height) / 2)); 5042 if (stp_get_top(pv->v) < top) 5043 stp_set_top(pv->v, top); 5044 5045 if (stp_get_top (pv->v) > bottom - print_height) 5046 stp_set_top (pv->v, bottom - print_height); 5047 5048 pv->invalid_mask = 0; 5049 5050 set_all_entry_values(); 5051 suppress_preview_update--; 5052 5053 /* draw image */ 5054 if (! suppress_preview_update && !thumbnail_update_pending) 5055 { 5056 thumbnail_update_pending = TRUE; 5057 g_idle_add(idle_preview_thumbnail, NULL); 5058 } 5059} 5060 5061/* 5062 * preview_button_callback() - 5063 */ 5064static void 5065preview_button_callback (GtkWidget *widget, 5066 GdkEventButton *event, 5067 gpointer data) 5068{ 5069 if (event->type == GDK_BUTTON_PRESS) 5070 { 5071 if (preview_active == 0) 5072 { 5073 mouse_x = event->x; 5074 mouse_y = event->y; 5075 orig_left = stp_get_left (pv->v); 5076 orig_top = stp_get_top (pv->v); 5077 mouse_button = event->button; 5078 buttons_mask = 1 << event->button; 5079 buttons_pressed++; 5080 preview_active = 1; 5081 stpui_disable_help(); 5082 move_constraint = 5083 (event->state & GDK_SHIFT_MASK) ? MOVE_CONSTRAIN : MOVE_ANY; 5084 if (event->state & GDK_CONTROL_MASK) 5085 move_constraint |= MOVE_GRID; 5086 } 5087 else if ((buttons_mask & (1 << event->button)) == 0) 5088 { 5089 if (preview_active == 1) 5090 { 5091 stpui_enable_help(); 5092 preview_active = -1; 5093 stp_set_left (pv->v, orig_left); 5094 stp_set_top (pv->v, orig_top); 5095 preview_update (); 5096 } 5097 buttons_mask |= 1 << event->button; 5098 buttons_pressed++; 5099 } 5100 } 5101 else if (event->type == GDK_BUTTON_RELEASE) 5102 { 5103 buttons_pressed--; 5104 buttons_mask &= ~(1 << event->button); 5105 if (buttons_pressed == 0) 5106 { 5107 stpui_enable_help (); 5108 preview_active = 0; 5109 } 5110 } 5111} 5112 5113/* 5114 * preview_motion_callback() - 5115 */ 5116static void 5117preview_motion_callback (GtkWidget *widget, 5118 GdkEventMotion *event, 5119 gpointer data) 5120{ 5121 5122 gint old_top = stp_get_top (pv->v); 5123 gint old_left = stp_get_left (pv->v); 5124 gint new_top = old_top; 5125 gint new_left = old_left; 5126 gint steps; 5127 if (preview_active != 1 || event->type != GDK_MOTION_NOTIFY) 5128 return; 5129 if (move_constraint == MOVE_CONSTRAIN) 5130 { 5131 int dx = abs(event->x - mouse_x); 5132 int dy = abs(event->y - mouse_y); 5133 if (dx > dy && dx > 3) 5134 move_constraint = MOVE_HORIZONTAL; 5135 else if (dy > dx && dy > 3) 5136 move_constraint = MOVE_VERTICAL; 5137 else 5138 return; 5139 } 5140 5141 switch (mouse_button) 5142 { 5143 case 1: 5144 if (move_constraint & MOVE_VERTICAL) 5145 new_top = orig_top + INCH * (event->y - mouse_y) / preview_ppi; 5146 if (move_constraint & MOVE_HORIZONTAL) 5147 new_left = orig_left + INCH * (event->x - mouse_x) / preview_ppi; 5148 break; 5149 case 3: 5150 if (move_constraint & MOVE_VERTICAL) 5151 new_top = orig_top + event->y - mouse_y; 5152 if (move_constraint & MOVE_HORIZONTAL) 5153 new_left = orig_left + event->x - mouse_x; 5154 break; 5155 case 2: 5156 if (move_constraint & MOVE_HORIZONTAL) 5157 { 5158 gint increment_width = 5159 ((move_constraint & MOVE_GRID) && pv->scaling > 0) ? 5160 printable_width * pv->scaling / 100 : print_width; 5161 gint x_threshold = MAX (1, (preview_ppi * increment_width) / INCH); 5162 if (event->x > mouse_x) 5163 steps = MIN((event->x - mouse_x) / x_threshold, 5164 ((right - orig_left) / increment_width) - 1); 5165 else 5166 steps = -(MIN((mouse_x - event->x) / x_threshold, 5167 (orig_left - left) / increment_width)); 5168 new_left = orig_left + steps * increment_width; 5169 } 5170 if (move_constraint & MOVE_VERTICAL) 5171 { 5172 gint increment_height = 5173 ((move_constraint & MOVE_GRID) && pv->scaling > 0) ? 5174 printable_height * pv->scaling / 100 : print_height; 5175 gint y_threshold = MAX (1, (preview_ppi * increment_height) / INCH); 5176 if (event->y > mouse_y) 5177 steps = MIN((event->y - mouse_y) / y_threshold, 5178 ((bottom - orig_top) / increment_height) - 1); 5179 else 5180 steps = -(MIN((mouse_y - event->y) / y_threshold, 5181 (orig_top - top) / increment_height)); 5182 new_top = orig_top + steps * increment_height; 5183 } 5184 break; 5185 } 5186 5187 if (new_top < top) 5188 new_top = top; 5189 if (new_top > bottom - print_height) 5190 new_top = bottom - print_height; 5191 if (new_left < left) 5192 new_left = left; 5193 if (new_left > right - print_width) 5194 new_left = right - print_width; 5195 5196 if (new_top != old_top || new_left != old_left) 5197 { 5198 stp_set_top (pv->v, new_top); 5199 stp_set_left (pv->v, new_left); 5200 preview_update (); 5201 } 5202} 5203 5204static void 5205color_update (GtkAdjustment *adjustment) 5206{ 5207 int i; 5208 for (i = 0; i < current_option_count; i++) 5209 { 5210 option_t *opt = &(current_options[i]); 5211 if (opt->fast_desc->p_type == STP_PARAMETER_TYPE_DOUBLE && 5212 opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL && 5213 opt->info.flt.adjustment && 5214 adjustment == GTK_ADJUSTMENT(opt->info.flt.adjustment)) 5215 { 5216 invalidate_preview_thumbnail (); 5217 if (stp_get_float_parameter(pv->v, opt->fast_desc->name) != 5218 adjustment->value) 5219 { 5220 stp_set_float_parameter(pv->v, opt->fast_desc->name, 5221 adjustment->value); 5222 update_adjusted_thumbnail(TRUE); 5223 } 5224 } 5225 } 5226} 5227 5228static void 5229dimension_update (GtkAdjustment *adjustment) 5230{ 5231 int i; 5232 gdouble unit_scaler = units[pv->unit].scale; 5233 for (i = 0; i < current_option_count; i++) 5234 { 5235 option_t *opt = &(current_options[i]); 5236 if (opt->fast_desc->p_type == STP_PARAMETER_TYPE_DIMENSION && 5237 opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL && 5238 opt->info.flt.adjustment && 5239 adjustment == GTK_ADJUSTMENT(opt->info.flt.adjustment)) 5240 { 5241 int new_value = (adjustment->value + (.5 / unit_scaler)) * unit_scaler; 5242 invalidate_preview_thumbnail (); 5243 if (stp_get_dimension_parameter(pv->v, opt->fast_desc->name) != 5244 new_value) 5245 { 5246 stp_set_dimension_parameter(pv->v, opt->fast_desc->name, 5247 new_value); 5248 update_adjusted_thumbnail(FALSE); 5249 } 5250 } 5251 } 5252} 5253 5254static void 5255integer_update (GtkAdjustment *adjustment) 5256{ 5257 int i; 5258 for (i = 0; i < current_option_count; i++) 5259 { 5260 option_t *opt = &(current_options[i]); 5261 if (opt->fast_desc->p_type == STP_PARAMETER_TYPE_INT && 5262 opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL && 5263 opt->info.flt.adjustment && 5264 adjustment == GTK_ADJUSTMENT(opt->info.flt.adjustment)) 5265 { 5266 invalidate_preview_thumbnail (); 5267 if (stp_get_int_parameter(pv->v, opt->fast_desc->name) != 5268 (int) adjustment->value) 5269 { 5270 stp_set_int_parameter(pv->v, opt->fast_desc->name, 5271 (int) adjustment->value); 5272 update_adjusted_thumbnail(FALSE); 5273 } 5274 } 5275 } 5276} 5277 5278static void 5279set_controls_active (GtkObject *checkbutton, gpointer xopt) 5280{ 5281 option_t *opt = (option_t *) xopt; 5282 stp_parameter_t desc; 5283 gboolean setting = 5284 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbutton)); 5285 if (setting && opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL) 5286 { 5287 switch (opt->fast_desc->p_type) 5288 { 5289 case STP_PARAMETER_TYPE_DOUBLE: 5290 set_adjustment_active(opt, TRUE, FALSE); 5291 if (! stp_check_float_parameter(pv->v, opt->fast_desc->name, 5292 STP_PARAMETER_INACTIVE)) 5293 { 5294 stp_describe_parameter(pv->v, opt->fast_desc->name, &desc); 5295 stp_set_float_parameter(pv->v, opt->fast_desc->name, 5296 desc.deflt.dbl); 5297 stp_parameter_description_destroy(&desc); 5298 } 5299 stp_set_float_parameter_active(pv->v, opt->fast_desc->name, 5300 STP_PARAMETER_ACTIVE); 5301 break; 5302 case STP_PARAMETER_TYPE_DIMENSION: 5303 set_adjustment_active(opt, TRUE, FALSE); 5304 if (! stp_check_dimension_parameter(pv->v, opt->fast_desc->name, 5305 STP_PARAMETER_INACTIVE)) 5306 { 5307 stp_describe_parameter(pv->v, opt->fast_desc->name, &desc); 5308 stp_set_dimension_parameter(pv->v, opt->fast_desc->name, 5309 desc.deflt.dimension); 5310 stp_parameter_description_destroy(&desc); 5311 } 5312 stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name, 5313 STP_PARAMETER_ACTIVE); 5314 break; 5315 case STP_PARAMETER_TYPE_INT: 5316 set_adjustment_active(opt, TRUE, FALSE); 5317 if (! stp_check_int_parameter(pv->v, opt->fast_desc->name, 5318 STP_PARAMETER_INACTIVE)) 5319 { 5320 stp_describe_parameter(pv->v, opt->fast_desc->name, &desc); 5321 stp_set_int_parameter(pv->v, opt->fast_desc->name, 5322 desc.deflt.integer); 5323 stp_parameter_description_destroy(&desc); 5324 } 5325 stp_set_int_parameter_active(pv->v, opt->fast_desc->name, 5326 STP_PARAMETER_ACTIVE); 5327 break; 5328 case STP_PARAMETER_TYPE_CURVE: 5329 set_curve_active(opt, TRUE, FALSE); 5330 if (! stp_check_curve_parameter(pv->v, opt->fast_desc->name, 5331 STP_PARAMETER_INACTIVE)) 5332 { 5333 stp_describe_parameter(pv->v, opt->fast_desc->name, &desc); 5334 stp_set_curve_parameter(pv->v, opt->fast_desc->name, 5335 desc.deflt.curve); 5336 stp_parameter_description_destroy(&desc); 5337 } 5338 stp_set_curve_parameter_active(pv->v, opt->fast_desc->name, 5339 STP_PARAMETER_ACTIVE); 5340 break; 5341 case STP_PARAMETER_TYPE_STRING_LIST: 5342 set_combo_active(opt, TRUE, FALSE); 5343 if (! stp_check_string_parameter(pv->v, opt->fast_desc->name, 5344 STP_PARAMETER_INACTIVE)) 5345 { 5346 stp_describe_parameter(pv->v, opt->fast_desc->name, &desc); 5347 stp_set_string_parameter(pv->v, opt->fast_desc->name, 5348 desc.deflt.str); 5349 stp_parameter_description_destroy(&desc); 5350 } 5351 stp_set_string_parameter_active(pv->v, opt->fast_desc->name, 5352 STP_PARAMETER_ACTIVE); 5353 break; 5354 case STP_PARAMETER_TYPE_BOOLEAN: 5355 set_bool_active(opt, TRUE, FALSE); 5356 if (! stp_check_boolean_parameter(pv->v, opt->fast_desc->name, 5357 STP_PARAMETER_INACTIVE)) 5358 { 5359 stp_describe_parameter(pv->v, opt->fast_desc->name, &desc); 5360 stp_set_boolean_parameter(pv->v, opt->fast_desc->name, 5361 desc.deflt.boolean); 5362 stp_parameter_description_destroy(&desc); 5363 } 5364 stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name, 5365 STP_PARAMETER_ACTIVE); 5366 break; 5367 case STP_PARAMETER_TYPE_FILE: 5368 set_file_active(opt, TRUE, FALSE); 5369 stp_set_file_parameter_active(pv->v, opt->fast_desc->name, 5370 STP_PARAMETER_ACTIVE); 5371 break; 5372 default: 5373 break; 5374 } 5375 } 5376 else 5377 { 5378 switch (opt->fast_desc->p_type) 5379 { 5380 case STP_PARAMETER_TYPE_DOUBLE: 5381 set_adjustment_active(opt, FALSE, FALSE); 5382 stp_set_float_parameter_active(pv->v, opt->fast_desc->name, 5383 STP_PARAMETER_INACTIVE); 5384 break; 5385 case STP_PARAMETER_TYPE_DIMENSION: 5386 set_adjustment_active(opt, FALSE, FALSE); 5387 stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name, 5388 STP_PARAMETER_INACTIVE); 5389 break; 5390 case STP_PARAMETER_TYPE_INT: 5391 set_adjustment_active(opt, FALSE, FALSE); 5392 stp_set_int_parameter_active(pv->v, opt->fast_desc->name, 5393 STP_PARAMETER_INACTIVE); 5394 break; 5395 case STP_PARAMETER_TYPE_CURVE: 5396 set_curve_active(opt, FALSE, FALSE); 5397 stp_set_curve_parameter_active(pv->v, opt->fast_desc->name, 5398 STP_PARAMETER_INACTIVE); 5399 break; 5400 case STP_PARAMETER_TYPE_STRING_LIST: 5401 set_combo_active(opt, FALSE, FALSE); 5402 stp_set_string_parameter_active(pv->v, opt->fast_desc->name, 5403 STP_PARAMETER_INACTIVE); 5404 break; 5405 case STP_PARAMETER_TYPE_BOOLEAN: /* ??? */ 5406 set_bool_active(opt, FALSE, FALSE); 5407 stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name, 5408 STP_PARAMETER_INACTIVE); 5409 break; 5410 case STP_PARAMETER_TYPE_FILE: /* ??? */ 5411 set_file_active(opt, FALSE, FALSE); 5412 stp_set_file_parameter_active(pv->v, opt->fast_desc->name, 5413 STP_PARAMETER_INACTIVE); 5414 break; 5415 default: 5416 break; 5417 } 5418 } 5419 invalidate_preview_thumbnail(); 5420 update_adjusted_thumbnail(TRUE); 5421} 5422 5423static void 5424set_one_default(option_t *opt) 5425{ 5426 stp_parameter_activity_t active; 5427 gdouble unit_scaler; 5428 switch (opt->fast_desc->p_type) 5429 { 5430 case STP_PARAMETER_TYPE_DOUBLE: 5431 active = stp_get_float_parameter_active(pv->v, opt->fast_desc->name); 5432 stp_set_float_parameter(pv->v, opt->fast_desc->name, opt->info.flt.deflt); 5433 stp_set_float_parameter_active(pv->v, opt->fast_desc->name, active); 5434 break; 5435 case STP_PARAMETER_TYPE_DIMENSION: 5436 unit_scaler = units[pv->unit].scale; 5437 active = stp_get_dimension_parameter_active(pv->v, opt->fast_desc->name); 5438 stp_set_dimension_parameter(pv->v, opt->fast_desc->name, 5439 opt->info.flt.deflt * unit_scaler); 5440 stp_set_dimension_parameter_active(pv->v, opt->fast_desc->name, active); 5441 break; 5442 case STP_PARAMETER_TYPE_INT: 5443 unit_scaler = units[pv->unit].scale; 5444 active = stp_get_int_parameter_active(pv->v, opt->fast_desc->name); 5445 stp_set_int_parameter(pv->v, opt->fast_desc->name, 5446 (int) opt->info.flt.deflt); 5447 stp_set_int_parameter_active(pv->v, opt->fast_desc->name, active); 5448 break; 5449 case STP_PARAMETER_TYPE_BOOLEAN: 5450 active = stp_get_boolean_parameter_active(pv->v, opt->fast_desc->name); 5451 stp_set_boolean_parameter(pv->v, opt->fast_desc->name, 5452 opt->info.bool.deflt); 5453 stp_set_boolean_parameter_active(pv->v, opt->fast_desc->name, active); 5454 break; 5455 case STP_PARAMETER_TYPE_STRING_LIST: 5456 active = stp_get_string_parameter_active(pv->v, opt->fast_desc->name); 5457 stp_set_string_parameter(pv->v, opt->fast_desc->name, 5458 opt->info.list.default_val); 5459 stp_set_string_parameter_active(pv->v, opt->fast_desc->name, active); 5460 break; 5461 case STP_PARAMETER_TYPE_FILE: 5462 active = stp_get_file_parameter_active(pv->v, opt->fast_desc->name); 5463 stp_set_file_parameter(pv->v, opt->fast_desc->name, ""); 5464 stp_set_file_parameter_active(pv->v, opt->fast_desc->name, active); 5465 break; 5466 default: 5467 break; 5468 } 5469} 5470 5471static void 5472reset_callback(GtkObject *button, gpointer xopt) 5473{ 5474 option_t *opt = (option_t *)xopt; 5475 if (opt) 5476 { 5477 set_one_default(opt); 5478 if (opt->reset_all) 5479 do_all_updates (); 5480 else 5481 do_color_updates (); 5482 } 5483} 5484 5485static void 5486set_printer_defaults (void) 5487{ 5488 int i; 5489 for (i = 0; i < current_option_count; i++) 5490 { 5491 option_t *opt = &(current_options[i]); 5492 if (opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL && 5493 opt->fast_desc->p_class == STP_PARAMETER_CLASS_FEATURE && 5494 opt->is_active && !opt->fast_desc->read_only) 5495 set_one_default(opt); 5496 } 5497 5498 do_all_updates (); 5499} 5500 5501static void 5502set_color_defaults (void) 5503{ 5504 int i; 5505 for (i = 0; i < current_option_count; i++) 5506 { 5507 option_t *opt = &(current_options[i]); 5508 if (opt->fast_desc->p_level <= MAXIMUM_PARAMETER_LEVEL && 5509 opt->fast_desc->p_class == STP_PARAMETER_CLASS_OUTPUT && 5510 opt->is_active && !opt->fast_desc->read_only) 5511 set_one_default(opt); 5512 } 5513 5514 do_color_updates (); 5515} 5516 5517gint 5518stpui_do_print_dialog(void) 5519{ 5520 /* 5521 * Get printrc options... 5522 */ 5523 stpui_printrc_load (); 5524 5525 /* 5526 * Print dialog window... 5527 */ 5528 create_main_window(); 5529 5530 gtk_main (); 5531 gdk_flush (); 5532 5533 /* 5534 * Set printrc options... 5535 */ 5536 if (saveme) 5537 stpui_printrc_save (); 5538 5539 /* 5540 * Return ok/cancel... 5541 */ 5542 return (runme); 5543} 5544