summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile.am1
-rw-r--r--src/Makefile.in661
-rw-r--r--src/book.c614
-rw-r--r--src/book.h4
-rw-r--r--src/page.c28
-rw-r--r--src/page.h4
-rw-r--r--src/scanner.c44
-rw-r--r--src/simple-scan.c54
-rw-r--r--src/ui.c632
-rw-r--r--src/ui.h1
10 files changed, 933 insertions, 1110 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index e6654d0..8a4f587 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -29,6 +29,7 @@ simple_scan_CFLAGS = \
simple_scan_LDADD = \
$(SIMPLE_SCAN_LIBS) \
-lsane \
+ -ljpeg \
-lm
DISTCLEANFILES = \
diff --git a/src/Makefile.in b/src/Makefile.in
deleted file mode 100644
index 5665293..0000000
--- a/src/Makefile.in
+++ /dev/null
@@ -1,661 +0,0 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-bin_PROGRAMS = simple-scan$(EXEEXT)
-subdir = src
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__installdirs = "$(DESTDIR)$(bindir)"
-PROGRAMS = $(bin_PROGRAMS)
-am_simple_scan_OBJECTS = simple_scan-book.$(OBJEXT) \
- simple_scan-book-view.$(OBJEXT) simple_scan-page.$(OBJEXT) \
- simple_scan-page-view.$(OBJEXT) \
- simple_scan-simple-scan.$(OBJEXT) \
- simple_scan-scanner.$(OBJEXT) simple_scan-ui.$(OBJEXT)
-simple_scan_OBJECTS = $(am_simple_scan_OBJECTS)
-am__DEPENDENCIES_1 =
-simple_scan_DEPENDENCIES = $(am__DEPENDENCIES_1)
-simple_scan_LINK = $(CCLD) $(simple_scan_CFLAGS) $(CFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-DEFAULT_INCLUDES = -I.@am__isrc@
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__depfiles_maybe = depfiles
-am__mv = mv -f
-AM_V_lt = $(am__v_lt_$(V))
-am__v_lt_ = $(am__v_lt_$(AM_DEFAULT_VERBOSITY))
-am__v_lt_0 = --silent
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_$(V))
-am__v_CC_ = $(am__v_CC_$(AM_DEFAULT_VERBOSITY))
-am__v_CC_0 = @echo " CC " $@;
-AM_V_at = $(am__v_at_$(V))
-am__v_at_ = $(am__v_at_$(AM_DEFAULT_VERBOSITY))
-am__v_at_0 = @
-CCLD = $(CC)
-LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_$(V))
-am__v_CCLD_ = $(am__v_CCLD_$(AM_DEFAULT_VERBOSITY))
-am__v_CCLD_0 = @echo " CCLD " $@;
-AM_V_GEN = $(am__v_GEN_$(V))
-am__v_GEN_ = $(am__v_GEN_$(AM_DEFAULT_VERBOSITY))
-am__v_GEN_0 = @echo " GEN " $@;
-SOURCES = $(simple_scan_SOURCES)
-DIST_SOURCES = $(simple_scan_SOURCES)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-ALL_LINGUAS = @ALL_LINGUAS@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CATALOGS = @CATALOGS@
-CATOBJEXT = @CATOBJEXT@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DATADIRNAME = @DATADIRNAME@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DISABLE_DEPRECATED = @DISABLE_DEPRECATED@
-DISTCHECK_CONFIGURE_FLAGS = @DISTCHECK_CONFIGURE_FLAGS@
-DOC_USER_FORMATS = @DOC_USER_FORMATS@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-GCONF_SCHEMA_CONFIG_SOURCE = @GCONF_SCHEMA_CONFIG_SOURCE@
-GCONF_SCHEMA_FILE_DIR = @GCONF_SCHEMA_FILE_DIR@
-GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
-GMOFILES = @GMOFILES@
-GMSGFMT = @GMSGFMT@
-GREP = @GREP@
-HELP_DIR = @HELP_DIR@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-INSTOBJEXT = @INSTOBJEXT@
-INTLLIBS = @INTLLIBS@
-INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
-INTLTOOL_MERGE = @INTLTOOL_MERGE@
-INTLTOOL_PERL = @INTLTOOL_PERL@
-INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MKINSTALLDIRS = @MKINSTALLDIRS@
-MSGFMT = @MSGFMT@
-MSGFMT_OPTS = @MSGFMT_OPTS@
-MSGMERGE = @MSGMERGE@
-OBJEXT = @OBJEXT@
-OMF_DIR = @OMF_DIR@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PKG_CONFIG = @PKG_CONFIG@
-POFILES = @POFILES@
-POSUB = @POSUB@
-PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
-PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-SIMPLE_SCAN_CFLAGS = @SIMPLE_SCAN_CFLAGS@
-SIMPLE_SCAN_LIBS = @SIMPLE_SCAN_LIBS@
-STRIP = @STRIP@
-USE_NLS = @USE_NLS@
-VERSION = @VERSION@
-WARN_CFLAGS = @WARN_CFLAGS@
-XGETTEXT = @XGETTEXT@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-simple_scan_SOURCES = \
- book.c \
- book.h \
- book-view.c \
- book-view.h \
- page.c \
- page.h \
- page-view.c \
- page-view.h \
- simple-scan.c \
- scanner.c \
- scanner.h \
- ui.c \
- ui.h
-
-simple_scan_CFLAGS = \
- $(SIMPLE_SCAN_CFLAGS) \
- $(WARN_CFLAGS) \
- -DVERSION=\"$(VERSION)\" \
- -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \
- -DLOCALE_DIR=\"$(localedir)\" \
- -DUI_DIR=\"$(datadir)/simple-scan/\" \
- -DICON_DIR=\"$(datadir)/simple-scan/icons\" \
- -DGCONF_DIR=\"/apps/simple-scan\" \
- -DSIMPLE_SCAN_BINARY=\"simple-scan\"
-
-simple_scan_LDADD = \
- $(SIMPLE_SCAN_LIBS) \
- -lsane \
- -lm
-
-DISTCLEANFILES = \
- Makefile.in
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --gnu src/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-install-binPROGRAMS: $(bin_PROGRAMS)
- @$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
- for p in $$list; do echo "$$p $$p"; done | \
- sed 's/$(EXEEXT)$$//' | \
- while read p p1; do if test -f $$p; \
- then echo "$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n;h' -e 's|.*|.|' \
- -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
- sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) files[d] = files[d] " " $$1; \
- else { print "f", $$3 "/" $$4, $$1; } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
- $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-binPROGRAMS:
- @$(NORMAL_UNINSTALL)
- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
- -e 's/$$/$(EXEEXT)/' `; \
- test -n "$$list" || exit 0; \
- echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(bindir)" && rm -f $$files
-
-clean-binPROGRAMS:
- -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
-simple-scan$(EXEEXT): $(simple_scan_OBJECTS) $(simple_scan_DEPENDENCIES)
- @rm -f simple-scan$(EXEEXT)
- $(AM_V_CCLD)$(simple_scan_LINK) $(simple_scan_OBJECTS) $(simple_scan_LDADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-book-view.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-book.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-page-view.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-page.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-scanner.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-simple-scan.Po@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/simple_scan-ui.Po@am__quote@
-
-.c.o:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-simple_scan-book.o: book.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-book.o -MD -MP -MF $(DEPDIR)/simple_scan-book.Tpo -c -o simple_scan-book.o `test -f 'book.c' || echo '$(srcdir)/'`book.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-book.Tpo $(DEPDIR)/simple_scan-book.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='book.c' object='simple_scan-book.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-book.o `test -f 'book.c' || echo '$(srcdir)/'`book.c
-
-simple_scan-book.obj: book.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-book.obj -MD -MP -MF $(DEPDIR)/simple_scan-book.Tpo -c -o simple_scan-book.obj `if test -f 'book.c'; then $(CYGPATH_W) 'book.c'; else $(CYGPATH_W) '$(srcdir)/book.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-book.Tpo $(DEPDIR)/simple_scan-book.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='book.c' object='simple_scan-book.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-book.obj `if test -f 'book.c'; then $(CYGPATH_W) 'book.c'; else $(CYGPATH_W) '$(srcdir)/book.c'; fi`
-
-simple_scan-book-view.o: book-view.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-book-view.o -MD -MP -MF $(DEPDIR)/simple_scan-book-view.Tpo -c -o simple_scan-book-view.o `test -f 'book-view.c' || echo '$(srcdir)/'`book-view.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-book-view.Tpo $(DEPDIR)/simple_scan-book-view.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='book-view.c' object='simple_scan-book-view.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-book-view.o `test -f 'book-view.c' || echo '$(srcdir)/'`book-view.c
-
-simple_scan-book-view.obj: book-view.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-book-view.obj -MD -MP -MF $(DEPDIR)/simple_scan-book-view.Tpo -c -o simple_scan-book-view.obj `if test -f 'book-view.c'; then $(CYGPATH_W) 'book-view.c'; else $(CYGPATH_W) '$(srcdir)/book-view.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-book-view.Tpo $(DEPDIR)/simple_scan-book-view.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='book-view.c' object='simple_scan-book-view.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-book-view.obj `if test -f 'book-view.c'; then $(CYGPATH_W) 'book-view.c'; else $(CYGPATH_W) '$(srcdir)/book-view.c'; fi`
-
-simple_scan-page.o: page.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-page.o -MD -MP -MF $(DEPDIR)/simple_scan-page.Tpo -c -o simple_scan-page.o `test -f 'page.c' || echo '$(srcdir)/'`page.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-page.Tpo $(DEPDIR)/simple_scan-page.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='page.c' object='simple_scan-page.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-page.o `test -f 'page.c' || echo '$(srcdir)/'`page.c
-
-simple_scan-page.obj: page.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-page.obj -MD -MP -MF $(DEPDIR)/simple_scan-page.Tpo -c -o simple_scan-page.obj `if test -f 'page.c'; then $(CYGPATH_W) 'page.c'; else $(CYGPATH_W) '$(srcdir)/page.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-page.Tpo $(DEPDIR)/simple_scan-page.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='page.c' object='simple_scan-page.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-page.obj `if test -f 'page.c'; then $(CYGPATH_W) 'page.c'; else $(CYGPATH_W) '$(srcdir)/page.c'; fi`
-
-simple_scan-page-view.o: page-view.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-page-view.o -MD -MP -MF $(DEPDIR)/simple_scan-page-view.Tpo -c -o simple_scan-page-view.o `test -f 'page-view.c' || echo '$(srcdir)/'`page-view.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-page-view.Tpo $(DEPDIR)/simple_scan-page-view.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='page-view.c' object='simple_scan-page-view.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-page-view.o `test -f 'page-view.c' || echo '$(srcdir)/'`page-view.c
-
-simple_scan-page-view.obj: page-view.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-page-view.obj -MD -MP -MF $(DEPDIR)/simple_scan-page-view.Tpo -c -o simple_scan-page-view.obj `if test -f 'page-view.c'; then $(CYGPATH_W) 'page-view.c'; else $(CYGPATH_W) '$(srcdir)/page-view.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-page-view.Tpo $(DEPDIR)/simple_scan-page-view.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='page-view.c' object='simple_scan-page-view.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-page-view.obj `if test -f 'page-view.c'; then $(CYGPATH_W) 'page-view.c'; else $(CYGPATH_W) '$(srcdir)/page-view.c'; fi`
-
-simple_scan-simple-scan.o: simple-scan.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-simple-scan.o -MD -MP -MF $(DEPDIR)/simple_scan-simple-scan.Tpo -c -o simple_scan-simple-scan.o `test -f 'simple-scan.c' || echo '$(srcdir)/'`simple-scan.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-simple-scan.Tpo $(DEPDIR)/simple_scan-simple-scan.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simple-scan.c' object='simple_scan-simple-scan.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-simple-scan.o `test -f 'simple-scan.c' || echo '$(srcdir)/'`simple-scan.c
-
-simple_scan-simple-scan.obj: simple-scan.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-simple-scan.obj -MD -MP -MF $(DEPDIR)/simple_scan-simple-scan.Tpo -c -o simple_scan-simple-scan.obj `if test -f 'simple-scan.c'; then $(CYGPATH_W) 'simple-scan.c'; else $(CYGPATH_W) '$(srcdir)/simple-scan.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-simple-scan.Tpo $(DEPDIR)/simple_scan-simple-scan.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='simple-scan.c' object='simple_scan-simple-scan.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-simple-scan.obj `if test -f 'simple-scan.c'; then $(CYGPATH_W) 'simple-scan.c'; else $(CYGPATH_W) '$(srcdir)/simple-scan.c'; fi`
-
-simple_scan-scanner.o: scanner.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-scanner.o -MD -MP -MF $(DEPDIR)/simple_scan-scanner.Tpo -c -o simple_scan-scanner.o `test -f 'scanner.c' || echo '$(srcdir)/'`scanner.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-scanner.Tpo $(DEPDIR)/simple_scan-scanner.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scanner.c' object='simple_scan-scanner.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-scanner.o `test -f 'scanner.c' || echo '$(srcdir)/'`scanner.c
-
-simple_scan-scanner.obj: scanner.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-scanner.obj -MD -MP -MF $(DEPDIR)/simple_scan-scanner.Tpo -c -o simple_scan-scanner.obj `if test -f 'scanner.c'; then $(CYGPATH_W) 'scanner.c'; else $(CYGPATH_W) '$(srcdir)/scanner.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-scanner.Tpo $(DEPDIR)/simple_scan-scanner.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='scanner.c' object='simple_scan-scanner.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-scanner.obj `if test -f 'scanner.c'; then $(CYGPATH_W) 'scanner.c'; else $(CYGPATH_W) '$(srcdir)/scanner.c'; fi`
-
-simple_scan-ui.o: ui.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-ui.o -MD -MP -MF $(DEPDIR)/simple_scan-ui.Tpo -c -o simple_scan-ui.o `test -f 'ui.c' || echo '$(srcdir)/'`ui.c
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-ui.Tpo $(DEPDIR)/simple_scan-ui.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ui.c' object='simple_scan-ui.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-ui.o `test -f 'ui.c' || echo '$(srcdir)/'`ui.c
-
-simple_scan-ui.obj: ui.c
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -MT simple_scan-ui.obj -MD -MP -MF $(DEPDIR)/simple_scan-ui.Tpo -c -o simple_scan-ui.obj `if test -f 'ui.c'; then $(CYGPATH_W) 'ui.c'; else $(CYGPATH_W) '$(srcdir)/ui.c'; fi`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/simple_scan-ui.Tpo $(DEPDIR)/simple_scan-ui.Po
-@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ui.c' object='simple_scan-ui.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(simple_scan_CFLAGS) $(CFLAGS) -c -o simple_scan-ui.obj `if test -f 'ui.c'; then $(CYGPATH_W) 'ui.c'; else $(CYGPATH_W) '$(srcdir)/ui.c'; fi`
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- set x; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(PROGRAMS)
-installdirs:
- for dir in "$(DESTDIR)$(bindir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
- -test -z "$(DISTCLEANFILES)" || rm -f $(DISTCLEANFILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
-
-distclean: distclean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am: install-binPROGRAMS
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -rf ./$(DEPDIR)
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-binPROGRAMS
-
-.MAKE: install-am install-strip
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
- clean-generic ctags distclean distclean-compile \
- distclean-generic distclean-tags distdir dvi dvi-am html \
- html-am info info-am install install-am install-binPROGRAMS \
- install-data install-data-am install-dvi install-dvi-am \
- install-exec install-exec-am install-html install-html-am \
- install-info install-info-am install-man install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic pdf pdf-am ps ps-am tags uninstall \
- uninstall-am uninstall-binPROGRAMS
-
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/src/book.c b/src/book.c
index 1c1cc6e..387c7f0 100644
--- a/src/book.c
+++ b/src/book.c
@@ -9,16 +9,22 @@
* license.
*/
+#include <stdio.h>
#include <string.h>
#include <math.h>
+#include <zlib.h>
+#include <jpeglib.h>
#include <gdk/gdk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <cairo/cairo-pdf.h>
#include <cairo/cairo-ps.h>
-#include <unistd.h> // TEMP: Needed for close() in get_temporary_filename()
#include "book.h"
+enum {
+ PROP_0,
+ PROP_NEEDS_SAVING
+};
enum {
PAGE_ADDED,
@@ -31,6 +37,8 @@ static guint signals[LAST_SIGNAL] = { 0, };
struct BookPrivate
{
GList *pages;
+
+ gboolean needs_saving;
};
G_DEFINE_TYPE (Book, book, G_TYPE_OBJECT);
@@ -57,17 +65,28 @@ book_clear (Book *book)
}
+static void
+page_changed_cb (Page *page, Book *book)
+{
+ book_set_needs_saving (book, TRUE);
+}
+
+
Page *
book_append_page (Book *book, gint width, gint height, gint dpi, Orientation orientation)
{
Page *page;
page = page_new ();
+ g_signal_connect (page, "image-changed", G_CALLBACK (page_changed_cb), book);
+ g_signal_connect (page, "crop-changed", G_CALLBACK (page_changed_cb), book);
page_setup (page, width, height, dpi, orientation);
book->priv->pages = g_list_append (book->priv->pages, page);
g_signal_emit (book, signals[PAGE_ADDED], 0, page);
+
+ book_set_needs_saving (book, TRUE);
return page;
}
@@ -76,10 +95,14 @@ book_append_page (Book *book, gint width, gint height, gint dpi, Orientation ori
void
book_delete_page (Book *book, Page *page)
{
+ g_signal_handlers_disconnect_by_func (page, page_changed_cb, book);
+
g_signal_emit (book, signals[PAGE_REMOVED], 0, page);
book->priv->pages = g_list_remove (book->priv->pages, page);
g_object_unref (page);
+
+ book_set_needs_saving (book, TRUE);
}
@@ -218,160 +241,148 @@ book_save_ps (Book *book, GFile *file, GError **error)
}
-// TEMP: Copied from simple-scan.c
-static GFile *
-get_temporary_file (const gchar *prefix, const gchar *extension)
+typedef struct
{
- gint fd;
- GFile *file;
- gchar *filename, *path;
- GError *error = NULL;
+ int offset;
+ int n_objects;
+ GList *object_offsets;
+ GFileOutputStream *stream;
+} PDFWriter;
- /* NOTE: I'm not sure if this is a 100% safe strategy to use g_file_open_tmp(), close and
- * use the filename but it appears to work in practise */
- filename = g_strdup_printf ("%s-XXXXXX.%s", prefix, extension);
- fd = g_file_open_tmp (filename, &path, &error);
- g_free (filename);
- if (fd < 0) {
- g_warning ("Error saving email attachment: %s", error->message);
- g_clear_error (&error);
- return NULL;
- }
- close (fd);
-
- file = g_file_new_for_path (path);
- g_free (path);
+static PDFWriter *
+pdf_writer_new (GFileOutputStream *stream)
+{
+ PDFWriter *writer;
+ writer = g_malloc0 (sizeof (PDFWriter));
+ writer->stream = g_object_ref (stream);
+ return writer;
+}
- return file;
+
+static void
+pdf_writer_free (PDFWriter *writer)
+{
+ g_object_unref (writer->stream);
+ g_list_free (writer->object_offsets);
+ g_free (writer);
}
-static goffset
-get_file_size (GFile *file)
+static void
+pdf_write (PDFWriter *writer, const unsigned char *data, size_t length)
{
- GFileInfo *info;
- goffset size = 0;
-
- info = g_file_query_info (file,
- G_FILE_ATTRIBUTE_STANDARD_SIZE,
- G_FILE_QUERY_INFO_NONE,
- NULL,
- NULL);
- if (info) {
- size = g_file_info_get_size (info);
- g_object_unref (info);
- }
+ g_output_stream_write_all (G_OUTPUT_STREAM (writer->stream), data, length, NULL, NULL, NULL);
+ writer->offset += length;
+}
+
- return size;
+static void
+pdf_printf (PDFWriter *writer, const char *format, ...)
+{
+ va_list args;
+ gchar *string;
+
+ va_start (args, format);
+ string = g_strdup_vprintf (format, args);
+ va_end (args);
+ pdf_write (writer, (unsigned char *)string, strlen (string));
+
+ g_free (string);
}
-static gboolean
-book_save_pdf_with_imagemagick (Book *book, GFile *file, GError **error)
+static int
+pdf_start_object (PDFWriter *writer)
{
- GList *iter;
- GString *command_line;
- gboolean result = TRUE;
- gint exit_status = 0;
- GFile *output_file = NULL;
- GList *link, *temporary_files = NULL;
+ writer->n_objects++;
+ writer->object_offsets = g_list_append (writer->object_offsets, GINT_TO_POINTER (writer->offset));
+ return writer->n_objects;
+}
- /* ImageMagick command to create a PDF */
- command_line = g_string_new ("convert -adjoin");
- /* Save each page to a file */
- for (iter = book->priv->pages; iter && result; iter = iter->next) {
- Page *page = iter->data;
- GFile *jpeg_file, *tiff_file;
- gchar *path, *resolution_command, *stdout_text = NULL, *stderr_text = NULL;
- gint jpeg_size, tiff_size;
-
- jpeg_file = get_temporary_file ("simple-scan", "jpg");
- result = page_save (page, "jpeg", jpeg_file, error);
- jpeg_size = get_file_size (jpeg_file);
- temporary_files = g_list_append (temporary_files, jpeg_file);
-
- tiff_file = get_temporary_file ("simple-scan", "tiff");
- result = page_save (page, "tiff", tiff_file, error);
- tiff_size = get_file_size (tiff_file);
- temporary_files = g_list_append (temporary_files, tiff_file);
-
- /* Use the smallest file */
- if (jpeg_size < tiff_size)
- path = g_file_get_path (jpeg_file);
- else
- path = g_file_get_path (tiff_file);
-
- resolution_command = g_strdup_printf ("convert %s -density %d %s", path, page_get_dpi (page), path);
- g_debug ("Executing ImageMagick command: %s", resolution_command);
- result = g_spawn_command_line_sync (resolution_command, &stdout_text, &stderr_text, &exit_status, error);
- if (result && exit_status != 0) {
- g_warning ("ImageMagick returned error code %d, command line was: %s", exit_status, resolution_command);
- g_warning ("stdout: %s", stdout_text);
- g_warning ("stderr: %s", stderr_text);
- result = FALSE;
- g_set_error (error, BOOK_TYPE, 0,
- "ImageMagick returned error code %d\n"
- "\n"
- "Command line: %s\n"
- "Stdout: %s\n"
- "Stderr: %s",
- exit_status, resolution_command, stdout_text, stderr_text);
- }
- if (!result)
+static guchar *
+compress_zlib (guchar *data, size_t length, size_t *n_written)
+{
+ z_stream stream;
+ guchar *out_data;
+
+ out_data = g_malloc (sizeof (guchar) * length);
+
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+ if (deflateInit (&stream, Z_BEST_COMPRESSION) != Z_OK)
+ return NULL;
+
+ stream.next_in = data;
+ stream.avail_in = length;
+ stream.next_out = out_data;
+ stream.avail_out = length;
+ while (stream.avail_in > 0) {
+ if (deflate (&stream, Z_FINISH) == Z_STREAM_ERROR)
break;
-
- g_string_append_printf (command_line, " %s", path);
- g_free (path);
}
- /* Use ImageMagick command to create a PDF */
- if (result) {
- gchar *path, *stdout_text = NULL, *stderr_text = NULL;
-
- output_file = get_temporary_file ("simple-scan", "pdf");
- path = g_file_get_path (output_file);
- g_string_append_printf (command_line, " %s", path);
- g_free (path);
-
- g_debug ("Executing ImageMagick command: %s", command_line->str);
- result = g_spawn_command_line_sync (command_line->str, &stdout_text, &stderr_text, &exit_status, error);
- if (result && exit_status != 0) {
- g_warning ("ImageMagick returned error code %d, command line was: %s", exit_status, command_line->str);
- g_warning ("stdout: %s", stdout_text);
- g_warning ("stderr: %s", stderr_text);
- result = FALSE;
- g_set_error (error, BOOK_TYPE, 0,
- "ImageMagick returned error code %d\n"
- "\n"
- "Command line: %s\n"
- "Stdout: %s\n"
- "Stderr: %s",
- exit_status, command_line->str, stdout_text, stderr_text);
- }
- g_free (stdout_text);
- g_free (stderr_text);
+ deflateEnd (&stream);
+
+ if (stream.avail_in > 0) {
+ g_free (out_data);
+ return NULL;
}
- /* Move to target URI */
- if (result)
- result = g_file_move (output_file, file, G_FILE_COPY_OVERWRITE, NULL, NULL, NULL, error);
-
- /* Delete page files */
- for (link = temporary_files; link; link = link->next) {
- GFile *f = link->data;
+ *n_written = length - stream.avail_out;
+
+ return out_data;
+}
- g_file_delete (f, NULL, NULL);
- g_object_unref (f);
+
+static void jpeg_init_cb (struct jpeg_compress_struct *info) {}
+static boolean jpeg_empty_cb (struct jpeg_compress_struct *info) { return TRUE; }
+static void jpeg_term_cb (struct jpeg_compress_struct *info) {}
+
+static guchar *
+compress_jpeg (GdkPixbuf *image, size_t *n_written)
+{
+ struct jpeg_compress_struct info;
+ struct jpeg_error_mgr jerr;
+ struct jpeg_destination_mgr dest_mgr;
+ int r;
+ guchar *pixels;
+ guchar *data;
+ size_t max_length;
+
+ info.err = jpeg_std_error (&jerr);
+ jpeg_create_compress (&info);
+
+ pixels = gdk_pixbuf_get_pixels (image);
+ info.image_width = gdk_pixbuf_get_width (image);
+ info.image_height = gdk_pixbuf_get_height (image);
+ info.input_components = 3;
+ info.in_color_space = JCS_RGB; /* TODO: JCS_GRAYSCALE? */
+ jpeg_set_defaults (&info);
+
+ max_length = info.image_width * info.image_height * info.input_components;
+ data = g_malloc (sizeof (guchar) * max_length);
+ dest_mgr.next_output_byte = data;
+ dest_mgr.free_in_buffer = max_length;
+ dest_mgr.init_destination = jpeg_init_cb;
+ dest_mgr.empty_output_buffer = jpeg_empty_cb;
+ dest_mgr.term_destination = jpeg_term_cb;
+ info.dest = &dest_mgr;
+
+ jpeg_start_compress (&info, TRUE);
+ for (r = 0; r < info.image_height; r++) {
+ JSAMPROW row[1];
+ row[0] = pixels + r * gdk_pixbuf_get_rowstride (image);
+ jpeg_write_scanlines (&info, row, 1);
}
- g_list_free (temporary_files);
+ jpeg_finish_compress (&info);
+ *n_written = max_length - dest_mgr.free_in_buffer;
- if (output_file)
- g_object_unref (output_file);
- g_string_free (command_line, TRUE);
+ jpeg_destroy_compress (&info);
- return result;
+ return data;
}
@@ -379,43 +390,249 @@ static gboolean
book_save_pdf (Book *book, GFile *file, GError **error)
{
GFileOutputStream *stream;
- GList *iter;
- cairo_surface_t *surface;
- gchar *imagemagick_executable;
-
- /* Use ImageMagick if it is available as then we can compress the images */
- imagemagick_executable = g_find_program_in_path ("convert");
- if (imagemagick_executable) {
- g_free (imagemagick_executable);
- return book_save_pdf_with_imagemagick (book, file, error);
- }
+ PDFWriter *writer;
+ int catalog_number, pages_number, info_number;
+ int xref_offset;
+ int i;
stream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error);
if (!stream)
return FALSE;
- surface = cairo_pdf_surface_create_for_stream ((cairo_write_func_t) write_cairo_data,
- stream, 0, 0);
+ writer = pdf_writer_new (stream);
+ g_object_unref (stream);
- for (iter = book->priv->pages; iter; iter = iter->next) {
- Page *page = iter->data;
- double width, height;
+ /* Header */
+ pdf_printf (writer, "%%PDF-1.3\n");
+
+ /* Catalog */
+ catalog_number = pdf_start_object (writer);
+ pdf_printf (writer, "%d 0 obj\n", catalog_number);
+ pdf_printf (writer, "<<\n");
+ pdf_printf (writer, "/Type /Catalog\n");
+ pdf_printf (writer, "/Pages %d 0 R\n", catalog_number + 1);
+ pdf_printf (writer, ">>\n");
+ pdf_printf (writer, "endobj\n");
+
+ /* Pages */
+ pdf_printf (writer, "\n");
+ pages_number = pdf_start_object (writer);
+ pdf_printf (writer, "%d 0 obj\n", pages_number);
+ pdf_printf (writer, "<<\n");
+ pdf_printf (writer, "/Type /Pages\n");
+ pdf_printf (writer, "/Kids [");
+ for (i = 0; i < book_get_n_pages (book); i++) {
+ pdf_printf (writer, " %d 0 R", pages_number + 1 + (i*3));
+ }
+ pdf_printf (writer, " ]\n");
+ pdf_printf (writer, "/Count %d\n", book_get_n_pages (book));
+ pdf_printf (writer, ">>\n");
+ pdf_printf (writer, "endobj\n");
+
+ for (i = 0; i < book_get_n_pages (book); i++) {
+ int number, width, height, depth;
+ size_t data_length, compressed_length;
+ Page *page;
GdkPixbuf *image;
-
+ guchar *pixels, *data, *compressed_data;
+ gchar *command;
+ const gchar *color_space, *filter = NULL;
+ float page_width, page_height;
+
+ page = book_get_page (book, i);
+ width = page_get_width (page);
+ height = page_get_height (page);
+ page_width = width * 72. / page_get_dpi (page);
+ page_height = height * 72. / page_get_dpi (page);
image = page_get_cropped_image (page);
+ pixels = gdk_pixbuf_get_pixels (image);
+
+ if (page_is_color (page)) {
+ int row;
+
+ depth = 8;
+ color_space = "DeviceRGB";
+ data_length = height * width * 3 + 1;
+ data = g_malloc (sizeof (guchar) * data_length);
+ for (row = 0; row < height; row++) {
+ int x;
+ guchar *in_line, *out_line;
+
+ in_line = pixels + row * gdk_pixbuf_get_rowstride (image);
+ out_line = data + row * width * 3;
+ for (x = 0; x < width; x++) {
+ guchar *in_p = in_line + x*3;
+ guchar *out_p = out_line + x*3;
+
+ out_p[0] = in_p[0];
+ out_p[1] = in_p[1];
+ out_p[2] = in_p[2];
+ }
+ }
+ }
+ else if (page_get_depth (page) == 1) {
+ int row, offset = 7;
+ guchar *write_ptr;
+
+ depth = 1;
+ color_space = "DeviceGray";
+ data_length = (height * width + 7) / 8;
+ data = g_malloc (sizeof (guchar) * data_length);
+ write_ptr = data;
+ write_ptr[0] = 0;
+ for (row = 0; row < height; row++) {
+ int x;
+ guchar *in_line;
+
+ in_line = pixels + row * gdk_pixbuf_get_rowstride (image);
+ for (x = 0; x < width; x++) {
+ guchar *in_p = in_line + x*3;
+ if (in_p[0])
+ write_ptr[0] |= 1 << offset;
+ offset--;
+ if (offset < 0) {
+ write_ptr++;
+ write_ptr[0] = 0;
+ offset = 7;
+ }
+ }
+ }
+ }
+ else {
+ int row;
+
+ depth = 8;
+ color_space = "DeviceGray";
+ data_length = height * width + 1;
+ data = g_malloc (sizeof (guchar) * data_length);
+ for (row = 0; row < height; row++) {
+ int x;
+ guchar *in_line, *out_line;
+
+ in_line = pixels + row * gdk_pixbuf_get_rowstride (image);
+ out_line = data + row * width;
+ for (x = 0; x < width; x++) {
+ guchar *in_p = in_line + x*3;
+ guchar *out_p = out_line + x;
+
+ out_p[0] = in_p[0];
+ }
+ }
+ }
- width = gdk_pixbuf_get_width (image) * 72.0 / page_get_dpi (page);
- height = gdk_pixbuf_get_height (image) * 72.0 / page_get_dpi (page);
- cairo_pdf_surface_set_size (surface, width, height);
- save_ps_pdf_surface (surface, image, page_get_dpi (page));
- cairo_surface_show_page (surface);
-
+ /* Compress data */
+ compressed_data = compress_zlib (data, data_length, &compressed_length);
+ if (compressed_data) {
+ /* Try if JPEG compression is better */
+ if (depth > 1) {
+ guchar *jpeg_data;
+ size_t jpeg_length;
+
+ jpeg_data = compress_jpeg (image, &jpeg_length);
+ if (jpeg_length < compressed_length) {
+ filter = "DCTDecode";
+ g_free (data);
+ g_free (compressed_data);
+ data = jpeg_data;
+ data_length = jpeg_length;
+ }
+ }
+
+ if (!filter) {
+ filter = "FlateDecode";
+ g_free (data);
+ data = compressed_data;
+ data_length = compressed_length;
+ }
+ }
+
+ /* Page */
+ pdf_printf (writer, "\n");
+ number = pdf_start_object (writer);
+ pdf_printf (writer, "%d 0 obj\n", number);
+ pdf_printf (writer, "<<\n");
+ pdf_printf (writer, "/Type /Page\n");
+ pdf_printf (writer, "/Parent %d 0 R\n", pages_number);
+ pdf_printf (writer, "/Resources << /XObject << /Im%d %d 0 R >> >>\n", i, number+1);
+ pdf_printf (writer, "/MediaBox [ 0 0 %.2f %.2f ]\n", page_width, page_height);
+ pdf_printf (writer, "/Contents %d 0 R\n", number+2);
+ pdf_printf (writer, ">>\n");
+ pdf_printf (writer, "endobj\n");
+
+ /* Page image */
+ pdf_printf (writer, "\n");
+ number = pdf_start_object (writer);
+ pdf_printf (writer, "%d 0 obj\n", number);
+ pdf_printf (writer, "<<\n");
+ pdf_printf (writer, "/Type /XObject\n");
+ pdf_printf (writer, "/Subtype /Image\n");
+ pdf_printf (writer, "/Width %d\n", width);
+ pdf_printf (writer, "/Height %d\n", height);
+ pdf_printf (writer, "/ColorSpace /%s\n", color_space);
+ pdf_printf (writer, "/BitsPerComponent %d\n", depth);
+ pdf_printf (writer, "/Length %d\n", data_length);
+ if (filter)
+ pdf_printf (writer, "/Filter /%s\n", filter);
+ pdf_printf (writer, ">>\n");
+ pdf_printf (writer, "stream\n");
+ pdf_write (writer, data, data_length);
+ g_free (data);
+ pdf_printf (writer, "\n");
+ pdf_printf (writer, "endstream\n");
+ pdf_printf (writer, "endobj\n");
+
+ /* Page contents */
+ command = g_strdup_printf ("q\n"
+ "%d 0 0 %d 0 0 cm\n"
+ "/Im%d Do\n"
+ "Q", width, height, i);
+ pdf_printf (writer, "\n");
+ number = pdf_start_object (writer);
+ pdf_printf (writer, "%d 0 obj\n", number);
+ pdf_printf (writer, "<<\n");
+ pdf_printf (writer, "/Length %d\n", strlen (command) + 1);
+ pdf_printf (writer, ">>\n");
+ pdf_printf (writer, "stream\n");
+ pdf_write (writer, (unsigned char *)command, strlen (command));
+ pdf_printf (writer, "\n");
+ pdf_printf (writer, "endstream\n");
+ pdf_printf (writer, "endobj\n");
+ g_free (command);
+
g_object_unref (image);
}
+
+ /* Info */
+ pdf_printf (writer, "\n");
+ info_number = pdf_start_object (writer);
+ pdf_printf (writer, "%d 0 obj\n", info_number);
+ pdf_printf (writer, "<<\n");
+ pdf_printf (writer, "/Creator (Simple Scan " VERSION ")\n");
+ pdf_printf (writer, ">>\n");
+ pdf_printf (writer, "endobj\n");
+
+ /* Cross-reference table */
+ xref_offset = writer->offset;
+ pdf_printf (writer, "xref\n");
+ pdf_printf (writer, "1 %d\n", writer->n_objects);
+ GList *link;
+ for (link = writer->object_offsets; link != NULL; link = link->next) {
+ int offset = GPOINTER_TO_INT (link->data);
+ pdf_printf (writer, "%010d 0000 n\n", offset);
+ }
- cairo_surface_destroy (surface);
-
- g_object_unref (stream);
+ /* Trailer */
+ pdf_printf (writer, "trailer\n");
+ pdf_printf (writer, "<<\n");
+ pdf_printf (writer, "/Size %d\n", writer->n_objects);
+ pdf_printf (writer, "/Info %d 0 R\n", info_number);
+ pdf_printf (writer, "/Root %d 0 R\n", catalog_number);
+ pdf_printf (writer, ">>\n");
+ pdf_printf (writer, "startxref\n");
+ pdf_printf (writer, "%d\n", xref_offset);
+ pdf_printf (writer, "%%%%EOF\n");
+
+ pdf_writer_free (writer);
return TRUE;
}
@@ -424,18 +641,79 @@ book_save_pdf (Book *book, GFile *file, GError **error)
gboolean
book_save (Book *book, const gchar *type, GFile *file, GError **error)
{
+ gboolean result = FALSE;
+
if (strcmp (type, "jpeg") == 0)
- return book_save_multi_file (book, "jpeg", file, error);
+ result = book_save_multi_file (book, "jpeg", file, error);
else if (strcmp (type, "png") == 0)
- return book_save_multi_file (book, "png", file, error);
+ result = book_save_multi_file (book, "png", file, error);
else if (strcmp (type, "tiff") == 0)
- return book_save_multi_file (book, "tiff", file, error);
+ result = book_save_multi_file (book, "tiff", file, error);
else if (strcmp (type, "ps") == 0)
- return book_save_ps (book, file, error);
+ result = book_save_ps (book, file, error);
else if (strcmp (type, "pdf") == 0)
- return book_save_pdf (book, file, error);
- else
- return FALSE;
+ result = book_save_pdf (book, file, error);
+
+ return result;
+}
+
+
+void
+book_set_needs_saving (Book *book, gboolean needs_saving)
+{
+ gboolean needed_saving = book->priv->needs_saving;
+ book->priv->needs_saving = needs_saving;
+ if (needed_saving != needs_saving)
+ g_object_notify (G_OBJECT (book), "needs-saving");
+}
+
+
+gboolean
+book_get_needs_saving (Book *book)
+{
+ return book->priv->needs_saving;
+}
+
+
+static void
+book_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ Book *self;
+
+ self = BOOK (object);
+
+ switch (prop_id) {
+ case PROP_NEEDS_SAVING:
+ book_set_needs_saving (self, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+
+static void
+book_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ Book *self;
+
+ self = BOOK (object);
+
+ switch (prop_id) {
+ case PROP_NEEDS_SAVING:
+ g_value_set_boolean (value, book_get_needs_saving (self));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
}
@@ -453,8 +731,18 @@ book_class_init (BookClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ object_class->get_property = book_get_property;
+ object_class->set_property = book_set_property;
object_class->finalize = book_finalize;
+ g_object_class_install_property (object_class,
+ PROP_NEEDS_SAVING,
+ g_param_spec_boolean ("needs-saving",
+ "needs-saving",
+ "TRUE if this book needs saving",
+ FALSE,
+ G_PARAM_READWRITE));
+
signals[PAGE_ADDED] =
g_signal_new ("page-added",
G_TYPE_FROM_CLASS (klass),
diff --git a/src/book.h b/src/book.h
index 4e9e05e..f8fc747 100644
--- a/src/book.h
+++ b/src/book.h
@@ -57,4 +57,8 @@ Page *book_get_page (Book *book, gint page_number);
gboolean book_save (Book *book, const gchar *type, GFile *file, GError **error);
+void book_set_needs_saving (Book *book, gboolean needs_saving);
+
+gboolean book_get_needs_saving (Book *book);
+
#endif /* _BOOK_H_ */
diff --git a/src/page.c b/src/page.c
index 5888a46..655b43b 100644
--- a/src/page.c
+++ b/src/page.c
@@ -31,6 +31,9 @@ struct PagePrivate
/* Number of rows in this page or -1 if currently unknown */
gint rows;
+ /* Bit depth */
+ gint depth;
+
/* Color profile */
gchar *color_profile;
@@ -43,6 +46,9 @@ struct PagePrivate
/* TRUE if have some page data */
gboolean has_data;
+ /* TRUE if have color data */
+ gboolean is_color;
+
/* Expected next scan row */
gint scan_line;
@@ -179,6 +185,21 @@ gboolean page_has_data (Page *page)
}
+gboolean page_is_color (Page *page)
+{
+ g_return_val_if_fail (page != NULL, FALSE);
+ return page->priv->is_color;
+}
+
+
+gint
+page_get_depth (Page *page)
+{
+ g_return_val_if_fail (page != NULL, 0);
+ return page->priv->depth;
+}
+
+
gint page_get_scan_line (Page *page)
{
g_return_val_if_fail (page != NULL, -1);
@@ -191,7 +212,7 @@ set_pixel (ScanLine *line, gint n, gint x, guchar *pixel)
{
gint sample;
guchar *data;
-
+
data = line->data + line->data_length * n;
switch (line->format) {
@@ -231,6 +252,11 @@ parse_line (Page *page, ScanLine *line, gint n, gboolean *size_changed)
line_number = line->number + n;
+ if (line->format != LINE_GRAY)
+ page->priv->is_color = TRUE;
+ if (line->depth > page->priv->depth)
+ page->priv->depth = line->depth;
+
/* Extend image if necessary */
while (line_number >= page_get_scan_height (page)) {
GdkPixbuf *image;
diff --git a/src/page.h b/src/page.h
index b36fe32..25e3018 100644
--- a/src/page.h
+++ b/src/page.h
@@ -82,6 +82,10 @@ gboolean page_is_scanning (Page *page);
gboolean page_has_data (Page *page);
+gboolean page_is_color (Page *page);
+
+gint page_get_depth (Page *page);
+
gint page_get_scan_line (Page *page);
void page_parse_scan_line (Page *page, ScanLine *line);
diff --git a/src/scanner.c b/src/scanner.c
index a8d09f9..8383f9f 100644
--- a/src/scanner.c
+++ b/src/scanner.c
@@ -792,7 +792,7 @@ close_device (Scanner *scanner)
g_debug ("sane_close ()");
scanner->priv->handle = NULL;
}
-
+
g_free (scanner->priv->buffer);
scanner->priv->buffer = NULL;
@@ -1320,10 +1320,12 @@ do_read (Scanner *scanner)
n_to_read, &n_read);
g_debug ("sane_read (%d) -> (%s, %d)", n_to_read, get_status_string (status), n_read);
- /* End of variable length frame */
- if (status == SANE_STATUS_EOF &&
- scanner->priv->parameters.lines == -1 &&
- scanner->priv->bytes_remaining == scanner->priv->parameters.bytes_per_line) {
+ /* Completed read */
+ if (status == SANE_STATUS_EOF) {
+ if (scanner->priv->parameters.lines > 0 && scanner->priv->line_count != scanner->priv->parameters.lines)
+ g_warning ("Scan completed with %d lines, expected %d lines", scanner->priv->parameters.lines, scanner->priv->parameters.lines);
+ if (scanner->priv->n_used > 0)
+ g_warning ("Scan complete with %d bytes of unused data", scanner->priv->n_used);
do_complete_page (scanner);
return;
}
@@ -1344,6 +1346,7 @@ do_read (Scanner *scanner)
/* Feed out lines */
if (scanner->priv->n_used >= scanner->priv->parameters.bytes_per_line) {
ScanLine *line;
+ int i, n_remaining;
line = g_malloc(sizeof(ScanLine));
switch (scanner->priv->parameters.format) {
@@ -1373,27 +1376,18 @@ do_read (Scanner *scanner)
scanner->priv->buffer = NULL;
scanner->priv->line_count += line->n_lines;
- /* On last line */
- if (scanner->priv->parameters.lines > 0 && scanner->priv->line_count >= scanner->priv->parameters.lines) {
- emit_signal (scanner, GOT_LINE, line);
- do_complete_page (scanner);
- }
- else {
- int i, n_remaining;
-
- /* Increase buffer size if did full read */
- if (full_read)
- scanner->priv->buffer_size += scanner->priv->parameters.bytes_per_line;
-
- scanner->priv->buffer = g_malloc(sizeof(SANE_Byte) * scanner->priv->buffer_size);
- n_remaining = scanner->priv->n_used - (line->n_lines * line->data_length);
- scanner->priv->n_used = 0;
- for (i = 0; i < n_remaining; i++) {
- scanner->priv->buffer[i] = line->data[i + (line->n_lines * line->data_length)];
- scanner->priv->n_used++;
- }
- emit_signal (scanner, GOT_LINE, line);
+ /* Increase buffer size if did full read */
+ if (full_read)
+ scanner->priv->buffer_size += scanner->priv->parameters.bytes_per_line;
+
+ scanner->priv->buffer = g_malloc(sizeof(SANE_Byte) * scanner->priv->buffer_size);
+ n_remaining = scanner->priv->n_used - (line->n_lines * line->data_length);
+ scanner->priv->n_used = 0;
+ for (i = 0; i < n_remaining; i++) {
+ scanner->priv->buffer[i] = line->data[i + (line->n_lines * line->data_length)];
+ scanner->priv->n_used++;
}
+ emit_signal (scanner, GOT_LINE, line);
}
}
diff --git a/src/simple-scan.c b/src/simple-scan.c
index b8c3962..54236ae 100644
--- a/src/simple-scan.c
+++ b/src/simple-scan.c
@@ -26,6 +26,8 @@
static ScanDevice *default_device = NULL;
+static gboolean have_devices = FALSE;
+
static GUdevClient *udev_client;
static SimpleScan *ui;
@@ -62,6 +64,7 @@ update_scan_devices_cb (Scanner *scanner, GList *devices)
devices_copy = g_list_prepend (devices_copy, default_device);
}
+ have_devices = devices_copy != NULL;
ui_set_scan_devices (ui, devices_copy);
g_list_free (devices_copy);
@@ -261,7 +264,7 @@ scanner_failed_cb (Scanner *scanner, GError *error)
/* Title of error dialog when scan failed */
_("Failed to scan"),
error->message,
- TRUE);
+ have_devices);
}
}
@@ -305,54 +308,6 @@ cancel_cb (SimpleScan *ui)
}
-static gboolean
-save_book_by_extension (GFile *file, GError **error)
-{
- gboolean result;
- gchar *uri, *uri_lower;
-
- uri = g_file_get_uri (file);
- uri_lower = g_utf8_strdown (uri, -1);
- if (g_str_has_suffix (uri_lower, ".pdf"))
- result = book_save (book, "pdf", file, error);
- else if (g_str_has_suffix (uri_lower, ".ps"))
- result = book_save (book, "ps", file, error);
- else if (g_str_has_suffix (uri_lower, ".png"))
- result = book_save (book, "png", file, error);
- else if (g_str_has_suffix (uri_lower, ".tif") || g_str_has_suffix (uri_lower, ".tiff"))
- result = book_save (book, "tiff", file, error);
- else
- result = book_save (book, "jpeg", file, error);
-
- g_free (uri);
- g_free (uri_lower);
-
- return result;
-}
-
-
-static void
-save_cb (SimpleScan *ui, const gchar *uri)
-{
- GError *error = NULL;
- GFile *file;
-
- g_debug ("Saving to '%s'", uri);
-
- file = g_file_new_for_uri (uri);
- if (!save_book_by_extension (file, &error)) {
- g_warning ("Error saving file: %s", error->message);
- ui_show_error (ui,
- /* Title of error dialog when save failed */
- _("Failed to save file"),
- error->message,
- FALSE);
- g_error_free (error);
- }
- g_object_unref (file);
-}
-
-
static gchar *
get_temporary_filename (const gchar *prefix, const gchar *extension)
{
@@ -625,7 +580,6 @@ main (int argc, char **argv)
book = ui_get_book (ui);
g_signal_connect (ui, "start-scan", G_CALLBACK (scan_cb), NULL);
g_signal_connect (ui, "stop-scan", G_CALLBACK (cancel_cb), NULL);
- g_signal_connect (ui, "save", G_CALLBACK (save_cb), NULL);
g_signal_connect (ui, "email", G_CALLBACK (email_cb), NULL);
g_signal_connect (ui, "quit", G_CALLBACK (quit_cb), NULL);
diff --git a/src/ui.c b/src/ui.c
index d67ee5e..0d23d25 100644
--- a/src/ui.c
+++ b/src/ui.c
@@ -28,7 +28,6 @@
enum {
START_SCAN,
STOP_SCAN,
- SAVE,
EMAIL,
QUIT,
LAST_SIGNAL
@@ -43,7 +42,10 @@ struct SimpleScanPrivate
GtkBuilder *builder;
GtkWidget *window, *main_vbox;
+ GtkWidget *info_bar, *info_bar_image, *info_bar_label;
+ GtkWidget *info_bar_close_button, *info_bar_change_scanner_button;
GtkWidget *page_delete_menuitem, *crop_rotate_menuitem;
+ GtkWidget *save_menuitem, *save_as_menuitem, *save_toolbutton;
GtkWidget *stop_menuitem, *stop_toolbutton;
GtkWidget *text_toolbar_menuitem, *text_menu_menuitem;
@@ -58,14 +60,18 @@ struct SimpleScanPrivate
GtkTreeModel *device_model, *text_dpi_model, *photo_dpi_model, *page_side_model, *paper_size_model;
gboolean setting_devices, user_selected_device;
+ gboolean have_error;
+ gchar *error_title, *error_text;
+ gboolean error_change_scanner_hint;
+
Book *book;
+ gchar *book_uri;
+
BookView *book_view;
gboolean updating_page_menu;
gint default_page_width, default_page_height, default_page_dpi;
Orientation default_page_orientation;
- gboolean have_device_list;
-
gchar *document_hint;
gchar *default_file_name;
@@ -110,6 +116,22 @@ find_scan_device (SimpleScan *ui, const char *device, GtkTreeIter *iter)
}
+static void
+show_error_dialog (SimpleScan *ui, const char *error_title, const char *error_text)
+{
+ GtkWidget *dialog;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ "%s", error_title);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, 0);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s", error_text);
+ gtk_widget_destroy (dialog);
+}
+
+
void
ui_set_default_file_name (SimpleScan *ui, const gchar *default_file_name)
{
@@ -154,6 +176,47 @@ device_combo_changed_cb (GtkWidget *widget, SimpleScan *ui)
}
+static void
+update_info_bar (SimpleScan *ui)
+{
+ GtkMessageType type;
+ const gchar *title, *text, *image_id;
+ gchar *message;
+ gboolean show_close_button = FALSE;
+ gboolean show_change_scanner_button = FALSE;
+
+ if (ui->priv->have_error) {
+ type = GTK_MESSAGE_ERROR;
+ image_id = GTK_STOCK_DIALOG_ERROR;
+ title = ui->priv->error_title;
+ text = ui->priv->error_text;
+ show_close_button = TRUE;
+ show_change_scanner_button = ui->priv->error_change_scanner_hint;
+ }
+ else if (gtk_tree_model_iter_n_children (ui->priv->device_model, NULL) == 0) {
+ type = GTK_MESSAGE_WARNING;
+ image_id = GTK_STOCK_DIALOG_WARNING;
+ /* Warning displayed when no scanners are detected */
+ title = _("No scanners detected");
+ /* Hint to user on why there are no scanners detected */
+ text = _("Please check your scanner is connected and powered on");
+ }
+ else {
+ gtk_widget_hide (ui->priv->info_bar);
+ return;
+ }
+
+ gtk_info_bar_set_message_type (GTK_INFO_BAR (ui->priv->info_bar), type);
+ gtk_image_set_from_stock (GTK_IMAGE (ui->priv->info_bar_image), image_id, GTK_ICON_SIZE_DIALOG);
+ message = g_strdup_printf ("<big><b>%s</b></big>\n\n%s", title, text);
+ gtk_label_set_markup (GTK_LABEL (ui->priv->info_bar_label), message);
+ g_free (message);
+ gtk_widget_set_visible (ui->priv->info_bar_close_button, show_close_button);
+ gtk_widget_set_visible (ui->priv->info_bar_change_scanner_button, show_change_scanner_button);
+ gtk_widget_show (ui->priv->info_bar);
+}
+
+
void
ui_set_scan_devices (SimpleScan *ui, GList *devices)
{
@@ -222,18 +285,7 @@ ui_set_scan_devices (SimpleScan *ui, GList *devices)
ui->priv->setting_devices = FALSE;
- if (!ui->priv->have_device_list) {
- ui->priv->have_device_list = TRUE;
-
- if (!devices) {
- ui_show_error (ui,
- /* Warning displayed when no scanners are detected */
- _("No scanners detected"),
- /* Hint to user on why there are no scanners detected */
- _("Please check your scanner is connected and powered on"),
- FALSE);
- }
- }
+ update_info_bar (ui);
}
@@ -279,13 +331,272 @@ add_default_page (SimpleScan *ui)
}
+static void
+on_file_type_changed (GtkTreeSelection *selection, GtkWidget *dialog)
+{
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gchar *path, *filename, *extension, *new_filename;
+
+ if (!gtk_tree_selection_get_selected (selection, &model, &iter))
+ return;
+
+ gtk_tree_model_get (model, &iter, 1, &extension, -1);
+ path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+ filename = g_path_get_basename (path);
+
+ /* Replace extension */
+ if (g_strrstr (filename, "."))
+ new_filename = g_strdup_printf ("%.*s%s", (int)(g_strrstr (filename, ".") - filename), filename, extension);
+ else
+ new_filename = g_strdup_printf ("%s%s", filename, extension);
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), new_filename);
+
+ g_free (path);
+ g_free (filename);
+ g_free (new_filename);
+ g_free (extension);
+}
+
+
+static gchar *
+choose_file_location (SimpleScan *ui)
+{
+ GtkWidget *dialog;
+ gint response;
+ GtkFileFilter *filter;
+ GtkWidget *expander, *file_type_view;
+ GtkListStore *file_type_store;
+ GtkTreeIter iter;
+ GtkTreeViewColumn *column;
+ const gchar *extension;
+ gchar *directory, *uri = NULL;
+ gint i;
+
+ struct
+ {
+ gchar *label, *extension;
+ } file_types[] =
+ {
+ /* Save dialog: Label for saving in PDF format */
+ { _("PDF (multi-page document)"), ".pdf" },
+ /* Save dialog: Label for saving in JPEG format */
+ { _("JPEG (compressed)"), ".jpg" },
+ /* Save dialog: Label for saving in PNG format */
+ { _("PNG (lossless)"), ".png" },
+ { NULL, NULL }
+ };
+
+ /* Get directory to save to */
+ directory = gconf_client_get_string (ui->priv->client, GCONF_DIR "/save_directory", NULL);
+ if (!directory || directory[0] == '\0') {
+ g_free (directory);
+ directory = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS));
+ }
+
+ dialog = gtk_file_chooser_dialog_new (/* Save dialog: Dialog title */
+ _("Save As..."),
+ GTK_WINDOW (ui->priv->window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+ gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
+ gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), directory);
+ gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), ui->priv->default_file_name);
+ g_free (directory);
+
+ /* Filter to only show images by default */
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter,
+ /* Save dialog: Filter name to show only image files */
+ _("Image Files"));
+ gtk_file_filter_add_pixbuf_formats (filter);
+ gtk_file_filter_add_mime_type (filter, "application/pdf");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter,
+ /* Save dialog: Filter name to show all files */
+ _("All Files"));
+ gtk_file_filter_add_pattern (filter, "*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
+
+ expander = gtk_expander_new_with_mnemonic (/* */
+ _("Select File _Type"));
+ gtk_expander_set_spacing (GTK_EXPANDER (expander), 5);
+ gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), expander);
+
+ extension = strstr (ui->priv->default_file_name, ".");
+ if (!extension)
+ extension = "";
+
+ file_type_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+ for (i = 0; file_types[i].label; i++) {
+ gtk_list_store_append (file_type_store, &iter);
+ gtk_list_store_set (file_type_store, &iter, 0, file_types[i].label, 1, file_types[i].extension, -1);
+ }
+
+ file_type_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file_type_store));
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (file_type_view), FALSE);
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (file_type_view), TRUE);
+ column = gtk_tree_view_column_new_with_attributes ("",
+ gtk_cell_renderer_text_new (),
+ "text", 0, NULL);
+ gtk_tree_view_append_column (GTK_TREE_VIEW (file_type_view), column);
+ gtk_container_add (GTK_CONTAINER (expander), file_type_view);
+
+ if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (file_type_store), &iter)) {
+ do {
+ gchar *e;
+ gtk_tree_model_get (GTK_TREE_MODEL (file_type_store), &iter, 1, &e, -1);
+ if (strcmp (extension, e) == 0)
+ gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)), &iter);
+ g_free (e);
+ } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (file_type_store), &iter));
+ }
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)),
+ "changed",
+ G_CALLBACK (on_file_type_changed),
+ dialog);
+
+ gtk_widget_show_all (expander);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+
+ if (response == GTK_RESPONSE_ACCEPT)
+ uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
+
+ gconf_client_set_string (ui->priv->client, GCONF_DIR "/save_directory",
+ gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)),
+ NULL);
+
+ gtk_widget_destroy (dialog);
+
+ return uri;
+}
+
+
+static gboolean
+save_document (SimpleScan *ui, gboolean force_choose_location)
+{
+ gboolean result;
+ gchar *uri, *uri_lower;
+ GError *error = NULL;
+ GFile *file;
+
+ if (ui->priv->book_uri && !force_choose_location)
+ uri = g_strdup (ui->priv->book_uri);
+ else
+ uri = choose_file_location (ui);
+ if (!uri)
+ return FALSE;
+
+ file = g_file_new_for_uri (uri);
+
+ g_debug ("Saving to '%s'", uri);
+
+ uri_lower = g_utf8_strdown (uri, -1);
+ if (g_str_has_suffix (uri_lower, ".pdf"))
+ result = book_save (ui->priv->book, "pdf", file, &error);
+ else if (g_str_has_suffix (uri_lower, ".ps"))
+ result = book_save (ui->priv->book, "ps", file, &error);
+ else if (g_str_has_suffix (uri_lower, ".png"))
+ result = book_save (ui->priv->book, "png", file, &error);
+ else if (g_str_has_suffix (uri_lower, ".tif") || g_str_has_suffix (uri_lower, ".tiff"))
+ result = book_save (ui->priv->book, "tiff", file, &error);
+ else
+ result = book_save (ui->priv->book, "jpeg", file, &error);
+
+ g_free (uri_lower);
+
+ if (result) {
+ g_free (ui->priv->book_uri);
+ ui->priv->book_uri = uri;
+ book_set_needs_saving (ui->priv->book, FALSE);
+ }
+ else {
+ g_free (uri);
+
+ g_warning ("Error saving file: %s", error->message);
+ ui_show_error (ui,
+ /* Title of error dialog when save failed */
+ _("Failed to save file"),
+ error->message,
+ FALSE);
+ g_clear_error (&error);
+ }
+
+ g_object_unref (file);
+
+ return result;
+}
+
+
+static gboolean
+prompt_to_save (SimpleScan *ui, const gchar *title, const gchar *discard_label)
+{
+ GtkWidget *dialog;
+ gint response;
+
+ if (!book_get_needs_saving (ui->priv->book))
+ return TRUE;
+
+ dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window),
+ GTK_DIALOG_MODAL,
+ GTK_MESSAGE_WARNING,
+ GTK_BUTTONS_NONE,
+ "%s", title);
+ gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), "%s",
+ /* Text in dialog warning when a document is about to be lost*/
+ _("If you don't save, changes will be permanently lost."));
+ gtk_dialog_add_button (GTK_DIALOG (dialog), discard_label, GTK_RESPONSE_NO);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
+ gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_SAVE, GTK_RESPONSE_YES);
+
+ response = gtk_dialog_run (GTK_DIALOG (dialog));
+ gtk_widget_destroy (dialog);
+
+ switch (response) {
+ case GTK_RESPONSE_YES:
+ if (save_document (ui, FALSE))
+ return TRUE;
+ else
+ return FALSE;
+ case GTK_RESPONSE_CANCEL:
+ return FALSE;
+ case GTK_RESPONSE_NO:
+ default:
+ return TRUE;
+ }
+}
+
+
+static void
+clear_document (SimpleScan *ui)
+{
+ book_clear (ui->priv->book);
+ add_default_page (ui);
+ g_free (ui->priv->book_uri);
+ ui->priv->book_uri = NULL;
+ book_set_needs_saving (ui->priv->book, FALSE);
+ gtk_widget_set_sensitive (ui->priv->save_as_menuitem, FALSE);
+}
+
+
void new_button_clicked_cb (GtkWidget *widget, SimpleScan *ui);
G_MODULE_EXPORT
void
new_button_clicked_cb (GtkWidget *widget, SimpleScan *ui)
{
- book_clear (ui->priv->book);
- add_default_page (ui);
+ if (!prompt_to_save (ui,
+ /* Text in dialog warning when a document is about to be lost */
+ _("Save current document?"),
+ /* Button in dialog to create new document and discard unsaved document */
+ _("Discard Changes")))
+ return;
+
+ clear_document (ui);
}
@@ -633,11 +944,10 @@ show_page_cb (BookView *view, Page *page, SimpleScan *ui)
g_object_unref (file);
if (error) {
- ui_show_error (ui,
- /* Error message display when unable to preview image */
- _("Unable to open image preview application"),
- error->message,
- FALSE);
+ show_error_dialog (ui,
+ /* Error message display when unable to preview image */
+ _("Unable to open image preview application"),
+ error->message);
g_clear_error (&error);
}
}
@@ -835,154 +1145,21 @@ page_delete_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)
}
-static void
-on_file_type_changed (GtkTreeSelection *selection, GtkWidget *dialog)
-{
- GtkTreeModel *model;
- GtkTreeIter iter;
- gchar *path, *filename, *extension, *new_filename;
-
- if (!gtk_tree_selection_get_selected (selection, &model, &iter))
- return;
-
- gtk_tree_model_get (model, &iter, 1, &extension, -1);
- path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
- filename = g_path_get_basename (path);
-
- /* Replace extension */
- if (g_strrstr (filename, "."))
- new_filename = g_strdup_printf ("%.*s%s", (int)(g_strrstr (filename, ".") - filename), filename, extension);
- else
- new_filename = g_strdup_printf ("%s%s", filename, extension);
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), new_filename);
-
- g_free (path);
- g_free (filename);
- g_free (new_filename);
- g_free (extension);
-}
-
-
void save_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui);
G_MODULE_EXPORT
void
save_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui)
{
- GtkWidget *dialog;
- gint response;
- GtkFileFilter *filter;
- GtkWidget *expander, *file_type_view;
- GtkListStore *file_type_store;
- GtkTreeIter iter;
- GtkTreeViewColumn *column;
- const gchar *extension;
- gchar *directory;
- gint i;
-
- struct
- {
- gchar *label, *extension;
- } file_types[] =
- {
- /* Save dialog: Label for saving in PDF format */
- { _("PDF (multi-page document)"), ".pdf" },
- /* Save dialog: Label for saving in JPEG format */
- { _("JPEG (compressed)"), ".jpg" },
- /* Save dialog: Label for saving in PNG format */
- { _("PNG (lossless)"), ".png" },
- { NULL, NULL }
- };
-
- /* Get directory to save to */
- directory = gconf_client_get_string (ui->priv->client, GCONF_DIR "/save_directory", NULL);
- if (!directory || directory[0] == '\0') {
- g_free (directory);
- directory = g_strdup (g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS));
- }
-
- dialog = gtk_file_chooser_dialog_new (/* Save dialog: Dialog title */
- _("Save As..."),
- GTK_WINDOW (ui->priv->window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
- gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), FALSE);
- gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), directory);
- gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), ui->priv->default_file_name);
- g_free (directory);
-
- /* Filter to only show images by default */
- filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (filter,
- /* Save dialog: Filter name to show only image files */
- _("Image Files"));
- gtk_file_filter_add_pixbuf_formats (filter);
- gtk_file_filter_add_mime_type (filter, "application/pdf");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
- filter = gtk_file_filter_new ();
- gtk_file_filter_set_name (filter,
- /* Save dialog: Filter name to show all files */
- _("All Files"));
- gtk_file_filter_add_pattern (filter, "*");
- gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);
-
- expander = gtk_expander_new_with_mnemonic (/* */
- _("Select File _Type"));
- gtk_expander_set_spacing (GTK_EXPANDER (expander), 5);
- gtk_file_chooser_set_extra_widget (GTK_FILE_CHOOSER (dialog), expander);
-
- extension = strstr (ui->priv->default_file_name, ".");
- if (!extension)
- extension = "";
-
- file_type_store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
- for (i = 0; file_types[i].label; i++) {
- gtk_list_store_append (file_type_store, &iter);
- gtk_list_store_set (file_type_store, &iter, 0, file_types[i].label, 1, file_types[i].extension, -1);
- }
-
- file_type_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (file_type_store));
- gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (file_type_view), FALSE);
- gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (file_type_view), TRUE);
- column = gtk_tree_view_column_new_with_attributes ("",
- gtk_cell_renderer_text_new (),
- "text", 0, NULL);
- gtk_tree_view_append_column (GTK_TREE_VIEW (file_type_view), column);
- gtk_container_add (GTK_CONTAINER (expander), file_type_view);
-
- if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (file_type_store), &iter)) {
- do {
- gchar *e;
- gtk_tree_model_get (GTK_TREE_MODEL (file_type_store), &iter, 1, &e, -1);
- if (strcmp (extension, e) == 0)
- gtk_tree_selection_select_iter (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)), &iter);
- g_free (e);
- } while (gtk_tree_model_iter_next (GTK_TREE_MODEL (file_type_store), &iter));
- }
- g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (file_type_view)),
- "changed",
- G_CALLBACK (on_file_type_changed),
- dialog);
-
- gtk_widget_show_all (expander);
-
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- if (response == GTK_RESPONSE_ACCEPT) {
- gchar *uri;
-
- uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
- g_signal_emit (G_OBJECT (ui), signals[SAVE], 0, uri);
+ save_document (ui, FALSE);
+}
- g_free (uri);
- }
- gconf_client_set_string (ui->priv->client, GCONF_DIR "/save_directory",
- gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)),
- NULL);
-
- gtk_widget_destroy (dialog);
+void save_as_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui);
+G_MODULE_EXPORT
+void
+save_as_file_button_clicked_cb (GtkWidget *widget, SimpleScan *ui)
+{
+ save_document (ui, TRUE);
}
@@ -1063,11 +1240,10 @@ help_contents_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)
if (error)
{
- ui_show_error (ui,
- /* Error message displayed when unable to launch help browser */
- _("Unable to open help file"),
- error->message,
- FALSE);
+ show_error_dialog (ui,
+ /* Error message displayed when unable to launch help browser */
+ _("Unable to open help file"),
+ error->message);
g_clear_error (&error);
}
}
@@ -1116,14 +1292,19 @@ about_menuitem_activate_cb (GtkWidget *widget, SimpleScan *ui)
}
-static void
+static gboolean
quit (SimpleScan *ui)
{
char *device;
gint paper_width = 0, paper_height = 0;
gint i;
- // FIXME: Warn if document with unsaved changes
+ if (!prompt_to_save (ui,
+ /* Text in dialog warning when a document is about to be lost */
+ _("Save document before quitting?"),
+ /* Button in dialog to quit and discard unsaved document */
+ _("Quit without Saving")))
+ return FALSE;
device = get_selected_device (ui);
if (device) {
@@ -1151,6 +1332,8 @@ quit (SimpleScan *ui)
gconf_client_set_int (ui->priv->client, GCONF_DIR "/page_dpi", ui->priv->default_page_dpi, NULL);
g_signal_emit (G_OBJECT (ui), signals[QUIT], 0);
+
+ return TRUE;
}
@@ -1177,6 +1360,24 @@ simple_scan_window_configure_event_cb (GtkWidget *widget, GdkEventConfigure *eve
}
+static void
+info_bar_response_cb (GtkWidget *widget, gint response_id, SimpleScan *ui)
+{
+ if (response_id == 1) {
+ gtk_widget_grab_focus (ui->priv->device_combo);
+ gtk_window_present (GTK_WINDOW (ui->priv->preferences_dialog));
+ }
+ else {
+ ui->priv->have_error = FALSE;
+ g_free (ui->priv->error_title);
+ ui->priv->error_title = NULL;
+ g_free (ui->priv->error_text);
+ ui->priv->error_text = NULL;
+ update_info_bar (ui);
+ }
+}
+
+
gboolean simple_scan_window_window_state_event_cb (GtkWidget *widget, GdkEventWindowState *event, SimpleScan *ui);
G_MODULE_EXPORT
gboolean
@@ -1193,8 +1394,7 @@ G_MODULE_EXPORT
gboolean
window_delete_event_cb (GtkWidget *widget, GdkEvent *event, SimpleScan *ui)
{
- quit (ui);
- return TRUE;
+ return !quit (ui);
}
@@ -1290,10 +1490,21 @@ set_dpi_combo (GtkWidget *combo, gint default_dpi, gint current_dpi)
static void
+needs_saving_cb (Book *book, GParamSpec *param, SimpleScan *ui)
+{
+ gtk_widget_set_sensitive (ui->priv->save_menuitem, book_get_needs_saving (book));
+ gtk_widget_set_sensitive (ui->priv->save_toolbutton, book_get_needs_saving (book));
+ if (book_get_needs_saving (book))
+ gtk_widget_set_sensitive (ui->priv->save_as_menuitem, TRUE);
+}
+
+
+static void
ui_load (SimpleScan *ui)
{
GtkBuilder *builder;
GError *error = NULL;
+ GtkWidget *hbox;
GtkCellRenderer *renderer;
gchar *device, *document_type, *scan_direction, *page_side;
gint dpi, paper_width, paper_height;
@@ -1306,12 +1517,11 @@ ui_load (SimpleScan *ui)
gtk_builder_add_from_file (builder, UI_DIR "simple-scan.ui", &error);
if (error) {
g_critical ("Unable to load UI: %s\n", error->message);
- ui_show_error (ui,
- /* Title of dialog when cannot load required files */
- _("Files missing"),
- /* Description in dialog when cannot load required files */
- _("Please check your installation"),
- FALSE);
+ show_error_dialog (ui,
+ /* Title of dialog when cannot load required files */
+ _("Files missing"),
+ /* Description in dialog when cannot load required files */
+ _("Please check your installation"));
exit (1);
}
gtk_builder_connect_signals (builder, ui);
@@ -1320,6 +1530,9 @@ ui_load (SimpleScan *ui)
ui->priv->main_vbox = GTK_WIDGET (gtk_builder_get_object (builder, "main_vbox"));
ui->priv->page_delete_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "page_delete_menuitem"));
ui->priv->crop_rotate_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "crop_rotate_menuitem"));
+ ui->priv->save_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "save_menuitem"));
+ ui->priv->save_as_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "save_as_menuitem"));
+ ui->priv->save_toolbutton = GTK_WIDGET (gtk_builder_get_object (builder, "save_toolbutton"));
ui->priv->stop_menuitem = GTK_WIDGET (gtk_builder_get_object (builder, "stop_scan_menuitem"));
ui->priv->stop_toolbutton = GTK_WIDGET (gtk_builder_get_object (builder, "stop_toolbutton"));
@@ -1345,6 +1558,28 @@ ui_load (SimpleScan *ui)
ui->priv->paper_size_combo = GTK_WIDGET (gtk_builder_get_object (builder, "paper_size_combo"));
ui->priv->paper_size_model = gtk_combo_box_get_model (GTK_COMBO_BOX (ui->priv->paper_size_combo));
+ /* Add InfoBar (not supported in Glade) */
+ ui->priv->info_bar = gtk_info_bar_new ();
+ g_signal_connect (ui->priv->info_bar, "response", G_CALLBACK (info_bar_response_cb), ui);
+ gtk_box_pack_start (GTK_BOX(ui->priv->main_vbox), ui->priv->info_bar, FALSE, TRUE, 0);
+ hbox = gtk_hbox_new (FALSE, 12);
+ gtk_container_add (GTK_CONTAINER (gtk_info_bar_get_content_area (GTK_INFO_BAR (ui->priv->info_bar))), hbox);
+ gtk_widget_show (hbox);
+
+ ui->priv->info_bar_image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG);
+ gtk_box_pack_start (GTK_BOX(hbox), ui->priv->info_bar_image, FALSE, TRUE, 0);
+ gtk_widget_show (ui->priv->info_bar_image);
+
+ ui->priv->info_bar_label = gtk_label_new (NULL);
+ gtk_misc_set_alignment (GTK_MISC (ui->priv->info_bar_label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX(hbox), ui->priv->info_bar_label, TRUE, TRUE, 0);
+ gtk_widget_show (ui->priv->info_bar_label);
+
+ ui->priv->info_bar_close_button = gtk_info_bar_add_button (GTK_INFO_BAR (ui->priv->info_bar), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE);
+ ui->priv->info_bar_change_scanner_button = gtk_info_bar_add_button (GTK_INFO_BAR (ui->priv->info_bar),
+ /* Button in error infobar to open preferences dialog and change scanner */
+ _("Change _Scanner"), 1);
+
GtkTreeIter iter;
gtk_list_store_append (GTK_LIST_STORE (ui->priv->paper_size_model), &iter);
gtk_list_store_set (GTK_LIST_STORE (ui->priv->paper_size_model), &iter, 0, 0, 1, 0, 2,
@@ -1451,6 +1686,8 @@ ui_load (SimpleScan *ui)
if (book_get_n_pages (ui->priv->book) == 0)
add_default_page (ui);
+ book_set_needs_saving (ui->priv->book, FALSE);
+ g_signal_connect (ui->priv->book, "notify::needs-saving", G_CALLBACK (needs_saving_cb), ui);
}
@@ -1495,28 +1732,13 @@ ui_set_scanning (SimpleScan *ui, gboolean scanning)
void
ui_show_error (SimpleScan *ui, const gchar *error_title, const gchar *error_text, gboolean change_scanner_hint)
{
- GtkWidget *dialog;
-
- dialog = gtk_message_dialog_new (GTK_WINDOW (ui->priv->window),
- GTK_DIALOG_MODAL,
- GTK_MESSAGE_WARNING,
- GTK_BUTTONS_NONE,
- "%s", error_title);
- if (change_scanner_hint)
- gtk_dialog_add_button (GTK_DIALOG (dialog),
- /* Button in error dialog to open prefereces dialog and change scanner */
- _("Change _Scanner"),
- 1);
- gtk_dialog_add_button (GTK_DIALOG (dialog), GTK_STOCK_CLOSE, 0);
- gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
- "%s", error_text);
-
- if (gtk_dialog_run (GTK_DIALOG (dialog)) == 1) {
- gtk_widget_grab_focus (ui->priv->device_combo);
- gtk_window_present (GTK_WINDOW (ui->priv->preferences_dialog));
- }
-
- gtk_widget_destroy (dialog);
+ ui->priv->have_error = TRUE;
+ g_free (ui->priv->error_title);
+ ui->priv->error_title = g_strdup (error_title);
+ g_free (ui->priv->error_text);
+ ui->priv->error_text = g_strdup (error_text);
+ ui->priv->error_change_scanner_hint = change_scanner_hint;
+ update_info_bar (ui);
}
@@ -1606,14 +1828,6 @@ ui_class_init (SimpleScanClass *klass)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
- signals[SAVE] =
- g_signal_new ("save",
- G_TYPE_FROM_CLASS (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (SimpleScanClass, save),
- NULL, NULL,
- g_cclosure_marshal_VOID__STRING,
- G_TYPE_NONE, 1, G_TYPE_STRING);
signals[EMAIL] =
g_signal_new ("email",
G_TYPE_FROM_CLASS (klass),
@@ -1650,5 +1864,5 @@ ui_init (SimpleScan *ui)
ui->priv->document_hint = g_strdup ("photo");
ui->priv->default_file_name = g_strdup (_("Scanned Document.pdf"));
ui->priv->scanning = FALSE;
- ui_load (ui);
+ ui_load (ui);
}
diff --git a/src/ui.h b/src/ui.h
index 41d551f..d43c187 100644
--- a/src/ui.h
+++ b/src/ui.h
@@ -36,7 +36,6 @@ typedef struct
void (*start_scan) (SimpleScan *ui, ScanOptions *options);
void (*stop_scan) (SimpleScan *ui);
- void (*save) (SimpleScan *ui, const gchar *format);
void (*email) (SimpleScan *ui, const gchar *profile);
void (*quit) (SimpleScan *ui);
} SimpleScanClass;