diff options
author | Alessio Treglia <alessio@debian.org> | 2010-07-12 19:34:33 +0200 |
---|---|---|
committer | Alessio Treglia <alessio@debian.org> | 2010-07-12 19:34:33 +0200 |
commit | 88ed5294e45c9a82b309c08aa5533388d90b1a1f (patch) | |
tree | 0f7ecf0420c14bed82d615e98005327e8e613fe8 /src | |
parent | 046e95e38e048f663efbf421894f3f84a212525b (diff) | |
parent | c15dc3b14e35850849f3559ac0305b4cac4a7046 (diff) |
Merge commit 'upstream/2.31.5.bzr424'
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 1 | ||||
-rw-r--r-- | src/Makefile.in | 661 | ||||
-rw-r--r-- | src/book.c | 614 | ||||
-rw-r--r-- | src/book.h | 4 | ||||
-rw-r--r-- | src/page.c | 28 | ||||
-rw-r--r-- | src/page.h | 4 | ||||
-rw-r--r-- | src/scanner.c | 44 | ||||
-rw-r--r-- | src/simple-scan.c | 54 | ||||
-rw-r--r-- | src/ui.c | 632 | ||||
-rw-r--r-- | src/ui.h | 1 |
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: @@ -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), @@ -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_ */ @@ -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; @@ -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); @@ -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); } @@ -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; |