diff options
Diffstat (limited to 'src/xsane-multipage-project.c')
-rw-r--r-- | src/xsane-multipage-project.c | 1087 |
1 files changed, 1087 insertions, 0 deletions
diff --git a/src/xsane-multipage-project.c b/src/xsane-multipage-project.c new file mode 100644 index 0000000..5a6f1ab --- /dev/null +++ b/src/xsane-multipage-project.c @@ -0,0 +1,1087 @@ +/* xsane -- a graphical (X11, gtk) scanner-oriented SANE frontend + + xsane-multipage-project.c + + Oliver Rauch <Oliver.Rauch@rauch-domain.de> + Copyright (C) 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 "stdio.h" +#include "xsane.h" +#include "xsane-back-gtk.h" +#include "xsane-front-gtk.h" +#include "xsane-preview.h" +#include "xsane-save.h" +#include "xsane-gamma.h" +#include "xsane-setup.h" +#include "xsane-scan.h" +#include "xsane-rc-io.h" +#include "xsane-device-preferences.h" +#include "xsane-preferences.h" +#include "xsane-icons.h" +#include "xsane-batch-scan.h" + +#ifdef HAVE_LIBTIFF +# include "tiffio.h" +#endif + +#include <sys/wait.h> + +/* ---------------------------------------------------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------------------------------------------------------- */ + +/* forward declarations: */ + + +void xsane_multipage_dialog(void); +void xsane_multipage_dialog_close(void); +void xsane_multipage_project_save(void); +static gint xsane_multipage_dialog_delete(); +static void xsane_multipage_filetype_callback(GtkWidget *filetype_option_menu, char *filetype); +static void xsane_multipage_project_changed_callback(GtkWidget *widget, gpointer data); +static void xsane_multipage_project_load(void); +static void xsane_multipage_project_delete(void); +static void xsane_multipage_project_create(void); +static void xsane_multipage_entry_move_up_callback(GtkWidget *widget, gpointer list); +static void xsane_multipage_entry_move_down_callback(GtkWidget *widget, gpointer list); +static void xsane_multipage_entry_delete_callback(GtkWidget *widget, gpointer list); +static void xsane_multipage_show_callback(GtkWidget *widget, gpointer data); +static void xsane_multipage_edit_callback(GtkWidget *widget, gpointer data); +static void xsane_multipage_save_file(void); + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static gint xsane_multipage_dialog_delete() +{ + return TRUE; +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_filetype_callback(GtkWidget *filetype_option_menu, char *filetype) +{ + DBG(DBG_proc, "xsane_multipage_filetype_callback(%s)\n", filetype); + + if (preferences.multipage_filetype) + { + free(preferences.multipage_filetype); + } + preferences.multipage_filetype = strdup(filetype); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_multipage_dialog() +{ + GtkWidget *multipage_dialog, *multipage_scan_vbox, *multipage_project_vbox; + GtkWidget *multipage_project_exists_hbox, *button; + GtkWidget *hbox; + GtkWidget *scrolled_window, *list; + GtkWidget *pixmapwidget, *text; + GtkWidget *pages_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_multipage_dialog\n"); + + if (xsane.project_dialog) + { + return; /* window already is open */ + } + + /* GTK_WINDOW_TOPLEVEL looks better but does not place it nice*/ + multipage_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL); + + snprintf(buf, sizeof(buf), "%s %s", xsane.prog_name, WINDOW_MULTIPAGE_PROJECT); + gtk_window_set_title(GTK_WINDOW(multipage_dialog), buf); + g_signal_connect(GTK_OBJECT(multipage_dialog), "delete_event", (GtkSignalFunc) xsane_multipage_dialog_delete, NULL); + xsane_set_window_icon(multipage_dialog, 0); + gtk_window_add_accel_group(GTK_WINDOW(multipage_dialog), xsane.accelerator_group); + + /* set the main vbox */ + multipage_scan_vbox = gtk_vbox_new(FALSE, 0); + gtk_container_set_border_width(GTK_CONTAINER(multipage_scan_vbox), 0); + gtk_container_add(GTK_CONTAINER(multipage_dialog), multipage_scan_vbox); + gtk_widget_show(multipage_scan_vbox); + + + /* multipage project */ + hbox = gtk_hbox_new(FALSE, 2); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 2); + gtk_box_pack_start(GTK_BOX(multipage_scan_vbox), hbox, FALSE, FALSE, 1); + + pixmap = gdk_pixmap_create_from_xpm_d(xsane.dialog->window, &mask, xsane.bg_trans, (gchar **) multipage_xpm); + pixmapwidget = gtk_image_new_from_pixmap(pixmap, mask); + gtk_box_pack_start(GTK_BOX(hbox), pixmapwidget, FALSE, FALSE, 2); + gdk_drawable_unref(pixmap); + + text = gtk_entry_new(); + xsane_back_gtk_set_tooltip(xsane.tooltips, text, DESC_MULTIPAGE_PROJECT); + gtk_entry_set_max_length(GTK_ENTRY(text), 128); + gtk_entry_set_text(GTK_ENTRY(text), (char *) preferences.multipage_project); + gtk_box_pack_start(GTK_BOX(hbox), text, TRUE, TRUE, 4); + g_signal_connect(GTK_OBJECT(text), "changed", (GtkSignalFunc) xsane_multipage_project_changed_callback, NULL); + + xsane.project_entry = text; + xsane.project_entry_box = hbox; + + gtk_widget_show(pixmapwidget); + gtk_widget_show(text); + gtk_widget_show(hbox); + + multipage_project_vbox = gtk_vbox_new(/* homogeneous */ FALSE, 0); + gtk_box_pack_start(GTK_BOX(multipage_scan_vbox), multipage_project_vbox, TRUE, TRUE, 0); + gtk_widget_show(multipage_project_vbox); + + + /* 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(multipage_project_vbox), hbox, FALSE, FALSE, 1); + gtk_widget_show(hbox); + + filetype_menu = gtk_menu_new(); + + filetype_nr = -1; + select_item = 0; + + + filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PDF); + gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item); + g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_multipage_filetype_callback, (void *) XSANE_FILETYPE_PDF); + gtk_widget_show(filetype_item); + filetype_nr++; + if ( (preferences.multipage_filetype) && (!strcasecmp(preferences.multipage_filetype, XSANE_FILETYPE_PDF)) ) + { + select_item = filetype_nr; + } + + + filetype_item = gtk_menu_item_new_with_label(MENU_ITEM_FILETYPE_PS); + gtk_container_add(GTK_CONTAINER(filetype_menu), filetype_item); + g_signal_connect(GTK_OBJECT(filetype_item), "activate", (GtkSignalFunc) xsane_multipage_filetype_callback, (void *) XSANE_FILETYPE_PS); + gtk_widget_show(filetype_item); + filetype_nr++; + if ( (preferences.multipage_filetype) && (!strcasecmp(preferences.multipage_filetype, XSANE_FILETYPE_PS)) ) + { + select_item = filetype_nr; + } + + +#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_multipage_filetype_callback, (void *) XSANE_FILETYPE_TIFF); + gtk_widget_show(filetype_item); + filetype_nr++; + if ( (preferences.multipage_filetype) && (!strcasecmp(preferences.multipage_filetype, XSANE_FILETYPE_TIFF)) ) + { + select_item = filetype_nr; + } +#endif + + label = gtk_label_new(TEXT_MULTIPAGE_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_MULTIPAGE_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); + + + /* pages frame */ + pages_frame = gtk_frame_new(TEXT_PAGES); + gtk_box_pack_start(GTK_BOX(multipage_project_vbox), pages_frame, TRUE, TRUE, 2); + gtk_widget_show(pages_frame); + + /* pages list */ + scrolled_window = gtk_scrolled_window_new(0, 0); + gtk_widget_set_size_request(scrolled_window, 200, 100); + gtk_container_add(GTK_CONTAINER(pages_frame), scrolled_window); + gtk_widget_show(scrolled_window); + + list = gtk_list_new(); +/* gtk_list_set_selection_mode(list, GTK_SELECTION_BROWSE); */ + + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled_window), list); + gtk_widget_show(list); + xsane.project_list = list; + + + /* 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(multipage_project_vbox), hbox, FALSE, FALSE, 1); + + button = gtk_button_new_with_label(BUTTON_IMAGE_SHOW); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_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_IMAGE_EDIT); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_edit_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); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_entry_delete_callback, list); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + xsane_button_new_with_pixmap(multipage_dialog->window, hbox, move_up_xpm, 0, (GtkSignalFunc) xsane_multipage_entry_move_up_callback, list); + xsane_button_new_with_pixmap(multipage_dialog->window, hbox, move_down_xpm, 0, (GtkSignalFunc) xsane_multipage_entry_move_down_callback, list); + + gtk_widget_show(hbox); + + xsane.project_box = multipage_project_vbox; + + /* set the main hbox */ + hbox = gtk_hbox_new(FALSE, 0); + xsane_separator_new(multipage_scan_vbox, 2); + gtk_box_pack_end(GTK_BOX(multipage_scan_vbox), hbox, FALSE, FALSE, 5); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 5); + gtk_widget_show(hbox); + + + multipage_project_exists_hbox = gtk_hbox_new(FALSE, 2); + gtk_box_pack_start(GTK_BOX(hbox), multipage_project_exists_hbox, TRUE, TRUE, 0); + + button = gtk_button_new_with_label(BUTTON_SAVE_MULTIPAGE); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_save_file, NULL); + gtk_box_pack_start(GTK_BOX(multipage_project_exists_hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + button = gtk_button_new_with_label(BUTTON_DELETE_PROJECT); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_project_delete, NULL); + gtk_box_pack_start(GTK_BOX(multipage_project_exists_hbox), button, TRUE, TRUE, 0); + gtk_widget_show(button); + + gtk_widget_show(multipage_project_exists_hbox); + xsane.project_exists = multipage_project_exists_hbox; + + button = gtk_button_new_with_label(BUTTON_CREATE_PROJECT); + g_signal_connect(GTK_OBJECT(button), "clicked", (GtkSignalFunc) xsane_multipage_project_create, NULL); + gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0); + xsane.project_not_exists = button; + + /* progress bar */ + xsane.project_progress_bar = (GtkProgressBar *) gtk_progress_bar_new(); + gtk_box_pack_start(GTK_BOX(multipage_scan_vbox), (GtkWidget *) xsane.project_progress_bar, FALSE, FALSE, 0); + gtk_progress_set_show_text(GTK_PROGRESS(xsane.project_progress_bar), TRUE); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), ""); + gtk_widget_show(GTK_WIDGET(xsane.project_progress_bar)); + + + xsane.project_dialog = multipage_dialog; + + xsane_multipage_project_load(); + + gtk_window_move(GTK_WINDOW(xsane.project_dialog), xsane.project_dialog_posx, xsane.project_dialog_posy); + gtk_widget_show(multipage_dialog); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_project_set_sensitive(int sensitive) +{ + gtk_widget_set_sensitive(xsane.project_box, sensitive); + gtk_widget_set_sensitive(xsane.project_exists, sensitive); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_project_load() +{ + FILE *projectfile; + char page[256]; + char filename[PATH_MAX]; + GtkWidget *list_item; + int i; + int c; + + DBG(DBG_proc, "xsane_multipage_project_load\n"); + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + xsane.multipage_status = NULL; + } + + if (xsane.multipage_filename) + { + free(xsane.multipage_filename); + xsane.multipage_filename = NULL; + } + + gtk_list_remove_items(GTK_LIST(xsane.project_list), GTK_LIST(xsane.project_list)->children); + + snprintf(filename, sizeof(filename), "%s/xsane-multipage-list", preferences.multipage_project); + projectfile = fopen(filename, "rb"); /* read binary (b for win32) */ + + if ((!projectfile) || (feof(projectfile))) + { + snprintf(filename, sizeof(filename), "%s/image-1.pnm", preferences.multipage_project); + xsane.multipage_filename=strdup(filename); + xsane_update_counter_in_filename(&xsane.multipage_filename, FALSE, 0, preferences.filename_counter_len); /* correct counter len */ + + xsane.multipage_status=strdup(TEXT_PROJECT_STATUS_NOT_CREATED); + + gtk_widget_hide(xsane.project_exists); + gtk_widget_show(xsane.project_not_exists); + + gtk_widget_set_sensitive(xsane.project_box, FALSE); + gtk_widget_set_sensitive(xsane.project_exists, FALSE); + /* do not change sensitivity of multipage_project_entry_box here !!! */ + gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE); + } + else + { + i=0; + c=0; + while ((i<255) && (c != 10) && (c != EOF)) /* first line is multipage status */ + { + c = fgetc(projectfile); + page[i++] = c; + } + page[i-1] = 0; + if (strchr(page, '@')) + { + *strchr(page, '@') = 0; + } + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(page); + + + i=0; + c=0; + while ((i<255) && (c != 10) && (c != EOF)) /* second line is next multipage filename */ + { + c = fgetc(projectfile); + page[i++] = c; + } + page[i-1] = 0; + + snprintf(filename, sizeof(filename), "%s/%s", preferences.multipage_project, page); + xsane.multipage_filename=strdup(filename); + + while (!feof(projectfile)) + { + i=0; + c=0; + + while ((i<255) && (c != 10) && (c != EOF)) + { + c = fgetc(projectfile); + page[i++] = c; + } + page[i-1]=0; + + 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.project_list), list_item); + gtk_widget_show(list_item); + } + } + + if (!strcmp(xsane.multipage_status, TEXT_PROJECT_STATUS_FILE_SAVING)) + { + xsane_multipage_project_set_sensitive(FALSE); + gtk_widget_set_sensitive(xsane.project_entry_box, TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), FALSE); + } + else + { + xsane_multipage_project_set_sensitive(TRUE); + gtk_widget_set_sensitive(xsane.project_entry_box, TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(xsane.start_button), TRUE); + } + + gtk_widget_show(xsane.project_exists); + gtk_widget_hide(xsane.project_not_exists); + } + + if (projectfile) + { + fclose(projectfile); + } + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_project_delete() +{ + char *page; + char *type; + char file[256]; + GList *list = (GList *) GTK_LIST(xsane.project_list)->children; + GtkObject *list_item; + + DBG(DBG_proc, "xsane_multipage_project_delete\n"); + + while (list) + { + 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%s", preferences.multipage_project, page, type); + free(page); + free(type); + remove(file); + list = list->next; + } + snprintf(file, sizeof(file), "%s/xsane-multipage-list", preferences.multipage_project); + remove(file); + snprintf(file, sizeof(file), "%s", preferences.multipage_project); + rmdir(file); + + xsane_multipage_project_load(); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +void xsane_multipage_project_save() +{ + FILE *projectfile; + GList *list = (GList *) GTK_LIST(xsane.project_list)->children; + GtkObject *list_item; + char *page; + char *type; + char filename[256]; + + DBG(DBG_proc, "xsane_multipage_project_save\n"); + + umask((mode_t) preferences.directory_umask); /* define new file permissions */ + mkdir(preferences.multipage_project, 0777); /* make sure directory exists */ + + snprintf(filename, sizeof(filename), "%s/xsane-multipage-list", preferences.multipage_project); + + if (xsane_create_secure_file(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, filename); + xsane_back_gtk_error(buf, TRUE); + return; /* error */ + } + + projectfile = fopen(filename, "wb"); /* write binary (b for win32) */ + + if (xsane.multipage_status) + { + char buf[256]; + + snprintf(buf, 32, "%s@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@", xsane.multipage_status); /* fill 32 characters status line */ + fprintf(projectfile, "%s\n", buf); /* first line is status of multipage */ + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + } + else + { + fprintf(projectfile, " \n"); /* no multipage status */ + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), ""); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + } + + if (xsane.multipage_filename) + { + fprintf(projectfile, "%s\n", strrchr(xsane.multipage_filename, '/')+1); /* third line is next multipage filename */ + } + else + { + fprintf(projectfile, "\n"); + } + + while (list) + { + list_item = GTK_OBJECT(list->data); + 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; + } + + fclose(projectfile); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_project_create() +{ + DBG(DBG_proc, "xsane_multipage_project_create\n"); + + if (strlen(preferences.multipage_project)) + { + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CREATED); + xsane_multipage_project_save(); + xsane_multipage_project_load(); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_project_changed_callback(GtkWidget *widget, gpointer data) +{ + DBG(DBG_proc, "xsane_multipage_project_changed_callback\n"); + + if (preferences.multipage_project) + { + free((void *) preferences.multipage_project); + } + preferences.multipage_project = strdup(gtk_entry_get_text(GTK_ENTRY(widget))); + + xsane_multipage_project_load(); +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_entry_move_up_callback(GtkWidget *widget, gpointer list) +{ + GList *select; + GList *item = GTK_LIST(list)->children; + GtkWidget *list_item_1; + GtkWidget *list_item_2; + int position; + int newpos; + + DBG(DBG_proc, "xsane_multipage_entry_move_up\n"); + + select = GTK_LIST(list)->selection; + if (select) + { + list_item_1 = select->data; + + position = gtk_list_child_position(GTK_LIST(list), list_item_1); + position--; /* move up */ + newpos = position; + + if (position >= 0) + { + while (position>0) + { + item = item->next; + position--; + } + + list_item_2 = item->data; + if (list_item_2) + { + xsane_front_gtk_list_entries_swap(list_item_1, list_item_2); + gtk_list_select_item(GTK_LIST(list), newpos); + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED); + xsane_multipage_project_save(); + } + } + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_entry_move_down_callback(GtkWidget *widget, gpointer list) +{ + GList *select; + GList *item = GTK_LIST(list)->children; + GtkWidget *list_item_1; + GtkWidget *list_item_2; + int position; + int newpos; + + DBG(DBG_proc, "xsane_multipage_entry_move_down\n"); + + select = GTK_LIST(list)->selection; + if (select) + { + list_item_1 = select->data; + + position = gtk_list_child_position(GTK_LIST(list), list_item_1); + position++; /* move down */ + newpos = position; + + while ((position>0) && (item)) + { + item = item->next; + position--; + } + + if (item) + { + list_item_2 = item->data; + if (list_item_2) + { + xsane_front_gtk_list_entries_swap(list_item_1, list_item_2); + gtk_list_select_item(GTK_LIST(list), newpos); + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED); + xsane_multipage_project_save(); + } + } + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_entry_delete_callback(GtkWidget *widget, gpointer list) +{ + GtkObject *list_item; + GList *select; + char *page; + char *type; + char file[256]; + + DBG(DBG_proc, "xsane_multipage_entry_delete_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(file, sizeof(file), "%s/%s%s", preferences.multipage_project, page, type); + free(page); + free(type); + remove(file); + gtk_widget_destroy(GTK_WIDGET(list_item)); + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED); + xsane_multipage_project_save(); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_show_callback(GtkWidget *widget, gpointer list) +{ + GtkObject *list_item; + GList *select; + char *page; + char *type; + char filename[256]; + + DBG(DBG_proc, "xsane_multipage_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.multipage_project, page, type); + free(page); + free(type); + + xsane_viewer_new(filename, NULL, FALSE, filename, VIEWER_NO_MODIFICATION, IMAGE_SAVED); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_edit_callback(GtkWidget *widget, gpointer list) +{ + GtkObject *list_item; + GList *select; + char *page; + char *type; + char filename[PATH_MAX]; + char outfilename[PATH_MAX]; + int cancel_save = 0; + + DBG(DBG_proc, "xsane_multipage_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.multipage_project, page, type); + free(page); + free(type); + + xsane_back_gtk_make_path(sizeof(outfilename), outfilename, 0, 0, "xsane-viewer-", xsane.dev_name, ".pnm", XSANE_PATH_TMP); + xsane_copy_file_by_name(outfilename, filename, xsane.project_progress_bar, &cancel_save); + + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_CHANGED); + xsane_multipage_project_save(); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + + xsane_viewer_new(outfilename, NULL, FALSE, filename, VIEWER_NO_NAME_MODIFICATION, IMAGE_SAVED); + } +} + +/* ---------------------------------------------------------------------------------------------------------------------- */ + +static void xsane_multipage_save_file() +{ + char *image; + char *type; + GList *list = (GList *) GTK_LIST(xsane.project_list)->children; + GtkObject *list_item; + char source_filename[PATH_MAX]; + char multipage_filename[PATH_MAX]; + int output_format; + int cancel_save = 0; + int page, pages = 0; + FILE *outfile = NULL, *imagefile = NULL; +#ifdef HAVE_LIBTIFF + TIFF *tiffile = NULL; +#endif + Image_info image_info; + long int source_size = 0; + float imagewidth, imageheight; + char buf[255]; + struct pdf_xref xref; + + DBG(DBG_proc, "xsane_multipage_save_file\n"); + + xsane_set_sensitivity(FALSE); /* do not allow changing xsane mode */ + xsane_multipage_project_set_sensitive(FALSE); + + while (gtk_events_pending()) + { + DBG(DBG_info, "calling gtk_main_iteration\n"); + gtk_main_iteration(); + } + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + + + snprintf(multipage_filename, sizeof(multipage_filename), "%s%s", preferences.multipage_project, preferences.multipage_filetype); + output_format = xsane_identify_output_format(multipage_filename, NULL, NULL); + + 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.multipage_project, image, type); + free(image); + free(type); + list = list->next; + pages++; + source_size += xsane_get_filesize(source_filename); + } + + + if ( (preferences.overwrite_warning) ) /* test if filename already used */ + { + FILE *testfile; + + testfile = fopen(multipage_filename, "rb"); /* read binary (b for win32) */ + if (testfile) /* filename used: skip */ + { + char buf[256]; + + fclose(testfile); + + snprintf(buf, sizeof(buf), WARN_FILE_EXISTS, multipage_filename); + if (xsane_back_gtk_decision(ERR_HEADER_WARNING, (gchar **) warning_xpm, buf, BUTTON_OVERWRITE, BUTTON_CANCEL, TRUE /* wait */) == FALSE) + { + xsane_set_sensitivity(TRUE); + xsane_multipage_project_set_sensitive(TRUE); + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING_ABORTED); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + return; + } + } + } + + + if (xsane_create_secure_file(multipage_filename)) /* remove possibly existing symbolic links for security */ + { + snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, multipage_filename); + xsane_back_gtk_error(buf, TRUE); + xsane_multipage_project_set_sensitive(TRUE); + xsane_set_sensitivity(TRUE); /* allow changing xsane mode */ + return; + } + + DBG(DBG_info, "xsane_multipage_save_file: created %s\n", multipage_filename); + + + if ((output_format == XSANE_PS) || (output_format == XSANE_PDF)) + { + outfile = fopen(multipage_filename, "wb"); /* b = binary mode for win32 */ + if (!outfile) + { + snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_CREATE_SECURE_FILE, multipage_filename); + xsane_back_gtk_error(buf, TRUE); + xsane_multipage_project_set_sensitive(TRUE); + xsane_set_sensitivity(TRUE); /* allow changing xsane mode */ + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING_ERROR); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + return; + } + + if (output_format == XSANE_PS) + { + xsane_save_ps_create_document_header(outfile, pages, preferences.save_ps_flatdecoded); + } + else if (output_format == XSANE_PDF) + { + xsane_save_pdf_create_document_header(outfile, &xref, pages, preferences.save_pdf_flatdecoded); + } + } +#ifdef HAVE_LIBTIFF + else if (output_format == XSANE_TIFF) + { + tiffile = TIFFOpen(multipage_filename, "w"); + if (!tiffile) + { + snprintf(buf, sizeof(buf), "%s %s %s\n", ERR_DURING_SAVE, ERR_OPEN_FAILED, multipage_filename); + xsane_back_gtk_error(buf, TRUE); + xsane_multipage_project_set_sensitive(TRUE); + xsane_set_sensitivity(TRUE); /* allow changing xsane mode */ + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING_ERROR); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + return; + } + } +#endif + else + { + snprintf(buf, sizeof(buf), "%s unsupported multipage fileformat\n", ERR_DURING_SAVE); + xsane_back_gtk_error(buf, TRUE); + xsane_multipage_project_set_sensitive(TRUE); + xsane_set_sensitivity(TRUE); /* allow changing xsane mode */ + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + } + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVING_ERROR); + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + return; + } + + + list = (GList *) GTK_LIST(xsane.project_list)->children; + + page = 1; + 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.multipage_project, image, type); + + snprintf(buf, sizeof(buf), "%s %s %d/%d", _(xsane.multipage_status), PROGRESS_PAGE, page, pages); + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), buf); + + imagefile = fopen(source_filename, "rb"); /* read binary (b for win32) */ + if (!imagefile) + { + DBG(DBG_error, "could not read imagefile %s\n", source_filename); + return; + } + + xsane_read_pnm_header(imagefile, &image_info); + + if (output_format == XSANE_PS) + { + 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 */ + + xsane_save_ps_page(outfile, page, + imagefile, &image_info, imagewidth, imageheight, + 0, 0, imagewidth, imageheight, 0 /* portrait top left */, + preferences.save_ps_flatdecoded, + xsane.project_progress_bar, &cancel_save); + } + else if (output_format == XSANE_PDF) + { + 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 */ + + xsane_save_pdf_page(outfile, &xref, page, + imagefile, &image_info, imagewidth, imageheight, + 0, 0, imagewidth, imageheight, 0 /* portrait top left */, + preferences.save_pdf_flatdecoded, + xsane.project_progress_bar, &cancel_save); + } +#ifdef HAVE_LIBTIFF + else if (output_format == XSANE_TIFF) + { + xsane_save_tiff_page(tiffile, page, pages, imagefile, &image_info, preferences.jpeg_quality, + xsane.project_progress_bar, &cancel_save); + } +#endif + + free(image); + free(type); + list = list->next; + + page++; + } + + if (output_format == XSANE_PS) + { + xsane_save_ps_create_document_trailer(outfile, 0 /* we defined pages at beginning */); + + if (ferror(outfile)) + { + char buf[255]; + + snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno)); + DBG(DBG_error, "%s\n", buf); + xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */); + cancel_save = 1; + } + + fclose(outfile); + } + else if (output_format == XSANE_PDF) + { + xsane_save_pdf_create_document_trailer(outfile, &xref, pages); + + if (ferror(outfile)) + { + char buf[255]; + + snprintf(buf, sizeof(buf), "%s %s", ERR_DURING_SAVE, strerror(errno)); + DBG(DBG_error, "%s\n", buf); + xsane_back_gtk_decision(ERR_HEADER_ERROR, (gchar **) error_xpm, buf, BUTTON_OK, NULL, TRUE /* wait */); + cancel_save = 1; + } + + fclose(outfile); + } +#ifdef HAVE_LIBTIFF + else if (output_format == XSANE_TIFF) + { + TIFFClose(tiffile); + } +#endif + + if (xsane.multipage_status) + { + free(xsane.multipage_status); + xsane.multipage_status = NULL; + } + + if (cancel_save) + { + xsane.multipage_status = strdup(ERR_DURING_SAVE); + } + else + { + xsane.multipage_status = strdup(TEXT_PROJECT_STATUS_FILE_SAVED); + } + xsane_multipage_project_save(); + + + gtk_progress_set_format_string(GTK_PROGRESS(xsane.project_progress_bar), _(xsane.multipage_status)); + gtk_progress_bar_update(GTK_PROGRESS_BAR(xsane.project_progress_bar), 0.0); + + xsane_multipage_project_set_sensitive(TRUE); + xsane_set_sensitivity(TRUE); /* allow changing xsane mode */ +} + + |