summaryrefslogtreecommitdiff
path: root/src/xsane-multipage-project.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xsane-multipage-project.c')
-rw-r--r--src/xsane-multipage-project.c1087
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 */
+}
+
+