From 817e6294b42b3e4435f1b99728afc1dca84a6445 Mon Sep 17 00:00:00 2001 From: Mattia Rizzolo Date: Fri, 3 Oct 2014 14:05:03 +0000 Subject: Imported Upstream version 0.97 --- src/xsane.c | 4860 ++++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 3015 insertions(+), 1845 deletions(-) (limited to 'src/xsane.c') diff --git a/src/xsane.c b/src/xsane.c index ae07b8c..9ef109f 100644 --- a/src/xsane.c +++ b/src/xsane.c @@ -3,7 +3,7 @@ xsane.c Oliver Rauch - Copyright (C) 1998-2002 Oliver Rauch + Copyright (C) 1998-2005 Oliver Rauch This file is part of the XSANE package. This program is free software; you can redistribute it and/or modify @@ -34,6 +34,7 @@ #include "xsane-device-preferences.h" #include "xsane-preferences.h" #include "xsane-icons.h" +#include "xsane-batch-scan.h" #ifdef HAVE_LIBPNG #ifdef HAVE_LIBZ @@ -42,7 +43,6 @@ #endif #endif -#include #include /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -65,7 +65,6 @@ struct option long_options[] = {"Resizeable", no_argument, 0, 'R'}, {"print-filenames", no_argument, 0, 'p'}, {"force-filename", required_argument, 0, 'N'}, - {"Medium-calibration", no_argument, 0, 'M'}, {0, } }; @@ -98,8 +97,8 @@ static const Preferences_medium_t pref_default_medium[]= { /* medium shadow highlight gamma negative */ /* name gray red green blue gray red green blue gray red gren blue */ - { MENU_ITEM_MEDIUM_FULL_RANGE, 0.0, 0.0, 0.0, 0.0, 100.0,100.0,100.0,100.0, 1.00, 1.00, 1.00, 1.00 , 0}, - { MENU_ITEM_MEDIUM_SLIDE, 0.0, 0.0, 0.0, 0.0, 30.0, 30.0, 30.0, 30.0, 1.00, 1.00, 1.00, 1.00 , 0}, + { MENU_ITEM_MEDIUM_FULL_COLOR_RANGE, 0.0, 0.0, 0.0, 0.0, 100.0,100.0,100.0,100.0, 1.00, 1.00, 1.00, 1.00 , 0}, + { MENU_ITEM_MEDIUM_SLIDE, 0.0, 0.0, 0.0, 0.0, 40.0, 40.0, 40.0, 40.0, 1.00, 1.00, 1.00, 1.00 , 0}, { MENU_ITEM_MEDIUM_STANDARD_NEG, 0.0, 7.0, 1.0, 0.0, 66.0, 66.0, 33.0, 16.0, 1.00, 1.00, 1.00, 1.00 , 1}, { MENU_ITEM_MEDIUM_AGFA_NEG, 0.0, 6.0, 2.0, 0.0, 31.0, 61.0, 24.0, 13.0, 1.00, 1.00, 1.00, 1.00 , 1}, { MENU_ITEM_MEDIUM_AGFA_NEG_XRG200_4, 0.0, 12.0, 2.0, 1.6, 35.0, 61.5, 21.5, 14.5, 1.00, 0.80, 0.67, 0.60 , 1}, @@ -114,6 +113,8 @@ static const Preferences_medium_t pref_default_medium[]= /* ---------------------------------------------------------------------------------------------------------------------- */ int DBG_LEVEL = 0; +static guint xsane_resolution_timer = 0; +static guint xsane_mail_send_timer = 0; /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -144,11 +145,6 @@ static void xsane_threshold_changed(void); static void xsane_gamma_changed(GtkAdjustment *adj_data, double *val); static void xsane_set_modus_defaults(void); static void xsane_modus_callback(GtkWidget *xsane_parent, int *num); -static void xsane_filename_counter_step_callback(GtkWidget *widget, gpointer data); -static void xsane_filetype_callback(GtkWidget *widget, gpointer data); -static void xsane_outputfilename_changed_callback(GtkWidget *widget, gpointer data); -static void xsane_browse_filename_callback(GtkWidget *widget, gpointer data); -static void xsane_outputfilename_new(GtkWidget *vbox); static void xsane_enhancement_rgb_default_callback(GtkWidget *widget); static void xsane_enhancement_negative_callback(GtkWidget *widget); static void xsane_auto_enhancement_callback(GtkWidget *widget); @@ -158,10 +154,14 @@ static void xsane_show_histogram_callback(GtkWidget *widget); #ifdef HAVE_WORKING_GTK_GAMMACURVE static void xsane_show_gamma_callback(GtkWidget *widget); #endif +static void xsane_show_batch_scan_callback(GtkWidget *widget); static void xsane_printer_callback(GtkWidget *widget, gpointer data); void xsane_pref_save(void); static int xsane_pref_restore(void); +static void xsane_pref_save_media(void); +static void xsane_pref_restore_media(void); static RETSIGTYPE xsane_quit_handler(int signal); +static RETSIGTYPE xsane_sigchld_handler(int signal); static void xsane_quit(void); static void xsane_exit(void); static gint xsane_standard_option_win_delete(GtkWidget *widget, gpointer data); @@ -170,24 +170,22 @@ static gint xsane_scan_win_delete(GtkWidget *w, gpointer data); static gint xsane_preview_window_destroyed(GtkWidget *widget, gpointer call_data); static void xsane_show_preview_callback(GtkWidget * widget, gpointer call_data); static GtkWidget *xsane_files_build_menu(void); +static gint xsane_medium_context_menu_callback(GtkWidget *widget, GdkEvent *event); static void xsane_set_medium_callback(GtkWidget *widget, gpointer data); static void xsane_set_pref_unit_callback(GtkWidget *widget, gpointer data); +static void xsane_edit_medium_definition_callback(GtkWidget *widget, gpointer data); static void xsane_set_update_policy_callback(GtkWidget *widget, gpointer data); static gint xsane_close_info_callback(GtkWidget *widget, gpointer data); static void xsane_info_dialog(GtkWidget *widget, gpointer data); static void xsane_about_dialog(GtkWidget *widget, gpointer data); static void xsane_about_translation_dialog(GtkWidget *widget, gpointer data); -static SANE_Status xsane_get_area_value(int option, float *val, SANE_Int *unit); -#ifdef XSANE_TEST -static void xsane_batch_scan_delete_callback(GtkWidget *widget, gpointer list); -static void xsane_batch_scan_add_callback(GtkWidget *widget, gpointer list); -static void xsane_batch_scan_dialog(GtkWidget *widget, gpointer data); -#endif +static gint xsane_fax_dialog_delete(); static void xsane_fax_dialog(void); static void xsane_fax_dialog_close(void); static void xsane_fax_receiver_changed_callback(GtkWidget *widget, gpointer data); static void xsane_fax_project_changed_callback(GtkWidget *widget, gpointer data); static void xsane_fax_fine_mode_callback(GtkWidget *widget); +static void xsane_fax_project_update_project_status(); void xsane_fax_project_save(void); static void xsane_fax_project_load(void); static void xsane_fax_project_delete(void); @@ -201,6 +199,8 @@ static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list); static void xsane_fax_show_callback(GtkWidget *widget, gpointer data); static void xsane_fax_send(void); #ifdef XSANE_ACTIVATE_MAIL +static gint xsane_mail_dialog_delete(); +static void xsane_mail_filetype_callback(GtkWidget *filetype_option_menu, char *filetype); static void xsane_mail_dialog(void); static void xsane_mail_dialog_close(void); static void xsane_mail_receiver_changed_callback(GtkWidget *widget, gpointer data); @@ -208,28 +208,34 @@ static void xsane_mail_subject_changed_callback(GtkWidget *widget, gpointer data static void xsane_mail_project_changed_callback(GtkWidget *widget, gpointer data); static void xsane_mail_html_mode_callback(GtkWidget *widget); void xsane_mail_project_save(void); +static void xsane_mail_project_display_status(void); static void xsane_mail_project_load(void); static void xsane_mail_project_delete(void); +static void xsane_mail_project_update_project_status(); static void xsane_mail_project_create(void); static void xsane_mail_entry_move_up_callback(GtkWidget *widget, gpointer list); static void xsane_mail_entry_move_down_callback(GtkWidget *widget, gpointer list); static void xsane_mail_entry_rename_callback(GtkWidget *widget, gpointer list); static void xsane_mail_entry_delete_callback(GtkWidget *widget, gpointer list); static void xsane_mail_show_callback(GtkWidget *widget, gpointer data); -static void xsane_mail_send(void); +#if 0 +static void xsane_mail_edit_callback(GtkWidget *widget, gpointer data); #endif -static void xsane_pref_toggle_tooltips(GtkWidget *widget, gpointer data); static void xsane_mail_send_process(void); static void xsane_mail_send(void); -static void xsane_show_license(GtkWidget *widget, gpointer data); +#endif +static void xsane_pref_toggle_tooltips(GtkWidget *widget, gpointer data); +static void xsane_show_eula(GtkWidget *widget, gpointer data); +static void xsane_show_gpl(GtkWidget *widget, gpointer data); static void xsane_show_doc(GtkWidget *widget, gpointer data); static GtkWidget *xsane_view_build_menu(void); -static GtkWidget *xsane_pref_build_menu(void); +static GtkWidget *xsane_window_build_menu(void); +static GtkWidget *xsane_preferences_build_menu(void); static GtkWidget *xsane_help_build_menu(void); static void xsane_device_dialog(void); static void xsane_choose_dialog_ok_callback(void); static void xsane_select_device_by_key_callback(GtkWidget * widget, gpointer data); -static void xsane_select_device_by_mouse_callback(GtkWidget * widget, GdkEventButton *event, gpointer data); +static int xsane_select_device_by_mouse_callback(GtkWidget * widget, GdkEventButton *event, gpointer data); static void xsane_choose_device(void); static void xsane_usage(void); static int xsane_init(int argc, char **argv); @@ -254,191 +260,6 @@ void xsane_debug_message(int level, const char *fmt, ...) /* ---------------------------------------------------------------------------------------------------------------------- */ -static void xsane_add_medium_definition(char *definition_name) -{ - int i; - - DBG(DBG_proc, "xsane_add_new_medium_definition\n"); - - i = preferences.medium_definitions; - - preferences.medium_definitions++; - preferences.medium = realloc( preferences.medium, preferences.medium_definitions * sizeof(void *)); - - if (xsane.negative == xsane.medium_negative) /* result is positive */ - { - preferences.medium[i] = calloc(sizeof(Preferences_medium_t), 1); - preferences.medium[i]->name = strdup(definition_name); - preferences.medium[i]->shadow_gray = xsane.medium_shadow_gray + (xsane.medium_highlight_gray - xsane.medium_shadow_gray) * xsane.slider_gray.value[0] / 100.0; - preferences.medium[i]->shadow_red = xsane.medium_shadow_red + (xsane.medium_highlight_red - xsane.medium_shadow_red) * xsane.slider_red.value[0] / 100.0; - preferences.medium[i]->shadow_green = xsane.medium_shadow_green + (xsane.medium_highlight_green - xsane.medium_shadow_green) * xsane.slider_green.value[0] / 100.0; - preferences.medium[i]->shadow_blue = xsane.medium_shadow_blue + (xsane.medium_highlight_blue - xsane.medium_shadow_blue) * xsane.slider_blue.value[0] / 100.0; - preferences.medium[i]->highlight_gray = xsane.medium_shadow_gray + (xsane.medium_highlight_gray - xsane.medium_shadow_gray) * xsane.slider_gray.value[2] / 100.0; - preferences.medium[i]->highlight_red = xsane.medium_shadow_red + (xsane.medium_highlight_red - xsane.medium_shadow_red) * xsane.slider_red.value[2] / 100.0; - preferences.medium[i]->highlight_green = xsane.medium_shadow_green + (xsane.medium_highlight_green - xsane.medium_shadow_green) * xsane.slider_green.value[2] / 100.0; - preferences.medium[i]->highlight_blue = xsane.medium_shadow_blue + (xsane.medium_highlight_blue - xsane.medium_shadow_blue) * xsane.slider_blue.value[2] / 100.0; - preferences.medium[i]->gamma_gray = xsane.gamma; - preferences.medium[i]->gamma_red = xsane.gamma * xsane.gamma_red * xsane.medium_gamma_red; - preferences.medium[i]->gamma_green = xsane.gamma * xsane.gamma_green * xsane.medium_gamma_green; - preferences.medium[i]->gamma_blue = xsane.gamma * xsane.gamma_blue * xsane.medium_gamma_blue; - preferences.medium[i]->negative = 0; - } - else /* result is negative */ - { - preferences.medium[i] = calloc(sizeof(Preferences_medium_t), 1); - preferences.medium[i]->name = strdup(definition_name); - preferences.medium[i]->shadow_gray = xsane.medium_shadow_gray + (xsane.medium_highlight_gray - xsane.medium_shadow_gray) * (1.0 - xsane.slider_gray.value[2] / 100.0); - preferences.medium[i]->shadow_red = xsane.medium_shadow_red + (xsane.medium_highlight_red - xsane.medium_shadow_red) * (1.0 - xsane.slider_red.value[2] / 100.0); - preferences.medium[i]->shadow_green = xsane.medium_shadow_green + (xsane.medium_highlight_green - xsane.medium_shadow_green) * (1.0 - xsane.slider_green.value[2] / 100.0); - preferences.medium[i]->shadow_blue = xsane.medium_shadow_blue + (xsane.medium_highlight_blue - xsane.medium_shadow_blue) * (1.0 - xsane.slider_blue.value[2] / 100.0); - preferences.medium[i]->highlight_gray = xsane.medium_shadow_gray + (xsane.medium_highlight_gray - xsane.medium_shadow_gray) * (1.0 - xsane.slider_gray.value[0] / 100.0); - preferences.medium[i]->highlight_red = xsane.medium_shadow_red + (xsane.medium_highlight_red - xsane.medium_shadow_red) * (1.0 - xsane.slider_red.value[0] / 100.0); - preferences.medium[i]->highlight_green = xsane.medium_shadow_green + (xsane.medium_highlight_green - xsane.medium_shadow_green) * (1.0 - xsane.slider_green.value[0] / 100.0); - preferences.medium[i]->highlight_blue = xsane.medium_shadow_blue + (xsane.medium_highlight_blue - xsane.medium_shadow_blue) * (1.0 - xsane.slider_blue.value[0] / 100.0); - preferences.medium[i]->gamma_gray = xsane.gamma; - preferences.medium[i]->gamma_red = xsane.gamma * xsane.gamma_red * xsane.medium_gamma_red; - preferences.medium[i]->gamma_green = xsane.gamma * xsane.gamma_green * xsane.medium_gamma_green; - preferences.medium[i]->gamma_blue = xsane.gamma * xsane.gamma_blue * xsane.medium_gamma_blue; - preferences.medium[i]->negative = 1; - } - - xsane_back_gtk_refresh_dialog(); -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -int xsane_add_medium_definition_flag; - -static void xsane_add_medium_definition_button_callback(GtkWidget *widget, gpointer data) -{ - DBG(DBG_proc, "xsane_add_medium_definiton_button_callback\n"); - - xsane_add_medium_definition_flag = (int) data; -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_add_medium_definition_callback() -{ - GtkWidget *add_medium_dialog; - GtkWidget *hbox, *vbox, *button, *text, *label; - - xsane_set_sensitivity(FALSE); - - /* set add medium dialog */ - add_medium_dialog = gtk_window_new(GTK_WINDOW_DIALOG); - gtk_window_set_position(GTK_WINDOW(add_medium_dialog), GTK_WIN_POS_MOUSE); - gtk_window_set_title(GTK_WINDOW(add_medium_dialog), WINDOW_STORE_MEDIUM); - xsane_set_window_icon(add_medium_dialog, 0); - gtk_signal_connect_object(GTK_OBJECT(add_medium_dialog), "delete_event", (GtkSignalFunc) xsane_add_medium_definition_button_callback, (GtkObject *) -1); - - /* set the main vbox */ - vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); - gtk_container_add(GTK_CONTAINER(add_medium_dialog), vbox); - gtk_widget_show(vbox); - - /* set the main hbox */ - hbox = gtk_hbox_new(FALSE, 0); - xsane_separator_new(vbox, 2); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); - gtk_widget_show(hbox); - - label = gtk_label_new(TEXT_MEDIUM_DEFINITION_NAME); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); - gtk_widget_show(label); - - text = gtk_entry_new_with_max_length(64); - xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_PRESET_AREA_NAME); - gtk_entry_set_text(GTK_ENTRY(text), ""); - gtk_widget_set_usize(text, 300, 0); - gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4); - gtk_widget_show(text); - - /* set the main hbox */ - hbox = gtk_hbox_new(FALSE, 0); - xsane_separator_new(vbox, 2); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); - gtk_widget_show(hbox); - - label = gtk_label_new(TEXT_MEDIUM_DEFINITION_NAME); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); - - - button = gtk_button_new_with_label("OK"); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_add_medium_definition_button_callback, (void *) 1); - gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); - gtk_widget_show(button); - - button = gtk_button_new_with_label("Cancel"); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_add_medium_definition_button_callback, (void *) -1); - gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); - gtk_widget_show(button); - - gtk_widget_show(add_medium_dialog); - - xsane_add_medium_definition_flag = 0; - - while (xsane_add_medium_definition_flag == 0) - { - while (gtk_events_pending()) - { - DBG(DBG_info, "xsane_add_medium_definition_callback: calling gtk_main_iteration\n"); - gtk_main_iteration(); - } - } - - if (xsane_add_medium_definition_flag == 1) - { - xsane_add_medium_definition(gtk_entry_get_text(GTK_ENTRY(text))); - } - - gtk_widget_destroy(add_medium_dialog); - - xsane_set_sensitivity(TRUE); -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_delete_medium_definition_callback() -{ - int i; - - if (xsane.medium_nr == 0) /* do not allow to delete "full range" */ - { - return; - } - - free(preferences.medium[xsane.medium_nr]); - - preferences.medium_definitions--; - - for (i = xsane.medium_nr; i < preferences.medium_definitions; i++) - { - preferences.medium[i] = preferences.medium[i+1]; - } - - if (xsane.medium_nr > 0) - { - xsane.medium_nr--; - } - - xsane.medium_changed = TRUE; - - xsane_set_medium(preferences.medium[xsane.medium_nr]); - - xsane_update_gamma_curve(TRUE); /* if necessary update preview gamma */ - - preview_display_valid(xsane.preview); /* update valid status of preview image */ - /* the valid status depends on gamma handling an medium change */ - - xsane_back_gtk_refresh_dialog(); /* update menu */ -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - static int xsane_option_defined(char *string) { if (string) @@ -493,9 +314,12 @@ static void xsane_gamma_changed(GtkAdjustment *adj_data, double *val) DBG(DBG_proc, "xsane_gamma_changed\n"); *val = adj_data->value; - xsane_enhancement_by_gamma(); - xsane_threshold_changed(); + if (!xsane.block_enhancement_update) + { + xsane_enhancement_by_gamma(); + xsane_threshold_changed(); + } } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -574,17 +398,6 @@ static void xsane_modus_callback(GtkWidget *xsane_parent, int *num) { DBG(DBG_proc, "xsane_modus_callback\n"); - if (xsane.filetype) /* add extension to filename */ - { - char buffer[256]; - - snprintf(buffer, sizeof(buffer), "%s%s", preferences.filename, xsane.filetype); - free(preferences.filename); - free(xsane.filetype); - xsane.filetype = NULL; - preferences.filename = strdup(buffer); - } - xsane.xsane_mode = *num; xsane_set_modus_defaults(); /* set defaults and maximum output size */ @@ -612,331 +425,12 @@ static void xsane_modus_callback(GtkWidget *xsane_parent, int *num) xsane_mail_dialog_close(); } #endif -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_filename_counter_step_callback(GtkWidget *widget, gpointer data) -{ - DBG(DBG_proc, "xsane_filename_counter_step_callback\n"); - - preferences.filename_counter_step = (int) data; -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_filetype_callback(GtkWidget *widget, gpointer data) -{ - DBG(DBG_proc, "xsane_filetype_callback\n"); - - if (data) - { - char *extension, *filename; - - extension = strrchr(preferences.filename, '.'); - - if ((extension) && (extension != preferences.filename)) - { - if ( (!strcasecmp(extension, ".pnm")) || (!strcasecmp(extension, ".raw")) - || (!strcasecmp(extension, ".png")) || (!strcasecmp(extension, ".ps")) - || (!strcasecmp(extension, ".rgba")) - || (!strcasecmp(extension, ".tiff")) || (!strcasecmp(extension, ".tif")) - || (!strcasecmp(extension, ".jpg")) || (!strcasecmp(extension, ".jpeg")) - ) /* remove filetype extension */ - { - filename = preferences.filename; - *extension = 0; /* remove extension */ - preferences.filename = strdup(filename); /* filename without extension */ - free(filename); /* free unused memory */ - } - } - } - else if (xsane.filetype) - { - char buffer[256]; - - snprintf(buffer, sizeof(buffer), "%s%s", preferences.filename, xsane.filetype); - free(preferences.filename); - free(xsane.filetype); - xsane.filetype = NULL; - preferences.filename = strdup(buffer); - } - - if (data) - { - xsane.filetype = strdup((char *) data); /* set extension for filename */ - } - - /* correct length of filename counter if it is shorter than minimum length */ - xsane_update_counter_in_filename(&preferences.filename, FALSE, 0, preferences.filename_counter_len); - gtk_entry_set_text(GTK_ENTRY(xsane.outputfilename_entry), preferences.filename); - xsane_define_maximum_output_size(); /* is necessary in postscript mode */ -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_outputfilename_changed_callback(GtkWidget *widget, gpointer data) -{ - DBG(DBG_proc, "xsane_outputfilename_changed_callback\n"); - - if (preferences.filename) - { - free((void *) preferences.filename); - } - preferences.filename = strdup(gtk_entry_get_text(GTK_ENTRY(widget))); - - xsane_define_maximum_output_size(); /* is necessary in postscript mode */ -} - -/* ----------------------------------------------------------------------------------------------------------------- */ - -static void xsane_browse_filename_callback(GtkWidget *widget, gpointer data) -{ - char filename[1024]; - char windowname[256]; - - DBG(DBG_proc, "xsane_browse_filename_callback\n"); - - xsane_set_sensitivity(FALSE); - - if (xsane.filetype) /* set filetype to "by ext." */ - { - char buffer[256]; - - snprintf(buffer, sizeof(buffer), "%s%s", preferences.filename, xsane.filetype); - free(preferences.filename); - free(xsane.filetype); - xsane.filetype = NULL; - preferences.filename = strdup(buffer); - } - - if (preferences.filename) /* make sure a correct filename is defined */ - { - strncpy(filename, preferences.filename, sizeof(filename)); - filename[sizeof(filename) - 1] = '\0'; - } - else /* no filename given, take standard filename */ - { - strcpy(filename, OUT_FILENAME); - } - - snprintf(windowname, sizeof(windowname), "%s %s %s", xsane.prog_name, WINDOW_OUTPUT_FILENAME, xsane.device_text); - - umask((mode_t) preferences.directory_umask); /* define new file permissions */ - xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, TRUE, TRUE, FALSE); - umask(XSANE_DEFAULT_UMASK); /* define new file permissions */ - - if (preferences.filename) - { - free((void *) preferences.filename); - } - - xsane_set_sensitivity(TRUE); - - preferences.filename = strdup(filename); - - /* correct length of filename counter if it is shorter than minimum length */ - xsane_update_counter_in_filename(&preferences.filename, FALSE, 0, preferences.filename_counter_len); - - gtk_entry_set_text(GTK_ENTRY(xsane.outputfilename_entry), preferences.filename); - - gtk_option_menu_set_history(GTK_OPTION_MENU(xsane.filetype_option_menu), 0); /* set menu to "by ext" */ - xsane_define_maximum_output_size(); /* is necessary in postscript mode */ -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_outputfilename_new(GtkWidget *vbox) -{ - GtkWidget *hbox; - GtkWidget *text; - GtkWidget *button; - GtkWidget *xsane_filetype_menu, *xsane_filetype_item; - GtkWidget *xsane_filename_counter_step_option_menu; - GtkWidget *xsane_filename_counter_step_menu; - GtkWidget *xsane_filename_counter_step_item; - GtkWidget *xsane_label; - gchar buf[200]; - int i,j; - int filetype_nr; - int select_item = 0; - - DBG(DBG_proc, "xsane_outputfilename_new\n"); - - /* first line: disk icon, filename box */ - - hbox = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2); - - button = xsane_button_new_with_pixmap(xsane.xsane_window->window, hbox, file_xpm, DESC_BROWSE_FILENAME, - (GtkSignalFunc) xsane_browse_filename_callback, NULL); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_B, GDK_CONTROL_MASK, GTK_ACCEL_LOCKED); - - text = gtk_entry_new_with_max_length(255); - gtk_widget_set_usize(text, 80, 0); /* set minimum size */ - xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FILENAME); - gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.filename); - gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4); - gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_outputfilename_changed_callback, NULL); - - xsane.outputfilename_entry = text; - - gtk_widget_show(text); - gtk_widget_show(hbox); - - - /* second line: Step, Type */ - - hbox = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); - gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 2); - - /* filename counter step */ - - xsane_label = gtk_label_new(TEXT_FILENAME_COUNTER_STEP); - gtk_box_pack_start(GTK_BOX(hbox), xsane_label, FALSE, FALSE, 2); - gtk_widget_show(xsane_label); - - xsane_filename_counter_step_option_menu = gtk_option_menu_new(); - xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_filename_counter_step_option_menu, DESC_FILENAME_COUNTER_STEP); - gtk_box_pack_start(GTK_BOX(hbox), xsane_filename_counter_step_option_menu, FALSE, FALSE, 2); - gtk_widget_show(xsane_filename_counter_step_option_menu); - gtk_widget_show(hbox); - - xsane_filename_counter_step_menu = gtk_menu_new(); - - select_item = 0; - j = -2; - for (i=0; i < 5; i++) - { - snprintf(buf, sizeof(buf), "%+d", j); - xsane_filename_counter_step_item = gtk_menu_item_new_with_label(buf); - gtk_container_add(GTK_CONTAINER(xsane_filename_counter_step_menu), xsane_filename_counter_step_item); - gtk_signal_connect(GTK_OBJECT(xsane_filename_counter_step_item), "activate", - (GtkSignalFunc) xsane_filename_counter_step_callback, (void *) j); - gtk_widget_show(xsane_filename_counter_step_item); - if (preferences.filename_counter_step == j++) - { - select_item = i; - } - } - - gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane_filename_counter_step_option_menu), xsane_filename_counter_step_menu); - gtk_option_menu_set_history(GTK_OPTION_MENU(xsane_filename_counter_step_option_menu), select_item); - - /* filetype */ - - xsane_filetype_menu = gtk_menu_new(); - - xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_BY_EXT); - gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item); - gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", - (GtkSignalFunc) xsane_filetype_callback, NULL); - gtk_widget_show(xsane_filetype_item); - filetype_nr = 0; - select_item = 0; - -#ifdef HAVE_LIBJPEG - xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_JPEG); - gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item); - gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", - (GtkSignalFunc) xsane_filetype_callback, XSANE_FILETYPE_JPEG); - gtk_widget_show(xsane_filetype_item); - filetype_nr++; - if ( (xsane.filetype) && (!strcasecmp(xsane.filetype, XSANE_FILETYPE_JPEG)) ) - { - select_item = filetype_nr; - } -#endif - -#ifdef HAVE_LIBPNG -#ifdef HAVE_LIBZ - xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNG); - gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item); - gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", - (GtkSignalFunc) xsane_filetype_callback, XSANE_FILETYPE_PNG); - gtk_widget_show(xsane_filetype_item); - filetype_nr++; - if ( (xsane.filetype) && (!strcasecmp(xsane.filetype, XSANE_FILETYPE_PNG)) ) - { - select_item = filetype_nr; - } -#endif -#endif - - xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNM); - gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item); - gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", - (GtkSignalFunc) xsane_filetype_callback, XSANE_FILETYPE_PNM); - gtk_widget_show(xsane_filetype_item); - filetype_nr++; - if ( (xsane.filetype) && (!strcasecmp(xsane.filetype, XSANE_FILETYPE_PNM)) ) - { - select_item = filetype_nr; - } - - xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PS); - gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item); - gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", - (GtkSignalFunc) xsane_filetype_callback, XSANE_FILETYPE_PS); - gtk_widget_show(xsane_filetype_item); - filetype_nr++; - if ( (xsane.filetype) && (!strcasecmp(xsane.filetype, XSANE_FILETYPE_PS)) ) - { - select_item = filetype_nr; - } - - xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_RAW); - gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item); - gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", - (GtkSignalFunc) xsane_filetype_callback, XSANE_FILETYPE_RAW); - gtk_widget_show(xsane_filetype_item); - filetype_nr++; - if ( (xsane.filetype) && (!strcasecmp(xsane.filetype, XSANE_FILETYPE_RAW)) ) - { - select_item = filetype_nr; - } - -#ifdef SUPPORT_RGBA - xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_RGBA); - gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item); - gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", - (GtkSignalFunc) xsane_filetype_callback, XSANE_FILETYPE_RGBA); - gtk_widget_show(xsane_filetype_item); - filetype_nr++; - if ( (xsane.filetype) && (!strcasecmp(xsane.filetype, XSANE_FILETYPE_RGBA)) ) - { - select_item = filetype_nr; - } -#endif -#ifdef HAVE_LIBTIFF - xsane_filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_TIFF); - gtk_container_add(GTK_CONTAINER(xsane_filetype_menu), xsane_filetype_item); - gtk_signal_connect(GTK_OBJECT(xsane_filetype_item), "activate", - (GtkSignalFunc) xsane_filetype_callback, XSANE_FILETYPE_TIFF); - gtk_widget_show(xsane_filetype_item); - filetype_nr++; - if ( (xsane.filetype) && (!strcasecmp(xsane.filetype, XSANE_FILETYPE_TIFF)) ) + /* make sure dialogs are rebuild, otherwise we can get in trouble */ + while (gtk_events_pending()) { - select_item = filetype_nr; + gtk_main_iteration(); } -#endif - - xsane.filetype_option_menu = gtk_option_menu_new(); - xsane_back_gtk_set_tooltip(xsane.tooltips, xsane.filetype_option_menu, DESC_FILETYPE); - gtk_box_pack_end(GTK_BOX(hbox), xsane.filetype_option_menu, FALSE, FALSE, 2); - gtk_option_menu_set_menu(GTK_OPTION_MENU(xsane.filetype_option_menu), xsane_filetype_menu); - gtk_option_menu_set_history(GTK_OPTION_MENU(xsane.filetype_option_menu), select_item); - gtk_widget_show(xsane.filetype_option_menu); - - xsane_label = gtk_label_new(TEXT_FILETYPE); /* opposite order because of box_pack_end */ - gtk_box_pack_end(GTK_BOX(hbox), xsane_label, FALSE, FALSE, 2); - gtk_widget_show(xsane_label); - - gtk_widget_show(text); - gtk_widget_show(hbox); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -1088,17 +582,8 @@ static void xsane_show_resolution_list_callback(GtkWidget *widget) DBG(DBG_proc, "xsane_show_resolution_list_callback\n"); preferences.show_resolution_list = (GTK_CHECK_MENU_ITEM(widget)->active != 0); - xsane_refresh_dialog(); -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ -static void xsane_page_rotate_callback(GtkWidget *widget) -{ - DBG(DBG_proc, "xsane_page_rotate_callback\n"); - - preferences.psrotate = (GTK_CHECK_MENU_ITEM(widget)->active != 0); - xsane_define_maximum_output_size(); + xsane_refresh_dialog(); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -1141,6 +626,35 @@ static void xsane_show_gamma_callback(GtkWidget *widget) /* ---------------------------------------------------------------------------------------------------------------------- */ +static void xsane_show_batch_scan_callback(GtkWidget * widget) +{ + DBG(DBG_proc, "xsane_show_batch_scan_callback\n"); + + preferences.show_batch_scan = (GTK_CHECK_MENU_ITEM(widget)->active != 0); + if (preferences.show_batch_scan) + { + gtk_widget_show(xsane.batch_scan_dialog); + } + else + { + gtk_widget_hide(xsane.batch_scan_dialog); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_paper_orientation_callback(GtkWidget *widget, gpointer data) +{ + int pos = (int) data; + + DBG(DBG_proc, "xsane_paper_orientation_callback\n"); + + preferences.paper_orientation = pos; + xsane_define_maximum_output_size(); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + static void xsane_printer_callback(GtkWidget *widget, gpointer data) { int printer_resolution; @@ -1182,32 +696,58 @@ static void xsane_printer_callback(GtkWidget *widget, gpointer data) /* ---------------------------------------------------------------------------------------------------------------------- */ -static void xsane_resolution_scale_update(GtkAdjustment *adj_data, double *val) +static gint xsane_resolution_timer_callback(GtkAdjustment *adj) +{ + if ((adj) && (!preferences.show_resolution_list)) /* make sure adjustment is valid */ + { + float val = adj->value; + + adj->value += 1.0; /* we need this to make sure that set_value really redraws the widgets */ + gtk_adjustment_set_value(adj, val); + } + + gtk_timeout_remove(xsane_resolution_timer); + xsane_resolution_timer = 0; + + return 0; /* stop timeout */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_resolution_scale_update(GtkAdjustment *adj, double *val) { int printer_resolution; -#if 1 /* gtk does not make sure that the value is quantisized correct */ float diff, old, new, quant; DBG(DBG_proc, "xsane_resolution_scale_update\n"); - quant = adj_data->step_increment; + quant = adj->step_increment; if (quant != 0) { - new = adj_data->value; + new = adj->value; old = *val; diff = quant*((int) ((new - old)/quant)); *val = old + diff; - adj_data->value = *val; - } -#else - DBG(DBG_proc, "xsane_resolution_scale_update\n"); + adj->value = *val; - *val = adj_data->value; +#ifndef _WIN32 + /* the resolution slider gets almost unusable when we do this with win32 */ + if (xsane_resolution_timer) + { + gtk_timeout_remove(xsane_resolution_timer); + xsane_resolution_timer = 0; + } + xsane_resolution_timer = gtk_timeout_add(XSANE_HOLD_TIME, (GtkFunction) xsane_resolution_timer_callback, (gpointer) adj); #endif + } + else + { + *val = adj->value; + } switch (xsane.param.format) { @@ -1243,9 +783,9 @@ static void xsane_resolution_scale_update(GtkAdjustment *adj_data, double *val) static void xsane_resolution_list_callback(GtkWidget *widget, gpointer data) { - GSGMenuItem *menu_item = data; + MenuItem *menu_item = data; SANE_Word val; - gchar *name = gtk_widget_get_name(widget->parent); + const gchar *name = gtk_widget_get_name(widget->parent); int printer_resolution; DBG(DBG_proc, "xsane_resolution_list_callback\n"); @@ -1367,8 +907,8 @@ static int xsane_resolution_widget_new(GtkWidget *parent, int well_known_option, if (!preferences.show_resolution_list) /* user wants slider */ { - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(parent), image_xpm, desc, - min, max, quant, quant*10, 0, 0, resolution, &resolution_widget, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(parent), image_xpm, desc, + min, max, quant, quant*10, 0, resolution, &resolution_widget, well_known_option, xsane_resolution_scale_update, SANE_OPTION_IS_SETTABLE(opt->cap)); } else /* user wants list instead of slider */ @@ -1466,6 +1006,7 @@ static int xsane_resolution_widget_new(GtkWidget *parent, int well_known_option, } str_list[j] = 0; xsane_control_option(xsane.dev, well_known_option, SANE_ACTION_GET_VALUE, &val, 0); + val = xsane_find_best_resolution(well_known_option, val); /* when backends uses default value not in list or range */ sprintf(str, "%d", (int) val); break; @@ -1477,6 +1018,7 @@ static int xsane_resolution_widget_new(GtkWidget *parent, int well_known_option, } str_list[j] = 0; xsane_control_option(xsane.dev, well_known_option, SANE_ACTION_GET_VALUE, &val, 0); + val = xsane_find_best_resolution(well_known_option, val); /* when backends uses default value not in list or range */ sprintf(str, "%d", (int) SANE_UNFIX(val)); break; @@ -1507,13 +1049,13 @@ static int xsane_resolution_widget_new(GtkWidget *parent, int well_known_option, /* ---------------------------------------------------------------------------------------------------------------------- */ -static void xsane_zoom_update(GtkAdjustment *adj_data, double *val) +static void xsane_zoom_update(GtkAdjustment *adj, double *val) { int printer_resolution; DBG(DBG_proc, "xsane_zoom_update\n"); - *val=adj_data->value; + *val=adj->value; switch (xsane.param.format) { @@ -1634,7 +1176,7 @@ static int xsane_zoom_widget_new(GtkWidget *parent, int well_known_option, doubl *zoom = resolution / printer_resolution; - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(parent), image_xpm, desc, min, max, 0.01, 0.1, 0.1, 2, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(parent), image_xpm, desc, min, max, 0.01, 0.1, 2, zoom, &xsane.zoom_widget, well_known_option, xsane_zoom_update, SANE_OPTION_IS_SETTABLE(opt->cap)); @@ -1647,8 +1189,8 @@ static int xsane_zoom_widget_new(GtkWidget *parent, int well_known_option, doubl static void xsane_scanmode_menu_callback(GtkWidget *widget, gpointer data) { - GSGMenuItem *menu_item = data; - GSGDialogElement *elem = menu_item->elem; + MenuItem *menu_item = data; + DialogElement *elem = menu_item->elem; const SANE_Option_Descriptor *opt; int opt_num; int printer_resolution; @@ -1713,7 +1255,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ GtkWidget *xsane_hbox_xsane_enhancement; GtkWidget *xsane_frame; GtkWidget *button; - gchar buf[200]; + gchar buf[256]; DBG(DBG_proc, "xsane_update_xsane_callback\n"); @@ -1758,41 +1300,35 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_VIEWER); - gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_V, GDK_CONTROL_MASK, GTK_ACCEL_LOCKED); - gtk_widget_lock_accelerators(xsane_modus_item); - gtk_widget_set_usize(xsane_modus_item, 60, 0); + gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_V, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_widget_set_size_request(xsane_modus_item, 60, -1); gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item); - gtk_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", - (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_VIEWER]); + g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_VIEWER]); gtk_widget_show(xsane_modus_item); xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_SAVE); - gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_S, GDK_CONTROL_MASK, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_S, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item); - gtk_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", - (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_SAVE]); + g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_SAVE]); gtk_widget_show(xsane_modus_item); xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_COPY); - gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_C, GDK_CONTROL_MASK, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_C, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item); - gtk_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", - (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_COPY]); + g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_COPY]); gtk_widget_show(xsane_modus_item); xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_FAX); - gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_F, GDK_CONTROL_MASK, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_F, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item); - gtk_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", - (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_FAX]); + g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_FAX]); gtk_widget_show(xsane_modus_item); #ifdef XSANE_ACTIVATE_MAIL xsane_modus_item = gtk_menu_item_new_with_label(MENU_ITEM_MAIL); - gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_M, GDK_CONTROL_MASK, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(xsane_modus_item, "activate", xsane.accelerator_group, GDK_M, GDK_CONTROL_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_container_add(GTK_CONTAINER(xsane_modus_menu), xsane_modus_item); - gtk_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", - (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_MAIL]); + g_signal_connect(GTK_OBJECT(xsane_modus_item), "activate", (GtkSignalFunc) xsane_modus_callback, &xsane_scanmode_number[XSANE_MAIL]); gtk_widget_show(xsane_modus_item); #endif @@ -1828,9 +1364,9 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 2); pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) colormode_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); gtk_widget_show(pixmapwidget); switch (opt->constraint_type) @@ -1868,9 +1404,9 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 2); pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) scanner_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); gtk_widget_show(pixmapwidget); switch (opt->constraint_type) @@ -1904,10 +1440,17 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 2); - pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) medium_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + if (xsane.medium_calibration) + { + pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) medium_edit_xpm); + } + else + { + pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) medium_xpm); + } + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); gtk_widget_show(pixmapwidget); xsane_medium_menu = gtk_menu_new(); @@ -1916,7 +1459,10 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ { xsane_medium_item = gtk_menu_item_new_with_label(preferences.medium[i]->name); gtk_menu_append(GTK_MENU(xsane_medium_menu), xsane_medium_item); - gtk_signal_connect(GTK_OBJECT(xsane_medium_item), "activate", (GtkSignalFunc) xsane_set_medium_callback, (void *)i); + g_signal_connect(GTK_OBJECT(xsane_medium_item), "button_press_event", (GtkSignalFunc) xsane_medium_context_menu_callback, (void *) i); + g_signal_connect(GTK_OBJECT(xsane_medium_item), "activate", (GtkSignalFunc) xsane_set_medium_callback, (void *) i); + gtk_object_set_data(GTK_OBJECT(xsane_medium_item), "Selection", (void *) i); + gtk_widget_show(xsane_medium_item); } @@ -1932,7 +1478,15 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ xsane.medium_widget = xsane_medium_option_menu; - xsane_set_medium(preferences.medium[xsane.medium_nr]); /* set selected medium */ + if (xsane.medium_calibration) /* are we running in medium calibration mode? */ + { + xsane_apply_medium_definition_as_enhancement(preferences.medium[xsane.medium_nr]); + xsane_set_medium(NULL); + } + else + { + xsane_set_medium(preferences.medium[xsane.medium_nr]); + } } else /* no medium selextion for lineart mode: use Full range gamma curve */ { @@ -1971,6 +1525,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ GtkWidget *pixmapwidget, *hbox, *xsane_printer_option_menu, *xsane_printer_menu, *xsane_printer_item; GdkBitmap *mask; GdkPixmap *pixmap; + GtkWidget *paper_orientation_option_menu, *paper_orientation_menu, *paper_orientation_item; int i; hbox = gtk_hbox_new(FALSE, 2); @@ -1978,11 +1533,102 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ gtk_box_pack_start(GTK_BOX(xsane_vbox_xsane_modus), hbox, FALSE, FALSE, 2); pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, (gchar **) printer_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); gtk_widget_show(pixmapwidget); + + /* printer position */ + paper_orientation_menu = gtk_menu_new(); + + for (i = 0; i <= 12; ++i) + { + gchar **xpm_d; + + if (i == 5) /* 5, 6, 7 are not used */ + { + i = 8; + } + + switch (i) + { + /* portrait */ + default: + case 0: + xpm_d = (gchar **) paper_orientation_portrait_top_left_xpm; + break; + + case 1: + xpm_d = (gchar **) paper_orientation_portrait_top_right_xpm; + break; + + case 2: + xpm_d = (gchar **) paper_orientation_portrait_bottom_right_xpm; + break; + + case 3: + xpm_d = (gchar **) paper_orientation_portrait_bottom_left_xpm; + break; + + case 4: + xpm_d = (gchar **) paper_orientation_portrait_center_xpm; + break; + + /* landscape */ + case 8: + xpm_d = (gchar **) paper_orientation_landscape_top_left_xpm; + break; + + case 9: + xpm_d = (gchar **) paper_orientation_landscape_top_right_xpm; + break; + + case 10: + xpm_d = (gchar **) paper_orientation_landscape_bottom_right_xpm; + break; + + case 11: + xpm_d = (gchar **) paper_orientation_landscape_bottom_left_xpm; + break; + + case 12: + xpm_d = (gchar **) paper_orientation_landscape_center_xpm; + break; + } + + paper_orientation_item = gtk_menu_item_new(); + pixmap = gdk_pixmap_create_from_xpm_d(xsane.histogram_dialog->window, &mask, xsane.bg_trans, xpm_d); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); + gtk_container_add(GTK_CONTAINER(paper_orientation_item), pixmapwidget); + gtk_widget_show(pixmapwidget); + gdk_drawable_unref(pixmap); + + + gtk_container_add(GTK_CONTAINER(paper_orientation_menu), paper_orientation_item); + g_signal_connect(GTK_OBJECT(paper_orientation_item), "activate", (GtkSignalFunc) xsane_paper_orientation_callback, (void *) i); + + gtk_widget_show(paper_orientation_item); + } + + paper_orientation_option_menu = gtk_option_menu_new(); + xsane_back_gtk_set_tooltip(xsane.tooltips, paper_orientation_option_menu, DESC_PAPER_ORIENTATION); + gtk_box_pack_end(GTK_BOX(hbox), paper_orientation_option_menu, FALSE, FALSE, 0); + gtk_option_menu_set_menu(GTK_OPTION_MENU(paper_orientation_option_menu), paper_orientation_menu); + + /* set default selection */ + if (preferences.paper_orientation < 8) /* portrai number is correct */ + { + gtk_option_menu_set_history(GTK_OPTION_MENU(paper_orientation_option_menu), preferences.paper_orientation); + } + else /* numbers 5, 6, 7 are unused, so we have to substract 3 for landscape mode */ + { + gtk_option_menu_set_history(GTK_OPTION_MENU(paper_orientation_option_menu), preferences.paper_orientation-3); + } + + gtk_widget_show(paper_orientation_option_menu); + + xsane_printer_menu = gtk_menu_new(); for (i=0; i < preferences.printerdefinitions; i++) @@ -1991,10 +1637,10 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ if (i<12) { gtk_widget_add_accelerator(xsane_printer_item, "activate", xsane.accelerator_group, - GDK_F1+i, GDK_SHIFT_MASK, GTK_ACCEL_LOCKED); + GDK_F1+i, GDK_SHIFT_MASK, DEF_GTK_MENU_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); } gtk_container_add(GTK_CONTAINER(xsane_printer_menu), xsane_printer_item); - gtk_signal_connect(GTK_OBJECT(xsane_printer_item), "activate", (GtkSignalFunc) xsane_printer_callback, (void *) i); + g_signal_connect(GTK_OBJECT(xsane_printer_item), "activate", (GtkSignalFunc) xsane_printer_callback, (void *) i); gtk_widget_show(xsane_printer_item); } @@ -2010,7 +1656,7 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ /* number of copies */ xsane_text = gtk_entry_new(); xsane_back_gtk_set_tooltip(xsane.tooltips, xsane_text, DESC_COPY_NUMBER); - gtk_widget_set_usize(xsane_text, 25, 0); + gtk_widget_set_size_request(xsane_text, 25, -1); snprintf(buf, sizeof(buf), "%d", xsane.copy_number); gtk_entry_set_text(GTK_ENTRY(xsane_text), (char *) buf); gtk_box_pack_end(GTK_BOX(hbox), xsane_text, FALSE, FALSE, 10); @@ -2107,8 +1753,8 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ case XSANE_LINEART_XSANE: if (xsane.well_known.threshold > 0) { - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), threshold_xpm, DESC_THRESHOLD, - xsane.threshold_min, xsane.threshold_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), threshold_xpm, DESC_THRESHOLD, + xsane.threshold_min, xsane.threshold_max, 1.0, 10.0, 0, &xsane.threshold, &xsane.threshold_widget, 0, xsane_gamma_changed, TRUE); xsane_threshold_changed(); } @@ -2128,55 +1774,55 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ xsane_separator_new(xsane_vbox_xsane_modus, 2); } - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), Gamma_xpm, DESC_GAMMA, - XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.1, 0.0, 2, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), Gamma_xpm, DESC_GAMMA, + XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.1, 2, &xsane.gamma, &xsane.gamma_widget, 0, xsane_gamma_changed, TRUE); if ( (xsane.xsane_colors > 1) && (!xsane.enhancement_rgb_default) ) { - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), Gamma_red_xpm, DESC_GAMMA_R, - XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.1, 0.0, 2, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), Gamma_red_xpm, DESC_GAMMA_R, + XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.1, 2, &xsane.gamma_red , &xsane.gamma_red_widget, 0, xsane_gamma_changed, TRUE); - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), Gamma_green_xpm, DESC_GAMMA_G, - XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.1, 0.0, 2, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), Gamma_green_xpm, DESC_GAMMA_G, + XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.1, 2, &xsane.gamma_green, &xsane.gamma_green_widget, 0, xsane_gamma_changed, TRUE); - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), Gamma_blue_xpm, DESC_GAMMA_B, - XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.1, 0.0, 2, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), Gamma_blue_xpm, DESC_GAMMA_B, + XSANE_GAMMA_MIN, XSANE_GAMMA_MAX, 0.01, 0.1, 2, &xsane.gamma_blue , &xsane.gamma_blue_widget, 0, xsane_gamma_changed, TRUE); xsane_separator_new(xsane_vbox_xsane_modus, 2); } - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), brightness_xpm, DESC_BRIGHTNESS, - xsane.brightness_min, xsane.brightness_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), brightness_xpm, DESC_BRIGHTNESS, + xsane.brightness_min, xsane.brightness_max, 0.1, 1.0, 1, &xsane.brightness, &xsane.brightness_widget, 0, xsane_gamma_changed, TRUE); if ( (xsane.xsane_colors > 1) && (!xsane.enhancement_rgb_default) ) { - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), brightness_red_xpm, DESC_BRIGHTNESS_R, - xsane.brightness_min, xsane.brightness_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), brightness_red_xpm, DESC_BRIGHTNESS_R, + xsane.brightness_min, xsane.brightness_max, 0.1, 1.0, 1, &xsane.brightness_red , &xsane.brightness_red_widget, 0, xsane_gamma_changed, TRUE); - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), brightness_green_xpm, DESC_BRIGHTNESS_G, - xsane.brightness_min, xsane.brightness_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), brightness_green_xpm, DESC_BRIGHTNESS_G, + xsane.brightness_min, xsane.brightness_max, 0.1, 1.0, 1, &xsane.brightness_green, &xsane.brightness_green_widget, 0, xsane_gamma_changed, TRUE); - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), brightness_blue_xpm, DESC_BRIGHTNESS_B, - xsane.brightness_min, xsane.brightness_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), brightness_blue_xpm, DESC_BRIGHTNESS_B, + xsane.brightness_min, xsane.brightness_max, 0.1, 1.0, 1, &xsane.brightness_blue, &xsane.brightness_blue_widget, 0, xsane_gamma_changed, TRUE); xsane_separator_new(xsane_vbox_xsane_modus, 2); } - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), contrast_xpm, DESC_CONTRAST, - xsane.contrast_gray_min, xsane.contrast_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), contrast_xpm, DESC_CONTRAST, + xsane.contrast_gray_min, xsane.contrast_max, 0.1, 1.0, 1, &xsane.contrast, &xsane.contrast_widget, 0, xsane_gamma_changed, TRUE); if ( (xsane.xsane_colors > 1) && (!xsane.enhancement_rgb_default) ) { - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), contrast_red_xpm, DESC_CONTRAST_R, - xsane.contrast_min, xsane.contrast_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), contrast_red_xpm, DESC_CONTRAST_R, + xsane.contrast_min, xsane.contrast_max, 0.1, 1.0, 1, &xsane.contrast_red , &xsane.contrast_red_widget, 0, xsane_gamma_changed, TRUE); - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), contrast_green_xpm, DESC_CONTRAST_G, - xsane.contrast_min, xsane.contrast_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), contrast_green_xpm, DESC_CONTRAST_G, + xsane.contrast_min, xsane.contrast_max, 0.1, 1.0, 1, &xsane.contrast_green, &xsane.contrast_green_widget, 0, xsane_gamma_changed, TRUE); - xsane_scale_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), contrast_blue_xpm, DESC_CONTRAST_B, - xsane.contrast_min, xsane.contrast_max, 1.0, 10.0, 0.0, 0, + xsane_range_new_with_pixmap(xsane.xsane_window->window, GTK_BOX(xsane_vbox_xsane_modus), contrast_blue_xpm, DESC_CONTRAST_B, + xsane.contrast_min, xsane.contrast_max, 0.1, 1.0, 1, &xsane.contrast_blue, &xsane.contrast_blue_widget, 0, xsane_gamma_changed, TRUE); } @@ -2192,36 +1838,31 @@ GtkWidget *xsane_update_xsane_callback() /* creates the XSane option window */ { button = xsane_toggle_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, rgb_default_xpm, DESC_RGB_DEFAULT, &xsane.enhancement_rgb_default, xsane_enhancement_rgb_default_callback); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_B, GDK_SHIFT_MASK, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_B, GDK_CONTROL_MASK, DEF_GTK_ACCEL_LOCKED); } button = xsane_toggle_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, negative_xpm, DESC_NEGATIVE, &xsane.negative, xsane_enhancement_negative_callback); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_N, GDK_SHIFT_MASK, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_N, GDK_CONTROL_MASK, DEF_GTK_ACCEL_LOCKED); button = xsane_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, enhance_xpm, DESC_ENH_AUTO, xsane_auto_enhancement_callback, NULL); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_E, GDK_SHIFT_MASK, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_E, GDK_CONTROL_MASK, DEF_GTK_ACCEL_LOCKED); button = xsane_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, default_enhancement_xpm, DESC_ENH_DEFAULT, xsane_enhancement_restore_default, NULL); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_D, GDK_SHIFT_MASK, GTK_ACCEL_LOCKED); - - button = xsane_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, restore_enhancement_xpm, DESC_ENH_RESTORE, - xsane_enhancement_restore, NULL); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_R, GDK_SHIFT_MASK, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_0, GDK_CONTROL_MASK, DEF_GTK_ACCEL_LOCKED); - button = xsane_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, store_enhancement_xpm, DESC_ENH_STORE, - xsane_enhancement_store, NULL); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_M, GDK_SHIFT_MASK, GTK_ACCEL_LOCKED); - if (xsane.medium_calibration) /* are we running in medium calibration mode? */ + if (!xsane.medium_calibration) /* do not display "M R" when we are we running in medium calibration mode */ { - button = xsane_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, medium_xpm, DESC_STORE_MEDIUM, - xsane_add_medium_definition_callback, NULL); + button = xsane_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, restore_enhancement_xpm, DESC_ENH_RESTORE, + xsane_enhancement_restore, NULL); + gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_R, GDK_CONTROL_MASK, DEF_GTK_ACCEL_LOCKED); - button = xsane_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, medium_delete_xpm, DESC_DELETE_MEDIUM, - xsane_delete_medium_definition_callback, NULL); + button = xsane_button_new_with_pixmap(xsane.xsane_window->window, xsane_hbox_xsane_enhancement, store_enhancement_xpm, DESC_ENH_STORE, + xsane_enhancement_store, NULL); + gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_plus, GDK_CONTROL_MASK, DEF_GTK_ACCEL_LOCKED); } xsane_update_histogram(TRUE /* update raw */); @@ -2321,33 +1962,6 @@ static int xsane_pref_restore(void) } } - if (!preferences.medium_definitions) - { - DBG(DBG_info, "no medium definitions in preferences file, using predefined list\n"); - - preferences.medium_definitions = sizeof(pref_default_medium)/sizeof(Preferences_medium_t); - preferences.medium = calloc(preferences.medium_definitions, sizeof(void *)); - - for (i=0; iname = strdup(_(pref_default_medium[i].name)); - preferences.medium[i]->shadow_gray = pref_default_medium[i].shadow_gray; - preferences.medium[i]->shadow_red = pref_default_medium[i].shadow_red; - preferences.medium[i]->shadow_green = pref_default_medium[i].shadow_green; - preferences.medium[i]->shadow_blue = pref_default_medium[i].shadow_blue; - preferences.medium[i]->highlight_gray = pref_default_medium[i].highlight_gray; - preferences.medium[i]->highlight_red = pref_default_medium[i].highlight_red; - preferences.medium[i]->highlight_green = pref_default_medium[i].highlight_green; - preferences.medium[i]->highlight_blue = pref_default_medium[i].highlight_blue; - preferences.medium[i]->gamma_gray = pref_default_medium[i].gamma_gray; - preferences.medium[i]->gamma_red = pref_default_medium[i].gamma_red; - preferences.medium[i]->gamma_green = pref_default_medium[i].gamma_green; - preferences.medium[i]->gamma_blue = pref_default_medium[i].gamma_blue; - preferences.medium[i]->negative = pref_default_medium[i].negative; - } - } - if (preferences.xsane_version_str) { free(preferences.xsane_version_str); @@ -2369,11 +1983,30 @@ static int xsane_pref_restore(void) } } + if (!preferences.working_directory) + { + char filename[PATH_MAX]; + + if (getcwd(filename, sizeof(filename))) + { + preferences.working_directory = strdup(filename); /* set current working directory */ + } + } + else + { + chdir(preferences.working_directory); /* set working directory */ + } + if (!preferences.filename) { preferences.filename = strdup(OUT_FILENAME); } + if (!preferences.filetype) + { + preferences.filetype = strdup(XSANE_FILETYPE_BY_EXT); + } + if (preferences.printerdefinitions == 0) { xsane_new_printer(); @@ -2414,7 +2047,6 @@ static int xsane_pref_restore(void) preferences.fax_viewer = strdup(FAXVIEWER); } - #ifdef XSANE_ACTIVATE_MAIL if (!preferences.mail_smtp_server) { @@ -2431,53 +2063,151 @@ static int xsane_pref_restore(void) preferences.mail_reply_to = strdup(""); } - if (!preferences.mail_pop3_server) - { - preferences.mail_pop3_server = strdup(""); - } + if (!preferences.mail_pop3_server) + { + preferences.mail_pop3_server = strdup(""); + } + + if (!preferences.mail_pop3_user) + { + preferences.mail_pop3_user = strdup(""); + } + + if (!preferences.mail_pop3_pass) + { + preferences.mail_pop3_pass = strdup(""); + } + + if (!preferences.mail_project) + { + preferences.mail_project = strdup(MAILPROJECT); + } + + if (!preferences.mail_viewer) + { + preferences.mail_viewer = strdup(MAILVIEWER); + } + + if (!preferences.mail_filetype) + { + preferences.mail_filetype = strdup(XSANE_DEFAULT_MAILTYPE); + } +#endif + + if (!preferences.ocr_command) + { + preferences.ocr_command = strdup(OCRCOMMAND); + } + + if (!preferences.ocr_inputfile_option) + { + preferences.ocr_inputfile_option = strdup(OCRINPUTFILEOPT); + } + + if (!preferences.ocr_outputfile_option) + { + preferences.ocr_outputfile_option = strdup(OCROUTPUTFILEOPT); + } + + if (!preferences.ocr_gui_outfd_option) + { + preferences.ocr_gui_outfd_option = strdup(OCROUTFDOPT); + } + + if (!preferences.ocr_progress_keyword) + { + preferences.ocr_progress_keyword = strdup(OCRPROGRESSKEY); + } + + if (!preferences.browser) + { + if (getenv(STRINGIFY(ENVIRONMENT_BROWSER_NAME))) + { + preferences.browser = getenv(STRINGIFY(ENVIRONMENT_BROWSER_NAME)); + } + else + { + preferences.browser = strdup(DEFAULT_BROWSER); + } + } + + return result; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_pref_save_media(void) +{ + char filename[PATH_MAX]; + int fd; + + DBG(DBG_proc, "xsane_pref_save_media\n"); + + xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", NULL, "xsane", NULL, ".mdf", XSANE_PATH_LOCAL_SANE); + + DBG(DBG_info2, "saving media to \"%s\"\n", filename); + + umask(XSANE_DEFAULT_UMASK); /* define new file permissions */ + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); /* rw- --- --- */ - if (!preferences.mail_pop3_user) + if (fd < 0) { - preferences.mail_pop3_user = strdup(""); - } + char buf[256]; - if (!preferences.mail_pop3_pass) - { - preferences.mail_pop3_pass = strdup(""); + snprintf(buf, sizeof(buf), "%s %s.", ERR_FAILED_CREATE_FILE, strerror(errno)); + xsane_back_gtk_error(buf, TRUE); + return; } + preferences_save_media(fd); + close(fd); +} +/* ---------------------------------------------------------------------------------------------------------------------- */ - if (!preferences.mail_project) - { - preferences.mail_project = strdup(MAILPROJECT); - } +static void xsane_pref_restore_media(void) +{ + char filename[PATH_MAX]; + int fd; + int i; - if (!preferences.mail_viewer) - { - preferences.mail_viewer = strdup(MAILVIEWER); - } -#endif + DBG(DBG_proc, "xsane_pref_restore_media\n"); - if (!preferences.ocr_command) - { - preferences.ocr_command = strdup(OCRCOMMAND); - } + preferences.medium_definitions = 0; - if (!preferences.ocr_inputfile_option) - { - preferences.ocr_inputfile_option = strdup(OCRINPUTFILEOPT); - } + xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", NULL, "xsane", NULL, ".mdf", XSANE_PATH_LOCAL_SANE); + fd = open(filename, O_RDONLY); - if (!preferences.ocr_outputfile_option) + if (fd >= 0) { - preferences.ocr_outputfile_option = strdup(OCROUTPUTFILEOPT); + preferences_restore_media(fd); + close(fd); } - if (!preferences.doc_viewer) + if (!preferences.medium_definitions) { - preferences.doc_viewer = strdup(DOCVIEWER); + DBG(DBG_info, "no medium definitions found, using predefined list\n"); + + preferences.medium_definitions = sizeof(pref_default_medium)/sizeof(Preferences_medium_t); + preferences.medium = calloc(preferences.medium_definitions, sizeof(void *)); + + for (i=0; iname = strdup(_(pref_default_medium[i].name)); + preferences.medium[i]->shadow_gray = pref_default_medium[i].shadow_gray; + preferences.medium[i]->shadow_red = pref_default_medium[i].shadow_red; + preferences.medium[i]->shadow_green = pref_default_medium[i].shadow_green; + preferences.medium[i]->shadow_blue = pref_default_medium[i].shadow_blue; + preferences.medium[i]->highlight_gray = pref_default_medium[i].highlight_gray; + preferences.medium[i]->highlight_red = pref_default_medium[i].highlight_red; + preferences.medium[i]->highlight_green = pref_default_medium[i].highlight_green; + preferences.medium[i]->highlight_blue = pref_default_medium[i].highlight_blue; + preferences.medium[i]->gamma_gray = pref_default_medium[i].gamma_gray; + preferences.medium[i]->gamma_red = pref_default_medium[i].gamma_red; + preferences.medium[i]->gamma_green = pref_default_medium[i].gamma_green; + preferences.medium[i]->gamma_blue = pref_default_medium[i].gamma_blue; + preferences.medium[i]->negative = pref_default_medium[i].negative; + } } - - return result; } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -2489,6 +2219,60 @@ static RETSIGTYPE xsane_quit_handler(int signal) xsane_quit(); } +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_add_process_to_list(pid_t pid) +{ + XsaneChildprocess *newprocess; + + DBG(DBG_proc, "xsane_add_process_to_list(%d)\n", pid); + + newprocess = malloc(sizeof(XsaneChildprocess)); + newprocess->pid = pid; + newprocess->next = xsane.childprocess_list; + xsane.childprocess_list = newprocess; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static RETSIGTYPE xsane_sigchld_handler(int signal) +{ + int status; + XsaneChildprocess **childprocess_listptr = &xsane.childprocess_list; + XsaneChildprocess *childprocess = xsane.childprocess_list; + + DBG(DBG_proc, "xsane_sigchld_handler\n"); + + /* normally we would do a wait(&status); here, but some backends fork() a reader + process and test the return status of waitpid() that returns with an error + when we get the signal at first and clean up the process with wait(). + A backend should not handle this as error but some do and so we have to handle this */ + + while (childprocess) + { + XsaneChildprocess *nextprocess; + pid_t pid; + + pid = waitpid(childprocess->pid, &status, WNOHANG); + if ( (WIFEXITED(status)) && (pid == childprocess->pid) ) + { + DBG(DBG_info, "deleteing pid %d from list\n", childprocess->pid); + + nextprocess = childprocess->next; + free(childprocess); /* free memory of element */ + childprocess = nextprocess; /* go to next element */ + *childprocess_listptr = childprocess; /* remove element from list */ + /* childprocess_listptr keeps the same !!! */ + } + else + { + DBG(DBG_info, "keeping pid %d in list\n", childprocess->pid); + + childprocess_listptr = &childprocess->next; /* set pointer to next element */ + childprocess = childprocess->next; /* go to next element */ + } + } +} /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -2548,7 +2332,7 @@ static void xsane_quit(void) xsane.preview_gamma_data_blue = 0; } -#ifdef HAVE_LIBGIMP_GIMP_H +#ifdef HAVE_ANY_GIMP if (xsane.mode == XSANE_GIMP_EXTENSION) { gimp_quit(); @@ -2577,7 +2361,7 @@ static void xsane_exit(void) /* this is called when xsane exits before gtk_main sane_exit(); -#ifdef HAVE_LIBGIMP_GIMP_H +#ifdef HAVE_ANY_GIMP if (xsane.mode == XSANE_GIMP_EXTENSION) { gimp_quit(); @@ -2642,18 +2426,8 @@ static gint xsane_scan_win_delete(GtkWidget *w, gpointer data) } } - if (xsane.filetype) /* add extension to filename */ - { - char buffer[256]; - - snprintf(buffer, sizeof(buffer), "%s%s", preferences.filename, xsane.filetype); - free(preferences.filename); - free(xsane.filetype); - xsane.filetype = 0; - preferences.filename = strdup(buffer); - } - xsane_pref_save(); + xsane_pref_save_media(); if (preferences.save_devprefs_at_exit) { @@ -2703,23 +2477,23 @@ static GtkWidget *xsane_files_build_menu(void) DBG(DBG_proc, "xsane_files_build_menu\n"); menu = gtk_menu_new(); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(menu)); + gtk_menu_set_accel_group(GTK_MENU(menu), xsane.accelerator_group); /* XSane info dialog */ item = gtk_menu_item_new_with_label(MENU_ITEM_INFO); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_I, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_I, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_info_dialog, NULL); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_info_dialog, NULL); gtk_widget_show(item); /* Quit */ item = gtk_menu_item_new_with_label(MENU_ITEM_QUIT); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_Q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_Q, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_container_add(GTK_CONTAINER(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_scan_win_delete, NULL); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_scan_win_delete, NULL); gtk_widget_show(item); return menu; @@ -2727,6 +2501,334 @@ static GtkWidget *xsane_files_build_menu(void) /* ---------------------------------------------------------------------------------------------------------------------- */ +static gint xsane_medium_move_up_callback(GtkWidget *widget, GtkWidget *medium_widget) +{ + int selection; + + DBG(DBG_proc, "xsane_medium_move_up_callback\n"); + + selection = (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); + + if (selection > 1) /* make sure "full range" stays at top */ + { + Preferences_medium_t *help_medium; + + DBG(DBG_info ,"moving up %s\n", preferences.medium[selection]->name); + + help_medium = preferences.medium[selection-1]; + preferences.medium[selection-1] = preferences.medium[selection]; + preferences.medium[selection] = help_medium; + + if (xsane.medium_nr == selection) + { + xsane.medium_nr--; + } + else if (xsane.medium_nr == selection-1) + { + xsane.medium_nr++; + } + + xsane_back_gtk_refresh_dialog(); /* brute-force: update menu */ + } + + return TRUE; /* event is handled */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static gint xsane_medium_move_down_callback(GtkWidget *widget, GtkWidget *medium_widget) +{ + int selection; + + DBG(DBG_proc, "xsane_medium_move_up_callback\n"); + + selection = (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); + + if ((selection) && (selection < preferences.medium_definitions-1)) + { + Preferences_medium_t *help_medium; + + DBG(DBG_info ,"moving down %s\n", preferences.medium[selection]->name); + + help_medium = preferences.medium[selection]; + preferences.medium[selection] = preferences.medium[selection+1]; + preferences.medium[selection+1] = help_medium; + + if (xsane.medium_nr == selection) + { + xsane.medium_nr++; + } + else if (xsane.medium_nr == selection+1) + { + xsane.medium_nr--; + } + + xsane_back_gtk_refresh_dialog(); /* brute-force: update menu */ + } + + return TRUE; /* event is handled */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static gint xsane_medium_rename_callback(GtkWidget *widget, GtkWidget *medium_widget) +{ + int selection; + char *oldname; + char *newname; + GtkWidget *old_medium_menu; + int old_selection; + + DBG(DBG_proc, "xsane_medium_rename_callback\n"); + + selection = (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); + + oldname = strdup(preferences.medium[selection]->name); + + DBG(DBG_info ,"rename %s\n", oldname); + + /* set menu in correct state, is a bit strange this way but I do not have a better idea */ + old_medium_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(xsane.medium_widget)); + old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_medium_menu))), "Selection"); + gtk_menu_popdown(GTK_MENU(old_medium_menu)); + gtk_option_menu_set_history(GTK_OPTION_MENU(xsane.medium_widget), old_selection); + + if (!xsane_front_gtk_getname_dialog(WINDOW_MEDIUM_RENAME, DESC_MEDIUM_RENAME, oldname, &newname)) + { + free(preferences.medium[selection]->name); + preferences.medium[selection]->name = strdup(newname); + DBG(DBG_info, "renaming %s to %s\n", oldname, newname); + + xsane_back_gtk_refresh_dialog(); /* update menu */ + } + + free(oldname); + free(newname); + + xsane_set_sensitivity(TRUE); + + return TRUE; /* event is handled */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static gint xsane_medium_add_callback(GtkWidget *widget, GtkWidget *medium_widget) +{ + int selection; + char *oldname; + char *newname; + GtkWidget *old_medium_menu; + int old_selection; + int i; + + DBG(DBG_proc, "xsane_medium_add_callback\n"); + + /* add new item after selected item */ + selection = 1 + (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); + + oldname = strdup(TEXT_NEW_MEDIA_NAME); + + /* set menu in correct state, is a bit strange this way but I do not have a better idea */ + old_medium_menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(xsane.medium_widget)); + old_selection = (int) gtk_object_get_data(GTK_OBJECT(gtk_menu_get_active(GTK_MENU(old_medium_menu))), "Selection"); + gtk_menu_popdown(GTK_MENU(old_medium_menu)); + gtk_option_menu_set_history(GTK_OPTION_MENU(xsane.medium_widget), old_selection); + + if (!xsane_front_gtk_getname_dialog(WINDOW_MEDIUM_ADD, DESC_MEDIUM_ADD, oldname, &newname)) + { + preferences.medium_definitions++; + preferences.medium = realloc(preferences.medium, preferences.medium_definitions * sizeof(void *)); + + for (i = preferences.medium_definitions-1; i > selection; i--) + { + preferences.medium[i] = preferences.medium[i-1]; + } + + DBG(DBG_info, "adding new media %s\n", newname); + + if (xsane.negative) + { + preferences.medium[selection] = calloc(sizeof(Preferences_medium_t), 1); + preferences.medium[selection]->name = strdup(newname); + preferences.medium[selection]->shadow_gray = 100.0 - xsane.slider_gray.value[2]; + preferences.medium[selection]->shadow_red = 100.0 - xsane.slider_red.value[2]; + preferences.medium[selection]->shadow_green = 100.0 - xsane.slider_green.value[2]; + preferences.medium[selection]->shadow_blue = 100.0 - xsane.slider_blue.value[2]; + preferences.medium[selection]->highlight_gray = 100.0 - xsane.slider_gray.value[0]; + preferences.medium[selection]->highlight_red = 100.0 - xsane.slider_red.value[0]; + preferences.medium[selection]->highlight_green = 100.0 - xsane.slider_green.value[0]; + preferences.medium[selection]->highlight_blue = 100.0 - xsane.slider_blue.value[0]; + preferences.medium[selection]->gamma_gray = xsane.gamma; + preferences.medium[selection]->gamma_red = xsane.gamma * xsane.gamma_red; + preferences.medium[selection]->gamma_green = xsane.gamma * xsane.gamma_green; + preferences.medium[selection]->gamma_blue = xsane.gamma * xsane.gamma_blue; + preferences.medium[selection]->negative = xsane.negative; + } + else + { + preferences.medium[selection] = calloc(sizeof(Preferences_medium_t), 1); + preferences.medium[selection]->name = strdup(newname); + preferences.medium[selection]->shadow_gray = xsane.slider_gray.value[0]; + preferences.medium[selection]->shadow_red = xsane.slider_red.value[0]; + preferences.medium[selection]->shadow_green = xsane.slider_green.value[0]; + preferences.medium[selection]->shadow_blue = xsane.slider_blue.value[0]; + preferences.medium[selection]->highlight_gray = xsane.slider_gray.value[2]; + preferences.medium[selection]->highlight_red = xsane.slider_red.value[2]; + preferences.medium[selection]->highlight_green = xsane.slider_green.value[2]; + preferences.medium[selection]->highlight_blue = xsane.slider_blue.value[2]; + preferences.medium[selection]->gamma_gray = xsane.gamma; + preferences.medium[selection]->gamma_red = xsane.gamma * xsane.gamma_red; + preferences.medium[selection]->gamma_green = xsane.gamma * xsane.gamma_green; + preferences.medium[selection]->gamma_blue = xsane.gamma * xsane.gamma_blue; + preferences.medium[selection]->negative = xsane.negative; + } + + xsane.medium_nr = selection; /* activate new created medium */ + + xsane_back_gtk_refresh_dialog(); /* update menu */ + xsane_enhancement_by_gamma(); /* update sliders */ + } + + free(oldname); + free(newname); + + xsane_set_sensitivity(TRUE); + + return TRUE; /* event is handled */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static gint xsane_medium_delete_callback(GtkWidget *widget, GtkWidget *medium_widget) +{ + int selection, i; + + DBG(DBG_proc, "xsane_medium_delete_callback\n"); + + selection = (int) gtk_object_get_data(GTK_OBJECT(medium_widget), "Selection"); + + if (selection) /* full range can not be deleted */ + { + DBG(DBG_info ,"deleting %s\n", preferences.medium[selection]->name); + + free(preferences.medium[selection]); + + preferences.medium_definitions--; + + for (i = selection; i < preferences.medium_definitions; i++) + { + preferences.medium[i] = preferences.medium[i+1]; + } + + if (xsane.medium_nr == selection) + { + xsane.medium_nr--; + xsane.medium_changed = TRUE; + + if (xsane.medium_calibration) /* are we running in medium calibration mode? */ + { + xsane_apply_medium_definition_as_enhancement(preferences.medium[xsane.medium_nr]); + xsane_set_medium(NULL); + } + else + { + xsane_set_medium(preferences.medium[xsane.medium_nr]); + } + + xsane_enhancement_by_gamma(); /* update sliders */ + } + + xsane_back_gtk_refresh_dialog(); /* update menu */ + + xsane_update_gamma_curve(TRUE); /* if necessary update preview gamma */ + + preview_display_valid(xsane.preview); /* update valid status of preview image */ + /* the valid status depends on gamma handling an medium change */ + } + + return TRUE; /* event is handled */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static gint xsane_medium_context_menu_callback(GtkWidget *widget, GdkEvent *event) +{ + GtkWidget *menu; + GtkWidget *menu_item; + GdkEventButton *event_button; + int selection; + + DBG(DBG_proc, "xsane_medium_context_menu_callback\n"); + + selection = (int) gtk_object_get_data(GTK_OBJECT(widget), "Selection"); + + if (event->type == GDK_BUTTON_PRESS) + { + event_button = (GdkEventButton *) event; + + if (event_button->button == 3) + { + char buf[256]; + + menu = gtk_menu_new(); + + if (xsane.medium_calibration) /* are we running in medium calibration mode? */ + { + /* add medium */ + menu_item = gtk_menu_item_new_with_label(MENU_ITEM_MEDIUM_ADD); + gtk_widget_show(menu_item); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + g_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) xsane_medium_add_callback, widget); + } + + /* rename medium */ + snprintf(buf, sizeof(buf), "%s: %s", preferences.medium[selection]->name, MENU_ITEM_RENAME); + menu_item = gtk_menu_item_new_with_label(buf); + gtk_widget_show(menu_item); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + g_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) xsane_medium_rename_callback, widget); + + if (selection) /* not available for "full area" */ + { + /* delete medium */ + snprintf(buf, sizeof(buf), "%s: %s", preferences.medium[selection]->name, MENU_ITEM_DELETE); + menu_item = gtk_menu_item_new_with_label(buf); + gtk_widget_show(menu_item); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + g_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) xsane_medium_delete_callback, widget); + } + + if (selection>1) /* available from 3rd item */ + { + /* move up */ + snprintf(buf, sizeof(buf), "%s: %s", preferences.medium[selection]->name, MENU_ITEM_MOVE_UP); + menu_item = gtk_menu_item_new_with_label(buf); + gtk_widget_show(menu_item); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + g_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) xsane_medium_move_up_callback, widget); + } + + if ((selection) && (selection < preferences.medium_definitions-1)) + { + /* move down */ + snprintf(buf, sizeof(buf), "%s: %s", preferences.medium[selection]->name, MENU_ITEM_MOVE_DWN); + menu_item = gtk_menu_item_new_with_label(buf); + gtk_widget_show(menu_item); + gtk_container_add(GTK_CONTAINER(menu), menu_item); + g_signal_connect(GTK_OBJECT(menu_item), "activate", (GtkSignalFunc) xsane_medium_move_down_callback, widget); + } + + gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, event_button->button, event_button->time); + + return TRUE; /* event is handled */ + } + } + + return FALSE; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + static void xsane_set_medium_callback(GtkWidget *widget, gpointer data) { int medium_nr = (int) data; @@ -2738,7 +2840,18 @@ static void xsane_set_medium_callback(GtkWidget *widget, gpointer data) xsane.medium_nr = medium_nr; - xsane_set_medium(preferences.medium[medium_nr]); + if (xsane.medium_calibration) /* are we running in medium calibration mode? */ + { + xsane_apply_medium_definition_as_enhancement(preferences.medium[xsane.medium_nr]); + xsane_set_medium(NULL); + } + else + { + xsane_set_medium(preferences.medium[xsane.medium_nr]); + } + + xsane_enhancement_by_gamma(); /* update sliders */ + xsane_back_gtk_refresh_dialog(); /* update menu */ xsane_update_gamma_curve(TRUE); /* if necessary update preview gamma */ @@ -2755,9 +2868,9 @@ static void xsane_set_pref_unit_callback(GtkWidget *widget, gpointer data) DBG(DBG_proc, "xsane_set_pref_unit_callback\n"); - gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.length_unit_mm), (GtkSignalFunc) xsane_set_pref_unit_callback, "mm"); - gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.length_unit_cm), (GtkSignalFunc) xsane_set_pref_unit_callback, "cm"); - gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.length_unit_in), (GtkSignalFunc) xsane_set_pref_unit_callback, "in"); + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.length_unit_mm), (GtkSignalFunc) xsane_set_pref_unit_callback, "mm"); + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.length_unit_cm), (GtkSignalFunc) xsane_set_pref_unit_callback, "cm"); + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.length_unit_in), (GtkSignalFunc) xsane_set_pref_unit_callback, "in"); if (strcmp(unit, "mm") == 0) { @@ -2780,19 +2893,67 @@ static void xsane_set_pref_unit_callback(GtkWidget *widget, gpointer data) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.length_unit_in), TRUE); } - gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.length_unit_mm), (GtkSignalFunc) xsane_set_pref_unit_callback, "mm"); - gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.length_unit_cm), (GtkSignalFunc) xsane_set_pref_unit_callback, "cm"); - gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.length_unit_in), (GtkSignalFunc) xsane_set_pref_unit_callback, "in"); + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.length_unit_mm), (GtkSignalFunc) xsane_set_pref_unit_callback, "mm"); + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.length_unit_cm), (GtkSignalFunc) xsane_set_pref_unit_callback, "cm"); + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.length_unit_in), (GtkSignalFunc) xsane_set_pref_unit_callback, "in"); + + preferences.length_unit = unit_conversion_factor; + + xsane_refresh_dialog(); + + if (xsane.preview) + { + preview_area_resize(xsane.preview); /* redraw rulers */ + } + + xsane_batch_scan_update_label_list(); /* update units in batch scan list */ + + xsane_pref_save(); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_edit_medium_definition_callback(GtkWidget *widget, gpointer data) +{ + DBG(DBG_proc, "xsane_edit_medium_definition_callback\n"); + + if (GTK_CHECK_MENU_ITEM(widget)->active) /* enable edit mode */ + { + DBG(DBG_info2, "enabling edit mode\n"); - preferences.length_unit = unit_conversion_factor; + xsane.medium_calibration = TRUE; + xsane.no_preview_medium_gamma = TRUE; - xsane_refresh_dialog(); - if (xsane.preview) + xsane.brightness_min = XSANE_MEDIUM_CALIB_BRIGHTNESS_MIN; + xsane.brightness_max = XSANE_MEDIUM_CALIB_BRIGHTNESS_MAX; + xsane.contrast_gray_min = XSANE_CONTRAST_GRAY_MIN; + xsane.contrast_min = XSANE_MEDIUM_CALIB_CONTRAST_MIN; + xsane.contrast_max = XSANE_MEDIUM_CALIB_CONTRAST_MAX; + + xsane_apply_medium_definition_as_enhancement(preferences.medium[xsane.medium_nr]); + xsane_set_medium(NULL); + } + else /* disable edit mode */ { - preview_area_resize(xsane.preview); /* redraw rulers */ + DBG(DBG_info2, "disabling edit mode\n"); + + xsane.medium_calibration = FALSE; + xsane.no_preview_medium_gamma = FALSE; + + xsane.brightness_min = XSANE_BRIGHTNESS_MIN; + xsane.brightness_max = XSANE_BRIGHTNESS_MAX; + xsane.contrast_gray_min = XSANE_CONTRAST_GRAY_MIN; + xsane.contrast_min = XSANE_CONTRAST_MIN; + xsane.contrast_max = XSANE_CONTRAST_MAX; + + xsane_apply_medium_definition_as_enhancement(preferences.medium[0]); + xsane_set_medium(preferences.medium[xsane.medium_nr]); } - xsane_pref_save(); + xsane_enhancement_by_gamma(); /* update sliders */ + xsane_back_gtk_refresh_dialog(); /* update dialog */ + + xsane_update_gamma_curve(TRUE); /* if necessary update preview gamma */ } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -2803,11 +2964,11 @@ static void xsane_set_update_policy_callback(GtkWidget *widget, gpointer data) DBG(DBG_proc, "xsane_set_update_policy_callback\n"); - gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.update_policy_continu), (GtkSignalFunc) xsane_set_update_policy_callback, + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.update_policy_continu), (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_CONTINUOUS); - gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.update_policy_discont), (GtkSignalFunc) xsane_set_update_policy_callback, + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.update_policy_discont), (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DISCONTINUOUS); - gtk_signal_handler_block_by_func(GTK_OBJECT(xsane.update_policy_delayed), (GtkSignalFunc) xsane_set_update_policy_callback, + g_signal_handlers_block_by_func(GTK_OBJECT(xsane.update_policy_delayed), (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DELAYED); if (policy == GTK_UPDATE_CONTINUOUS) @@ -2829,11 +2990,11 @@ static void xsane_set_update_policy_callback(GtkWidget *widget, gpointer data) gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.update_policy_delayed), TRUE); } - gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.update_policy_continu), (GtkSignalFunc) xsane_set_update_policy_callback, + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.update_policy_continu), (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_CONTINUOUS); - gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.update_policy_discont), (GtkSignalFunc) xsane_set_update_policy_callback, + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.update_policy_discont), (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DISCONTINUOUS); - gtk_signal_handler_unblock_by_func(GTK_OBJECT(xsane.update_policy_delayed), (GtkSignalFunc) xsane_set_update_policy_callback, + g_signal_handlers_unblock_by_func(GTK_OBJECT(xsane.update_policy_delayed), (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DELAYED); preferences.gtk_update_policy = policy; @@ -2854,11 +3015,6 @@ static gint xsane_close_info_callback(GtkWidget *widget, gpointer data) xsane_set_sensitivity(TRUE); - xsane_update_histogram(TRUE /* update raw */); -#ifdef HAVE_WORKING_GTK_GAMMACURVE - xsane_update_gamma_dialog(); -#endif - return FALSE; } @@ -2875,15 +3031,16 @@ static void xsane_info_dialog(GtkWidget *widget, gpointer data) sane_get_parameters(xsane.dev, &xsane.param); /* update xsane.param */ - info_dialog = gtk_window_new(GTK_WINDOW_DIALOG); + info_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(info_dialog), GTK_WIN_POS_CENTER); - gtk_window_set_policy(GTK_WINDOW(info_dialog), FALSE, FALSE, FALSE); - gtk_signal_connect(GTK_OBJECT(info_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_close_info_callback), info_dialog); + gtk_window_set_resizable(GTK_WINDOW(info_dialog), FALSE); + g_signal_connect(GTK_OBJECT(info_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_close_info_callback), info_dialog); snprintf(buf, sizeof(buf), "%s %s %s", xsane.prog_name, WINDOW_INFO, xsane.device_text); gtk_window_set_title(GTK_WINDOW(info_dialog), buf); + gtk_container_set_border_width(GTK_CONTAINER(info_dialog), 5); accelerator_group = gtk_accel_group_new(); - gtk_accel_group_attach(accelerator_group, GTK_OBJECT(info_dialog)); + gtk_window_add_accel_group(GTK_WINDOW(info_dialog), accelerator_group); xsane_set_window_icon(info_dialog, 0); @@ -3104,6 +3261,9 @@ static void xsane_info_dialog(GtkWidget *widget, gpointer data) bufptr += strlen(bufptr); #endif + sprintf(bufptr, "TXT, "); + bufptr += strlen(bufptr); + bufptr--; bufptr--; *bufptr = 0; /* erase last comma */ @@ -3125,9 +3285,6 @@ static void xsane_info_dialog(GtkWidget *widget, gpointer data) sprintf(bufptr, "PNM, "); bufptr += strlen(bufptr); - sprintf(bufptr, "RAW, "); - bufptr += strlen(bufptr); - #ifdef SUPPORT_RGBA sprintf(bufptr, "RGBA, "); bufptr += strlen(bufptr); @@ -3146,19 +3303,20 @@ static void xsane_info_dialog(GtkWidget *widget, gpointer data) /* gtk_label_set((GtkLabel *)label, "HALLO"); */ +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); +#else button = gtk_button_new_with_label(BUTTON_CLOSE); - gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, GTK_ACCEL_LOCKED); +#endif + gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, DEF_GTK_ACCEL_LOCKED); GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_info_callback, info_dialog); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_info_callback, info_dialog); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); gtk_widget_grab_default(button); gtk_widget_show(button); gtk_widget_show(info_dialog); - xsane_clear_histogram(&xsane.histogram_raw); - xsane_clear_histogram(&xsane.histogram_enh); - xsane_set_sensitivity(FALSE); } @@ -3197,15 +3355,16 @@ static void xsane_about_dialog(GtkWidget *widget, gpointer data) return; } - about_dialog = gtk_window_new(GTK_WINDOW_DIALOG); + about_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(about_dialog), GTK_WIN_POS_CENTER); - gtk_window_set_policy(GTK_WINDOW(about_dialog), FALSE, FALSE, FALSE); - gtk_signal_connect(GTK_OBJECT(about_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_close_about_dialog_callback), NULL); + gtk_window_set_resizable(GTK_WINDOW(about_dialog), FALSE); + g_signal_connect(GTK_OBJECT(about_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_close_about_dialog_callback), NULL); snprintf(buf, sizeof(buf), "%s %s", WINDOW_ABOUT_XSANE, xsane.prog_name); gtk_window_set_title(GTK_WINDOW(about_dialog), buf); + gtk_container_set_border_width(GTK_CONTAINER(about_dialog), 5); accelerator_group = gtk_accel_group_new(); - gtk_accel_group_attach(accelerator_group, GTK_OBJECT(about_dialog)); + gtk_window_add_accel_group(GTK_WINDOW(about_dialog), accelerator_group); xsane_set_window_icon(about_dialog, 0); @@ -3226,10 +3385,10 @@ static void xsane_about_dialog(GtkWidget *widget, gpointer data) xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", 0, "xsane-logo", 0, ".xpm", XSANE_PATH_SYSTEM); pixmap = gdk_pixmap_create_from_xpm(about_dialog->window, &mask, bg_trans, filename); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(vbox), pixmapwidget, FALSE, FALSE, 2); gtk_widget_show(pixmapwidget); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); xsane_separator_new(vbox, 5); @@ -3250,10 +3409,14 @@ static void xsane_about_dialog(GtkWidget *widget, gpointer data) gtk_widget_show(label); +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); +#else button = gtk_button_new_with_label(BUTTON_CLOSE); - gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, GTK_ACCEL_LOCKED); +#endif + gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, DEF_GTK_ACCEL_LOCKED); GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_about_dialog_callback, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_about_dialog_callback, NULL); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); gtk_widget_grab_default(button); gtk_widget_show(button); @@ -3280,7 +3443,7 @@ static int xsane_close_about_translation_dialog_callback(GtkWidget *widget, gpoi static void xsane_about_translation_dialog(GtkWidget *widget, gpointer data) { GtkWidget *vbox, *hbox, *button, *label; - char buf[512]; + char buf[1024]; char filename[PATH_MAX]; GtkWidget *pixmapwidget; GdkBitmap *mask; @@ -3296,15 +3459,16 @@ static void xsane_about_translation_dialog(GtkWidget *widget, gpointer data) return; } - about_translation_dialog = gtk_window_new(GTK_WINDOW_DIALOG); + about_translation_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(about_translation_dialog), GTK_WIN_POS_CENTER); - gtk_window_set_policy(GTK_WINDOW(about_translation_dialog), FALSE, FALSE, FALSE); - gtk_signal_connect(GTK_OBJECT(about_translation_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_close_about_translation_dialog_callback), NULL); + gtk_window_set_resizable(GTK_WINDOW(about_translation_dialog), FALSE); + g_signal_connect(GTK_OBJECT(about_translation_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_close_about_translation_dialog_callback), NULL); snprintf(buf, sizeof(buf), "%s %s", WINDOW_ABOUT_TRANSLATION, xsane.prog_name); gtk_window_set_title(GTK_WINDOW(about_translation_dialog), buf); + gtk_container_set_border_width(GTK_CONTAINER(about_translation_dialog), 5); accelerator_group = gtk_accel_group_new(); - gtk_accel_group_attach(accelerator_group, GTK_OBJECT(about_translation_dialog)); + gtk_window_add_accel_group(GTK_WINDOW(about_translation_dialog), accelerator_group); xsane_set_window_icon(about_translation_dialog, 0); @@ -3325,10 +3489,10 @@ static void xsane_about_translation_dialog(GtkWidget *widget, gpointer data) xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", 0, "xsane-logo", 0, ".xpm", XSANE_PATH_SYSTEM); pixmap = gdk_pixmap_create_from_xpm(about_translation_dialog->window, &mask, bg_trans, filename); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(vbox), pixmapwidget, FALSE, FALSE, 2); gtk_widget_show(pixmapwidget); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); xsane_separator_new(vbox, 5); @@ -3343,10 +3507,14 @@ static void xsane_about_translation_dialog(GtkWidget *widget, gpointer data) gtk_widget_show(label); +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); +#else button = gtk_button_new_with_label(BUTTON_CLOSE); - gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, GTK_ACCEL_LOCKED); +#endif + gtk_widget_add_accelerator(button, "clicked", accelerator_group, GDK_Escape, 0, DEF_GTK_ACCEL_LOCKED); GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_about_translation_dialog_callback, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_about_translation_dialog_callback, NULL); gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); gtk_widget_grab_default(button); gtk_widget_show(button); @@ -3356,154 +3524,9 @@ static void xsane_about_translation_dialog(GtkWidget *widget, gpointer data) /* ---------------------------------------------------------------------------------------------------------------------- */ -static SANE_Status xsane_get_area_value(int option, float *val, SANE_Int *unit) -{ - const SANE_Option_Descriptor *opt; - SANE_Handle dev; - SANE_Word word; - - DBG(DBG_proc, "xsane_get_area_value\n"); - - if (option <= 0) - { - return -1; - } - - if (xsane_control_option(xsane.dev, option, SANE_ACTION_GET_VALUE, &word, 0) == SANE_STATUS_GOOD) - { - dev = xsane.dev; - opt = xsane_get_option_descriptor(dev, option); - - if (unit) - { - *unit = opt->unit; - } - - if (val) - { - if (opt->type == SANE_TYPE_FIXED) - { - *val = (float) word / 65536.0; - } - else - { - *val = (float) word; - } - } - - return 0; - } - else if (val) - { - *val = 0; - } - return -2; -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -#ifdef XSANE_TEST -static void xsane_batch_scan_delete_callback(GtkWidget *widget, gpointer list) -{ - gtk_list_remove_items(GTK_LIST(list), GTK_LIST(list)->selection); -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_batch_scan_add_callback(GtkWidget *widget, gpointer list) -{ - GtkWidget *list_item; - float tlx, tly, brx, bry; - SANE_Int unit; - char buf[255]; - - DBG(DBG_proc, "xsane_batch_scan_add_callback\n"); - - xsane_get_area_value(xsane.well_known.coord[0], &tlx, &unit); - xsane_get_area_value(xsane.well_known.coord[1], &tly, &unit); - xsane_get_area_value(xsane.well_known.coord[2], &brx, &unit); - xsane_get_area_value(xsane.well_known.coord[3], &bry, &unit); - - if (unit == SANE_UNIT_MM) - { - snprintf(buf, sizeof(buf), " top left (%7.2fmm, %7.2fmm), bottom right (%7.2fmm, %7.2fmm)", tlx, tly, brx, bry); - } - else - { - snprintf(buf, sizeof(buf), " top left (%5.0fpx, %5.0fpx), bottom right (%5.0fpx, %5.0fpx)", tlx, tly, brx, bry); - } - - list_item = gtk_list_item_new_with_label(buf); - gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(buf)); - gtk_container_add(GTK_CONTAINER(list), list_item); - gtk_widget_show(list_item); -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_batch_scan_dialog(GtkWidget *widget, gpointer data) -{ - GtkWidget *batch_scan_dialog, *batch_scan_vbox, *hbox, *button, *scrolled_window, *list; - char buf[64]; - - DBG(DBG_proc, "xsane_batch_scan_dialog\n"); - - batch_scan_dialog = gtk_window_new(GTK_WINDOW_DIALOG); - xsane_set_window_icon(batch_scan_dialog, 0); - - snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_BATCH_SCAN); - gtk_window_set_title(GTK_WINDOW(batch_scan_dialog), buf); - - /* set the main vbox */ - batch_scan_vbox = gtk_vbox_new(FALSE, 0); - gtk_container_set_border_width(GTK_CONTAINER(batch_scan_vbox), 0); - gtk_container_add(GTK_CONTAINER(batch_scan_dialog), batch_scan_vbox); - gtk_widget_show(batch_scan_vbox); - - /* set the main hbox */ - hbox = gtk_hbox_new(FALSE, 0); - xsane_separator_new(vbox, 2); - gtk_box_pack_end(GTK_BOX(batch_scan_vbox), hbox, FALSE, FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); - gtk_widget_show(hbox); - - scrolled_window = gtk_scrolled_window_new(0, 0); - gtk_widget_set_usize(scrolled_window, 400, 200); - gtk_container_add(GTK_CONTAINER(batch_scan_vbox), scrolled_window); - gtk_widget_show(scrolled_window); - - list = gtk_list_new(); - - gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list); - - gtk_widget_show(list); - - - button = gtk_button_new_with_label(BUTTON_OK); - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_close_dialog_callback, batch_scan_dialog); - gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); - gtk_widget_grab_default(button); - gtk_widget_show(button); - - button = gtk_button_new_with_label(BUTTON_ADD_AREA); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_add_callback, list); - gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); - gtk_widget_show(button); - - button = gtk_button_new_with_label(BUTTON_DELETE); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_delete_callback, list); - gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); - gtk_widget_show(button); - - gtk_widget_show(batch_scan_dialog); -} -#endif - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static void xsane_fax_dialog_delete() +static gint xsane_fax_dialog_delete() { + return TRUE; } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -3524,15 +3547,14 @@ static void xsane_fax_dialog() return; /* window already is open */ } - /* GTK_WINDOW_DIALOG looks better but does not place it nice*/ + /* GTK_WINDOW_TOPLEVEL looks better but does not place it nice*/ fax_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(fax_dialog), buf); snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_FAX_PROJECT); gtk_window_set_title(GTK_WINDOW(fax_dialog), buf); - gtk_signal_connect(GTK_OBJECT(fax_dialog), "delete_event", (GtkSignalFunc) xsane_fax_dialog_delete, NULL); + g_signal_connect(GTK_OBJECT(fax_dialog), "delete_event", (GtkSignalFunc) xsane_fax_dialog_delete, NULL); xsane_set_window_icon(fax_dialog, 0); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(fax_dialog)); + gtk_window_add_accel_group(GTK_WINDOW(fax_dialog), xsane.accelerator_group); /* set the main vbox */ fax_scan_vbox = gtk_vbox_new(FALSE, 0); @@ -3547,17 +3569,19 @@ static void xsane_fax_dialog() gtk_box_pack_start(GTK_BOX(fax_scan_vbox), hbox, FALSE, FALSE, 2); pixmap = gdk_pixmap_create_from_xpm_d(xsane.shell->window, &mask, xsane.bg_trans, (gchar **) fax_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); - text = gtk_entry_new_with_max_length(128); + text = gtk_entry_new(); xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXPROJECT); + gtk_entry_set_max_length(GTK_ENTRY(text), 128); gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.fax_project); gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4); - gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_fax_project_changed_callback, NULL); + g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_fax_project_changed_callback, NULL); xsane.fax_project_entry = text; + xsane.fax_project_entry_box = hbox; gtk_widget_show(pixmapwidget); gtk_widget_show(text); @@ -3576,14 +3600,15 @@ static void xsane_fax_dialog() gtk_widget_realize(fax_dialog); pixmap = gdk_pixmap_create_from_xpm_d(fax_dialog->window, &mask, xsane.bg_trans, (gchar **) faxreceiver_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); - text = gtk_entry_new_with_max_length(128); + text = gtk_entry_new(); xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXRECEIVER); + gtk_entry_set_max_length(GTK_ENTRY(text), 128); gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4); - gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_fax_receiver_changed_callback, NULL); + g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_fax_receiver_changed_callback, NULL); xsane.fax_receiver_entry = text; @@ -3594,14 +3619,14 @@ static void xsane_fax_dialog() /* fine mode */ button = gtk_check_button_new_with_label(RADIO_BUTTON_FINE_MODE); xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_FAX_FINE_MODE); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), xsane.fax_fine_mode); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), preferences.fax_fine_mode); gtk_box_pack_start(GTK_BOX(fax_project_vbox), button, FALSE, FALSE, 2); gtk_widget_show(button); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_fine_mode_callback, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_fine_mode_callback, NULL); scrolled_window = gtk_scrolled_window_new(0, 0); - gtk_widget_set_usize(scrolled_window, 200, 100); + gtk_widget_set_size_request(scrolled_window, 200, 100); gtk_container_add(GTK_CONTAINER(fax_project_vbox), scrolled_window); gtk_widget_show(scrolled_window); @@ -3620,22 +3645,22 @@ static void xsane_fax_dialog() gtk_box_pack_start(GTK_BOX(fax_project_vbox), hbox, FALSE, FALSE, 2); button = gtk_button_new_with_label(BUTTON_FILE_INSERT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_insert_callback, list); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_insert_callback, list); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_label(BUTTON_PAGE_SHOW); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_show_callback, list); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_show_callback, list); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_label(BUTTON_PAGE_RENAME); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_callback, list); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_callback, list); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_label(BUTTON_PAGE_DELETE); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_delete_callback, list); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_delete_callback, list); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); @@ -3658,12 +3683,12 @@ static void xsane_fax_dialog() gtk_box_pack_start(GTK_BOX(hbox), fax_project_exists_hbox, TRUE, TRUE, 0); button = gtk_button_new_with_label(BUTTON_SEND_PROJECT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_send, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_send, NULL); gtk_box_pack_start(GTK_BOX(fax_project_exists_hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_label(BUTTON_DELETE_PROJECT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_delete, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_delete, NULL); gtk_box_pack_start(GTK_BOX(fax_project_exists_hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); @@ -3671,10 +3696,18 @@ static void xsane_fax_dialog() xsane.fax_project_exists = fax_project_exists_hbox; button = gtk_button_new_with_label(BUTTON_CREATE_PROJECT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_create, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_project_create, NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); xsane.fax_project_not_exists = button; + /* progress bar */ + xsane.fax_progress_bar = (GtkProgressBar *) gtk_progress_bar_new(); + gtk_box_pack_start(GTK_BOX(fax_scan_vbox), (GtkWidget *) xsane.fax_progress_bar, FALSE, FALSE, 0); + gtk_progress_set_show_text(GTK_PROGRESS(xsane.fax_progress_bar), TRUE); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), ""); + gtk_widget_show(GTK_WIDGET(xsane.fax_progress_bar)); + + xsane.fax_dialog = fax_dialog; xsane_fax_project_load(); @@ -3693,7 +3726,6 @@ static void xsane_fax_dialog_close() return; } - gtk_accel_group_detach(xsane.accelerator_group, GTK_OBJECT(xsane.fax_dialog)); gtk_widget_destroy(xsane.fax_dialog); xsane.fax_dialog = NULL; @@ -3706,23 +3738,37 @@ static void xsane_fax_project_load() { FILE *projectfile; char page[256]; - char buf[256]; + char filename[PATH_MAX]; GtkWidget *list_item; int i; - char c; + int c; DBG(DBG_proc, "xsane_fax_project_load\n"); - gtk_signal_disconnect_by_func(GTK_OBJECT(xsane.fax_receiver_entry), GTK_SIGNAL_FUNC(xsane_fax_receiver_changed_callback), 0); + if (xsane.fax_status) + { + free(xsane.fax_status); + xsane.fax_status = NULL; + } + + if (xsane.fax_receiver) + { + free(xsane.fax_receiver); + xsane.fax_receiver = NULL; + } + + g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.fax_receiver_entry), GTK_SIGNAL_FUNC(xsane_fax_receiver_changed_callback), 0); gtk_list_remove_items(GTK_LIST(xsane.fax_list), GTK_LIST(xsane.fax_list)->children); - snprintf(buf, sizeof(buf), "%s/xsane-fax-list", preferences.fax_project); - projectfile = fopen(buf, "rb"); /* read binary (b for win32) */ + snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project); + projectfile = fopen(filename, "rb"); /* read binary (b for win32) */ if ((!projectfile) || (feof(projectfile))) { - snprintf(buf, sizeof(buf), "%s/page-1.ps", preferences.fax_project); - xsane.fax_filename=strdup(buf); + xsane.fax_status=strdup(TEXT_FAX_STATUS_NOT_CREATED); + + snprintf(filename, sizeof(filename), "%s/page-1.pnm", preferences.fax_project); + xsane.fax_filename=strdup(filename); xsane_update_counter_in_filename(&xsane.fax_filename, FALSE, 0, preferences.filename_counter_len); /* correct counter len */ xsane.fax_receiver=strdup(""); @@ -3735,6 +3781,20 @@ static void xsane_fax_project_load() } else { + i=0; + c=0; + while ((i<255) && (c != 10) && (c != EOF)) /* first line is receiver phone number or address */ + { + c = fgetc(projectfile); + page[i++] = c; + } + page[i-1] = 0; + if (strchr(page, '@')) + { + *strchr(page, '@') = 0; + } + xsane.fax_status = strdup(page); + i=0; c=0; while ((i<255) && (c != 10) && (c != EOF)) /* first line is receiver phone number or address */ @@ -3757,8 +3817,8 @@ static void xsane_fax_project_load() } page[i-1] = 0; - snprintf(buf, sizeof(buf), "%s/%s", preferences.fax_project, page); - xsane.fax_filename=strdup(buf); + snprintf(filename, sizeof(filename), "%s/%s", preferences.fax_project, page); + xsane.fax_filename=strdup(filename); while (!feof(projectfile)) { @@ -3774,8 +3834,23 @@ static void xsane_fax_project_load() if (c > 1) { + char *type; + char *extension; + + extension = strrchr(page, '.'); + if (extension) + { + type = strdup(extension); + *extension = 0; + } + else + { + type = strdup(""); + } + list_item = gtk_list_item_new_with_label(page); gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page)); + gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type)); gtk_container_add(GTK_CONTAINER(xsane.fax_list), list_item); gtk_widget_show(list_item); } @@ -3791,7 +3866,10 @@ static void xsane_fax_project_load() fclose(projectfile); } - gtk_signal_connect(GTK_OBJECT(xsane.fax_receiver_entry), "changed", (GtkSignalFunc) xsane_fax_receiver_changed_callback, NULL); + g_signal_connect(GTK_OBJECT(xsane.fax_receiver_entry), "changed", (GtkSignalFunc) xsane_fax_receiver_changed_callback, NULL); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -3810,7 +3888,7 @@ static void xsane_fax_project_delete() list_item = GTK_OBJECT(list->data); page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); xsane_convert_text_to_filename(&page); - snprintf(file, sizeof(file), "%s/%s.ps", preferences.fax_project, page); + snprintf(file, sizeof(file), "%s/%s.pnm", preferences.fax_project, page); free(page); remove(file); list = list->next; @@ -3825,10 +3903,28 @@ static void xsane_fax_project_delete() /* ---------------------------------------------------------------------------------------------------------------------- */ +static void xsane_fax_project_update_project_status() +{ + FILE *projectfile; + char filename[PATH_MAX]; + char buf[256]; + + snprintf(filename, sizeof(filename), "%s/xsane-fax-list", preferences.fax_project); + projectfile = fopen(filename, "r+b"); /* r+ = read and write, position = start of file */ + + snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.fax_status); /* fill 32 characters status line */ + fprintf(projectfile, "%s\n", buf); /* first line is status of mail */ + + fclose(projectfile); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + void xsane_fax_project_save() { FILE *projectfile; char *page; + char *type; char filename[256]; GList *list = (GList *) GTK_LIST(xsane.fax_list)->children; GtkObject *list_item; @@ -3858,6 +3954,22 @@ void xsane_fax_project_save() return; } + if (xsane.fax_status) + { + char buf[256]; + + snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.fax_status); /* fill 32 characters status line */ + fprintf(projectfile, "%s\n", buf); /* first line is status of mail */ + gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0); + } + else + { + fprintf(projectfile, " \n"); /* no mail status */ + gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), ""); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0); + } + if (xsane.fax_receiver) { fprintf(projectfile, "%s\n", xsane.fax_receiver); /* first line is receiver phone number or address */ @@ -3881,7 +3993,8 @@ void xsane_fax_project_save() { list_item = GTK_OBJECT(list->data); page = (char *) gtk_object_get_data(list_item, "list_item_data"); - fprintf(projectfile, "%s\n", page); + type = (char *) gtk_object_get_data(list_item, "list_item_type"); + fprintf(projectfile, "%s%s\n", page, type); list = list->next; } fclose(projectfile); @@ -3895,6 +4008,11 @@ static void xsane_fax_project_create() if (strlen(preferences.fax_project)) { + if (xsane.fax_status) + { + free(xsane.fax_status); + } + xsane.fax_status = strdup(TEXT_FAX_STATUS_CREATED); xsane_fax_project_save(); xsane_fax_project_load(); } @@ -3906,6 +4024,12 @@ static void xsane_fax_receiver_changed_callback(GtkWidget *widget, gpointer data { DBG(DBG_proc, "xsane_fax_receiver_changed_callback\n"); + if (xsane.fax_status) + { + free(xsane.fax_status); + } + xsane.fax_status = strdup(TEXT_FAX_STATUS_CHANGED); + if (xsane.fax_receiver) { free((void *) xsane.fax_receiver); @@ -3913,6 +4037,9 @@ static void xsane_fax_receiver_changed_callback(GtkWidget *widget, gpointer data xsane.fax_receiver = strdup(gtk_entry_get_text(GTK_ENTRY(widget))); xsane_fax_project_save(); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -3936,25 +4063,31 @@ static void xsane_fax_fine_mode_callback(GtkWidget * widget) { DBG(DBG_proc, "xsane_fax_fine_mode_callback\n"); - xsane.fax_fine_mode = (GTK_TOGGLE_BUTTON(widget)->active != 0); + preferences.fax_fine_mode = (GTK_TOGGLE_BUTTON(widget)->active != 0); } /* ---------------------------------------------------------------------------------------------------------------------- */ static void xsane_list_entrys_swap(GtkWidget *list_item_1, GtkWidget *list_item_2) { - char *text1; - char *text2; + char *page1; + char *page2; + char *type1; + char *type2; DBG(DBG_proc, "xsane_list_entrys_swap\n"); - text1 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_1), "list_item_data"); - text2 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_2), "list_item_data"); - - gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_1))->data), text2); - gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_2))->data), text1); - gtk_object_set_data(GTK_OBJECT(list_item_1), "list_item_data", text2); - gtk_object_set_data(GTK_OBJECT(list_item_2), "list_item_data", text1); + page1 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_1), "list_item_data"); + type1 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_1), "list_item_type"); + page2 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_2), "list_item_data"); + type2 = (char *) gtk_object_get_data(GTK_OBJECT(list_item_2), "list_item_type"); + + gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_1))->data), page2); + gtk_label_set(GTK_LABEL(gtk_container_children(GTK_CONTAINER(list_item_2))->data), page1); + gtk_object_set_data(GTK_OBJECT(list_item_1), "list_item_data", page2); + gtk_object_set_data(GTK_OBJECT(list_item_1), "list_item_type", type2); + gtk_object_set_data(GTK_OBJECT(list_item_2), "list_item_data", page1); + gtk_object_set_data(GTK_OBJECT(list_item_2), "list_item_type", type1); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -4058,6 +4191,7 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) GList *select; char *oldpage; char *newpage; + char *type; char oldfile[256]; char newfile[256]; @@ -4070,14 +4204,15 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) GtkWidget *text; GtkWidget *button; GtkWidget *vbox, *hbox; - char buf[256]; + char filename[PATH_MAX]; list_item = select->data; oldpage = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_data")); + type = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_type")); xsane_set_sensitivity(FALSE); - rename_dialog = gtk_window_new(GTK_WINDOW_DIALOG); + rename_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); xsane_set_window_icon(rename_dialog, 0); /* set the main vbox */ @@ -4094,27 +4229,36 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) gtk_widget_show(hbox); gtk_window_set_position(GTK_WINDOW(rename_dialog), GTK_WIN_POS_CENTER); - gtk_window_set_policy(GTK_WINDOW(rename_dialog), FALSE, FALSE, FALSE); - snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_FAX_RENAME); - gtk_window_set_title(GTK_WINDOW(rename_dialog), buf); - gtk_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) -1); + gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE); + snprintf(filename, sizeof(filename), "%s %s", xsane.prog_name, WINDOW_FAX_RENAME); + gtk_window_set_title(GTK_WINDOW(rename_dialog), filename); + g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_fax_entry_rename_button_callback,(void *) -1); gtk_widget_show(rename_dialog); - text = gtk_entry_new_with_max_length(64); + text = gtk_entry_new(); xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_FAXPAGENAME); + gtk_entry_set_max_length(GTK_ENTRY(text), 64); gtk_entry_set_text(GTK_ENTRY(text), oldpage); - gtk_widget_set_usize(text, 300, 0); + gtk_widget_set_size_request(text, 300, -1); gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 4); gtk_widget_show(text); - button = gtk_button_new_with_label("OK"); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) 1); +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_OK); +#else + button = gtk_button_new_with_label(BUTTON_OK); +#endif + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) 1); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); - button = gtk_button_new_with_label("Cancel"); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) -1); +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); +#else + button = gtk_button_new_with_label(BUTTON_CANCEL); +#endif + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_fax_entry_rename_button_callback, (void *) -1); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); @@ -4138,8 +4282,8 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) xsane_convert_text_to_filename(&oldpage); xsane_convert_text_to_filename(&newpage); - snprintf(oldfile, sizeof(oldfile), "%s/%s.ps", preferences.fax_project, oldpage); - snprintf(newfile, sizeof(newfile), "%s/%s.ps", preferences.fax_project, newpage); + snprintf(oldfile, sizeof(oldfile), "%s/%s%s", preferences.fax_project, oldpage, type); + snprintf(newfile, sizeof(newfile), "%s/%s%s", preferences.fax_project, newpage, type); rename(oldfile, newfile); @@ -4148,6 +4292,7 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) free(oldpage); free(newpage); + free(type); gtk_widget_destroy(rename_dialog); @@ -4160,14 +4305,11 @@ static void xsane_fax_entry_rename_callback(GtkWidget *widget, gpointer list) static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list) { GtkWidget *list_item; - char filename[1024]; + char filename[PATH_MAX]; char windowname[255]; DBG(DBG_proc, "xsane_fax_entry_insert_callback\n"); - xsane_clear_histogram(&xsane.histogram_raw); - xsane_clear_histogram(&xsane.histogram_enh); - xsane_set_sensitivity(FALSE); snprintf(windowname, sizeof(windowname), "%s %s %s", xsane.prog_name, WINDOW_FAX_INSERT, preferences.fax_project); @@ -4175,7 +4317,7 @@ static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list) umask((mode_t) preferences.directory_umask); /* define new file permissions */ - if (!xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, TRUE, FALSE, FALSE)) /* filename is selected */ + if (!xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, NULL, TRUE, FALSE, FALSE, FALSE)) /* filename is selected */ { FILE *sourcefile; @@ -4184,34 +4326,48 @@ static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list) { char buf[1024]; - fgets(buf, 1024, sourcefile); + fgets(buf, sizeof(buf), sourcefile); if (!strncmp("%!PS", buf, 4)) { FILE *destfile; - + char destpath[PATH_MAX]; + char *destfilename; + char *destfiletype; + char *extension; + + destfilename = strdup(strrchr(filename, '/')+1); + extension = strrchr(destfilename, '.'); + if (extension) + { + destfiletype = strdup(extension); + *extension = 0; + } + else + { + destfiletype = strdup(""); + } + + snprintf(destpath, sizeof(destpath), "%s/%s%s", preferences.fax_project, destfilename, destfiletype); /* copy file to project directory */ - if (xsane_create_secure_file(xsane.fax_filename)) /* remove possibly existing symbolic links for security + if (xsane_create_secure_file(destpath)) /* remove possibly existing symbolic links for security */ { fclose(sourcefile); - snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, xsane.fax_filename); + snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, destpath); xsane_back_gtk_error(buf, TRUE); return; /* error */ } - destfile = fopen(xsane.fax_filename, "wb"); /* write binary (b for win32) */ + destfile = fopen(destpath, "wb"); /* write binary (b for win32) */ if (destfile) /* file is created */ { - char *extension; - char *page; - fprintf(destfile, "%s\n", buf); while (!feof(sourcefile)) { - fgets(buf, 1024, sourcefile); + fgets(buf, sizeof(buf), sourcefile); fprintf(destfile, "%s", buf); } @@ -4219,21 +4375,15 @@ static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list) /* add filename to fax page list */ - page = strdup(strrchr(xsane.fax_filename,'/')+1); - extension = strrchr(page, '.'); - if (extension) - { - *extension = 0; - } - - list_item = gtk_list_item_new_with_label(page); - gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page)); + list_item = gtk_list_item_new_with_label(destfilename); + gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(destfilename)); + gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(destfiletype)); gtk_container_add(GTK_CONTAINER(xsane.fax_list), list_item); gtk_widget_show(list_item); xsane_update_counter_in_filename(&xsane.fax_filename, TRUE, 1, preferences.filename_counter_len); xsane_fax_project_save(); - free(page); + free(destfilename); } else /* file could not be created */ { @@ -4260,7 +4410,6 @@ static void xsane_fax_entry_insert_callback(GtkWidget *widget, gpointer list) umask(XSANE_DEFAULT_UMASK); /* define new file permissions */ xsane_set_sensitivity(TRUE); - xsane_update_histogram(TRUE /* update raw */); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -4270,7 +4419,8 @@ static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list) GtkObject *list_item; GList *select; char *page; - char file[256]; + char *type; + char filename[PATH_MAX]; DBG(DBG_proc, "xsane_fax_entry_delete_callback\n"); @@ -4279,10 +4429,12 @@ static void xsane_fax_entry_delete_callback(GtkWidget *widget, gpointer list) { list_item = GTK_OBJECT(select->data); page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + type = strdup((char *) gtk_object_get_data(list_item, "list_item_type")); xsane_convert_text_to_filename(&page); - snprintf(file, sizeof(file), "%s/%s.ps", preferences.fax_project, page); + snprintf(filename, sizeof(filename), "%s/%s%s", preferences.fax_project, page, type); free(page); - remove(file); + free(type); + remove(filename); gtk_widget_destroy(GTK_WIDGET(list_item)); xsane_fax_project_save(); } @@ -4294,42 +4446,162 @@ static void xsane_fax_show_callback(GtkWidget *widget, gpointer list) { GtkObject *list_item; GList *select; - pid_t pid; - char *arg[100]; char *page; + char *type; + char filename[256]; + + DBG(DBG_proc, "xsane_fax_entry_show_callback\n"); + + select = GTK_LIST(list)->selection; + if (select) + { + list_item = GTK_OBJECT(select->data); + page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + type = strdup((char *) gtk_object_get_data(list_item, "list_item_type")); + xsane_convert_text_to_filename(&page); + snprintf(filename, sizeof(filename), "%s/%s%s", preferences.fax_project, page, type); + + if (!strncmp(type, ".pnm", 4)) + { + /* when we do not allow any modification then we can work with the original file */ + /* so we do not have to copy the image into a dummy file here! */ + + xsane_viewer_new(filename, FALSE, filename, VIEWER_NO_MODIFICATION); + } + else if (!strncmp(type, ".ps", 3)) + { + char *arg[100]; + int argnr; + pid_t pid; + + argnr = xsane_parse_options(preferences.fax_viewer, arg); + arg[argnr++] = filename; + arg[argnr] = 0; + + pid = fork(); + + if (pid == 0) /* new process */ + { + FILE *ipc_file = NULL; + + if (xsane.ipc_pipefd[0]) + { + close(xsane.ipc_pipefd[0]); /* close reading end of pipe */ + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + + DBG(DBG_info, "trying to change user id fo new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); + setuid(getuid()); + DBG(DBG_info, "new effective uid = %d\n", (int) geteuid()); + + execvp(arg[0], arg); /* does not return if successfully */ + DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_FAX_VIEWER, preferences.fax_viewer); + + /* send error message via IPC pipe to parent process */ + if (ipc_file) + { + fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_FAX_VIEWER, preferences.fax_viewer, strerror(errno)); + fflush(ipc_file); /* make sure message is displayed */ + fclose(ipc_file); + } + + _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ + } + else /* parent process */ + { + xsane_add_process_to_list(pid); /* add pid to child process list */ + } + } + + free(page); + free(type); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static int xsane_fax_convert_pnm_to_ps(char *source_filename, char *fax_filename) +{ + FILE *outfile; + FILE *infile; + Image_info image_info; char buf[256]; - int argnr; + int cancel_save; + + /* open progressbar */ + snprintf(buf, sizeof(buf), "%s - %s", PROGRESS_CONVERTING_DATA, source_filename); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), buf); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0); + + while (gtk_events_pending()) + { + DBG(DBG_info, "calling gtk_main_iteration\n"); + gtk_main_iteration(); + } + + infile = fopen(source_filename, "rb"); /* read binary (b for win32) */ + if (infile != 0) + { + xsane_read_pnm_header(infile, &image_info); + + umask((mode_t) preferences.image_umask); /* define image file permissions */ + outfile = fopen(fax_filename, "wb"); /* b = binary mode for win32 */ + umask(XSANE_DEFAULT_UMASK); /* define new file permissions */ + if (outfile != 0) + { + float imagewidth, imageheight; + + imagewidth = 72.0 * image_info.image_width /image_info.resolution_x; /* width in 1/72 inch */ + imageheight = 72.0 * image_info.image_height/image_info.resolution_y; /* height in 1/72 inch */ + + DBG(DBG_info, "imagewidth = %f 1/72 inch\n", imagewidth); + DBG(DBG_info, "imageheight = %f 1/72 inch\n", imageheight); + + xsane_save_ps(outfile, infile, + &image_info, + imagewidth, imageheight, + preferences.fax_leftoffset * 72.0/MM_PER_INCH, /* paper_left_margin */ + preferences.fax_bottomoffset * 72.0/MM_PER_INCH, /* paper_bottom_margin */ + preferences.fax_width * 72.0/MM_PER_INCH, /* paper_width */ + preferences.fax_height * 72.0/MM_PER_INCH, /* paper_height */ + 0 /* portrait top left */, + xsane.fax_progress_bar, + &cancel_save); + fclose(outfile); + } + else + { + char buf[256]; - DBG(DBG_proc, "xsane_fax_entry_show_callback\n"); + DBG(DBG_info, "open of faxfile `%s'failed : %s\n", fax_filename, strerror(errno)); - select = GTK_LIST(list)->selection; - if (select) + snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, fax_filename, strerror(errno)); + xsane_back_gtk_error(buf, TRUE); + } + + fclose(infile); + } + else { - argnr = xsane_parse_options(preferences.fax_viewer, arg); + char buf[256]; - list_item = GTK_OBJECT(select->data); - page = (char *) gtk_object_get_data(list_item, "list_item_data"); - page = strdup(page); - xsane_convert_text_to_filename(&page); - snprintf(buf, sizeof(buf), "%s/%s.ps", preferences.fax_project, page); - free(page); - arg[argnr++] = buf; - arg[argnr] = 0; + DBG(DBG_info, "open of faxfile `%s'failed : %s\n", source_filename, strerror(errno)); - pid = fork(); + snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, source_filename, strerror(errno)); + xsane_back_gtk_error(buf, TRUE); + } - if (pid == 0) /* new process */ - { - DBG(DBG_info, "trying to change user id fo new subprocess:\n"); - DBG(DBG_info, "old effective uid = %d\n", geteuid()); - setuid(getuid()); - DBG(DBG_info, "new effective uid = %d\n", geteuid()); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), ""); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0); - execvp(arg[0], arg); /* does not return if successfully */ - DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_FAX_VIEWER, preferences.fax_viewer); - _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ - } + while (gtk_events_pending()) + { + DBG(DBG_info, "calling gtk_main_iteration\n"); + gtk_main_iteration(); } + + return 0; } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -4337,11 +4609,15 @@ static void xsane_fax_show_callback(GtkWidget *widget, gpointer list) static void xsane_fax_send() { char *page; + char *type; + char *fax_type=".ps"; GList *list = (GList *) GTK_LIST(xsane.fax_list)->children; GtkObject *list_item; pid_t pid; char *arg[1000]; char buf[256]; + char source_filename[PATH_MAX]; + char fax_filename[PATH_MAX]; int argnr = 0; int i; @@ -4356,14 +4632,12 @@ static void xsane_fax_send() return; } - xsane_clear_histogram(&xsane.histogram_raw); - xsane_clear_histogram(&xsane.histogram_enh); - xsane_set_sensitivity(FALSE); + /* gtk_widget_set_sensitive(xsane.fax_dialog, FALSE); */ argnr = xsane_parse_options(preferences.fax_command, arg); - if (xsane.fax_fine_mode) /* fine mode */ + if (preferences.fax_fine_mode) /* fine mode */ { if (xsane_option_defined(preferences.fax_fine_option)) { @@ -4393,11 +4667,33 @@ static void xsane_fax_send() { list_item = GTK_OBJECT(list->data); page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + type = strdup((char *) gtk_object_get_data(list_item, "list_item_type")); xsane_convert_text_to_filename(&page); - snprintf(buf, sizeof(buf), "%s/%s.ps", preferences.fax_project, page); - free(page); - arg[argnr++] = strdup(buf); + snprintf(source_filename, sizeof(source_filename), "%s/%s%s", preferences.fax_project, page, type); + snprintf(fax_filename, sizeof(fax_filename), "%s/%s-fax%s", preferences.fax_project, page, fax_type); + if (xsane_create_secure_file(fax_filename)) /* remove possibly existing symbolic links for security */ + { + char buf[256]; + + snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, fax_filename); + xsane_back_gtk_error(buf, TRUE); + return; /* error */ + } + + if (!strncmp(type, ".pnm", 4)) + { + DBG(DBG_info, "converting %s to %s\n", source_filename, fax_filename); + xsane_fax_convert_pnm_to_ps(source_filename, fax_filename); + } + else if (!strncmp(type, ".ps", 3)) + { + int cancel_save = 0; + xsane_copy_file_by_name(fax_filename, source_filename, xsane.fax_progress_bar, &cancel_save); + } + arg[argnr++] = strdup(fax_filename); list = list->next; + free(page); + free(type); } arg[argnr] = 0; @@ -4406,27 +4702,57 @@ static void xsane_fax_send() if (pid == 0) /* new process */ { - DBG(DBG_info, "trying to change user id fo new subprocess:\n"); - DBG(DBG_info, "old effective uid = %d\n", geteuid()); + FILE *ipc_file = NULL; + + if (xsane.ipc_pipefd[0]) + { + close(xsane.ipc_pipefd[0]); /* close reading end of pipe */ + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + + DBG(DBG_info, "trying to change user id for new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); setuid(getuid()); - DBG(DBG_info, "new effective uid = %d\n", geteuid()); + DBG(DBG_info, "new effective uid = %d\n", (int) geteuid()); execvp(arg[0], arg); /* does not return if successfully */ DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_FAX_CMD, preferences.fax_command); + + /* send error message via IPC pipe to parent process */ + if (ipc_file) + { + fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_FAX_CMD, preferences.fax_command, strerror(errno)); + fflush(ipc_file); /* make sure message is displayed */ + fclose(ipc_file); + } + _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ } + else /* parent process */ + { + xsane_add_process_to_list(pid); /* add pid to child process list */ + } for (i=0; ichildren; + while (list) + { + list_item = GTK_OBJECT(list->data); + page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + xsane_convert_text_to_filename(&page); + snprintf(fax_filename, sizeof(fax_filename), "%s/%s-fax%s", preferences.fax_project, page, fax_type); + free(page); + + DBG(DBG_info, "removing %s\n", fax_filename); + remove(fax_filename); + + list = list->next; + } + + xsane.fax_status = strdup(TEXT_FAX_STATUS_FAX_QUEUED); + xsane_fax_project_update_project_status(); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.fax_progress_bar), _(xsane.fax_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.fax_progress_bar), 0.0); + xsane_set_sensitivity(TRUE); - xsane_update_histogram(TRUE /* update raw */); + + /* gtk_widget_set_sensitive(xsane.fax_dialog, TRUE); */ } + + DBG(DBG_info, "xsane_fax_send: done\n"); } /* ---------------------------------------------------------------------------------------------------------------------- */ #ifdef XSANE_ACTIVATE_MAIL -static void xsane_mail_dialog_delete() +static gint xsane_mail_dialog_delete() +{ + return TRUE; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_mail_filetype_callback(GtkWidget *filetype_option_menu, char *filetype) { + DBG(DBG_proc, "xsane_mail_filetype_callback(%s)\n", filetype); + + if (preferences.mail_filetype) + { + free(preferences.mail_filetype); + } + preferences.mail_filetype = strdup(filetype); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -4458,12 +4822,15 @@ static void xsane_mail_dialog() GtkWidget *hbox; GtkWidget *scrolled_window, *list; GtkWidget *pixmapwidget, *text; - GtkWidget *vscrollbar; GtkWidget *attachment_frame, *text_frame; GtkWidget *label; + GtkWidget *filetype_menu, *filetype_item; + GtkWidget *filetype_option_menu; GdkPixmap *pixmap; GdkBitmap *mask; char buf[64]; + int filetype_nr; + int select_item; DBG(DBG_proc, "xsane_mail_dialog\n"); @@ -4472,15 +4839,14 @@ static void xsane_mail_dialog() return; /* window already is open */ } - /* GTK_WINDOW_DIALOG looks better but does not place it nice*/ + /* GTK_WINDOW_TOPLEVEL looks better but does not place it nice*/ mail_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_window_set_title(GTK_WINDOW(mail_dialog), buf); snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_MAIL_PROJECT); gtk_window_set_title(GTK_WINDOW(mail_dialog), buf); - gtk_signal_connect(GTK_OBJECT(mail_dialog), "delete_event", (GtkSignalFunc) xsane_mail_dialog_delete, NULL); + g_signal_connect(GTK_OBJECT(mail_dialog), "delete_event", (GtkSignalFunc) xsane_mail_dialog_delete, NULL); xsane_set_window_icon(mail_dialog, 0); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(mail_dialog)); + gtk_window_add_accel_group(GTK_WINDOW(mail_dialog), xsane.accelerator_group); /* set the main vbox */ mail_scan_vbox = gtk_vbox_new(FALSE, 0); @@ -4495,17 +4861,19 @@ static void xsane_mail_dialog() gtk_box_pack_start(GTK_BOX(mail_scan_vbox), hbox, FALSE, FALSE, 2); pixmap = gdk_pixmap_create_from_xpm_d(xsane.shell->window, &mask, xsane.bg_trans, (gchar **) mail_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); - text = gtk_entry_new_with_max_length(128); + text = gtk_entry_new(); xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAILPROJECT); + gtk_entry_set_max_length(GTK_ENTRY(text), 128); gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.mail_project); gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4); - gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_project_changed_callback, NULL); + g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_project_changed_callback, NULL); xsane.mail_project_entry = text; + xsane.mail_project_entry_box = hbox; gtk_widget_show(pixmapwidget); gtk_widget_show(text); @@ -4524,14 +4892,15 @@ static void xsane_mail_dialog() gtk_widget_realize(mail_dialog); pixmap = gdk_pixmap_create_from_xpm_d(mail_dialog->window, &mask, xsane.bg_trans, (gchar **) mailreceiver_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); - text = gtk_entry_new_with_max_length(128); + text = gtk_entry_new(); + gtk_entry_set_max_length(GTK_ENTRY(text), 128); xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAILRECEIVER); gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4); - gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_receiver_changed_callback, NULL); + g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_receiver_changed_callback, NULL); xsane.mail_receiver_entry = text; @@ -4548,14 +4917,15 @@ static void xsane_mail_dialog() gtk_widget_realize(mail_dialog); pixmap = gdk_pixmap_create_from_xpm_d(mail_dialog->window, &mask, xsane.bg_trans, (gchar **) subject_xpm); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); - text = gtk_entry_new_with_max_length(128); + text = gtk_entry_new(); xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAILSUBJECT); + gtk_entry_set_max_length(GTK_ENTRY(text), 128); gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4); - gtk_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_subject_changed_callback, NULL); + g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_mail_subject_changed_callback, NULL); xsane.mail_subject_entry = text; @@ -4574,19 +4944,47 @@ static void xsane_mail_dialog() gtk_container_set_border_width(GTK_CONTAINER(hbox), 4); gtk_container_add(GTK_CONTAINER(text_frame), hbox); gtk_widget_show(hbox); + +#ifdef HAVE_GTK_TEXT_VIEW_H + { + GtkWidget *scrolled_window, *text_view, *text_buffer; - /* Create the GtkText widget */ - text = gtk_text_new(NULL, NULL); - gtk_text_set_editable(GTK_TEXT(text), TRUE); /* text is editable */ - gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); /* wrap complete words */ - gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 0); - gtk_widget_show(text); - xsane.mail_text_widget = text; + /* create a scrolled window to get a vertical scrollbar */ + scrolled_window = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(hbox), scrolled_window); + gtk_widget_show(scrolled_window); + + /* create the gtk_text_view widget */ + text_view = gtk_text_view_new(); + gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), TRUE); + gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view), GTK_WRAP_WORD); + gtk_container_add(GTK_CONTAINER(scrolled_window), text_view); + gtk_widget_show(text_view); + + /* get the text_buffer widget and insert the text from file */ + text_buffer = (GtkWidget *) gtk_text_view_get_buffer(GTK_TEXT_VIEW(text_view)); + + xsane.mail_text_widget = text_buffer; + } +#else + { + GtkWidget *vscrollbar; + + /* Create the GtkText widget */ + text = gtk_text_new(NULL, NULL); + gtk_text_set_editable(GTK_TEXT(text), TRUE); /* text is editable */ + gtk_text_set_word_wrap(GTK_TEXT(text), TRUE); /* wrap complete words */ + gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 0); + gtk_widget_show(text); + xsane.mail_text_widget = text; - /* Add a vertical scrollbar to the GtkText widget */ - vscrollbar = gtk_vscrollbar_new(GTK_TEXT(text)->vadj); - gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0); - gtk_widget_show(vscrollbar); + /* Add a vertical scrollbar to the GtkText widget */ + vscrollbar = gtk_vscrollbar_new(GTK_TEXT(text)->vadj); + gtk_box_pack_start(GTK_BOX(hbox), vscrollbar, FALSE, FALSE, 0); + gtk_widget_show(vscrollbar); + } +#endif /* html mail */ @@ -4595,9 +4993,80 @@ static void xsane_mail_dialog() gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), xsane.mail_html_mode); gtk_box_pack_start(GTK_BOX(mail_project_vbox), button, FALSE, FALSE, 2); gtk_widget_show(button); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_html_mode_callback, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_html_mode_callback, NULL); xsane.mail_html_mode_widget = button; + xsane_separator_new(mail_scan_vbox, 2); + + /* FILETYPE MENU */ + /* button box, active when project exists */ + hbox = gtk_hbox_new(FALSE, 2); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); + gtk_box_pack_start(GTK_BOX(mail_project_vbox), hbox, FALSE, FALSE, 2); + gtk_widget_show(hbox); + + filetype_menu = gtk_menu_new(); + + filetype_nr = -1; + select_item = 0; + + +#ifdef HAVE_LIBJPEG + filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_JPEG); + gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item); + g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_JPEG); + gtk_widget_show(filetype_item); + filetype_nr++; + if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_JPEG)) ) + { + select_item = filetype_nr; + } +#endif + + +#ifdef HAVE_LIBPNG +#ifdef HAVE_LIBZ + filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PNG); + gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item); + g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_PNG); + gtk_widget_show(filetype_item); + filetype_nr++; + if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_PNG)) ) + { + select_item = filetype_nr; + } +#endif +#endif + + +#ifdef HAVE_LIBTIFF + filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_TIFF); + gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item); + g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_mail_filetype_callback, (void *) XSANE_FILETYPE_TIFF); + gtk_widget_show(filetype_item); + filetype_nr++; + if ( (preferences.mail_filetype) && (!strcasecmp(preferences.mail_filetype, XSANE_FILETYPE_TIFF)) ) + { + select_item = filetype_nr; + } +#endif + + label = gtk_label_new(TEXT_MAIL_FILETYPE); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); + gtk_widget_show(label); + + filetype_option_menu = gtk_option_menu_new(); + xsane_back_gtk_set_tooltip(xsane.tooltips, filetype_option_menu, DESC_MAIL_FILETYPE); + gtk_option_menu_set_menu(GTK_OPTION_MENU(filetype_option_menu), filetype_menu); + if (select_item >= 0) + { + gtk_option_menu_set_history(GTK_OPTION_MENU(filetype_option_menu), select_item); + } + gtk_box_pack_end(GTK_BOX(hbox), filetype_option_menu, FALSE, FALSE, 2); + gtk_widget_show(filetype_menu); + gtk_widget_show(filetype_option_menu); + + /* attachment frame */ attachment_frame = gtk_frame_new(TEXT_ATTACHMENTS); gtk_box_pack_start(GTK_BOX(mail_project_vbox), attachment_frame, FALSE, FALSE, 2); @@ -4605,7 +5074,7 @@ static void xsane_mail_dialog() /* attachment list */ scrolled_window = gtk_scrolled_window_new(0, 0); - gtk_widget_set_usize(scrolled_window, 200, 100); + gtk_widget_set_size_request(scrolled_window, 200, 100); gtk_container_add(GTK_CONTAINER(attachment_frame), scrolled_window); gtk_widget_show(scrolled_window); @@ -4623,17 +5092,26 @@ static void xsane_mail_dialog() gtk_box_pack_start(GTK_BOX(mail_project_vbox), hbox, FALSE, FALSE, 2); button = gtk_button_new_with_label(BUTTON_IMAGE_SHOW); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_show_callback, list); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_show_callback, list); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + +#if 0 + /* before we enable the edit function we have to make sure that the rename function + does also rename the image name of the opened viewer */ + button = gtk_button_new_with_label(BUTTON_IMAGE_EDIT); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_edit_callback, list); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); +#endif button = gtk_button_new_with_label(BUTTON_IMAGE_RENAME); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_callback, list); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_callback, list); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_label(BUTTON_IMAGE_DELETE); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_delete_callback, list); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_delete_callback, list); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); @@ -4644,22 +5122,6 @@ static void xsane_mail_dialog() xsane.mail_project_box = mail_project_vbox; - - /* status info */ - hbox = gtk_hbox_new(FALSE, 2); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); - gtk_box_pack_start(GTK_BOX(mail_scan_vbox), hbox, FALSE, FALSE, 2); - gtk_widget_show(hbox); - - label = gtk_label_new(TEXT_MAIL_STATUS); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_widget_show(label); - - label = gtk_label_new(""); - gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); - gtk_widget_show(label); - xsane.mail_status_label = label; - xsane_separator_new(mail_scan_vbox, 2); @@ -4675,12 +5137,12 @@ static void xsane_mail_dialog() gtk_box_pack_start(GTK_BOX(hbox), mail_project_exists_hbox, TRUE, TRUE, 0); button = gtk_button_new_with_label(BUTTON_SEND_PROJECT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_send, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_send, NULL); gtk_box_pack_start(GTK_BOX(mail_project_exists_hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); button = gtk_button_new_with_label(BUTTON_DELETE_PROJECT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_project_delete, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_project_delete, NULL); gtk_box_pack_start(GTK_BOX(mail_project_exists_hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); @@ -4688,10 +5150,18 @@ static void xsane_mail_dialog() xsane.mail_project_exists = mail_project_exists_hbox; button = gtk_button_new_with_label(BUTTON_CREATE_PROJECT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_project_create, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_project_create, NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); xsane.mail_project_not_exists = button; + /* progress bar */ + xsane.mail_progress_bar = (GtkProgressBar *) gtk_progress_bar_new(); + gtk_box_pack_start(GTK_BOX(mail_scan_vbox), (GtkWidget *) xsane.mail_progress_bar, FALSE, FALSE, 0); + gtk_progress_set_show_text(GTK_PROGRESS(xsane.mail_progress_bar), TRUE); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), ""); + gtk_widget_show(GTK_WIDGET(xsane.mail_progress_bar)); + + xsane.mail_dialog = mail_dialog; xsane_mail_project_load(); @@ -4710,11 +5180,135 @@ static void xsane_mail_dialog_close() return; } - gtk_accel_group_detach(xsane.accelerator_group, GTK_OBJECT(xsane.mail_dialog)); gtk_widget_destroy(xsane.mail_dialog); xsane.mail_dialog = NULL; xsane.mail_list = NULL; + xsane.mail_progress_bar = NULL; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_mail_project_set_sensitive(int sensitive) +{ + gtk_widget_set_sensitive(xsane.mail_project_box, sensitive); + gtk_widget_set_sensitive(xsane.mail_project_exists, sensitive); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_mail_project_display_status() +{ + FILE *lockfile; + char buf[256]; + char filename[PATH_MAX]; + int val; + int i, c; + + DBG(DBG_proc, "xsane_mail_project_display_status\n"); + + snprintf(filename, sizeof(filename), "%s/lockfile", preferences.mail_project); + lockfile = fopen(filename, "rb"); /* read binary (b for win32) */ + + if (lockfile) + { + i=0; + c=0; + while ((i<255) && (c != 10) && (c != EOF)) /* first line is mail status */ + { + c = fgetc(lockfile); + buf[i++] = c; + } + buf[i-1] = 0; + + fscanf(lockfile, "%d\n", &val); + + fclose(lockfile); + + if ( (!strcmp(buf, TEXT_MAIL_STATUS_SENDING)) || + (!strcmp(buf, TEXT_MAIL_STATUS_SENT)) || + (!strcmp(buf, TEXT_MAIL_STATUS_ERR_READ_PROJECT)) || + (!strcmp(buf, TEXT_MAIL_STATUS_POP3_CONNECTION_FAILED)) || + (!strcmp(buf, TEXT_MAIL_STATUS_POP3_LOGIN_FAILED)) || + (!strcmp(buf, TEXT_MAIL_STATUS_SMTP_CONNECTION_FAILED)) || + (!strcmp(buf, TEXT_MAIL_STATUS_SMTP_ERR_FROM)) || + (!strcmp(buf, TEXT_MAIL_STATUS_SMTP_ERR_RCPT)) || + (!strcmp(buf, TEXT_MAIL_STATUS_SMTP_ERR_DATA)) || + (!strcmp(buf, TEXT_MAIL_STATUS_SENT)) ) + { + if (strcmp(xsane.mail_status, buf)) + { + if (xsane.mail_status) + { + free(xsane.mail_status); + } + xsane.mail_status = strdup(buf); + + if (xsane.mail_progress_bar) + { + gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status)); + } + } + + xsane.mail_progress_val = val / 100.0; + if (xsane.mail_progress_bar) + { + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), xsane.mail_progress_val); + } + + DBG(DBG_info, "reading from lockfile: mail_status %s, mail_progress_val %1.3f\n" , xsane.mail_status, xsane.mail_progress_val); + + if (strcmp(xsane.mail_status, TEXT_MAIL_STATUS_SENDING)) /* not sending */ + { + DBG(DBG_info, "removing %s\n", filename); + remove(filename); /* remove lockfile */ + + xsane.mail_progress_val = 0.0; + + xsane_mail_project_update_project_status(); + + if (xsane.mail_dialog) + { + xsane_mail_project_load(); + + xsane_mail_project_set_sensitive(TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE); + } + } + } + } + else + { + DBG(DBG_info, "no lockfile present\n"); + if (xsane.mail_progress_bar) + { + gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), xsane.mail_progress_val); + } + + while (gtk_events_pending()) + { + gtk_main_iteration(); + } + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static gint xsane_mail_send_timer_callback(gpointer data) +{ + xsane_mail_project_display_status(); + + if (strcmp(xsane.mail_status, TEXT_MAIL_STATUS_SENDING)) /* not sending */ + { + if (xsane_mail_send_timer) + { + DBG(DBG_info, "disabling mail send timer\n"); + xsane_mail_send_timer = 0; + } + } + + return xsane_mail_send_timer; } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -4723,10 +5317,13 @@ static void xsane_mail_project_load() { FILE *projectfile; char page[256]; + char *type; + char *extension; char buf[256]; + char filename[PATH_MAX]; GtkWidget *list_item; int i; - char c; + int c; DBG(DBG_proc, "xsane_mail_project_load\n"); @@ -4754,25 +5351,29 @@ static void xsane_mail_project_load() xsane.mail_subject = NULL; } - gtk_signal_disconnect_by_func(GTK_OBJECT(xsane.mail_receiver_entry), GTK_SIGNAL_FUNC(xsane_mail_receiver_changed_callback), 0); - gtk_signal_disconnect_by_func(GTK_OBJECT(xsane.mail_subject_entry), GTK_SIGNAL_FUNC(xsane_mail_subject_changed_callback), 0); - gtk_signal_disconnect_by_func(GTK_OBJECT(xsane.mail_html_mode_widget), GTK_SIGNAL_FUNC(xsane_mail_html_mode_callback), 0); + g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.mail_receiver_entry), GTK_SIGNAL_FUNC(xsane_mail_receiver_changed_callback), 0); + g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.mail_subject_entry), GTK_SIGNAL_FUNC(xsane_mail_subject_changed_callback), 0); + g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.mail_html_mode_widget), GTK_SIGNAL_FUNC(xsane_mail_html_mode_callback), 0); +#ifdef HAVE_GTK_TEXT_VIEW_H + gtk_text_buffer_set_text(GTK_TEXT_BUFFER(xsane.mail_text_widget), "", 0); +#else gtk_text_set_point(GTK_TEXT(xsane.mail_text_widget), 0); gtk_text_forward_delete(GTK_TEXT(xsane.mail_text_widget), gtk_text_get_length(GTK_TEXT(xsane.mail_text_widget))); +#endif gtk_list_remove_items(GTK_LIST(xsane.mail_list), GTK_LIST(xsane.mail_list)->children); - snprintf(buf, sizeof(buf), "%s/xsane-mail-list", preferences.mail_project); - projectfile = fopen(buf, "rb"); /* read binary (b for win32) */ + snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project); + projectfile = fopen(filename, "rb"); /* read binary (b for win32) */ if ((!projectfile) || (feof(projectfile))) { - snprintf(buf, sizeof(buf), "%s/page-1.png", preferences.mail_project); - xsane.mail_filename=strdup(buf); + snprintf(filename, sizeof(filename), "%s/image-1.pnm", preferences.mail_project); + xsane.mail_filename=strdup(filename); xsane_update_counter_in_filename(&xsane.mail_filename, FALSE, 0, preferences.filename_counter_len); /* correct counter len */ - xsane.mail_status=strdup("not existant"); - gtk_label_set(GTK_LABEL(xsane.mail_status_label), _(xsane.mail_status)); + xsane.mail_status=strdup(TEXT_MAIL_STATUS_NOT_CREATED); + xsane.mail_progress_val = 0.0; xsane.mail_receiver=strdup(""); gtk_entry_set_text(GTK_ENTRY(xsane.mail_receiver_entry), (char *) xsane.mail_receiver); @@ -4780,9 +5381,12 @@ static void xsane_mail_project_load() xsane.mail_subject=strdup(""); gtk_entry_set_text(GTK_ENTRY(xsane.mail_subject_entry), (char *) xsane.mail_subject); - gtk_widget_set_sensitive(xsane.mail_project_box, FALSE); gtk_widget_hide(xsane.mail_project_exists); gtk_widget_show(xsane.mail_project_not_exists); + + gtk_widget_set_sensitive(xsane.mail_project_box, FALSE); + gtk_widget_set_sensitive(xsane.mail_project_exists, FALSE); + /* do not change sensitivity of mail_project_entry_box here !!! */ gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE); xsane.mail_project_save = 0; @@ -4797,13 +5401,17 @@ static void xsane_mail_project_load() page[i++] = c; } page[i-1] = 0; + if (strchr(page, '@')) + { + *strchr(page, '@') = 0; + } if (xsane.mail_status) { free(xsane.mail_status); } xsane.mail_status = strdup(page); - gtk_label_set(GTK_LABEL(xsane.mail_status_label), _(xsane.mail_status)); + xsane.mail_progress_val = 0.0; i=0; @@ -4828,8 +5436,8 @@ static void xsane_mail_project_load() } page[i-1] = 0; - snprintf(buf, sizeof(buf), "%s/%s", preferences.mail_project, page); - xsane.mail_filename=strdup(buf); + snprintf(filename, sizeof(filename), "%s/%s", preferences.mail_project, page); + xsane.mail_filename=strdup(filename); i=0; @@ -4883,10 +5491,22 @@ static void xsane_mail_project_load() break; /* mailtext follows */ } + extension = strrchr(page, '.'); + if (extension) + { + type = strdup(extension); + *extension = 0; + } + else + { + type = strdup(""); + } + if (c > 1) { list_item = gtk_list_item_new_with_label(page); gtk_object_set_data(GTK_OBJECT(list_item), "list_item_data", strdup(page)); + gtk_object_set_data(GTK_OBJECT(list_item), "list_item_type", strdup(type)); gtk_container_add(GTK_CONTAINER(xsane.mail_list), list_item); gtk_widget_show(list_item); } @@ -4895,22 +5515,35 @@ static void xsane_mail_project_load() while (!feof(projectfile)) { i = fread(buf, 1, sizeof(buf), projectfile); +#ifdef HAVE_GTK_TEXT_VIEW_H + gtk_text_buffer_insert_at_cursor(GTK_TEXT_BUFFER(xsane.mail_text_widget), buf, i); +#else gtk_text_insert(GTK_TEXT(xsane.mail_text_widget), NULL, NULL, NULL, buf, i); +#endif } - if (xsane.mail_status[0] == '*') /* mail project is locked (sending) */ + if (!strcmp(xsane.mail_status, TEXT_MAIL_STATUS_SENDING)) /* mail project is locked (sending) */ { - gtk_widget_set_sensitive(xsane.mail_project_box, FALSE); + xsane_mail_project_set_sensitive(FALSE); + gtk_widget_set_sensitive(xsane.mail_project_entry_box, TRUE); gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE); + + if (xsane_mail_send_timer == 0) + { + xsane_mail_send_timer = gtk_timeout_add(100, (GtkFunction) xsane_mail_send_timer_callback, NULL); + DBG(DBG_info, "enabling mail send timer (%d)\n", xsane_mail_send_timer); + } } else { - gtk_widget_set_sensitive(xsane.mail_project_box, TRUE); - gtk_widget_show(xsane.mail_project_exists); - gtk_widget_hide(xsane.mail_project_not_exists); + xsane_mail_project_set_sensitive(TRUE); + gtk_widget_set_sensitive(xsane.mail_project_entry_box, TRUE); gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE); } + gtk_widget_show(xsane.mail_project_exists); + gtk_widget_hide(xsane.mail_project_not_exists); + xsane.mail_project_save = 1; } @@ -4919,9 +5552,14 @@ static void xsane_mail_project_load() fclose(projectfile); } - gtk_signal_connect(GTK_OBJECT(xsane.mail_html_mode_widget), "clicked", (GtkSignalFunc) xsane_mail_html_mode_callback, NULL); - gtk_signal_connect(GTK_OBJECT(xsane.mail_receiver_entry), "changed", (GtkSignalFunc) xsane_mail_receiver_changed_callback, NULL); - gtk_signal_connect(GTK_OBJECT(xsane.mail_subject_entry), "changed", (GtkSignalFunc) xsane_mail_subject_changed_callback, NULL); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), xsane.mail_progress_val); + + xsane_mail_project_display_status(); + + g_signal_connect(GTK_OBJECT(xsane.mail_html_mode_widget), "clicked", (GtkSignalFunc) xsane_mail_html_mode_callback, NULL); + g_signal_connect(GTK_OBJECT(xsane.mail_receiver_entry), "changed", (GtkSignalFunc) xsane_mail_receiver_changed_callback, NULL); + g_signal_connect(GTK_OBJECT(xsane.mail_subject_entry), "changed", (GtkSignalFunc) xsane_mail_subject_changed_callback, NULL); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -4929,6 +5567,7 @@ static void xsane_mail_project_load() static void xsane_mail_project_delete() { char *page; + char *type; char file[256]; GList *list = (GList *) GTK_LIST(xsane.mail_list)->children; GtkObject *list_item; @@ -4939,9 +5578,11 @@ static void xsane_mail_project_delete() { list_item = GTK_OBJECT(list->data); page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + type = strdup((char *) gtk_object_get_data(list_item, "list_item_type")); xsane_convert_text_to_filename(&page); - snprintf(file, sizeof(file), "%s/%s.png", preferences.mail_project, page); + snprintf(file, sizeof(file), "%s/%s%s", preferences.mail_project, page, type); free(page); + free(type); remove(file); list = list->next; } @@ -4955,15 +5596,18 @@ static void xsane_mail_project_delete() /* ---------------------------------------------------------------------------------------------------------------------- */ -void xsane_mail_project_update_status() +static void xsane_mail_project_update_project_status() { FILE *projectfile; + char filename[PATH_MAX]; char buf[256]; - snprintf(buf, sizeof(buf), "%s/xsane-mail-list", preferences.mail_project); - projectfile = fopen(buf, "r+b"); /* r+ = read and write, position = start of file */ - snprintf(buf, 32, "%s ", xsane.mail_status); /* fill 32 characters status line */ + snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project); + projectfile = fopen(filename, "r+b"); /* r+ = read and write, position = start of file */ + + snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.mail_status); /* fill 32 characters status line */ fprintf(projectfile, "%s\n", buf); /* first line is status of mail */ + fclose(projectfile); } @@ -4974,7 +5618,8 @@ void xsane_mail_project_save() FILE *projectfile; GList *list = (GList *) GTK_LIST(xsane.mail_list)->children; GtkObject *list_item; - char *image; + char *page; + char *type; gchar *mail_text; char filename[256]; @@ -4983,16 +5628,8 @@ void xsane_mail_project_save() umask((mode_t) preferences.directory_umask); /* define new file permissions */ mkdir(preferences.mail_project, 0777); /* make sure directory exists */ - snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project); - - if (xsane.mail_status) - { - if (xsane.mail_status[0] == '?') - { - return; - } - } - + snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project); + if (xsane_create_secure_file(filename)) /* remove possibly existing symbolic links for security */ { char buf[256]; @@ -5006,14 +5643,18 @@ void xsane_mail_project_save() if (xsane.mail_status) { - snprintf(filename, 32, "%s ", xsane.mail_status); /* fill 32 characters status line */ - fprintf(projectfile, "%s\n", filename); /* first line is status of mail */ - gtk_label_set(GTK_LABEL(xsane.mail_status_label), _(xsane.mail_status)); + char buf[256]; + + snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.mail_status); /* fill 32 characters status line */ + fprintf(projectfile, "%s\n", buf); /* first line is status of mail */ + gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), _(xsane.mail_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0); } else { fprintf(projectfile, " \n"); /* no mail status */ - gtk_label_set(GTK_LABEL(xsane.mail_status_label), ""); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), ""); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0); } if (xsane.mail_receiver) @@ -5056,14 +5697,25 @@ void xsane_mail_project_save() while (list) { list_item = GTK_OBJECT(list->data); - image = (char *) gtk_object_get_data(list_item, "list_item_data"); - fprintf(projectfile, "%s\n", image); + page = (char *) gtk_object_get_data(list_item, "list_item_data"); + type = (char *) gtk_object_get_data(list_item, "list_item_type"); + fprintf(projectfile, "%s%s\n", page, type); list = list->next; } /* save mail text */ fprintf(projectfile, "mailtext:\n"); +#ifdef HAVE_GTK_TEXT_VIEW_H + { + GtkTextIter start, end; + + gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(xsane.mail_text_widget), &start); + gtk_text_buffer_get_end_iter(GTK_TEXT_BUFFER(xsane.mail_text_widget), &end); + mail_text = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(xsane.mail_text_widget), &start, &end, FALSE); + } +#else mail_text = gtk_editable_get_chars(GTK_EDITABLE(xsane.mail_text_widget), 0, -1); +#endif fprintf(projectfile, "%s", mail_text); fclose(projectfile); @@ -5081,7 +5733,7 @@ static void xsane_mail_project_create() { free(xsane.mail_status); } - xsane.mail_status = strdup("created"); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_CREATED); xsane_mail_project_save(); xsane_mail_project_load(); } @@ -5103,8 +5755,9 @@ static void xsane_mail_receiver_changed_callback(GtkWidget *widget, gpointer dat { free(xsane.mail_status); } - xsane.mail_status = strdup("changed"); - xsane_mail_project_save(); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED); + xsane.mail_project_save = 1; + xsane_mail_project_display_status(); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -5123,8 +5776,9 @@ static void xsane_mail_subject_changed_callback(GtkWidget *widget, gpointer data { free(xsane.mail_status); } - xsane.mail_status = strdup("changed"); - xsane_mail_project_save(); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED); + xsane.mail_project_save = 1; + xsane_mail_project_display_status(); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -5161,8 +5815,9 @@ static void xsane_mail_html_mode_callback(GtkWidget * widget) { free(xsane.mail_status); } - xsane.mail_status = strdup("changed"); - xsane_mail_project_save(); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED); + xsane.mail_project_save = 1; + xsane_mail_project_display_status(); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -5205,7 +5860,7 @@ static void xsane_mail_entry_move_up_callback(GtkWidget *widget, gpointer list) { free(xsane.mail_status); } - xsane.mail_status = strdup("changed"); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED); xsane_mail_project_save(); } } @@ -5252,7 +5907,7 @@ static void xsane_mail_entry_move_down_callback(GtkWidget *widget, gpointer list { free(xsane.mail_status); } - xsane.mail_status = strdup("changed"); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED); xsane_mail_project_save(); } } @@ -5278,6 +5933,7 @@ static void xsane_mail_entry_rename_callback(GtkWidget *widget, gpointer list) GList *select; char *oldpage; char *newpage; + char *type; char oldfile[256]; char newfile[256]; @@ -5290,14 +5946,15 @@ static void xsane_mail_entry_rename_callback(GtkWidget *widget, gpointer list) GtkWidget *text; GtkWidget *button; GtkWidget *vbox, *hbox; - char buf[256]; + char filename[PATH_MAX]; list_item = select->data; oldpage = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_data")); + type = strdup((char *) gtk_object_get_data(GTK_OBJECT(list_item), "list_item_type")); xsane_set_sensitivity(FALSE); - rename_dialog = gtk_window_new(GTK_WINDOW_DIALOG); + rename_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); xsane_set_window_icon(rename_dialog, 0); /* set the main vbox */ @@ -5314,27 +5971,36 @@ static void xsane_mail_entry_rename_callback(GtkWidget *widget, gpointer list) gtk_widget_show(hbox); gtk_window_set_position(GTK_WINDOW(rename_dialog), GTK_WIN_POS_CENTER); - gtk_window_set_policy(GTK_WINDOW(rename_dialog), FALSE, FALSE, FALSE); - snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_MAIL_RENAME); - gtk_window_set_title(GTK_WINDOW(rename_dialog), buf); - gtk_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_mail_entry_rename_button_callback, (void *) -1); + gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE); + snprintf(filename, sizeof(filename), "%s %s", xsane.prog_name, WINDOW_MAIL_RENAME); + gtk_window_set_title(GTK_WINDOW(rename_dialog), filename); + g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_mail_entry_rename_button_callback, (void *) -1); gtk_widget_show(rename_dialog); - text = gtk_entry_new_with_max_length(64); + text = gtk_entry_new(); xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MAILIMAGENAME); + gtk_entry_set_max_length(GTK_ENTRY(text), 64); gtk_entry_set_text(GTK_ENTRY(text), oldpage); - gtk_widget_set_usize(text, 300, 0); + gtk_widget_set_size_request(text, 300, -1); gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 4); gtk_widget_show(text); - button = gtk_button_new_with_label("OK"); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_button_callback, (void *) 1); +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_OK); +#else + button = gtk_button_new_with_label(BUTTON_OK); +#endif + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_button_callback, (void *) 1); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); - button = gtk_button_new_with_label("Cancel"); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_button_callback, (void *) -1); +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); +#else + button = gtk_button_new_with_label(BUTTON_CANCEL); +#endif + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_mail_entry_rename_button_callback,(void *) -1); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); @@ -5358,8 +6024,8 @@ static void xsane_mail_entry_rename_callback(GtkWidget *widget, gpointer list) xsane_convert_text_to_filename(&oldpage); xsane_convert_text_to_filename(&newpage); - snprintf(oldfile, sizeof(oldfile), "%s/%s.png", preferences.mail_project, oldpage); - snprintf(newfile, sizeof(newfile), "%s/%s.png", preferences.mail_project, newpage); + snprintf(oldfile, sizeof(oldfile), "%s/%s%s", preferences.mail_project, oldpage, type); + snprintf(newfile, sizeof(newfile), "%s/%s%s", preferences.mail_project, newpage, type); rename(oldfile, newfile); @@ -5367,7 +6033,7 @@ static void xsane_mail_entry_rename_callback(GtkWidget *widget, gpointer list) { free(xsane.mail_status); } - xsane.mail_status = strdup("changed"); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED); xsane_mail_project_save(); } @@ -5387,6 +6053,7 @@ static void xsane_mail_entry_delete_callback(GtkWidget *widget, gpointer list) GtkObject *list_item; GList *select; char *page; + char *type; char file[256]; DBG(DBG_proc, "xsane_mail_entry_delete_callback\n"); @@ -5396,9 +6063,11 @@ static void xsane_mail_entry_delete_callback(GtkWidget *widget, gpointer list) { list_item = GTK_OBJECT(select->data); page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + type = strdup((char *) gtk_object_get_data(list_item, "list_item_type")); xsane_convert_text_to_filename(&page); - snprintf(file, sizeof(file), "%s/%s.png", preferences.mail_project, page); + snprintf(file, sizeof(file), "%s/%s%s", preferences.mail_project, page, type); free(page); + free(type); remove(file); gtk_widget_destroy(GTK_WIDGET(list_item)); @@ -5406,7 +6075,7 @@ static void xsane_mail_entry_delete_callback(GtkWidget *widget, gpointer list) { free(xsane.mail_status); } - xsane.mail_status = strdup("changed"); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_CHANGED); xsane_mail_project_save(); } } @@ -5417,43 +6086,92 @@ static void xsane_mail_show_callback(GtkWidget *widget, gpointer list) { GtkObject *list_item; GList *select; - pid_t pid; - char *arg[100]; char *page; - char buf[256]; - int argnr; + char *type; + char filename[256]; DBG(DBG_proc, "xsane_mail_entry_show_callback\n"); select = GTK_LIST(list)->selection; if (select) { - argnr = xsane_parse_options(preferences.mail_viewer, arg); + list_item = GTK_OBJECT(select->data); + page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + type = strdup((char *) gtk_object_get_data(list_item, "list_item_type")); + xsane_convert_text_to_filename(&page); + snprintf(filename, sizeof(filename), "%s/%s%s", preferences.mail_project, page, type); + free(page); + free(type); + + xsane_viewer_new(filename, FALSE, filename, VIEWER_NO_MODIFICATION); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +#if 0 +static void xsane_mail_edit_callback(GtkWidget *widget, gpointer list) +{ + GtkObject *list_item; + GList *select; + char *page; + char *type; + char filename[256]; + FILE *outfile; + FILE *infile; + char outfilename[256]; + Image_info image_info; + int cancel_save; + + DBG(DBG_proc, "xsane_mail_entry_show_callback\n"); + select = GTK_LIST(list)->selection; + if (select) + { list_item = GTK_OBJECT(select->data); - page = (char *) gtk_object_get_data(list_item, "list_item_data"); - page = strdup(page); + page = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + type = strdup((char *) gtk_object_get_data(list_item, "list_item_type")); xsane_convert_text_to_filename(&page); - snprintf(buf, sizeof(buf), "%s/%s.png", preferences.mail_project, page); + snprintf(filename, sizeof(filename), "%s/%s%s", preferences.mail_project, page, type); free(page); - arg[argnr++] = buf; - arg[argnr] = 0; + free(type); - pid = fork(); - if (pid == 0) /* new process */ + infile = fopen(filename, "rb"); + if (!infile) { - DBG(DBG_info, "trying to change user id fo new subprocess:\n"); - DBG(DBG_info, "old effective uid = %d\n", geteuid()); - setuid(getuid()); - DBG(DBG_info, "new effective uid = %d\n", geteuid()); + DBG(DBG_error, "could not load file %s\n", filename); + return; + } - execvp(arg[0], arg); /* does not return if successfully */ - DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_MAIL_VIEWER, preferences.mail_viewer); - _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ + xsane_read_pnm_header(infile, &image_info); + + DBG(DBG_info, "copying image %s with geometry: %d x %d x %d, %d colors\n", filename, image_info.image_width, image_info.image_height, image_info.depth, image_info.colors); + + xsane_back_gtk_make_path(sizeof(outfilename), outfilename, 0, 0, "xsane-viewer-", xsane.dev_name, ".pnm", XSANE_PATH_TMP); + + outfile = fopen(outfilename, "wb"); + if (!outfile) + { + DBG(DBG_error, "could not save file %s\n", outfilename); + return; } + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), PROGRESS_CLONING_DATA); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0); + + xsane_save_rotate_image(outfile, infile, &image_info, 0, xsane.mail_progress_bar, &cancel_save); + + fclose(infile); + fclose(outfile); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.mail_progress_bar), ""); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.mail_progress_bar), 0.0); + + xsane_viewer_new(outfilename, FALSE, filename, VIEWER_NO_NAME_MODIFICATION); } } +#endif /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -5466,29 +6184,32 @@ static void xsane_create_mail(int fd) char *mail_text = NULL; char *mail_text_pos = NULL; char **attachment_filename = NULL; - char c; char buf[256]; char filename[256]; char content_id[256]; char image[256]; int i, j; + int c; int attachments = 0; int use_attachment = 0; int mail_text_size = 0; - snprintf(buf, sizeof(buf), "%s/xsane-mail-list", preferences.mail_project); - projectfile = fopen(buf, "rb"); /* read binary (b for win32) */ + DBG(DBG_proc, "xsane_create_mail\n"); + + snprintf(filename, sizeof(filename), "%s/xsane-mail-list", preferences.mail_project); + projectfile = fopen(filename, "rb"); /* read binary (b for win32) */ if ((!projectfile) || (feof(projectfile))) { - DBG(DBG_error, "could not open mail project file %s\n", buf); + DBG(DBG_error, "could not open mail project file %s\n", filename); if (xsane.mail_status) { free(xsane.mail_status); } - xsane.mail_status = strdup("could not read mailproject"); - xsane_mail_project_update_status(); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_ERR_READ_PROJECT); + xsane.mail_progress_val = 0.0; + xsane_front_gtk_mail_project_update_lockfile_status(); return; } @@ -5520,9 +6241,24 @@ static void xsane_create_mail(int fd) if (strcmp("mailtext:", image) && (c > 1)) { + char imagename[256]; + char *filename; + char *extension; + DBG(DBG_info, " - %s\n", image); + + extension = strrchr(image, '.'); + if (extension) + { + *extension = 0; + } + + snprintf(imagename, sizeof(imagename), "%s%s", image, preferences.mail_filetype); + filename=strdup(imagename); + xsane_convert_text_to_filename(&filename); attachment_filename = realloc(attachment_filename, (attachments+1)*sizeof(void *)); - attachment_filename[attachments++] = strdup(image); + attachment_filename[attachments++] = strdup(filename); + free(filename); } else { @@ -5533,11 +6269,12 @@ static void xsane_create_mail(int fd) /* read mail text */ while (!feof(projectfile)) { - mail_text = realloc(mail_text, mail_text_size+1024); /* increase mail_text by 1KB */ + mail_text = realloc(mail_text, mail_text_size+1025); /* increase mail_text by 1KB */ mail_text_size += fread(mail_text+mail_text_size, 1, 1024, projectfile); /* read next KB */ } DBG(DBG_info, "%d bytes mailtext read\n", mail_text_size); + *(mail_text + mail_text_size) = 0; /* set end of text marker */ mail_text_pos = mail_text; if (xsane.mail_html_mode) /* create html mail */ @@ -5556,13 +6293,11 @@ static void xsane_create_mail(int fd) if (use_attachment < attachments) { - image_filename = strdup(attachment_filename[use_attachment++]); - xsane_convert_text_to_filename(&image_filename); + image_filename = attachment_filename[use_attachment++]; DBG(DBG_info, "inserting image cid for %s\n", image_filename); snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */ snprintf(buf, sizeof(buf), "

\n", content_id); write(fd, buf, strlen(buf)); - free(image_filename); } else /* more images selected than available */ { @@ -5582,13 +6317,11 @@ static void xsane_create_mail(int fd) while (use_attachment < attachments) /* append not already referenced images */ { - image_filename = strdup(attachment_filename[use_attachment++]); - xsane_convert_text_to_filename(&image_filename); + image_filename = attachment_filename[use_attachment++]; DBG(DBG_info, "appending image cid for %s\n", image_filename); snprintf(content_id, sizeof(content_id), "%s", image_filename); /* content_id */ snprintf(buf, sizeof(buf), "

\n", content_id); write(fd, buf, strlen(buf)); - free(image_filename); } snprintf(buf, sizeof(buf), "\n"); @@ -5597,25 +6330,35 @@ static void xsane_create_mail(int fd) for (i=0; ichildren; + GtkObject *list_item; + char source_filename[PATH_MAX]; + char mail_filename[PATH_MAX]; + int output_format; + int cancel_save = 0; DBG(DBG_proc, "xsane_mail_send\n"); - gtk_widget_set_sensitive(xsane.mail_project_box, FALSE); - gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE); + xsane_set_sensitivity(FALSE); /* do not allow changing xsane mode */ while (gtk_events_pending()) { + DBG(DBG_info, "calling gtk_main_iteration\n"); gtk_main_iteration(); } + if (xsane.mail_project_save) + { + xsane.mail_project_save = 0; + xsane_mail_project_save(); + } + + xsane.mail_progress_size = 0; + xsane.mail_progress_bytes = 0; + + while (list) + { + list_item = GTK_OBJECT(list->data); + image = strdup((char *) gtk_object_get_data(list_item, "list_item_data")); + type = strdup((char *) gtk_object_get_data(list_item, "list_item_type")); + xsane_convert_text_to_filename(&image); + snprintf(source_filename, sizeof(source_filename), "%s/%s%s", preferences.mail_project, image, type); + snprintf(mail_filename, sizeof(mail_filename), "%s/mail-%s%s", preferences.mail_project, image, preferences.mail_filetype); + free(image); + free(type); + DBG(DBG_info, "converting %s to %s\n", source_filename, mail_filename); + output_format = xsane_identify_output_format(mail_filename, NULL, NULL); + xsane_save_image_as(mail_filename, source_filename, output_format, xsane.mail_progress_bar, &cancel_save); + list = list->next; + xsane.mail_progress_size += xsane_get_filesize(mail_filename); + } + + if (xsane.mail_status) { free(xsane.mail_status); } - xsane.mail_status = strdup("* sending"); - xsane_mail_project_save(); + xsane.mail_status = strdup(TEXT_MAIL_STATUS_SENDING); + xsane.mail_progress_val = 0.0; + xsane_mail_project_display_status(); /* display status before creating lockfile! */ + xsane_front_gtk_mail_project_update_lockfile_status(); /* create lockfile and update status */ pid = fork(); if (pid == 0) /* new process */ { - DBG(DBG_info, "trying to change user id fo new subprocess:\n"); - DBG(DBG_info, "old effective uid = %d\n", geteuid()); + FILE *ipc_file = NULL; + + if (xsane.ipc_pipefd[0]) + { + close(xsane.ipc_pipefd[0]); /* close reading end of pipe */ + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + + DBG(DBG_info, "trying to change user id for new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); setuid(getuid()); - DBG(DBG_info, "new effective uid = %d\n", geteuid()); + DBG(DBG_info, "new effective uid = %d\n", (int) geteuid()); xsane_mail_send_process(); _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ } - - memset (&act, 0, sizeof (act)); - act.sa_handler = xsane_mail_send_process_exited; - sigaction (SIGCHLD, &act, 0); - - if (xsane.mail_status) + else /* parent process */ { - free(xsane.mail_status); + xsane_add_process_to_list(pid); /* add pid to child process list */ } - xsane.mail_status = strdup("?"); + + xsane_mail_send_timer = gtk_timeout_add(100, (GtkFunction) xsane_mail_send_timer_callback, NULL); + DBG(DBG_info, "enabling mail send timer (%d)\n", xsane_mail_send_timer); + + xsane_set_sensitivity(TRUE); /* allow changing xsane mode */ +#if 0 + gtk_widget_set_sensitive(xsane.mail_project_entry_box, TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE); + gtk_widget_set_sensitive(xsane.mail_project_box, FALSE); +#endif + xsane_mail_project_set_sensitive(FALSE); } #endif @@ -5829,9 +6632,16 @@ static void xsane_pref_toggle_tooltips(GtkWidget *widget, gpointer data) /* ---------------------------------------------------------------------------------------------------------------------- */ -static void xsane_show_license(GtkWidget *widget, gpointer data) +static void xsane_show_eula(GtkWidget *widget, gpointer data) +{ + xsane_display_eula(0); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_show_gpl(GtkWidget *widget, gpointer data) { - xsane_display_license(0); + xsane_display_gpl(); } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -5847,6 +6657,7 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via DBG(DBG_proc, "xsane_show_doc_via_nsr(%s)\n", name); + /* at first we have to test if netscape is running */ /* a simple way is to take a look at ~/.netscape/lock */ /* when this is a link we can assume that netscape is running */ @@ -5879,15 +6690,36 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via if (pid == 0) /* new process */ { - DBG(DBG_info, "trying to change user id fo new subprocess:\n"); - DBG(DBG_info, "old effective uid = %d\n", geteuid()); + FILE *ipc_file = NULL; + + if (xsane.ipc_pipefd[0]) + { + close(xsane.ipc_pipefd[0]); /* close reading end of pipe */ + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + + DBG(DBG_info, "trying to change user id for new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); setuid(getuid()); - DBG(DBG_info, "new effective uid = %d\n", geteuid()); + DBG(DBG_info, "new effective uid = %d\n", (int) geteuid()); execvp(arg[0], arg); /* does not return if successfully */ - DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_DOC_VIEWER, preferences.doc_viewer); + DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_DOC_VIEWER, preferences.browser); + + /* send error message via IPC pipe to parent process */ + if (ipc_file) + { + fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_DOC_VIEWER, preferences.browser, strerror(errno)); + fflush(ipc_file); /* make sure message is displayed */ + fclose(ipc_file); + } + _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ } + else /* parent process */ + { + xsane_add_process_to_list(pid); /* add pid to child process list */ + } } else /* netscape not running */ { @@ -5900,15 +6732,36 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via if (pid == 0) /* new process */ { - DBG(DBG_info, "trying to change user id fo new subprocess:\n"); - DBG(DBG_info, "old effective uid = %d\n", geteuid()); + FILE *ipc_file = NULL; + + if (xsane.ipc_pipefd[0]) + { + close(xsane.ipc_pipefd[0]); /* close reading end of pipe */ + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + + DBG(DBG_info, "trying to change user id for new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); setuid(getuid()); - DBG(DBG_info, "new effective uid = %d\n", geteuid()); + DBG(DBG_info, "new effective uid = %d\n", (int) geteuid()); execvp(arg[0], arg); /* does not return if successfully */ - DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_DOC_VIEWER, preferences.doc_viewer); + DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_DOC_VIEWER, preferences.browser); + + /* send error message via IPC pipe to parent process */ + if (ipc_file) + { + fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_DOC_VIEWER, preferences.browser, strerror(errno)); + fflush(ipc_file); /* make sure message is displayed */ + fclose(ipc_file); + } + _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ } + else /* parent process */ + { + xsane_add_process_to_list(pid); /* add pid to child process list */ + } } while (gtk_events_pending()) @@ -5917,6 +6770,54 @@ static void xsane_show_doc_via_nsr(GtkWidget *widget, gpointer data) /* show via } } +/* ---------------------------------------------------------------------------------------------------------------------- */ +#if 0 +/* may be used to parse command lines for execvp like popen does */ +static char **xsane_parse_command(char *command_line, char *url) +{ + char **argv = NULL; + //char *command = strdup(command_line); + char command[1024]; + char *command_pos = command; + char *arg_end; + int size = 0; + + snprintf(command, sizeof(command), command_line, url); + + argv = malloc(sizeof(char *) * 2); + + while (command_pos) + { + argv = realloc(argv, sizeof(char *) * (size+2)); + + arg_end = strchr(command_pos, ' '); + if (arg_end) + { + *arg_end = 0; + } + + argv[size] = strdup(command_pos); + + if (arg_end) + { + command_pos = arg_end + 1; + } + else + { + command_pos = NULL; + } + + size++; + } + + argv[size] = NULL; + + free(command); + + return (argv); +} +#endif + /* ---------------------------------------------------------------------------------------------------------------------- */ static void xsane_show_doc(GtkWidget *widget, gpointer data) @@ -5939,135 +6840,82 @@ static void xsane_show_doc(GtkWidget *widget, gpointer data) snprintf(path, sizeof(path), "%s/%s-doc.html", STRINGIFY(PATH_XSANE_DOC_DIR), name); /* no, we use original doc */ } - if (!strcmp(preferences.doc_viewer, DOCVIEWER_NETSCAPE)) + if (!strcmp(preferences.browser, BROWSER_NETSCAPE)) { xsane_show_doc_via_nsr(widget, (void *) path); } else { - arg[0] = preferences.doc_viewer; + arg[0] = preferences.browser; arg[1] = path; arg[2] = 0; pid = fork(); if (pid == 0) /* new process */ - { - DBG(DBG_info, "trying to change user id fo new subprocess:\n"); - DBG(DBG_info, "old effective uid = %d\n", geteuid()); + { + FILE *ipc_file = NULL; + + if (xsane.ipc_pipefd[0]) + { + close(xsane.ipc_pipefd[0]); /* close reading end of pipe */ + ipc_file = fdopen(xsane.ipc_pipefd[1], "w"); + } + + DBG(DBG_info, "trying to change user id for new subprocess:\n"); + DBG(DBG_info, "old effective uid = %d\n", (int) geteuid()); setuid(getuid()); - DBG(DBG_info, "new effective uid = %d\n", geteuid()); + DBG(DBG_info, "new effective uid = %d\n", (int) geteuid()); DBG(DBG_info, "executing %s %s\n", arg[0], arg[1]); execvp(arg[0], arg); /* does not return if successfully */ - DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_DOC_VIEWER, preferences.doc_viewer); - _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ - } - } -} - -/* ---------------------------------------------------------------------------------------------------------------------- */ - -static GtkWidget *xsane_view_build_menu(void) -{ - GtkWidget *menu, *item; - - DBG(DBG_proc, "xsane_view_build_menu\n"); - - menu = gtk_menu_new(); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(menu)); - /* gtk_menu_set_accel_group(GTK_MENU(menu), xsane.accelerator_group); */ - - /* show tooltips */ - - item = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_TOOLTIPS); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_1, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), preferences.tooltips_enabled); - gtk_menu_append(GTK_MENU(menu), item); - gtk_widget_show(item); - gtk_signal_connect(GTK_OBJECT(item), "toggled", (GtkSignalFunc) xsane_pref_toggle_tooltips, NULL); - - - /* insert separator: */ - - item = gtk_menu_item_new(); - gtk_menu_append(GTK_MENU(menu), item); - gtk_widget_show(item); - - - /* show preview */ - - xsane.show_preview_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_PREVIEW); - gtk_widget_add_accelerator(xsane.show_preview_widget, "activate", xsane.accelerator_group, GDK_2, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_menu_append(GTK_MENU(menu), xsane.show_preview_widget); - gtk_widget_show(xsane.show_preview_widget); - gtk_signal_connect(GTK_OBJECT(xsane.show_preview_widget), "toggled", (GtkSignalFunc) xsane_show_preview_callback, NULL); - - /* show histogram */ - - xsane.show_histogram_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_HISTOGRAM); - gtk_widget_add_accelerator(xsane.show_histogram_widget, "activate", xsane.accelerator_group, GDK_3, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_histogram_widget), preferences.show_histogram); - gtk_menu_append(GTK_MENU(menu), xsane.show_histogram_widget); - gtk_widget_show(xsane.show_histogram_widget); - gtk_signal_connect(GTK_OBJECT(xsane.show_histogram_widget), "toggled", (GtkSignalFunc) xsane_show_histogram_callback, NULL); - - -#ifdef HAVE_WORKING_GTK_GAMMACURVE - /* show gamma */ - - xsane.show_gamma_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_GAMMA); - gtk_widget_add_accelerator(xsane.show_gamma_widget, "activate", xsane.accelerator_group, GDK_4, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_gamma_widget), preferences.show_gamma); - gtk_menu_append(GTK_MENU(menu), xsane.show_gamma_widget); - gtk_widget_show(xsane.show_gamma_widget); - gtk_signal_connect(GTK_OBJECT(xsane.show_gamma_widget), "toggled", (GtkSignalFunc) xsane_show_gamma_callback, NULL); -#endif - - - /* show standard options */ - - xsane.show_standard_options_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_STANDARDOPTIONS); - gtk_widget_add_accelerator(xsane.show_standard_options_widget, "activate", xsane.accelerator_group, GDK_5, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_standard_options_widget), preferences.show_standard_options); - gtk_menu_append(GTK_MENU(menu), xsane.show_standard_options_widget); - gtk_widget_show(xsane.show_standard_options_widget); - gtk_signal_connect(GTK_OBJECT(xsane.show_standard_options_widget), "toggled", - (GtkSignalFunc) xsane_show_standard_options_callback, NULL); + DBG(DBG_error, "%s %s\n", ERR_FAILED_EXEC_DOC_VIEWER, preferences.browser); + /* send error message via IPC pipe to parent process */ + if (ipc_file) + { + fprintf(ipc_file, "%s %s:\n%s", ERR_FAILED_EXEC_DOC_VIEWER, preferences.browser, strerror(errno)); + fflush(ipc_file); /* make sure message is displayed */ + fclose(ipc_file); + } - /* show advanced options */ + _exit(0); /* do not use exit() here! otherwise gtk gets in trouble */ + } + else /* parent process */ + { + xsane_add_process_to_list(pid); /* add pid to child process list */ + } + } +} - xsane.show_advanced_options_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_ADVANCEDOPTIONS); - gtk_widget_add_accelerator(xsane.show_advanced_options_widget, "activate", xsane.accelerator_group, GDK_6, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_advanced_options_widget), preferences.show_advanced_options); - gtk_menu_append(GTK_MENU(menu), xsane.show_advanced_options_widget); - gtk_widget_show(xsane.show_advanced_options_widget); - gtk_signal_connect(GTK_OBJECT(xsane.show_advanced_options_widget), "toggled", - (GtkSignalFunc) xsane_show_advanced_options_callback, NULL); +/* ---------------------------------------------------------------------------------------------------------------------- */ - return menu; +static void xsane_scan_callback(void) +{ + xsane.scan_rotation = xsane.preview->rotation; + xsane_scan_dialog(); } /* ---------------------------------------------------------------------------------------------------------------------- */ -static GtkWidget *xsane_pref_build_menu(void) +static GtkWidget *xsane_view_build_menu(void) { GtkWidget *menu, *item, *submenu, *subitem; - DBG(DBG_proc, "xsane_pref_build_menu\n"); + DBG(DBG_proc, "xsane_view_build_menu\n"); menu = gtk_menu_new(); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(menu)); + gtk_menu_set_accel_group(GTK_MENU(menu), xsane.accelerator_group); + /* show tooltips */ - /* XSane setup dialog */ - - item = gtk_menu_item_new_with_label(MENU_ITEM_SETUP); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_S, GDK_SHIFT_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + item = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_TOOLTIPS); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_T, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), preferences.tooltips_enabled); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_setup_dialog, NULL); gtk_widget_show(item); + g_signal_connect(GTK_OBJECT(item), "toggled", (GtkSignalFunc) xsane_pref_toggle_tooltips, NULL); + /* insert separator: */ @@ -6076,126 +6924,205 @@ static GtkWidget *xsane_pref_build_menu(void) gtk_widget_show(item); -#ifdef XSANE_TEST - /* XSane batch scan dialog */ + /* show resolution list */ + + xsane.show_resolution_list_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_RESOLUTIONLIST); + gtk_widget_add_accelerator(xsane.show_resolution_list_widget, "activate", xsane.accelerator_group, GDK_L, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_resolution_list_widget), preferences.show_resolution_list); + gtk_menu_append(GTK_MENU(menu), xsane.show_resolution_list_widget); + gtk_widget_show(xsane.show_resolution_list_widget); + g_signal_connect(GTK_OBJECT(xsane.show_resolution_list_widget), "toggled", (GtkSignalFunc) xsane_show_resolution_list_callback, NULL); - item = gtk_menu_item_new_with_label("Batch scan"); - gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_batch_scan_dialog, NULL); - gtk_widget_show(item); /* insert separator: */ item = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), item); gtk_widget_show(item); -#endif - /* length unit */ + /* update policy */ - item = gtk_menu_item_new_with_label(MENU_ITEM_LENGTH_UNIT); + item = gtk_menu_item_new_with_label(MENU_ITEM_UPDATE_POLICY); gtk_menu_append(GTK_MENU(menu), item); gtk_widget_show(item); submenu = gtk_menu_new(); - subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_MILLIMETERS); + subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_CONTINUOUS); gtk_menu_append(GTK_MENU(submenu), subitem); - if ( (preferences.length_unit > 0.9) && (preferences.length_unit < 1.1)) + if (preferences.gtk_update_policy == GTK_UPDATE_CONTINUOUS) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); } - gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_pref_unit_callback, "mm"); + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_CONTINUOUS); gtk_widget_show(subitem); - xsane.length_unit_mm = subitem; + xsane.update_policy_continu = subitem; - subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_CENTIMETERS); + subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_DISCONTINU); gtk_menu_append(GTK_MENU(submenu), subitem); - if ( (preferences.length_unit > 9.9) && (preferences.length_unit < 10.1)) + if (preferences.gtk_update_policy == GTK_UPDATE_DISCONTINUOUS) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); } - gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_pref_unit_callback, "cm"); + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DISCONTINUOUS); gtk_widget_show(subitem); - xsane.length_unit_cm = subitem; + xsane.update_policy_discont = subitem; - subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_INCHES); + subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_DELAYED); gtk_menu_append(GTK_MENU(submenu), subitem); - if ( (preferences.length_unit > 25.3) && (preferences.length_unit < 25.5)) + if (preferences.gtk_update_policy == GTK_UPDATE_DELAYED) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); } - gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_pref_unit_callback, "in"); + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DELAYED); gtk_widget_show(subitem); - xsane.length_unit_in = subitem; + xsane.update_policy_delayed = subitem; gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); + /* insert separator: */ item = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), item); gtk_widget_show(item); - /* update policy */ - item = gtk_menu_item_new_with_label(MENU_ITEM_UPDATE_POLICY); + /* length unit */ + + item = gtk_menu_item_new_with_label(MENU_ITEM_LENGTH_UNIT); gtk_menu_append(GTK_MENU(menu), item); gtk_widget_show(item); submenu = gtk_menu_new(); - subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_CONTINUOUS); + subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_MILLIMETERS); gtk_menu_append(GTK_MENU(submenu), subitem); - if (preferences.gtk_update_policy == GTK_UPDATE_CONTINUOUS) + if ( (preferences.length_unit > 0.9) && (preferences.length_unit < 1.1)) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); } - gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_CONTINUOUS); + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_pref_unit_callback, "mm"); gtk_widget_show(subitem); - xsane.update_policy_continu = subitem; + xsane.length_unit_mm = subitem; - subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_DISCONTINU); + subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_CENTIMETERS); gtk_menu_append(GTK_MENU(submenu), subitem); - if (preferences.gtk_update_policy == GTK_UPDATE_DISCONTINUOUS) + if ( (preferences.length_unit > 9.9) && (preferences.length_unit < 10.1)) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); } - gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DISCONTINUOUS); + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_pref_unit_callback, "cm"); gtk_widget_show(subitem); - xsane.update_policy_discont = subitem; + xsane.length_unit_cm = subitem; - subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_POLICY_DELAYED); + subitem = gtk_check_menu_item_new_with_label(SUBMENU_ITEM_LENGTH_INCHES); gtk_menu_append(GTK_MENU(submenu), subitem); - if (preferences.gtk_update_policy == GTK_UPDATE_DELAYED) + if ( (preferences.length_unit > 25.3) && (preferences.length_unit < 25.5)) { gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(subitem), TRUE); } - gtk_signal_connect(GTK_OBJECT(subitem), "activate", (GtkSignalFunc) xsane_set_update_policy_callback, (void *) GTK_UPDATE_DELAYED); + g_signal_connect(GTK_OBJECT(subitem), "toggled", (GtkSignalFunc) xsane_set_pref_unit_callback, "in"); gtk_widget_show(subitem); - xsane.update_policy_delayed = subitem; + xsane.length_unit_in = subitem; gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu); + return menu; +} - /* insert separator: */ +/* ---------------------------------------------------------------------------------------------------------------------- */ - item = gtk_menu_item_new(); - gtk_menu_append(GTK_MENU(menu), item); - gtk_widget_show(item); +static GtkWidget *xsane_window_build_menu(void) +{ + GtkWidget *menu; + DBG(DBG_proc, "xsane_window_build_menu\n"); - /* show resolution list */ + menu = gtk_menu_new(); + gtk_menu_set_accel_group(GTK_MENU(menu), xsane.accelerator_group); - xsane.show_resolution_list_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_RESOLUTIONLIST); - gtk_widget_add_accelerator(xsane.show_resolution_list_widget, "activate", xsane.accelerator_group, GDK_L, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_resolution_list_widget), preferences.show_resolution_list); - gtk_menu_append(GTK_MENU(menu), xsane.show_resolution_list_widget); - gtk_widget_show(xsane.show_resolution_list_widget); - gtk_signal_connect(GTK_OBJECT(xsane.show_resolution_list_widget), "toggled", - (GtkSignalFunc) xsane_show_resolution_list_callback, NULL); + /* show preview */ + + xsane.show_preview_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_PREVIEW); + gtk_widget_add_accelerator(xsane.show_preview_widget, "activate", xsane.accelerator_group, GDK_1, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_menu_append(GTK_MENU(menu), xsane.show_preview_widget); + gtk_widget_show(xsane.show_preview_widget); + g_signal_connect(GTK_OBJECT(xsane.show_preview_widget), "toggled", (GtkSignalFunc) xsane_show_preview_callback, NULL); + + /* show histogram */ + + xsane.show_histogram_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_HISTOGRAM); + gtk_widget_add_accelerator(xsane.show_histogram_widget, "activate", xsane.accelerator_group, GDK_2, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_histogram_widget), preferences.show_histogram); + gtk_menu_append(GTK_MENU(menu), xsane.show_histogram_widget); + gtk_widget_show(xsane.show_histogram_widget); + g_signal_connect(GTK_OBJECT(xsane.show_histogram_widget), "toggled", (GtkSignalFunc) xsane_show_histogram_callback, NULL); + + +#ifdef HAVE_WORKING_GTK_GAMMACURVE + /* show gamma */ + + xsane.show_gamma_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_GAMMA); + gtk_widget_add_accelerator(xsane.show_gamma_widget, "activate", xsane.accelerator_group, GDK_3, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_gamma_widget), preferences.show_gamma); + gtk_menu_append(GTK_MENU(menu), xsane.show_gamma_widget); + gtk_widget_show(xsane.show_gamma_widget); + g_signal_connect(GTK_OBJECT(xsane.show_gamma_widget), "toggled", (GtkSignalFunc) xsane_show_gamma_callback, NULL); +#endif + + /* show batch_scan */ + + xsane.show_batch_scan_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_BATCH_SCAN); + gtk_widget_add_accelerator(xsane.show_batch_scan_widget, "activate", xsane.accelerator_group, GDK_4, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_batch_scan_widget), preferences.show_batch_scan); + gtk_menu_append(GTK_MENU(menu), xsane.show_batch_scan_widget); + gtk_widget_show(xsane.show_batch_scan_widget); + g_signal_connect(GTK_OBJECT(xsane.show_batch_scan_widget), "toggled", (GtkSignalFunc) xsane_show_batch_scan_callback, NULL); + + /* show standard options */ + + xsane.show_standard_options_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_STANDARDOPTIONS); + gtk_widget_add_accelerator(xsane.show_standard_options_widget, "activate", xsane.accelerator_group, GDK_5, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_standard_options_widget), preferences.show_standard_options); + gtk_menu_append(GTK_MENU(menu), xsane.show_standard_options_widget); + gtk_widget_show(xsane.show_standard_options_widget); + g_signal_connect(GTK_OBJECT(xsane.show_standard_options_widget), "toggled", (GtkSignalFunc) xsane_show_standard_options_callback, NULL); + + + /* show advanced options */ + + xsane.show_advanced_options_widget = gtk_check_menu_item_new_with_label(MENU_ITEM_SHOW_ADVANCEDOPTIONS); + gtk_widget_add_accelerator(xsane.show_advanced_options_widget, "activate", xsane.accelerator_group, GDK_6, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_advanced_options_widget), preferences.show_advanced_options); + gtk_menu_append(GTK_MENU(menu), xsane.show_advanced_options_widget); + gtk_widget_show(xsane.show_advanced_options_widget); + g_signal_connect(GTK_OBJECT(xsane.show_advanced_options_widget), "toggled", (GtkSignalFunc) xsane_show_advanced_options_callback, NULL); + + return menu; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static GtkWidget *xsane_preferences_build_menu(void) +{ + GtkWidget *menu, *item; + + DBG(DBG_proc, "xsane_preferences_build_menu\n"); + + menu = gtk_menu_new(); + gtk_menu_set_accel_group(GTK_MENU(menu), xsane.accelerator_group); + + + /* XSane setup dialog */ + + item = gtk_menu_item_new_with_label(MENU_ITEM_SETUP); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_S, GDK_MOD1_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_menu_append(GTK_MENU(menu), item); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_setup_dialog, NULL); + gtk_widget_show(item); /* insert separator: */ @@ -6204,16 +7131,14 @@ static GtkWidget *xsane_pref_build_menu(void) gtk_widget_show(item); - /* page orientation */ - item = gtk_check_menu_item_new_with_label(MENU_ITEM_PAGE_ROTATE); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_R, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), preferences.psrotate); + /* change working directory */ + + item = gtk_menu_item_new_with_label(MENU_ITEM_CHANGE_WORKING_DIR); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_D, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_menu_append(GTK_MENU(menu), item); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_change_working_directory, NULL); gtk_widget_show(item); - gtk_signal_connect(GTK_OBJECT(item), "toggled", (GtkSignalFunc) xsane_page_rotate_callback, NULL); - - /* insert separator: */ @@ -6221,34 +7146,33 @@ static GtkWidget *xsane_pref_build_menu(void) gtk_menu_append(GTK_MENU(menu), item); gtk_widget_show(item); - /* Save device setting */ + /* edit medium definitions */ - item = gtk_menu_item_new_with_label(MENU_ITEM_SAVE_DEVICE_SETTINGS); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_P, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + item = gtk_check_menu_item_new_with_label(MENU_ITEM_EDIT_MEDIUM_DEF); + g_signal_connect(GTK_OBJECT(item), "toggled", (GtkSignalFunc) xsane_edit_medium_definition_callback, NULL); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_device_preferences_save, NULL); gtk_widget_show(item); - /* Load device setting */ + /* insert separator: */ - item = gtk_menu_item_new_with_label(MENU_ITEM_LOAD_DEVICE_SETTINGS); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_G, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + item = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_device_preferences_load, NULL); gtk_widget_show(item); - /* insert separator: */ + /* Save device setting */ - item = gtk_menu_item_new(); + item = gtk_menu_item_new_with_label(MENU_ITEM_SAVE_DEVICE_SETTINGS); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_P, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_menu_append(GTK_MENU(menu), item); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_device_preferences_save, NULL); gtk_widget_show(item); - /* change working directory */ + /* Load device setting */ - item = gtk_menu_item_new_with_label(MENU_ITEM_CHANGE_WORKING_DIR); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_D, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + item = gtk_menu_item_new_with_label(MENU_ITEM_LOAD_DEVICE_SETTINGS); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_G, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_change_working_directory, NULL); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_device_preferences_load, NULL); gtk_widget_show(item); return menu; @@ -6263,23 +7187,16 @@ static GtkWidget *xsane_help_build_menu(void) DBG(DBG_proc, "xsane_help_build_menu\n"); menu = gtk_menu_new(); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(menu)); + gtk_menu_set_accel_group(GTK_MENU(menu), xsane.accelerator_group); - /* XSane about dialog */ - - item = gtk_menu_item_new_with_label(MENU_ITEM_ABOUT_XSANE); - gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_about_dialog, NULL); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F6, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_widget_show(item); - /* XSane about translation dialog */ + /* XSane doc -> html viewer */ - item = gtk_menu_item_new_with_label(MENU_ITEM_ABOUT_TRANSLATION); + item = gtk_menu_item_new_with_label(MENU_ITEM_XSANE_DOC); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_about_translation_dialog, NULL); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F7, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-xsane"); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F1, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_widget_show(item); @@ -6290,28 +7207,46 @@ static GtkWidget *xsane_help_build_menu(void) gtk_widget_show(item); - /* XSane license */ + /* Backend doc -> html viewer */ + + if (xsane.backend) + { + item = gtk_menu_item_new_with_label(MENU_ITEM_BACKEND_DOC); + gtk_menu_append(GTK_MENU(menu), item); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) xsane.backend); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F2, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_widget_show(item); + } + + + /* available backends -> html viewer */ - item = gtk_menu_item_new_with_label(MENU_ITEM_XSANE_LICENSE); + item = gtk_menu_item_new_with_label(MENU_ITEM_AVAILABLE_BACKENDS); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_license, NULL); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F8, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-backends"); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F3, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_widget_show(item); + + /* problems -> html viewer */ - /* separator */ + item = gtk_menu_item_new_with_label(MENU_ITEM_PROBLEMS); + gtk_menu_append(GTK_MENU(menu), item); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-problems"); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F4, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_widget_show(item); item = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), item); gtk_widget_show(item); - /* XSane doc -> html viewer */ + /* scantips -> html viewer */ - item = gtk_menu_item_new_with_label(MENU_ITEM_XSANE_DOC); + item = gtk_menu_item_new_with_label(MENU_ITEM_SCANTIPS); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-xsane"); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F1, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-scantips"); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F5, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_widget_show(item); @@ -6322,48 +7257,47 @@ static GtkWidget *xsane_help_build_menu(void) gtk_widget_show(item); - /* Backend doc -> html viewer */ - - if (xsane.backend) - { - item = gtk_menu_item_new_with_label(MENU_ITEM_BACKEND_DOC); - gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) xsane.backend); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F2, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_widget_show(item); - } - - - /* available backends -> html viewer */ + /* XSane about dialog */ - item = gtk_menu_item_new_with_label(MENU_ITEM_AVAILABLE_BACKENDS); + item = gtk_menu_item_new_with_label(MENU_ITEM_ABOUT_XSANE); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-backends"); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F3, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_about_dialog, NULL); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F6, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_widget_show(item); - - /* problems -> html viewer */ + /* XSane about translation dialog */ - item = gtk_menu_item_new_with_label(MENU_ITEM_PROBLEMS); + item = gtk_menu_item_new_with_label(MENU_ITEM_ABOUT_TRANSLATION); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-problems"); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F4, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_about_translation_dialog, NULL); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F7, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_widget_show(item); + + /* separator */ + item = gtk_menu_item_new(); gtk_menu_append(GTK_MENU(menu), item); gtk_widget_show(item); - /* scantips -> html viewer */ + /* XSane eula */ - item = gtk_menu_item_new_with_label(MENU_ITEM_SCANTIPS); + item = gtk_menu_item_new_with_label(MENU_ITEM_XSANE_EULA); + gtk_menu_append(GTK_MENU(menu), item); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_eula, NULL); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F8, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_widget_show(item); + + /* gpl */ + + item = gtk_menu_item_new_with_label(MENU_ITEM_XSANE_GPL); gtk_menu_append(GTK_MENU(menu), item); - gtk_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_doc, (void *) "sane-scantips"); - gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F5, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); + g_signal_connect(GTK_OBJECT(item), "activate", (GtkSignalFunc) xsane_show_gpl, NULL); + gtk_widget_add_accelerator(item, "activate", xsane.accelerator_group, GDK_F9, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); gtk_widget_show(item); + return menu; } @@ -6373,12 +7307,14 @@ void xsane_panel_build() { GtkWidget *standard_vbox; GtkWidget *advanced_vbox; - GtkWidget *parent, *vbox, *button, *label; + GtkWidget *standard_parent; + GtkWidget *advanced_parent; + GtkWidget *parent, *button, *label; const SANE_Option_Descriptor *opt; SANE_Handle dev = xsane.dev; double dval, dmin, dmax, dquant; char *buf, str[16], title[256]; - GSGDialogElement *elem; + DialogElement *elem; SANE_Word quant, val; SANE_Status status; SANE_Int num_words; @@ -6414,6 +7350,10 @@ void xsane_panel_build() xsane.well_known.highlight_r = -1; xsane.well_known.highlight_g = -1; xsane.well_known.highlight_b = -1; + xsane.well_known.batch_scan_start = -1; + xsane.well_known.batch_scan_loop = -1; + xsane.well_known.batch_scan_end = -1; + xsane.well_known.batch_scan_next_tl_y = -1; /* standard options */ @@ -6444,97 +7384,142 @@ void xsane_panel_build() vector_opts = alloca(xsane.num_elements * sizeof (int)); - parent = standard_vbox; + standard_parent = standard_vbox; + advanced_parent = advanced_vbox; for (i = 1; i < xsane.num_elements; ++i) + { + opt = xsane_get_option_descriptor(dev, i); + if (!SANE_OPTION_IS_ACTIVE(opt->cap)) + { + continue; + } + + /* pick up well-known options as we go: */ + if (opt->name) { - opt = xsane_get_option_descriptor(dev, i); - if (!SANE_OPTION_IS_ACTIVE(opt->cap)) + if (strcmp(opt->name, SANE_NAME_PREVIEW) == 0 && opt->type == SANE_TYPE_BOOL) + { + xsane.well_known.preview = i; continue; + } + else if (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) == 0 + && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED)) + xsane.well_known.dpi = i; + else if (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION) == 0 + && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED)) + xsane.well_known.dpi_x = i; + else if (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION) == 0 + && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED)) + xsane.well_known.dpi_y = i; + else if (strcmp (opt->name, SANE_NAME_SCAN_MODE) == 0) + xsane.well_known.scanmode = i; + else if (strcmp (opt->name, SANE_NAME_SCAN_SOURCE) == 0) + xsane.well_known.scansource = i; + else if (strcmp (opt->name, SANE_NAME_SCAN_TL_X) == 0) + xsane.well_known.coord[xsane_back_gtk_TL_X] = i; + else if (strcmp (opt->name, SANE_NAME_SCAN_TL_Y) == 0) + xsane.well_known.coord[xsane_back_gtk_TL_Y] = i; + else if (strcmp (opt->name, SANE_NAME_SCAN_BR_X) == 0) + xsane.well_known.coord[xsane_back_gtk_BR_X] = i; + else if (strcmp (opt->name, SANE_NAME_SCAN_BR_Y) == 0) + xsane.well_known.coord[xsane_back_gtk_BR_Y] = i; + else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR) == 0) + xsane.well_known.gamma_vector = i; + else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_R) == 0) + xsane.well_known.gamma_vector_r = i; + else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_G) == 0) + xsane.well_known.gamma_vector_g = i; + else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_B) == 0) + xsane.well_known.gamma_vector_b = i; + else if (strcmp (opt->name, SANE_NAME_BIT_DEPTH) == 0) + xsane.well_known.bit_depth = i; + else if (strcmp (opt->name, SANE_NAME_THRESHOLD) == 0) + xsane.well_known.threshold = i; + else if (strcmp (opt->name, SANE_NAME_HIGHLIGHT) == 0) + xsane.well_known.highlight = i; + else if (strcmp (opt->name, SANE_NAME_HIGHLIGHT_R) == 0) + xsane.well_known.highlight_r = i; + else if (strcmp (opt->name, SANE_NAME_HIGHLIGHT_G) == 0) + xsane.well_known.highlight_g = i; + else if (strcmp (opt->name, SANE_NAME_HIGHLIGHT_B) == 0) + xsane.well_known.highlight_b = i; + else if (strcmp (opt->name, SANE_NAME_SHADOW) == 0) + xsane.well_known.shadow = i; + else if (strcmp (opt->name, SANE_NAME_SHADOW_R) == 0) + xsane.well_known.shadow_r = i; + else if (strcmp (opt->name, SANE_NAME_SHADOW_G) == 0) + xsane.well_known.shadow_g = i; + else if (strcmp (opt->name, SANE_NAME_SHADOW_B) == 0) + xsane.well_known.shadow_b = i; + else if (strcmp (opt->name, SANE_NAME_BATCH_SCAN_START) == 0) + xsane.well_known.batch_scan_start = i; + else if (strcmp (opt->name, SANE_NAME_BATCH_SCAN_LOOP) == 0) + xsane.well_known.batch_scan_loop = i; + else if (strcmp (opt->name, SANE_NAME_BATCH_SCAN_END) == 0) + xsane.well_known.batch_scan_end = i; + else if (strcmp (opt->name, SANE_NAME_BATCH_SCAN_NEXT_TL_Y) == 0) + xsane.well_known.batch_scan_next_tl_y = i; + } + + elem = xsane.element + i; + + if (opt->unit == SANE_UNIT_NONE) + { + snprintf(title, sizeof(title), "%s", _BGT(opt->title)); + } + else + { + snprintf(title, sizeof(title), "%s [%s]", _BGT(opt->title), xsane_back_gtk_unit_string(opt->unit)); + } + + if (opt->cap & SANE_CAP_ADVANCED) + { + parent = advanced_parent; + } + else + { + parent = standard_parent; + } - /* pick up well-known options as we go: */ - if (opt->name) + switch (opt->type) + { + case SANE_TYPE_GROUP: + /* group a set of options */ + if (opt->cap & SANE_CAP_ADVANCED) { - if (strcmp(opt->name, SANE_NAME_PREVIEW) == 0 && opt->type == SANE_TYPE_BOOL) - { - xsane.well_known.preview = i; - continue; - } - else if (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) == 0 - && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED)) - xsane.well_known.dpi = i; - else if (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION) == 0 - && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED)) - xsane.well_known.dpi_x = i; - else if (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION) == 0 - && opt->unit == SANE_UNIT_DPI && (opt->type == SANE_TYPE_INT || opt->type == SANE_TYPE_FIXED)) - xsane.well_known.dpi_y = i; - else if (strcmp (opt->name, SANE_NAME_SCAN_MODE) == 0) - xsane.well_known.scanmode = i; - else if (strcmp (opt->name, SANE_NAME_SCAN_SOURCE) == 0) - xsane.well_known.scansource = i; - else if (strcmp (opt->name, SANE_NAME_SCAN_TL_X) == 0) - xsane.well_known.coord[xsane_back_gtk_TL_X] = i; - else if (strcmp (opt->name, SANE_NAME_SCAN_TL_Y) == 0) - xsane.well_known.coord[xsane_back_gtk_TL_Y] = i; - else if (strcmp (opt->name, SANE_NAME_SCAN_BR_X) == 0) - xsane.well_known.coord[xsane_back_gtk_BR_X] = i; - else if (strcmp (opt->name, SANE_NAME_SCAN_BR_Y) == 0) - xsane.well_known.coord[xsane_back_gtk_BR_Y] = i; - else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR) == 0) - xsane.well_known.gamma_vector = i; - else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_R) == 0) - xsane.well_known.gamma_vector_r = i; - else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_G) == 0) - xsane.well_known.gamma_vector_g = i; - else if (strcmp (opt->name, SANE_NAME_GAMMA_VECTOR_B) == 0) - xsane.well_known.gamma_vector_b = i; - else if (strcmp (opt->name, SANE_NAME_BIT_DEPTH) == 0) - xsane.well_known.bit_depth = i; - else if (strcmp (opt->name, SANE_NAME_THRESHOLD) == 0) - xsane.well_known.threshold = i; - else if (strcmp (opt->name, SANE_NAME_HIGHLIGHT) == 0) - xsane.well_known.highlight = i; - else if (strcmp (opt->name, SANE_NAME_HIGHLIGHT_R) == 0) - xsane.well_known.highlight_r = i; - else if (strcmp (opt->name, SANE_NAME_HIGHLIGHT_G) == 0) - xsane.well_known.highlight_g = i; - else if (strcmp (opt->name, SANE_NAME_HIGHLIGHT_B) == 0) - xsane.well_known.highlight_b = i; - else if (strcmp (opt->name, SANE_NAME_SHADOW) == 0) - xsane.well_known.shadow = i; - else if (strcmp (opt->name, SANE_NAME_SHADOW_R) == 0) - xsane.well_known.shadow_r = i; - else if (strcmp (opt->name, SANE_NAME_SHADOW_G) == 0) - xsane.well_known.shadow_g = i; - else if (strcmp (opt->name, SANE_NAME_SHADOW_B) == 0) - xsane.well_known.shadow_b = i; + /* advanced group: put all options to the advanced options window */ + standard_parent = xsane_back_gtk_group_new(advanced_vbox, title); + advanced_parent = standard_parent; + elem->widget = standard_parent; } + else + { + /* we create the group twice. if no option is defined in one of this groups */ + /* then the group is not shown */ - elem = xsane.element + i; - - if (opt->unit == SANE_UNIT_NONE) - { - snprintf(title, sizeof(title), "%s", _BGT(opt->title)); - } - else - { - snprintf(title, sizeof(title), "%s [%s]", _BGT(opt->title), xsane_back_gtk_unit_string(opt->unit)); - } + /* standard group: put standard options to the standard options window */ + standard_parent = xsane_back_gtk_group_new(standard_vbox, title); + elem->widget = standard_parent; - switch (opt->type) - { - case SANE_TYPE_GROUP: - /* group a set of options */ - vbox = standard_vbox; - if (opt->cap & SANE_CAP_ADVANCED) - { - vbox = advanced_vbox; - } - parent = xsane_back_gtk_group_new(vbox, title); - elem->widget = parent; - break; + /* standard group: put advanced options to the advanced options window */ + advanced_parent = xsane_back_gtk_group_new(advanced_vbox, title); + elem->widget2 = advanced_parent; + } + break; + + case SANE_TYPE_BOOL: + if (!opt->name) + { + DBG(DBG_error, "xsane_panel_build: Option %d, type SANE_TYPE_BOOL\n", i); + DBG(DBG_error, "=> %s\n", ERR_OPTION_NAME_NULL); + DBG(DBG_error, "=> %s\n", ERR_BACKEND_BUG); + break; + } - case SANE_TYPE_BOOL: + if ( (strcmp(opt->name, SANE_NAME_BATCH_SCAN_START) ) && /* do not show batch scan options */ + (strcmp(opt->name, SANE_NAME_BATCH_SCAN_LOOP) ) && + (strcmp(opt->name, SANE_NAME_BATCH_SCAN_END) ) ) + { assert(opt->size == sizeof(SANE_Word)); status = xsane_control_option(xsane.dev, i, SANE_ACTION_GET_VALUE, &val, 0); if (status != SANE_STATUS_GOOD) @@ -6543,209 +7528,266 @@ void xsane_panel_build() } xsane_back_gtk_button_new(parent, title, val, elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); gtk_widget_show(parent->parent); + } + break; + + case SANE_TYPE_INT: + if (!opt->name) + { + DBG(DBG_error, "xsane_panel_build: Option %d, type SANE_TYPE_INT\n", i); + DBG(DBG_error, "=> %s\n", ERR_OPTION_NAME_NULL); + DBG(DBG_error, "=> %s\n", ERR_BACKEND_BUG); + break; + } + + if (opt->size != sizeof(SANE_Word)) + { + vector_opts[num_vector_opts++] = i; break; + } - case SANE_TYPE_INT: - if (opt->size != sizeof(SANE_Word)) - { - vector_opts[num_vector_opts++] = i; - break; - } - status = xsane_control_option(xsane.dev, i, SANE_ACTION_GET_VALUE, &val, 0); - if (status != SANE_STATUS_GOOD) - { - goto get_value_failed; - } + status = xsane_control_option(xsane.dev, i, SANE_ACTION_GET_VALUE, &val, 0); + if (status != SANE_STATUS_GOOD) + { + goto get_value_failed; + } - switch (opt->constraint_type) - { - case SANE_CONSTRAINT_RANGE: - if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */ - (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */ - (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */ - { - /* use a scale */ - quant = opt->constraint.range->quant; - if (quant == 0) - { - quant = 1; /* we have integers */ - } + switch (opt->constraint_type) + { + case SANE_CONSTRAINT_NONE: + xsane_back_gtk_value_new(parent, title, val, 1, + (opt->cap & SANE_CAP_AUTOMATIC), elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); + gtk_widget_show(parent->parent); + break; - xsane_back_gtk_scale_new(parent, title, val, opt->constraint.range->min, opt->constraint.range->max, quant, - (opt->cap & SANE_CAP_AUTOMATIC), elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); - gtk_widget_show(parent->parent); + case SANE_CONSTRAINT_RANGE: + if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */ + (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */ + (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */ + { + /* use a scale */ + quant = opt->constraint.range->quant; + if (quant == 0) + { + quant = 1; /* we have integers */ } - break; - case SANE_CONSTRAINT_WORD_LIST: - if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */ - (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */ - (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */ + xsane_back_gtk_range_new(parent, title, val, opt->constraint.range->min, opt->constraint.range->max, quant, + (opt->cap & SANE_CAP_AUTOMATIC), elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); + gtk_widget_show(parent->parent); + } + break; + + case SANE_CONSTRAINT_WORD_LIST: + if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */ + (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */ + (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */ + { + /* use a "list-selection" widget */ + num_words = opt->constraint.word_list[0]; + str_list = malloc((num_words + 1) * sizeof(str_list[0])); + for (j = 0; j < num_words; ++j) { - /* use a "list-selection" widget */ - num_words = opt->constraint.word_list[0]; - str_list = malloc((num_words + 1) * sizeof(str_list[0])); - for (j = 0; j < num_words; ++j) - { - sprintf(str, "%d", opt->constraint.word_list[j + 1]); - str_list[j] = strdup(str); - } - str_list[j] = 0; - sprintf(str, "%d", val); - xsane_back_gtk_option_menu_new(parent, title, str_list, str, elem, xsane.tooltips, _BGT(opt->desc), - SANE_OPTION_IS_SETTABLE(opt->cap)); - free(str_list); - gtk_widget_show(parent->parent); + sprintf(str, "%d", opt->constraint.word_list[j + 1]); + str_list[j] = strdup(str); } - break; + str_list[j] = 0; + sprintf(str, "%d", val); + xsane_back_gtk_option_menu_new(parent, title, str_list, str, elem, xsane.tooltips, _BGT(opt->desc), + SANE_OPTION_IS_SETTABLE(opt->cap)); + free(str_list); + gtk_widget_show(parent->parent); + } + break; - default: - DBG(DBG_error, "xsane_panel_build: %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type); - break; - } + default: + DBG(DBG_error, "xsane_panel_build: Option %d, type SANE_TYPE_INT\n", i); + DBG(DBG_error, "=> %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type); + break; + } + break; + + case SANE_TYPE_FIXED: + if (!opt->name) + { + DBG(DBG_error, "xsane_panel_build: Option %d, type SANE_TYPE_FIXED\n", i); + DBG(DBG_error, "=> %s\n", ERR_OPTION_NAME_NULL); + DBG(DBG_error, "=> %s\n", ERR_BACKEND_BUG); + break; + } + + if (opt->size != sizeof (SANE_Word)) + { + vector_opts[num_vector_opts++] = i; break; + } + status = xsane_control_option(xsane.dev, i, SANE_ACTION_GET_VALUE, &val, 0); + if (status != SANE_STATUS_GOOD) + { + goto get_value_failed; + } - case SANE_TYPE_FIXED: - if (opt->size != sizeof (SANE_Word)) - { - vector_opts[num_vector_opts++] = i; - break; - } - status = xsane_control_option(xsane.dev, i, SANE_ACTION_GET_VALUE, &val, 0); - if (status != SANE_STATUS_GOOD) - { - goto get_value_failed; - } + switch (opt->constraint_type) + { + case SANE_CONSTRAINT_NONE: + dval = SANE_UNFIX(val); - switch (opt->constraint_type) - { - case SANE_CONSTRAINT_RANGE: - if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */ - (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */ - (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) && /* do not show y-resolution */ - ((strcmp(opt->name, SANE_NAME_THRESHOLD) || (xsane.lineart_mode == XSANE_LINEART_STANDARD))) - /* do not show threshold if user wants the slider in the xsane main window */ - ) - { - /* use a scale */ - dval = SANE_UNFIX(val); - dmin = SANE_UNFIX(opt->constraint.range->min); - dmax = SANE_UNFIX(opt->constraint.range->max); - dquant = SANE_UNFIX(quant = opt->constraint.range->quant); + if (opt->unit == SANE_UNIT_MM) + { + dval /= preferences.length_unit; + } - if (opt->unit == SANE_UNIT_MM) - { - dval /= preferences.length_unit; - dmin /= preferences.length_unit; - dmax /= preferences.length_unit; - dquant /= preferences.length_unit; - } + xsane_back_gtk_value_new(parent, title, dval, 0.001, (opt->cap & SANE_CAP_AUTOMATIC), elem, + xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); + gtk_widget_show(parent->parent); + break; - if (dquant == 0) /* no quantization specified */ - { - dquant = 0.01; /* display x.2 digits */ - } + case SANE_CONSTRAINT_RANGE: + if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */ + (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */ + (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) && /* do not show y-resolution */ + ((strcmp(opt->name, SANE_NAME_THRESHOLD) || (xsane.lineart_mode == XSANE_LINEART_STANDARD))) && + /* do not show threshold if user wants the slider in the xsane main window */ + (strcmp(opt->name, SANE_NAME_BATCH_SCAN_NEXT_TL_Y) ) /* do not show batch scan options */ + ) + { + /* use a scale */ + dval = SANE_UNFIX(val); + dmin = SANE_UNFIX(opt->constraint.range->min); + dmax = SANE_UNFIX(opt->constraint.range->max); + dquant = SANE_UNFIX(quant = opt->constraint.range->quant); - xsane_back_gtk_scale_new(parent, title, dval, dmin, dmax, dquant, (opt->cap & SANE_CAP_AUTOMATIC), elem, - xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); - gtk_widget_show(parent->parent); + if (opt->unit == SANE_UNIT_MM) + { + dval /= preferences.length_unit; + dmin /= preferences.length_unit; + dmax /= preferences.length_unit; + dquant /= preferences.length_unit; } - break; - case SANE_CONSTRAINT_WORD_LIST: - if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */ - (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */ - (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */ + if (dquant == 0) /* no quantization specified */ { - /* use a "list-selection" widget */ - num_words = opt->constraint.word_list[0]; - str_list = malloc ((num_words + 1) * sizeof (str_list[0])); - for (j = 0; j < num_words; ++j) - { - sprintf(str, "%g", SANE_UNFIX(opt->constraint.word_list[j + 1])); - str_list[j] = strdup(str); - } - str_list[j] = 0; - sprintf(str, "%g", SANE_UNFIX(val)); - xsane_back_gtk_option_menu_new(parent, title, str_list, str, elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); - free (str_list); - gtk_widget_show(parent->parent); + dquant = 0.001; /* display x.3 digits */ } - break; - default: - DBG(DBG_error, "xsane_panel_build: %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type); - break; - } - break; - - case SANE_TYPE_STRING: - buf = malloc (opt->size); - status = xsane_control_option(xsane.dev, i, SANE_ACTION_GET_VALUE, buf, 0); - if (status != SANE_STATUS_GOOD) - { - free (buf); - goto get_value_failed; - } + xsane_back_gtk_range_new(parent, title, dval, dmin, dmax, dquant, (opt->cap & SANE_CAP_AUTOMATIC), elem, + xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); + gtk_widget_show(parent->parent); + } + break; - switch (opt->constraint_type) - { - case SANE_CONSTRAINT_STRING_LIST: - if ( (strcmp (opt->name, SANE_NAME_SCAN_MODE) != 0) && /* do not show scanmode */ - (strcmp (opt->name, SANE_NAME_SCAN_SOURCE) != 0) ) /* do not show scansource */ + case SANE_CONSTRAINT_WORD_LIST: + if ( (strcmp(opt->name, SANE_NAME_SCAN_RESOLUTION) ) && /* do not show resolution */ + (strcmp(opt->name, SANE_NAME_SCAN_X_RESOLUTION)) && /* do not show x-resolution */ + (strcmp(opt->name, SANE_NAME_SCAN_Y_RESOLUTION)) ) /* do not show y-resolution */ + { + /* use a "list-selection" widget */ + num_words = opt->constraint.word_list[0]; + str_list = malloc ((num_words + 1) * sizeof (str_list[0])); + for (j = 0; j < num_words; ++j) { - /* use a "list-selection" widget */ - xsane_back_gtk_option_menu_new(parent, title, (char **) opt->constraint.string_list, buf, - elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); - gtk_widget_show (parent->parent); + sprintf(str, "%g", SANE_UNFIX(opt->constraint.word_list[j + 1])); + str_list[j] = strdup(str); } - break; + str_list[j] = 0; + sprintf(str, "%g", SANE_UNFIX(val)); + xsane_back_gtk_option_menu_new(parent, title, str_list, str, elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); + free (str_list); + gtk_widget_show(parent->parent); + } + break; + + default: + DBG(DBG_error, "xsane_panel_build: Option %d, type SANE_TYPE_FIXED\n", i); + DBG(DBG_error, "=> %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type); + break; + } + break; + + case SANE_TYPE_STRING: + if (!opt->name) + { + DBG(DBG_error, "xsane_panel_build: Option %d, type SANE_TYPE_STRING\n", i); + DBG(DBG_error, "=> %s\n", ERR_OPTION_NAME_NULL); + DBG(DBG_error, "=> %s\n", ERR_BACKEND_BUG); + break; + } - case SANE_CONSTRAINT_NONE: - xsane_back_gtk_text_entry_new(parent, title, buf, elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); + buf = malloc(opt->size); + status = xsane_control_option(xsane.dev, i, SANE_ACTION_GET_VALUE, buf, 0); + if (status != SANE_STATUS_GOOD) + { + free(buf); + goto get_value_failed; + } + + switch (opt->constraint_type) + { + case SANE_CONSTRAINT_STRING_LIST: + if ( (strcmp (opt->name, SANE_NAME_SCAN_MODE) != 0) && /* do not show scanmode */ + (strcmp (opt->name, SANE_NAME_SCAN_SOURCE) != 0) ) /* do not show scansource */ + { + /* use a "list-selection" widget */ + xsane_back_gtk_option_menu_new(parent, title, (char **) opt->constraint.string_list, buf, + elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); gtk_widget_show (parent->parent); - break; + } + break; - default: - DBG(DBG_error, "xsane_panel_build: %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type); - break; - } - free (buf); - break; + case SANE_CONSTRAINT_NONE: + xsane_back_gtk_text_entry_new(parent, title, buf, elem, xsane.tooltips, _BGT(opt->desc), SANE_OPTION_IS_SETTABLE(opt->cap)); + gtk_widget_show (parent->parent); + break; + + default: + DBG(DBG_error, "xsane_panel_build: Option %d, type SANE_TYPE_STRING\n", i); + DBG(DBG_error, "=> %s %d!\n", ERR_UNKNOWN_CONSTRAINT_TYPE, opt->constraint_type); + break; + } + free(buf); + break; - case SANE_TYPE_BUTTON: - button = gtk_button_new(); - gtk_signal_connect(GTK_OBJECT (button), "clicked", (GtkSignalFunc) xsane_back_gtk_push_button_callback, elem); - xsane_back_gtk_set_tooltip(xsane.tooltips, button, _BGT(opt->desc)); + case SANE_TYPE_BUTTON: + if (!opt->name) + { + DBG(DBG_error, "xsane_panel_build: Option %d, type SANE_TYPE_BUTTON\n", i); + DBG(DBG_error, "=> %s\n", ERR_OPTION_NAME_NULL); + DBG(DBG_error, "=> %s\n", ERR_BACKEND_BUG); + break; + } - label = gtk_label_new(title); - gtk_container_add(GTK_CONTAINER (button), label); + button = gtk_button_new(); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_back_gtk_push_button_callback, elem); + xsane_back_gtk_set_tooltip(xsane.tooltips, button, _BGT(opt->desc)); - gtk_box_pack_start(GTK_BOX (parent), button, FALSE, TRUE, 0); + label = gtk_label_new(title); + gtk_container_add(GTK_CONTAINER (button), label); - gtk_widget_show(label); - gtk_widget_show(button); + gtk_box_pack_start(GTK_BOX (parent), button, FALSE, TRUE, 0); - gtk_widget_set_sensitive(button, SANE_OPTION_IS_SETTABLE(opt->cap)); + gtk_widget_show(label); + gtk_widget_show(button); - elem->widget = button; - gtk_widget_show(parent->parent); - break; + gtk_widget_set_sensitive(button, SANE_OPTION_IS_SETTABLE(opt->cap)); - default: - DBG(DBG_error, "xsane_panel_build: %s %d\n", ERR_UNKNOWN_TYPE, opt->type); - break; - } - continue; + elem->widget = button; + gtk_widget_show(parent->parent); + break; + + default: + DBG(DBG_error, "xsane_panel_build: %s %d\n", ERR_UNKNOWN_TYPE, opt->type); + break; + } + continue; get_value_failed: - { - char msg[256]; + { + char msg[256]; - sprintf(msg, "%s %s: %s.", ERR_GET_OPTION, opt->name, XSANE_STRSTATUS(status)); - xsane_back_gtk_error(msg, TRUE); - } + sprintf(msg, "%s %s: %s.", ERR_GET_OPTION, opt->name, XSANE_STRSTATUS(status)); + xsane_back_gtk_error(msg, TRUE); } + } if ((xsane.well_known.dpi_x == -1) && (xsane.well_known.dpi_y != -1)) { @@ -6777,6 +7819,7 @@ void xsane_panel_build() - create tooltip style - create dialog xsane.histogram_dialog - create dialog xsane.gamma_dialog + - create dialog xsane.batch_scan - panel_build() - create dialog xsane.preview */ @@ -6785,6 +7828,7 @@ static void xsane_device_dialog(void) { GtkWidget *vbox, *hbox, *button, *frame, *infobox; GtkWidget *menubar, *menubar_item; + GtkStyle *current_style; const gchar *devname; char buf[256]; char windowname[255]; @@ -6810,7 +7854,7 @@ static void xsane_device_dialog(void) /* will never come to here */ } - if (xsane_control_option(xsane.dev, 0, SANE_ACTION_GET_VALUE, &xsane.num_elements, 0) != SANE_STATUS_GOOD) + if (sane_control_option(xsane.dev, 0, SANE_ACTION_GET_VALUE, &xsane.num_elements, 0) != SANE_STATUS_GOOD) { xsane_back_gtk_error(ERR_OPTION_COUNT, TRUE); sane_close(xsane.dev); @@ -6835,11 +7879,39 @@ static void xsane_device_dialog(void) xsane.backend = malloc(strlen(textptr)+6); sprintf(xsane.backend, "sane-%s", textptr); /* add "sane-" */ + DBG(DBG_info, "Setting backend name \"%s\"\n", xsane.backend); + + xsane.backend_translation = xsane.backend; + bindtextdomain(xsane.backend_translation, STRINGIFY(LOCALEDIR)); /* set path for backend translation texts */ +#ifdef HAVE_GTK2 + bind_textdomain_codeset(xsane.backend_translation, "UTF-8"); +#endif + + if (!strlen(dgettext(xsane.backend_translation, ""))) /* translation not valid, use general translation table */ + { + xsane.backend_translation = "sane-backends"; + DBG(DBG_info, "Setting general translation table \"sane-backends\" with localedir: %s\n", STRINGIFY(LOCALEDIR)); + } + else /* we have a valid table for the backend */ + { + DBG(DBG_info, "Setting backend translation table \"%s\" with localedir: %s\n", xsane.backend_translation, STRINGIFY(LOCALEDIR)); + } + } + else /* use general backend name "sane-backends" for sane */ + { + xsane.backend = strdup("sane-backends"); + DBG(DBG_info, "Setting general backend name \"%s\"\n", xsane.backend); - DBG(DBG_info, "Setting backend \"%s\" localedir: %s\n", xsane.backend, STRINGIFY(LOCALEDIR)); - bindtextdomain(xsane.backend, STRINGIFY(LOCALEDIR)); /* set path for backend translation texts */ + xsane.backend_translation = xsane.backend; + DBG(DBG_info, "Setting general translation table \"sane-backends\" with localedir: %s\n", STRINGIFY(LOCALEDIR)); } + bindtextdomain("sane-backends", STRINGIFY(LOCALEDIR)); /* set path for backend translation texts */ +#ifdef HAVE_GTK2 + bind_textdomain_codeset(xsane.backend_translation, "UTF-8"); +#endif + + /* create device-text for window titles */ snprintf(devicetext, sizeof(devicetext), "%s", xsane.devlist[xsane.selected_dev]->model); @@ -6890,16 +7962,16 @@ static void xsane_device_dialog(void) /* create the xsane dialog box */ xsane.shell = gtk_window_new(GTK_WINDOW_TOPLEVEL); - gtk_widget_set_uposition(xsane.shell, XSANE_SHELL_POS_X, XSANE_SHELL_POS_Y); + gtk_window_move(GTK_WINDOW(xsane.shell), XSANE_SHELL_POS_X, XSANE_SHELL_POS_Y); sprintf(windowname, "%s %s %s", xsane.prog_name, XSANE_VERSION, xsane.device_text); gtk_window_set_title(GTK_WINDOW(xsane.shell), (char *) windowname); - gtk_signal_connect(GTK_OBJECT(xsane.shell), "delete_event", GTK_SIGNAL_FUNC(xsane_scan_win_delete), NULL); + g_signal_connect(GTK_OBJECT(xsane.shell), "delete_event", GTK_SIGNAL_FUNC(xsane_scan_win_delete), NULL); xsane_set_window_icon(xsane.shell, 0); /* create the xsane main window accelerator table */ xsane.accelerator_group = gtk_accel_group_new(); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(xsane.shell)); + gtk_window_add_accel_group(GTK_WINDOW(xsane.shell), xsane.accelerator_group); /* set the main vbox */ @@ -6916,21 +7988,29 @@ static void xsane_device_dialog(void) menubar_item = gtk_menu_item_new_with_label(MENU_FILE); gtk_container_add(GTK_CONTAINER(menubar), menubar_item); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_files_build_menu()); -/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_F, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); */ +/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_F, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); */ gtk_widget_show(menubar_item); /* "Preferences" submenu: */ menubar_item = gtk_menu_item_new_with_label(MENU_PREFERENCES); gtk_container_add(GTK_CONTAINER(menubar), menubar_item); - gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_pref_build_menu()); -/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_P, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); */ + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_preferences_build_menu()); +/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_P, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); */ gtk_widget_show(menubar_item); /* "View" submenu: */ menubar_item = gtk_menu_item_new_with_label(MENU_VIEW); gtk_container_add(GTK_CONTAINER(menubar), menubar_item); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_view_build_menu()); -/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_V, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); */ +/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_V, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); */ + gtk_widget_show(menubar_item); + + + /* "Window" submenu: */ + menubar_item = gtk_menu_item_new_with_label(MENU_WINDOW); + gtk_container_add(GTK_CONTAINER(menubar), menubar_item); + gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_window_build_menu()); +/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_V, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); */ gtk_widget_show(menubar_item); @@ -6939,7 +8019,7 @@ static void xsane_device_dialog(void) gtk_container_add(GTK_CONTAINER(menubar), menubar_item); gtk_menu_item_right_justify((GtkMenuItem *) menubar_item); gtk_menu_item_set_submenu(GTK_MENU_ITEM(menubar_item), xsane_help_build_menu()); -/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_H, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); */ +/* gtk_widget_add_accelerator(menubar_item, "select", xsane.accelerator_group, GDK_H, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); */ gtk_widget_show(menubar_item); gtk_widget_show(menubar); @@ -6949,7 +8029,7 @@ static void xsane_device_dialog(void) if (xsane.main_window_fixed) /* fixed window: use it like it is */ { /* shrink grow auto_shrink */ - gtk_window_set_policy(GTK_WINDOW(xsane.shell), FALSE, FALSE, TRUE); /* auto size */ + gtk_window_set_resizable(GTK_WINDOW(xsane.shell), FALSE); xsane_vbox_main = gtk_vbox_new(TRUE, 5); /* we need this to set the wanted borders */ gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_main), 5); @@ -6960,11 +8040,10 @@ static void xsane_device_dialog(void) gtk_window_set_default_size(GTK_WINDOW(xsane.shell), XSANE_SHELL_WIDTH, XSANE_SHELL_HEIGHT); /* set default size */ /* shrink grow auto_shrink */ - gtk_window_set_policy(GTK_WINDOW(xsane.shell), TRUE, TRUE, FALSE); /* allow resizing */ + gtk_window_set_resizable(GTK_WINDOW(xsane.shell), TRUE); /* allow resizing */ xsane.main_dialog_scrolled = gtk_scrolled_window_new(0, 0); - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(xsane.main_dialog_scrolled), - GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(xsane.main_dialog_scrolled), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(xsane_window), xsane.main_dialog_scrolled); gtk_widget_show(xsane.main_dialog_scrolled); @@ -6982,32 +8061,30 @@ static void xsane_device_dialog(void) gtk_widget_show(xsane_vbox_main); #if 0 - /* add vendorīs logo */ + /* add vendor`s logo */ xsane_vendor_pixmap_new(xsane.shell->window, xsane_window); #endif /* create the scanner standard options dialog box */ - xsane.standard_options_shell = gtk_window_new(GTK_WINDOW_DIALOG); - gtk_widget_set_uposition(xsane.standard_options_shell, XSANE_STD_OPTIONS_POS_X, XSANE_STD_OPTIONS_POS_Y); + xsane.standard_options_shell = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_move(GTK_WINDOW(xsane.standard_options_shell), XSANE_STD_OPTIONS_POS_X, XSANE_STD_OPTIONS_POS_Y); sprintf(windowname, "%s %s", WINDOW_STANDARD_OPTIONS, xsane.device_text); gtk_window_set_title(GTK_WINDOW(xsane.standard_options_shell), (char *) windowname); - /* shrink grow auto_shrink */ - gtk_window_set_policy(GTK_WINDOW(xsane.standard_options_shell), FALSE, FALSE, TRUE); - gtk_signal_connect(GTK_OBJECT(xsane.standard_options_shell), "delete_event", - GTK_SIGNAL_FUNC(xsane_standard_option_win_delete), NULL); + gtk_window_set_resizable(GTK_WINDOW(xsane.standard_options_shell), FALSE); + g_signal_connect(GTK_OBJECT(xsane.standard_options_shell), "delete_event", GTK_SIGNAL_FUNC(xsane_standard_option_win_delete), NULL); xsane_set_window_icon(xsane.standard_options_shell, 0); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(xsane.standard_options_shell)); + gtk_window_add_accel_group(GTK_WINDOW(xsane.standard_options_shell), xsane.accelerator_group); xsane_vbox_standard = gtk_vbox_new(FALSE, 5); /* has been TRUE before I added backend pixmap */ gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_standard), 5); gtk_container_add(GTK_CONTAINER(xsane.standard_options_shell), xsane_vbox_standard); gtk_widget_show(xsane_vbox_standard); - /* add vendorīs logo */ + /* add vendor`s logo */ xsane_vendor_pixmap_new(xsane.standard_options_shell->window, xsane_vbox_standard); /* create a subwindow so the standard dialog keeps its position on rebuilds: */ @@ -7018,18 +8095,16 @@ static void xsane_device_dialog(void) /* create the scanner advanced options dialog box */ - xsane.advanced_options_shell = gtk_window_new(GTK_WINDOW_DIALOG); - gtk_widget_set_uposition(xsane.advanced_options_shell, XSANE_ADV_OPTIONS_POS_X, XSANE_ADV_OPTIONS_POS_Y); + xsane.advanced_options_shell = gtk_window_new(GTK_WINDOW_TOPLEVEL); + gtk_window_move(GTK_WINDOW(xsane.advanced_options_shell), XSANE_ADV_OPTIONS_POS_X, XSANE_ADV_OPTIONS_POS_Y); sprintf(windowname, "%s %s",WINDOW_ADVANCED_OPTIONS, xsane.device_text); gtk_window_set_title(GTK_WINDOW(xsane.advanced_options_shell), (char *) windowname); - /* shrink grow auto_shrink */ - gtk_window_set_policy(GTK_WINDOW(xsane.advanced_options_shell), FALSE, FALSE, TRUE); - gtk_signal_connect(GTK_OBJECT(xsane.advanced_options_shell), "delete_event", - GTK_SIGNAL_FUNC(xsane_advanced_option_win_delete), NULL); + gtk_window_set_resizable(GTK_WINDOW(xsane.advanced_options_shell), FALSE); + g_signal_connect(GTK_OBJECT(xsane.advanced_options_shell), "delete_event", GTK_SIGNAL_FUNC(xsane_advanced_option_win_delete), NULL); xsane_set_window_icon(xsane.advanced_options_shell, 0); - gtk_accel_group_attach(xsane.accelerator_group, GTK_OBJECT(xsane.advanced_options_shell)); + gtk_window_add_accel_group(GTK_WINDOW(xsane.advanced_options_shell), xsane.accelerator_group); xsane_vbox_advanced = gtk_vbox_new(FALSE, 5); /* has been TRUE before I added backend pixmap */ gtk_container_set_border_width(GTK_CONTAINER(xsane_vbox_advanced), 5); @@ -7073,10 +8148,8 @@ static void xsane_device_dialog(void) /* define tooltips colors */ xsane.tooltips = gtk_tooltips_new(); - colormap = gdk_window_get_colormap(xsane.shell->window); + colormap = gdk_drawable_get_colormap(xsane.shell->window); -/* I don`t know why the following does not work with gtk-1.2.x */ -/* but the gimp has the same problems ;-) */ /* use black as foreground: */ xsane.tooltips_fg.red = 0; xsane.tooltips_fg.green = 0; @@ -7089,21 +8162,14 @@ static void xsane_device_dialog(void) xsane.tooltips_bg.blue = 35979; gdk_color_alloc(colormap, &xsane.tooltips_bg); -/* as long as gtk_tooltips_set_colors() does not work : */ -#ifdef BUGGY_GTK_TOOLTIPS_SET_COLORS gtk_tooltips_force_window(xsane.tooltips); - { - GtkStyle *current_style = gtk_style_copy(gtk_widget_get_style(xsane.tooltips->tip_window)); - current_style->bg[GTK_STATE_NORMAL] = xsane.tooltips_bg; - current_style->fg[GTK_STATE_NORMAL] = xsane.tooltips_fg; - gtk_widget_set_style(xsane.tooltips->tip_window, current_style); - } -#else - gtk_tooltips_set_colors(xsane.tooltips, &xsane.tooltips_bg, &xsane.tooltips_fg); -#endif - xsane_back_gtk_set_tooltips(preferences.tooltips_enabled); + current_style = gtk_style_copy(gtk_widget_get_style(xsane.tooltips->tip_window)); + current_style->bg[GTK_STATE_NORMAL] = xsane.tooltips_bg; + current_style->fg[GTK_STATE_NORMAL] = xsane.tooltips_fg; + gtk_widget_set_style(xsane.tooltips->tip_window, current_style); + xsane_back_gtk_set_tooltips(preferences.tooltips_enabled); /* create histogram dialog and set colors */ @@ -7114,17 +8180,19 @@ static void xsane_device_dialog(void) xsane_create_gamma_dialog(xsane.device_text); /* create the free gamma curve dialog */ #endif + /* create batch_scan dialog */ + xsane_create_batch_scan_dialog(xsane.device_text); + /* The bottom area: info frame, progress bar, start and cancel button */ - xsane_separator_new(xsane_window, 2); - hbox = gtk_hbox_new(FALSE, 5); - gtk_box_pack_end(GTK_BOX(xsane_window), hbox, FALSE, FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); + hbox = gtk_hbox_new(FALSE, 3); + gtk_box_pack_end(GTK_BOX(xsane_window), hbox, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 3); gtk_widget_show(hbox); /* vertical box for info frame and progress bar */ - vbox = gtk_vbox_new(FALSE, 5); - gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); + vbox = gtk_vbox_new(FALSE, 3); + gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 5); gtk_widget_show(vbox); @@ -7135,7 +8203,7 @@ static void xsane_device_dialog(void) gtk_widget_show(frame); infobox = gtk_hbox_new(FALSE, 5); - gtk_container_set_border_width(GTK_CONTAINER(infobox), 2); + gtk_container_set_border_width(GTK_CONTAINER(infobox), 4); gtk_container_add(GTK_CONTAINER(frame), infobox); gtk_widget_show(infobox); @@ -7152,24 +8220,28 @@ static void xsane_device_dialog(void) /* vertical box for scan and cancel button */ - vbox = gtk_vbox_new(FALSE, 5); + vbox = gtk_vbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0); gtk_widget_show(vbox); /* The Scan button */ - button = gtk_button_new_with_label(BUTTON_START); + button = gtk_button_new_with_label(BUTTON_SCAN); xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_SCAN_START); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_Return, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_scan_dialog, NULL); - gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); + gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_Return, GDK_CONTROL_MASK, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_scan_callback, NULL); + gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0); gtk_widget_show(button); xsane.start_button = GTK_OBJECT(button); /* The Cancel button */ +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); +#else button = gtk_button_new_with_label(BUTTON_CANCEL); +#endif xsane_back_gtk_set_tooltip(xsane.tooltips, button, DESC_SCAN_CANCEL); - gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_Escape, 0, GTK_ACCEL_VISIBLE | GTK_ACCEL_LOCKED); - gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 0); + gtk_widget_add_accelerator(button, "clicked", xsane.accelerator_group, GDK_Escape, 0, GTK_ACCEL_VISIBLE | DEF_GTK_ACCEL_LOCKED); + gtk_box_pack_start(GTK_BOX(vbox), button, TRUE, TRUE, 0); gtk_widget_show(button); gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE); xsane.cancel_button = GTK_OBJECT(button); @@ -7181,7 +8253,7 @@ static void xsane_device_dialog(void) /* create preview dialog */ xsane.preview = preview_new(); - gtk_signal_connect(GTK_OBJECT(xsane.preview->top), "delete_event", GTK_SIGNAL_FUNC(xsane_preview_window_destroyed), NULL); + g_signal_connect(GTK_OBJECT(xsane.preview->top), "delete_event", GTK_SIGNAL_FUNC(xsane_preview_window_destroyed), NULL); xsane_device_preferences_restore(); /* restore device-settings */ xsane_set_modus_defaults(); @@ -7201,6 +8273,11 @@ static void xsane_device_dialog(void) gtk_widget_show(xsane.advanced_options_shell); } + if (preferences.show_batch_scan) + { + gtk_widget_show(xsane.batch_scan_dialog); + } + gtk_widget_show(xsane.shell); /* call as last so focus is on it */ while (gtk_events_pending()) @@ -7220,9 +8297,20 @@ static void xsane_device_dialog(void) } gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_preview_widget), xsane.show_preview); - xsane_set_all_resolutions(); /* make sure resolution, resolution_x and resolution_y are up to date */ xsane_define_maximum_output_size(); /* draw maximum output frame in preview window if necessary */ xsane_refresh_dialog(); + xsane_set_all_resolutions(); /* make sure resolution, resolution_x and resolution_y are up to date */ + + if (xsane.batch_scan_load_default_list) + { + char filename[PATH_MAX]; + + DBG(DBG_proc, "batch_scan:load default list\n"); + xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", "batch-lists", 0, "default", ".xbl", XSANE_PATH_LOCAL_SANE); + xsane_batch_scan_load_list_from_file(filename); + + xsane.batch_scan_load_default_list = 0; /* mark list is loaded, we only want to load the list at program startup */ + } } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -7231,7 +8319,7 @@ static void xsane_choose_dialog_ok_callback(void) { DBG(DBG_proc, "xsane_choose_dialog_ok_callback\n"); - gtk_signal_disconnect_by_func(GTK_OBJECT(xsane.choose_device_dialog), GTK_SIGNAL_FUNC(xsane_exit), 0); + g_signal_handlers_disconnect_by_func(GTK_OBJECT(xsane.choose_device_dialog), GTK_SIGNAL_FUNC(xsane_exit), 0); gtk_widget_destroy(xsane.choose_device_dialog); xsane_device_dialog(); } @@ -7247,7 +8335,7 @@ static void xsane_select_device_by_key_callback(GtkWidget * widget, gpointer dat /* ---------------------------------------------------------------------------------------------------------------------- */ -static void xsane_select_device_by_mouse_callback(GtkWidget * widget, GdkEventButton *event, gpointer data) +static int xsane_select_device_by_mouse_callback(GtkWidget * widget, GdkEventButton *event, gpointer data) { DBG(DBG_proc, "xsane_select_device_by_mouse_callback\n"); @@ -7256,6 +8344,8 @@ static void xsane_select_device_by_mouse_callback(GtkWidget * widget, GdkEventBu { xsane_choose_dialog_ok_callback(); } + + return 0; } /* ---------------------------------------------------------------------------------------------------------------------- */ @@ -7263,8 +8353,8 @@ static void xsane_select_device_by_mouse_callback(GtkWidget * widget, GdkEventBu static void xsane_choose_device(void) { GtkWidget *main_vbox, *vbox, *hbox, *button, *device_frame, *device_vbox, *pixmapwidget, *label; - GdkBitmap *mask; - GdkPixmap *pixmap; + GdkBitmap *mask = NULL; + GdkPixmap *pixmap = NULL; GtkStyle *style; GdkColor *bg_trans; GSList *owner; @@ -7272,7 +8362,7 @@ static void xsane_choose_device(void) gint i; const SANE_Device *adev; char buf[256]; - char vendor[9]; + char vendor[12]; char model[17]; char type[20]; char filename[PATH_MAX]; @@ -7299,15 +8389,15 @@ static void xsane_choose_device(void) } } - xsane.choose_device_dialog = gtk_window_new(GTK_WINDOW_DIALOG); + xsane.choose_device_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(xsane.choose_device_dialog), GTK_WIN_POS_CENTER); - gtk_window_set_policy(GTK_WINDOW(xsane.choose_device_dialog), FALSE, FALSE, FALSE); - gtk_signal_connect(GTK_OBJECT(xsane.choose_device_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_exit), NULL); + gtk_window_set_resizable(GTK_WINDOW(xsane.choose_device_dialog), FALSE); + g_signal_connect(GTK_OBJECT(xsane.choose_device_dialog), "destroy", GTK_SIGNAL_FUNC(xsane_exit), NULL); snprintf(buf, sizeof(buf), "%s %s %s", xsane.prog_name, XSANE_VERSION, WINDOW_DEVICE_SELECTION); gtk_window_set_title(GTK_WINDOW(xsane.choose_device_dialog), buf); device_selection_accelerator_group = gtk_accel_group_new(); /* do we have to delete it when dialog is closed ? */ - gtk_accel_group_attach(device_selection_accelerator_group, GTK_OBJECT(xsane.choose_device_dialog)); + gtk_window_add_accel_group(GTK_WINDOW(xsane.choose_device_dialog), device_selection_accelerator_group); main_vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 0); @@ -7327,10 +8417,10 @@ static void xsane_choose_device(void) xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", 0, "xsane-logo", 0, ".xpm", XSANE_PATH_SYSTEM); pixmap = gdk_pixmap_create_from_xpm(xsane.choose_device_dialog->window, &mask, bg_trans, filename); - pixmapwidget = gtk_pixmap_new(pixmap, mask); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); gtk_box_pack_start(GTK_BOX(vbox), pixmapwidget, FALSE, FALSE, 2); gtk_widget_show(pixmapwidget); - gdk_pixmap_unref(pixmap); + gdk_drawable_unref(pixmap); xsane_set_window_icon(xsane.choose_device_dialog, (gchar **) 0); @@ -7339,11 +8429,10 @@ static void xsane_choose_device(void) gtk_widget_show(label); gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 2); - xsane_separator_new(vbox, 5); - /* list the drivers with radiobuttons */ device_frame = gtk_frame_new(TEXT_AVAILABLE_DEVICES); + gtk_container_set_border_width(GTK_CONTAINER(device_frame), 4); gtk_box_pack_start(GTK_BOX(vbox), device_frame, FALSE, FALSE, 2); gtk_widget_show(device_frame); @@ -7406,13 +8495,11 @@ static void xsane_choose_device(void) if (i<12) { - gtk_widget_add_accelerator(button, "clicked", device_selection_accelerator_group, GDK_F1+i, 0, GTK_ACCEL_LOCKED); + gtk_widget_add_accelerator(button, "clicked", device_selection_accelerator_group, GDK_F1+i, 0, DEF_GTK_ACCEL_LOCKED); } - gtk_signal_connect(GTK_OBJECT(button), "button_press_event", - (GtkSignalFunc) xsane_select_device_by_mouse_callback, (void *) (long) i); - gtk_signal_connect(GTK_OBJECT(button), "clicked", - (GtkSignalFunc) xsane_select_device_by_key_callback, (void *) (long) i); + g_signal_connect(GTK_OBJECT(button), "button_press_event", (GtkSignalFunc) xsane_select_device_by_mouse_callback, (void *) (long) i); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_select_device_by_key_callback, (void *) (long) i); gtk_box_pack_start(GTK_BOX(device_vbox), button, TRUE, TRUE, 0); gtk_widget_show(button); owner = gtk_radio_button_group(GTK_RADIO_BUTTON(button));; @@ -7432,17 +8519,25 @@ static void xsane_choose_device(void) gtk_widget_show(hbox); /* The OK button */ +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_OK); +#else button = gtk_button_new_with_label(BUTTON_OK); +#endif GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_choose_dialog_ok_callback, NULL); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_choose_dialog_ok_callback, NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_grab_default(button); gtk_widget_show(button); /* The Cancel button */ +#ifdef HAVE_GTK2 + button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); +#else button = gtk_button_new_with_label(BUTTON_CANCEL); - gtk_widget_add_accelerator(button, "clicked", device_selection_accelerator_group, GDK_Escape, 0, GTK_ACCEL_LOCKED); - gtk_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_exit, NULL); +#endif + gtk_widget_add_accelerator(button, "clicked", device_selection_accelerator_group, GDK_Escape, 0, DEF_GTK_ACCEL_LOCKED); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_exit, NULL); gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); gtk_widget_show(button); @@ -7468,8 +8563,12 @@ static int xsane_init(int argc, char **argv) 3 - if wrong sane major version was found */ { GtkWidget *device_scanning_dialog; - GtkWidget *main_vbox; + GtkWidget *main_vbox, *hbox; + GdkPixmap *pixmap; + GdkBitmap *mask; + GtkWidget *pixmapwidget; GtkWidget *label; + GtkWidget *frame; struct stat st; char filename[PATH_MAX]; char buf[256]; @@ -7482,10 +8581,15 @@ static int xsane_init(int argc, char **argv) gtk_init(&argc, &argv); setlocale(LC_NUMERIC, "C"); -#ifdef HAVE_LIBGIMP_GIMP_H +#ifdef HAVE_ANY_GIMP gtk_rc_parse(gimp_gtkrc()); +# ifdef HAVE_GIMP_2 + gdk_set_use_xshm(TRUE); +# else gdk_set_use_xshm(gimp_use_xshm()); +# endif + #endif /* before we open any windows we have to read the style file */ @@ -7509,7 +8613,7 @@ static int xsane_init(int argc, char **argv) { int ch; - while((ch = getopt_long(argc, argv, "cd:fghlmnpsvFMN:RV", long_options, 0)) != EOF) + while((ch = getopt_long(argc, argv, "cd:fghlmnpsvFN:RV", long_options, 0)) != EOF) { switch(ch) { @@ -7517,7 +8621,7 @@ static int xsane_init(int argc, char **argv) /* GIMP. If xsane is compiled without GIMP support */ /* then you get the error message when GIMP does */ /* query or tries to start the xsane plugin! */ -#ifndef HAVE_LIBGIMP_GIMP_H +#ifndef HAVE_ANY_GIMP printf("%s: %s\n", argv[0], ERR_GIMP_SUPPORT_MISSING); exit(0); #endif @@ -7526,10 +8630,10 @@ static int xsane_init(int argc, char **argv) case 'v': /* --version */ printf("%s-%s %s %s\n", xsane.prog_name, XSANE_VERSION, XSANE_COPYRIGHT_SIGN, XSANE_COPYRIGHT_TXT); printf(" %s %s\n", TEXT_EMAIL, XSANE_EMAIL); - printf(" %s %s\n", TEXT_PACKAGE, PACKAGE_VERSION); + printf(" %s %s\n", TEXT_PACKAGE, XSANE_PACKAGE_VERSION); printf(" %s%d.%d.%d\n", TEXT_GTK_VERSION, GTK_MAJOR_VERSION, GTK_MINOR_VERSION, GTK_MICRO_VERSION); -#ifdef HAVE_LIBGIMP_GIMP_H +#ifdef HAVE_ANY_GIMP printf(" %s, %s%s\n", TEXT_WITH_GIMP_SUPPORT, TEXT_GIMP_VERSION, GIMP_VERSION); #else printf(" %s\n", TEXT_WITHOUT_GIMP_SUPPORT); @@ -7548,8 +8652,7 @@ static int xsane_init(int argc, char **argv) #endif printf("pnm, "); - printf("ps, "); - printf("raw"); + printf("ps"); #ifdef SUPPORT_RGBA printf(", rgba"); @@ -7558,6 +8661,9 @@ static int xsane_init(int argc, char **argv) #ifdef HAVE_LIBTIFF printf(", tiff"); #endif + + printf(", txt"); + printf("\n"); exit(0); break; @@ -7613,17 +8719,6 @@ static int xsane_init(int argc, char **argv) xsane.print_filenames = TRUE; break; - case 'M': /* --Medium-calibration */ - xsane.medium_calibration = TRUE; - xsane.no_preview_medium_gamma = TRUE; - - xsane.brightness_min = XSANE_MEDIUM_CALIB_BRIGHTNESS_MIN; - xsane.brightness_max = XSANE_MEDIUM_CALIB_BRIGHTNESS_MAX; - xsane.contrast_gray_min = XSANE_MEDIUM_CALIB_CONTRAST_MIN; - xsane.contrast_min = XSANE_MEDIUM_CALIB_CONTRAST_MIN; - xsane.contrast_max = XSANE_MEDIUM_CALIB_CONTRAST_MAX; - break; - case 'h': /* --help */ default: xsane_usage(); @@ -7634,13 +8729,15 @@ static int xsane_init(int argc, char **argv) if (xsane_pref_restore()) /* restore preferences, returns TRUE if license is not accpted yet */ { - if (xsane_display_license(1)) /* show license and ask for accept/not accept */ + if (xsane_display_eula(1)) /* show license and ask for accept/not accept */ { - DBG(DBG_info, "user did not accept license, we abort\n"); - return 1; /* User did not accept license */ + DBG(DBG_info, "user did not accept eula, we abort\n"); + return 1; /* User did not accept eula */ } } + xsane_pref_restore_media(); + #ifndef HAVE_OS2_H if (!getuid()) /* root ? */ { @@ -7670,27 +8767,53 @@ static int xsane_init(int argc, char **argv) return 3; } - device_scanning_dialog = gtk_window_new(GTK_WINDOW_DIALOG); + device_scanning_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(device_scanning_dialog), GTK_WIN_POS_CENTER); - gtk_window_set_policy(GTK_WINDOW(device_scanning_dialog), FALSE, FALSE, FALSE); + gtk_window_set_resizable(GTK_WINDOW(device_scanning_dialog), FALSE); snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, XSANE_VERSION); gtk_window_set_title(GTK_WINDOW(device_scanning_dialog), buf); + g_signal_connect(GTK_OBJECT(device_scanning_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_quit), NULL); + xsane_set_window_icon(device_scanning_dialog, 0); + + frame = gtk_frame_new(NULL); + gtk_container_set_border_width(GTK_CONTAINER(frame), 10); + gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_ETCHED_IN); + gtk_container_add(GTK_CONTAINER(device_scanning_dialog), frame); + gtk_widget_show(frame); main_vbox = gtk_vbox_new(FALSE, 0); gtk_container_set_border_width(GTK_CONTAINER(main_vbox), 20); - gtk_container_add(GTK_CONTAINER(device_scanning_dialog), main_vbox); + gtk_container_add(GTK_CONTAINER(frame), main_vbox); gtk_widget_show(main_vbox); + hbox = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(main_vbox), hbox, FALSE, FALSE, 2); + gtk_widget_show(hbox); + + /* add device icon */ + pixmap = gdk_pixmap_create_from_xpm_d(device_scanning_dialog->window, &mask, xsane.bg_trans, (gchar **) device_xpm); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); + gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 10); + gtk_widget_show(pixmapwidget); + gdk_drawable_unref(pixmap); + + /* add text */ snprintf(buf, sizeof(buf), " %s ", TEXT_SCANNING_DEVICES); label = gtk_label_new(buf); - gtk_box_pack_start(GTK_BOX(main_vbox), label, FALSE, FALSE, 2); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 2); gtk_widget_show(label); - xsane_set_window_icon(device_scanning_dialog, 0); - gtk_widget_show(device_scanning_dialog); + /* wait 100 ms to make sure window is displayed */ + usleep(100000); /* this makes sure that the text "scanning for devices" is displayed */ + + while (gtk_events_pending()) + { + gtk_main_iteration(); + } + xsane_widget_test_uposition(device_scanning_dialog); /* wait 100 ms to make sure window is displayed */ @@ -7746,6 +8869,16 @@ static int xsane_init(int argc, char **argv) /* ---------------------------------------------------------------------------------------------------------------------- */ +static void xsane_help_no_devices(void) +{ + char buf[512]; + + snprintf(buf, sizeof(buf), "%s\n\n%s", ERR_NO_DEVICES, HELP_NO_DEVICES); + xsane_back_gtk_decision(WINDOW_NO_DEVICES, (gchar**) no_device_xpm, buf, BUTTON_CLOSE, NULL, TRUE); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + void xsane_interface(int argc, char **argv) { struct SIGACTION act; @@ -7783,17 +8916,28 @@ void xsane_interface(int argc, char **argv) { char buf[256]; - snprintf(buf, sizeof(buf), "%s: %s\n", xsane.prog_name, ERR_NO_DEVICES); - xsane_back_gtk_error(buf, TRUE); + snprintf(buf, sizeof(buf), "%s\n", ERR_NO_DEVICES); + + if (xsane_back_gtk_decision(WINDOW_NO_DEVICES, (gchar**) no_device_xpm, buf, BUTTON_HELP, BUTTON_CLOSE, TRUE)) + { + xsane_help_no_devices(); + } xsane_exit(); } } - /* define SIGTERM-handler to make sure that e.g. all temporary files are deleted */ - /* when xsane gets a SIGTERM signal */ + /* define SIGTERM, SIGINT, SIGHUP-handler to make sure that e.g. all temporary files are deleted */ + /* when xsane gets such a signal */ memset(&act, 0, sizeof(act)); act.sa_handler = xsane_quit_handler; sigaction(SIGTERM, &act, 0); + sigaction(SIGINT, &act, 0); + sigaction(SIGHUP, &act, 0); + + /* add a signal handler that cleans up zombie child processes */ + memset(&act, 0, sizeof(act)); + act.sa_handler = xsane_sigchld_handler; + sigaction(SIGCHLD, &act, 0); gtk_main(); sane_exit(); @@ -7817,8 +8961,6 @@ int main(int argc, char **argv) xsane.main_window_fixed = -1; /* no command line option given, use preferences or fixed */ - xsane.get_deskrelative_origin = 0; - xsane.mode = XSANE_STANDALONE; xsane.xsane_mode = XSANE_VIEWER; xsane.lineart_mode = XSANE_LINEART_STANDARD; @@ -7904,6 +9046,8 @@ int main(int argc, char **argv) xsane.print_filenames = FALSE; xsane.force_filename = FALSE; + xsane.batch_scan_load_default_list = TRUE; /* load default batch scan list at program startup */ + xsane.prog_name = strrchr(argv[0], '/'); if (xsane.prog_name) { @@ -7914,16 +9058,36 @@ int main(int argc, char **argv) xsane.prog_name = argv[0]; } + if (!pipe(xsane.ipc_pipefd)) /* success */ + { + DBG(DBG_info, "created ipc_pipefd for inter progress communication\n"); +#ifndef BUGGY_GDK_INPUT_EXCEPTION + gdk_input_add(xsane.ipc_pipefd[0], GDK_INPUT_READ | GDK_INPUT_EXCEPTION, xsane_back_gtk_ipc_dialog_callback, 0); +#endif + } + else + { + DBG(DBG_info, "could not create pipe for inter progress communication\n"); + xsane.ipc_pipefd[0] = 0; + xsane.ipc_pipefd[1] = 0; + } + #if 0 bindtextdomain(PACKAGE, STRINGIFY(LOCALEDIR)); textdomain(PACKAGE); +#ifdef HAVE_GTK2 + bind_textdomain_codeset(PACKAGE, "UTF-8"); +#endif #else - DBG(DBG_info, "Setting xsane localedir: %s\n", STRINGIFY(LOCALEDIR)); + DBG(DBG_info, "Setting xsane translation table with localedir: %s\n", STRINGIFY(LOCALEDIR)); bindtextdomain(xsane.prog_name, STRINGIFY(LOCALEDIR)); textdomain(xsane.prog_name); +#ifdef HAVE_GTK2 + bind_textdomain_codeset(xsane.prog_name, "UTF-8"); +#endif #endif -#ifdef HAVE_LIBGIMP_GIMP_H +#ifdef HAVE_ANY_GIMP { GPrintFunc old_print_func; GPrintFunc old_printerr_func; @@ -7945,8 +9109,14 @@ int main(int argc, char **argv) /* don`t know why, but os2 does need this one, a bit different to WIN32 */ set_gimp_PLUG_IN_INFO(&PLUG_IN_INFO); #endif + +#ifdef HAVE_GIMP_2 + /* gimp_main() returns 1 if xsane wasn't invoked by GIMP */ + result = gimp_main(&PLUG_IN_INFO, argc, argv); +#else /* gimp_main() returns 1 if xsane wasn't invoked by GIMP */ result = gimp_main(argc, argv); +#endif #if 0 /* this is the old version that seems to use the compatibility functions */ -- cgit v1.2.3