diff options
Diffstat (limited to 'src/xsane-batch-scan.c')
-rw-r--r-- | src/xsane-batch-scan.c | 1041 |
1 files changed, 1041 insertions, 0 deletions
diff --git a/src/xsane-batch-scan.c b/src/xsane-batch-scan.c new file mode 100644 index 0000000..bf5f57c --- /dev/null +++ b/src/xsane-batch-scan.c @@ -0,0 +1,1041 @@ +/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend + + xsane-batch-scan.c + + Oliver Rauch <Oliver.Rauch@rauch-domain.de> + 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 + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +#include "xsane.h" +#include "xsane-scan.h" +#include "xsane-batch-scan.h" +#include "xsane-back-gtk.h" +#include "xsane-front-gtk.h" +#include "xsane-rc-io.h" +#include "xsane-preview.h" +#include "xsane-gamma.h" + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static GtkWidget *xsane_batch_scan_create_list_entry(Batch_Scan_Parameters *parameters); + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +#define BOFFSET(field) ((char *) &((Batch_Scan_Parameters *) 0)->field - (char *) 0) + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static struct + { + SANE_String name; + void (*codec) (Wire *w, void *p, long offset); + long offset; + } +desc[] = + { + {"name", xsane_rc_pref_string, BOFFSET(name)}, + {"scanmode", xsane_rc_pref_string, BOFFSET(scanmode)}, + {"tl-x", xsane_rc_pref_double, BOFFSET(tl_x)}, + {"tl-y", xsane_rc_pref_double, BOFFSET(tl_y)}, + {"br-x", xsane_rc_pref_double, BOFFSET(br_x)}, + {"br-y", xsane_rc_pref_double, BOFFSET(br_y)}, + {"unit", xsane_rc_pref_int, BOFFSET(unit)}, + {"rotation", xsane_rc_pref_int, BOFFSET(rotation)}, + {"resolution-x", xsane_rc_pref_double, BOFFSET(resolution_x)}, + {"resolution-y", xsane_rc_pref_double, BOFFSET(resolution_y)}, + {"bit-depth", xsane_rc_pref_int, BOFFSET(bit_depth)}, + {"gamma", xsane_rc_pref_double, BOFFSET(gamma)}, + {"gamma-red", xsane_rc_pref_double, BOFFSET(gamma_red)}, + {"gamma-green", xsane_rc_pref_double, BOFFSET(gamma_green)}, + {"gamma-blue", xsane_rc_pref_double, BOFFSET(gamma_blue)}, + {"contrast", xsane_rc_pref_double, BOFFSET(contrast)}, + {"contrast-red", xsane_rc_pref_double, BOFFSET(contrast_red)}, + {"contrast-green", xsane_rc_pref_double, BOFFSET(contrast_green)}, + {"contrast-blue", xsane_rc_pref_double, BOFFSET(contrast_blue)}, + {"brightness", xsane_rc_pref_double, BOFFSET(brightness)}, + {"brightness-red", xsane_rc_pref_double, BOFFSET(brightness_red)}, + {"brightness-green", xsane_rc_pref_double, BOFFSET(brightness_green)}, + {"brightness-blue", xsane_rc_pref_double, BOFFSET(brightness_blue)}, + {"enhancement-rgb-default", xsane_rc_pref_int, BOFFSET(enhancement_rgb_default)}, + {"negative", xsane_rc_pref_int, BOFFSET(negative)}, + {"BATCH_END", xsane_rc_pref_string, 0} + }; + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_get_parameters(Batch_Scan_Parameters *parameters) +{ + char buf[255]; + SANE_Int unit; + + DBG(DBG_proc, "xsane_batch_scan_get_parameters\n"); + + xsane_back_gtk_get_option_double(xsane.well_known.coord[0], ¶meters->tl_x, &unit); + xsane_back_gtk_get_option_double(xsane.well_known.coord[1], ¶meters->tl_y, &unit); + xsane_back_gtk_get_option_double(xsane.well_known.coord[2], ¶meters->br_x, &unit); + xsane_back_gtk_get_option_double(xsane.well_known.coord[3], ¶meters->br_y, &unit); + + parameters->unit = unit; + + if (!xsane_back_gtk_get_option_double(xsane.well_known.dpi_x, ¶meters->resolution_x, NULL)) + { + if (xsane_back_gtk_get_option_double(xsane.well_known.dpi_y, ¶meters->resolution_y, NULL)) + { + parameters->resolution_y = parameters->resolution_x; + } + } + else /* only one resolution available */ + { + xsane_back_gtk_get_option_double(xsane.well_known.dpi, ¶meters->resolution_x, NULL); + parameters->resolution_y = parameters->resolution_x; + } + + + if (xsane_control_option(xsane.dev, xsane.well_known.bit_depth, SANE_ACTION_GET_VALUE, ¶meters->bit_depth, 0)) + { + parameters->bit_depth = -1; + } + + if (xsane_control_option(xsane.dev, xsane.well_known.scanmode, SANE_ACTION_GET_VALUE, buf, 0)) + { + parameters->scanmode = NULL; + } + else + { + parameters->scanmode = strdup(buf); + } + + parameters->rotation = xsane.preview->rotation; + + parameters->gamma = xsane.gamma; + parameters->gamma_red = xsane.gamma_red; + parameters->gamma_green = xsane.gamma_green; + parameters->gamma_blue = xsane.gamma_blue; + + parameters->brightness = xsane.brightness; + parameters->brightness_red = xsane.brightness_red; + parameters->brightness_green = xsane.brightness_green; + parameters->brightness_blue = xsane.brightness_blue; + + parameters->contrast = xsane.contrast; + parameters->contrast_red = xsane.contrast_red; + parameters->contrast_green = xsane.contrast_green; + parameters->contrast_blue = xsane.contrast_blue; + + parameters->enhancement_rgb_default = xsane.enhancement_rgb_default; + parameters->negative = xsane.negative; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_batch_scan_establish_parameters(Batch_Scan_Parameters *parameters, int panel_rebuild) +{ + SANE_Int info = 0; + + if ( (parameters->scanmode) && (xsane.batch_scan_use_stored_scanmode) ) + { + xsane_control_option(xsane.dev, xsane.well_known.scanmode, SANE_ACTION_SET_VALUE, parameters->scanmode, &info); + } + + xsane_back_gtk_set_option_double(xsane.well_known.coord[0], parameters->tl_x); + xsane_back_gtk_set_option_double(xsane.well_known.coord[1], parameters->tl_y); + xsane_back_gtk_set_option_double(xsane.well_known.coord[2], parameters->br_x); + xsane_back_gtk_set_option_double(xsane.well_known.coord[3], parameters->br_y); + + xsane.scan_rotation = parameters->rotation; + + if (xsane.batch_scan_use_stored_resolution) + { + if (!xsane_back_gtk_set_option_double(xsane.well_known.dpi_x, parameters->resolution_x)) + { + xsane_back_gtk_set_option_double(xsane.well_known.dpi_y, parameters->resolution_y); + } + else /* only one resolution */ + { + xsane_back_gtk_set_option_double(xsane.well_known.dpi, parameters->resolution_x); + } + } + + if (xsane.batch_scan_use_stored_bit_depth) + { + /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ + } + + if (info & SANE_INFO_RELOAD_OPTIONS) + { + xsane_refresh_dialog(); + preview_update_surface(xsane.preview, 0); + } + + xsane_update_param(0); + xsane_update_gamma_curve(TRUE); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static int xsane_batch_scan_list_item_activated_callback(GtkObject *list_item, gpointer data) + +{ + Batch_Scan_Parameters *parameters; + + if (list_item) + { + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + xsane_batch_scan_establish_parameters(parameters, TRUE); + } + } + + return 0; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_empty_list(void) +{ + GtkObject *list_item; + GList *list = GTK_LIST(xsane.batch_scan_list)->children; + Batch_Scan_Parameters *parameters = NULL; + + while (list) + { + list_item = GTK_OBJECT(list->data); + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + free(parameters); + } + + list = list->next; + + gtk_widget_destroy(GTK_WIDGET(list_item)); /* delete list element */ + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static int xsane_batch_scan_read_parameters(Wire *w, Batch_Scan_Parameters *parameters) +/* returns 0 if ok, otherwise error/eof */ +{ + SANE_String name; + int i; + + DBG(DBG_proc, "batch_scan_read_parameters\n"); + + while (1) + { + xsane_rc_io_w_space(w, 3); + if (w->status) + { + return -1; + } + + xsane_rc_io_w_string(w, &name); + if (w->status || !name) + { + return -2; + } + + if (!strcmp(name, "BATCH_END")) + { + return 0; /* ok */ + } + + for (i = 0; i < NELEMS (desc); ++i) + { + if (strcmp(name, desc[i].name) == 0) + { + DBG(DBG_info2, "reading batch-scan-parameter for %s\n", desc[i].name); + (*desc[i].codec) (w, parameters, desc[i].offset); + break; + } + } + } + + return -3; /* we should never come here */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +/* returns 0 if OK, -1 if file could not be loaded */ +int xsane_batch_scan_load_list_from_file(char *filename) +{ + Batch_Scan_Parameters *parameters = NULL; + int fd; + int eof = 0; + Wire w; + + DBG(DBG_proc, "xsane_batch_scan_load_list_from_file(%s)\n", filename); + + xsane_batch_scan_empty_list(); + + fd = open(filename, O_RDONLY); + + if (fd > 0) + { + w.io.fd = fd; + w.io.read = read; + w.io.write = write; + xsane_rc_io_w_init(&w); + xsane_rc_io_w_set_dir(&w, WIRE_DECODE); + + while (!eof) + { + eof = 1; + + parameters = calloc(1, sizeof(Batch_Scan_Parameters)); + + if (parameters) + { + eof = xsane_batch_scan_read_parameters(&w, parameters); + + if (!eof) + { + xsane_batch_scan_create_list_entry(parameters); + } + } + } + free(parameters); /* last one is unused */ + + xsane_rc_io_w_exit(&w); + + close(fd); + + /* scroll list to beginning */ + gtk_adjustment_set_value(xsane.batch_scan_vadjustment, xsane.batch_scan_vadjustment->lower); + gtk_adjustment_value_changed(xsane.batch_scan_vadjustment); + + return 0; + } + + return -1; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_load_list(void) +{ + char filename[PATH_MAX]; + char windowname[256]; + + DBG(DBG_proc, "xsane_batch_scan_load_list\n"); + + xsane_set_sensitivity(FALSE); + + sprintf(windowname, "%s %s %s", xsane.prog_name, WINDOW_LOAD_BATCH_LIST, xsane.device_text); + xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", "batch-lists", 0, "default", ".xbl", XSANE_PATH_LOCAL_SANE); + + if (!xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, NULL, FALSE, FALSE, FALSE, FALSE)) + { + if (xsane_batch_scan_load_list_from_file(filename)) /* error while loading file ? */ + { + char buf[256]; + + snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, filename, strerror(errno)); + xsane_back_gtk_error(buf, TRUE); + } + } + + xsane_set_sensitivity(TRUE); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_write_parameters(Wire *w, Batch_Scan_Parameters *parameters) +{ + int i; + + DBG(DBG_proc, "batch_scan_parameters_save\n"); + + for (i = 0; i < NELEMS(desc)-1; ++i) + { + DBG(DBG_info2, "saving batch-scan-parameter for %s\n", desc[i].name); + xsane_rc_io_w_string(w, &desc[i].name); + (*desc[i].codec) (w, parameters, desc[i].offset); + } + + xsane_rc_io_w_string(w, &desc[NELEMS(desc)-1].name); /* write BATCH_END */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_save_list(void) +{ + GtkObject *list_item; + GList *list = GTK_LIST(xsane.batch_scan_list)->children; + Batch_Scan_Parameters *parameters = NULL; + int fd; + Wire w; + char filename[PATH_MAX]; + char windowname[256]; + + DBG(DBG_proc, "xsane_batch_scan_save_list\n"); + + xsane_set_sensitivity(FALSE); + + sprintf(windowname, "%s %s %s", xsane.prog_name, WINDOW_SAVE_BATCH_LIST, xsane.device_text); + xsane_back_gtk_make_path(sizeof(filename), filename, "xsane", "batch-lists", 0, "default", ".xbl", XSANE_PATH_LOCAL_SANE); + + if (!xsane_back_gtk_get_filename(windowname, filename, sizeof(filename), filename, NULL, FALSE, FALSE, FALSE, FALSE)) + { + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0600); + + if (fd > 0) + { + w.io.fd = fd; + w.io.read = read; + w.io.write = write; + xsane_rc_io_w_init(&w); + xsane_rc_io_w_set_dir(&w, WIRE_ENCODE); + + while (list) + { + list_item = GTK_OBJECT(list->data); + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + xsane_batch_scan_write_parameters(&w, parameters); + } + + list = list->next; + } + + xsane_rc_io_w_set_dir(&w, WIRE_DECODE); /* flush it out */ + xsane_rc_io_w_exit(&w); + + close(fd); + } + else + { + char buf[256]; + + snprintf(buf, sizeof(buf), "%s `%s': %s", ERR_OPEN_FAILED, filename, strerror(errno)); + xsane_back_gtk_error(buf, TRUE); + } + } + + xsane_set_sensitivity(TRUE); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_scan_list(void) +{ + GtkObject *list_item; + GList *list = GTK_LIST(xsane.batch_scan_list)->children; + Batch_Scan_Parameters *parameters = NULL; + SANE_Int val_start = SANE_TRUE; + SANE_Int val_loop = SANE_TRUE; + SANE_Int val_end = SANE_FALSE; + SANE_Word val_next_tl_y = SANE_FIX(0.0); + + gtk_list_scroll_vertical(GTK_LIST(xsane.batch_scan_list), GTK_SCROLL_JUMP, 0.0); + + while (gtk_events_pending()) + { + gtk_main_iteration(); + } + + + while (list) + { + if (!list->next) /* last scan */ + { + val_loop = SANE_FALSE; + val_end = SANE_TRUE; + val_next_tl_y = SANE_FIX(0.0); + } + else /* not last scan */ + { + parameters = gtk_object_get_data(GTK_OBJECT(list->next->data), "parameters"); + if (parameters) + { + val_next_tl_y = SANE_FIX(parameters->tl_y); + } + } + xsane_control_option(xsane.dev, xsane.well_known.batch_scan_start, SANE_ACTION_SET_VALUE, &val_start, NULL); + xsane_control_option(xsane.dev, xsane.well_known.batch_scan_loop, SANE_ACTION_SET_VALUE, &val_loop, NULL); + xsane_control_option(xsane.dev, xsane.well_known.batch_scan_end, SANE_ACTION_SET_VALUE, &val_end, NULL); + xsane_control_option(xsane.dev, xsane.well_known.batch_scan_next_tl_y, SANE_ACTION_SET_VALUE, &val_next_tl_y, NULL); + + val_start = SANE_FALSE; + + xsane.batch_loop = val_loop; /* tell scanning routine if we have more scans */ + + list_item = GTK_OBJECT(list->data); + + gtk_list_select_child(GTK_LIST(xsane.batch_scan_list), GTK_WIDGET(list_item)); + /* selecting the child normally does establish the parameters, but not always for the first element! */ + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + xsane_batch_scan_establish_parameters(parameters, FALSE); + } + + while (gtk_events_pending()) + { + gtk_main_iteration(); + } + + xsane_scan_dialog(); + + while (xsane.scanning) + { +#if 0 + if (gtk_events_pending()) + { + gtk_main_iteration(); + } +#elseif + gtk_main_iteration(); +#endif + } + + if ( (xsane.status_of_last_scan != SANE_STATUS_GOOD) && (xsane.status_of_last_scan != SANE_STATUS_EOF) ) + { + break; /* cancel or error occured */ + } + + list = list->next; + + gtk_list_scroll_vertical(GTK_LIST(xsane.batch_scan_list), GTK_SCROLL_STEP_FORWARD, 1.0); + } + + val_start = SANE_FALSE; + val_loop = SANE_FALSE; + val_end = SANE_FALSE; + val_next_tl_y = SANE_FIX(0.0); + + /* make sure all batch scan options are reset */ + xsane_control_option(xsane.dev, xsane.well_known.batch_scan_start, SANE_ACTION_SET_VALUE, &val_start, NULL); + xsane_control_option(xsane.dev, xsane.well_known.batch_scan_loop, SANE_ACTION_SET_VALUE, &val_loop, NULL); + xsane_control_option(xsane.dev, xsane.well_known.batch_scan_end, SANE_ACTION_SET_VALUE, &val_end, NULL); + xsane_control_option(xsane.dev, xsane.well_known.batch_scan_next_tl_y, SANE_ACTION_SET_VALUE, &val_next_tl_y, NULL); + + xsane.batch_loop = FALSE; /* make sure we reset the batch scan loop flag */ + + if (parameters) + { + xsane_batch_scan_establish_parameters(parameters, FALSE); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_scan_selected(void) +{ + GList *select; + GtkObject *list_item; + Batch_Scan_Parameters *parameters = NULL; + + select = GTK_LIST(xsane.batch_scan_list)->selection; + if (select) + { + list_item = GTK_OBJECT(select->data); + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + xsane_batch_scan_establish_parameters(parameters, TRUE); + } + + xsane_scan_dialog(); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_delete(void) +{ + GList *select; + GtkObject *list_item; + Batch_Scan_Parameters *parameters = NULL; + + DBG(DBG_proc, "xsane_batch_scan_delete\n"); + + select = GTK_LIST(xsane.batch_scan_list)->selection; + if (select) + { + list_item = GTK_OBJECT(select->data); + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + free(parameters); + } + + gtk_widget_destroy(GTK_WIDGET(list_item)); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_update_label(Batch_Scan_Parameters *parameters) +{ + char buf[256]; + const char *unit_str; + double tl_x = parameters->tl_x; + double tl_y = parameters->tl_y; + double br_x = parameters->br_x; + double br_y = parameters->br_y; + char areaname_str[100]; + char geometry_tl_str[100]; + char geometry_size_str[100]; + char scanmode_str[100]; + char resolution_str[100]; + char bit_depth_str[100]; + + + snprintf(areaname_str, sizeof(areaname_str), "%s %s", TEXT_BATCH_LIST_AREANAME, parameters->name); + + if (xsane.batch_scan_use_stored_scanmode) + { + snprintf(scanmode_str, sizeof(scanmode_str), "%s %s", TEXT_BATCH_LIST_SCANMODE, parameters->scanmode); + } + else + { + snprintf(scanmode_str, sizeof(scanmode_str), "%s %s", TEXT_BATCH_LIST_SCANMODE, TEXT_BATCH_LIST_BY_GUI); + } + + unit_str = xsane_back_gtk_unit_string(parameters->unit); + if (parameters->unit == SANE_UNIT_MM) + { + tl_x /= preferences.length_unit; + tl_y /= preferences.length_unit; + br_x /= preferences.length_unit; + br_y /= preferences.length_unit; + } + snprintf(geometry_tl_str, sizeof(geometry_tl_str), "%s %0.2f %s, %0.2f %s", TEXT_BATCH_LIST_GEOMETRY_TL, + tl_x, unit_str, tl_y, unit_str); + + snprintf(geometry_size_str, sizeof(geometry_size_str), "%s %0.2f %s x %0.2f %s", TEXT_BATCH_LIST_GEOMETRY_SIZE, + br_x - tl_x, unit_str, br_y - tl_y, unit_str); + + if (xsane.batch_scan_use_stored_resolution) + { + snprintf(resolution_str, sizeof(resolution_str), "%s %3.0f dpi x %3.0f dpi", TEXT_BATCH_LIST_RESOLUTION, + parameters->resolution_x, parameters->resolution_y); + } + else + { + snprintf(resolution_str, sizeof(resolution_str), "%s %s", TEXT_BATCH_LIST_RESOLUTION, TEXT_BATCH_LIST_BY_GUI); + } + + if (xsane.batch_scan_use_stored_bit_depth) + { + snprintf(bit_depth_str, sizeof(bit_depth_str), "%s %d", TEXT_BATCH_LIST_BIT_DEPTH, parameters->bit_depth); + } + else + { + snprintf(bit_depth_str, sizeof(bit_depth_str), "%s %s", TEXT_BATCH_LIST_BIT_DEPTH, TEXT_BATCH_LIST_BY_GUI); + } + + snprintf(buf, sizeof(buf), "%s\n" /* name */ + "%s\n" /* scanmode */ + "%s\n" /* geometry_tl */ + "%s\n" /* geometry_size */ + "%s\n" /* resolution */ + "%s", /* bit_depth */ + areaname_str, + scanmode_str, + geometry_tl_str, + geometry_size_str, + resolution_str, + bit_depth_str); + + gtk_label_set_text(GTK_LABEL(parameters->label), buf); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static GtkWidget *xsane_batch_scan_create_list_entry(Batch_Scan_Parameters *parameters) +{ + GtkWidget *list_item; + GtkWidget *hbox; + int size = 120; + char *data; + + list_item = gtk_list_item_new(); + + hbox = gtk_hbox_new(FALSE, 10); + gtk_container_add(GTK_CONTAINER(list_item), hbox); + gtk_widget_show(hbox); + + data = calloc(size, size); + + parameters->gtk_preview = gtk_preview_new(GTK_PREVIEW_COLOR); + gtk_preview_size(GTK_PREVIEW(parameters->gtk_preview), size, size); + gtk_box_pack_start(GTK_BOX(hbox), parameters->gtk_preview, FALSE, FALSE, 0); + gtk_widget_show(parameters->gtk_preview); + + parameters->gtk_preview_size = size; + + preview_create_batch_icon(xsane.preview, parameters); + + + parameters->label = gtk_label_new(""); + gtk_box_pack_start(GTK_BOX(hbox), parameters->label, FALSE, FALSE, 0); + gtk_label_set_justify(GTK_LABEL(parameters->label), GTK_JUSTIFY_LEFT); + gtk_widget_show(parameters->label); + xsane_batch_scan_update_label(parameters); + + gtk_object_set_data(GTK_OBJECT(list_item), "parameters", parameters); + g_signal_connect(GTK_OBJECT(list_item), "select", (GtkSignalFunc) xsane_batch_scan_list_item_activated_callback, NULL); + gtk_container_add(GTK_CONTAINER(xsane.batch_scan_list), list_item); + gtk_widget_show(list_item); + + return(list_item); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_batch_scan_add() +{ + Batch_Scan_Parameters *parameters; + GtkWidget *list_item; + + DBG(DBG_proc, "xsane_batch_scan_add\n"); + + parameters = calloc(1, sizeof(Batch_Scan_Parameters)); + + if (parameters) + { + xsane_batch_scan_get_parameters(parameters); + + parameters->name = strdup(TEXT_BATCH_AREA_DEFAULT_NAME); + } + + list_item = xsane_batch_scan_create_list_entry(parameters); + + /* scroll list to end */ + gtk_adjustment_set_value(xsane.batch_scan_vadjustment, xsane.batch_scan_vadjustment->upper); + gtk_adjustment_value_changed(xsane.batch_scan_vadjustment); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_batch_scan_update_label_list(void) +{ + GtkObject *list_item; + GList *list = GTK_LIST(xsane.batch_scan_list)->children; + Batch_Scan_Parameters *parameters = NULL; + + while (list) + { + list_item = GTK_OBJECT(list->data); + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + xsane_batch_scan_update_label(parameters); + } + + list = list->next; + } + + gtk_widget_queue_draw(xsane.batch_scan_list); /* update gtk_pixmap widgets */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_batch_scan_update_icon_list(void) +{ + GtkObject *list_item; + GList *list = GTK_LIST(xsane.batch_scan_list)->children; + Batch_Scan_Parameters *parameters = NULL; + + while (list) + { + list_item = GTK_OBJECT(list->data); + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + preview_create_batch_icon(xsane.preview, parameters); + } + + list = list->next; + } + + gtk_widget_queue_draw(xsane.batch_scan_list); /* update gtk_pixmap widgets */ +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_batch_scan_rotate_mirror(GtkWidget *widget, gpointer data) +{ + GList *select; + GtkObject *list_item; + Batch_Scan_Parameters *parameters = NULL; + int rotate_info = (int) data; + int rotate, mirror; + + DBG(DBG_proc, "xsane_batch_scan_rotate_mirror\n"); + + select = GTK_LIST(xsane.batch_scan_list)->selection; + if (select) + { + list_item = GTK_OBJECT(select->data); + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + rotate = parameters->rotation & 3; + mirror = parameters->rotation & 4; + + if (parameters->rotation < 4) + { + parameters->rotation = ( (rotate + rotate_info) & 3 ) + ( (mirror+ rotate_info) & 4); + } + else + { + parameters->rotation = ( (rotate - rotate_info) & 3 ) + ( (mirror+ rotate_info) & 4); + } + + xsane_batch_scan_update_icon_list(); + } + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ +int xsane_batch_scan_rename; + +static void xsane_batch_scan_rename_button_callback(GtkWidget *widget, gpointer data) +{ + DBG(DBG_proc, "xsane_batch_scan_rename\n"); + + xsane_batch_scan_rename = (int) data; +} + + +static void xsane_batch_scan_rename_callback(GtkWidget *widget, gpointer data) +{ + GList *select; + GtkObject *list_item; + Batch_Scan_Parameters *parameters = NULL; + GtkWidget *rename_dialog; + GtkWidget *text; + GtkWidget *button; + GtkWidget *vbox, *hbox; + char buf[256]; + + DBG(DBG_proc, "xsane_batch_scan_rename\n"); + + select = GTK_LIST(xsane.batch_scan_list)->selection; + if (select) + { + list_item = GTK_OBJECT(select->data); + + parameters = gtk_object_get_data(list_item, "parameters"); + + if (parameters) + { + xsane_set_sensitivity(FALSE); + + rename_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + xsane_set_window_icon(rename_dialog, 0); + + /* set the main vbox */ + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(vbox), 0); + gtk_container_add(GTK_CONTAINER(rename_dialog), vbox); + gtk_widget_show(vbox); + + /* set the main hbox */ + hbox = gtk_hbox_new(FALSE, 0); + xsane_separator_new(vbox, 2); + gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 5); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); + gtk_widget_show(hbox); + + gtk_window_set_position(GTK_WINDOW(rename_dialog), GTK_WIN_POS_CENTER); + gtk_window_set_resizable(GTK_WINDOW(rename_dialog), FALSE); + snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_BATCH_RENAME); + gtk_window_set_title(GTK_WINDOW(rename_dialog), buf); + g_signal_connect(GTK_OBJECT(rename_dialog), "delete_event", (GtkSignalFunc) xsane_batch_scan_rename_button_callback,(void *) -1); + gtk_widget_show(rename_dialog); + + text = gtk_entry_new(); + xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_BATCH_RENAME); + gtk_entry_set_max_length(GTK_ENTRY(text), 64); + gtk_entry_set_text(GTK_ENTRY(text), parameters->name); + gtk_widget_set_size_request(text, 300, -1); + gtk_box_pack_start(GTK_BOX(vbox), text, TRUE, TRUE, 4); + gtk_widget_show(text); + +#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); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_rename_button_callback, (void *) 1); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_grab_default(button); + gtk_widget_show(button); + + +#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_batch_scan_rename_button_callback, (void *) -1); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + xsane_batch_scan_rename = 0; + + while (xsane_batch_scan_rename == 0) + { + while (gtk_events_pending()) + { + gtk_main_iteration(); + } + } + + if (xsane_batch_scan_rename == 1) + { + free(parameters->name); + parameters->name = strdup(gtk_entry_get_text(GTK_ENTRY(text))); + xsane_batch_scan_update_label(parameters); + } + gtk_widget_destroy(rename_dialog); + + xsane_set_sensitivity(TRUE); + } + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static gint xsane_batch_scan_win_delete(GtkWidget *widget, gpointer data) +{ + DBG(DBG_proc, "xsane_batch_scan_win_delete\n"); + + gtk_widget_hide(widget); + preferences.show_batch_scan = FALSE; + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(xsane.show_batch_scan_widget), preferences.show_batch_scan); + return TRUE; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_create_batch_scan_dialog(const char *devicetext) +{ + GtkWidget *batch_scan_vbox, *button, *scrolled_window; + char buf[64]; + + DBG(DBG_proc, "xsane_batch_scan_dialog\n"); + + xsane.batch_scan_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + xsane_set_window_icon(xsane.batch_scan_dialog, 0); + gtk_window_add_accel_group(GTK_WINDOW(xsane.batch_scan_dialog), xsane.accelerator_group); + + snprintf(buf, sizeof(buf), "%s %s", WINDOW_BATCH_SCAN, devicetext); + gtk_window_set_title(GTK_WINDOW(xsane.batch_scan_dialog), buf); + gtk_widget_set_size_request(xsane.batch_scan_dialog, 400, -1); + + g_signal_connect(GTK_OBJECT(xsane.batch_scan_dialog), "delete_event", GTK_SIGNAL_FUNC(xsane_batch_scan_win_delete), NULL); + + /* set the main vbox */ + batch_scan_vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(batch_scan_vbox), 5); + gtk_container_add(GTK_CONTAINER(xsane.batch_scan_dialog), batch_scan_vbox); + gtk_widget_show(batch_scan_vbox); + + /* set the hbox for load/save */ + xsane.batch_scan_button_box = gtk_hbox_new(FALSE, 0); + gtk_box_pack_start(GTK_BOX(batch_scan_vbox), xsane.batch_scan_button_box, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(xsane.batch_scan_button_box), 0); + gtk_widget_show(xsane.batch_scan_button_box); + + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, empty_batch_xpm, DESC_BATCH_LIST_EMPTY, (GtkSignalFunc) xsane_batch_scan_empty_list, NULL); + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, load_xpm, DESC_BATCH_LIST_LOAD, (GtkSignalFunc) xsane_batch_scan_load_list, NULL); + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, save_xpm, DESC_BATCH_LIST_SAVE, (GtkSignalFunc) xsane_batch_scan_save_list, NULL); + + xsane_vseparator_new(xsane.batch_scan_button_box, 3); + + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, add_batch_xpm, DESC_BATCH_ADD, (GtkSignalFunc) xsane_batch_scan_add, NULL); + + xsane_vseparator_new(xsane.batch_scan_button_box, 3); + + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, del_batch_xpm, DESC_BATCH_DEL, (GtkSignalFunc) xsane_batch_scan_delete, NULL); + + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, ascii_xpm, DESC_BATCH_RENAME, (GtkSignalFunc) xsane_batch_scan_rename_callback, NULL); + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate90_xpm, DESC_ROTATE90, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 1); + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate180_xpm, DESC_ROTATE180, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 2); + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, rotate270_xpm, DESC_ROTATE270, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 3); + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, mirror_x_xpm, DESC_MIRROR_X, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 4); + xsane_button_new_with_pixmap(xsane.batch_scan_dialog->window, xsane.batch_scan_button_box, mirror_y_xpm, DESC_MIRROR_Y, (GtkSignalFunc) xsane_batch_scan_rotate_mirror, (void *) 6); + + + /* the scolled window with the list */ + scrolled_window = gtk_scrolled_window_new(0, 0); + gtk_widget_set_size_request(scrolled_window, 400, 200); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_container_add(GTK_CONTAINER(batch_scan_vbox), scrolled_window); + gtk_widget_show(scrolled_window); + + xsane.batch_scan_list = gtk_list_new(); + + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), xsane.batch_scan_list); + + xsane.batch_scan_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrolled_window)); + gtk_container_set_focus_vadjustment(GTK_CONTAINER(xsane.batch_scan_list), xsane.batch_scan_vadjustment); + + gtk_widget_show(xsane.batch_scan_list); + + + xsane_separator_new(batch_scan_vbox, 2); + + + /* set the hbox for scan all / scan selected */ + xsane.batch_scan_action_box = gtk_hbox_new(TRUE, 0); + gtk_box_pack_start(GTK_BOX(batch_scan_vbox), xsane.batch_scan_action_box, FALSE, FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(xsane.batch_scan_action_box), 0); + gtk_widget_show(xsane.batch_scan_action_box); + + button = gtk_button_new_with_label(BUTTON_BATCH_LIST_SCAN); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_scan_list, NULL); + gtk_box_pack_start(GTK_BOX(xsane.batch_scan_action_box), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + button = gtk_button_new_with_label(BUTTON_BATCH_AREA_SCAN); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_batch_scan_scan_selected, NULL); + gtk_box_pack_start(GTK_BOX(xsane.batch_scan_action_box), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + gtk_widget_realize(xsane.batch_scan_dialog); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ |