diff --git a/AUTHORS b/AUTHORS
index fadb86c..7950cc0 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -4,10 +4,11 @@ The source code includes contributions by the following people:
 
 Alvaro, Kit Barnes, Eduardo de Barros Lima, Mathieu Bouchard, 
 Ole Joergen Broenner, Robert Buchholz, Vincenzo Ciancia, Luca de Cicco, 
-Michele Codutti, Robert Gerlach, Daniel German, Dirk Gerrits,
+Michele Codutti, Robert Gerlach, Daniel German, Dirk Gerrits, Simon Guest,
 Lukasz Kaiser, Timo Kluck, David Kolibac, Danny Kukawka, Stefan Lembach, 
 Bob McElrath, Andy Neitzke, David Planella, Marco Poletti, Alex Ray, 
-Jean-Baptiste Rouquier, Marco Souza, Mike Ter Louw, Uwe Winter, Lu Zhihe.
+Jean-Baptiste Rouquier, Victor Saase, Marco Souza, Mike Ter Louw, 
+Uwe Winter, Lu Zhihe.
 
 (Let me know if you are missing from this list or if your name is 
 mis-spelled)
diff --git a/ChangeLog b/ChangeLog
index dd5f70a..c4f2fd0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+This version:
+  - insert image tool (based on patches by Victor Saase and Simon Guest)
+  - renamed "Journal" menu to "Page"
+
 Version 0.4.6 (May 22, 2012):
   - win32 portability code (contributed by Dirk Gerrits)
   - fix bug in PDF export code on 64-bit systems (patch by Robert Buchholz)
diff --git a/configure b/configure
index f3c87c8..1f0cd5d 100755
--- a/configure
+++ b/configure
@@ -2627,7 +2627,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE=xournal
- VERSION=0.4.6
+ VERSION=0.4.6+image
 
 
 cat >>confdefs.h <<_ACEOF
diff --git a/configure.in b/configure.in
index 5d4aa09..99d500b 100644
--- a/configure.in
+++ b/configure.in
@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 
 AC_INIT(configure.in)
-AM_INIT_AUTOMAKE(xournal, 0.4.6)
+AM_INIT_AUTOMAKE(xournal, 0.4.6+image)
 AM_CONFIG_HEADER(config.h)
 AM_MAINTAINER_MODE
 
diff --git a/debian/README.Debian b/debian/README.Debian
deleted file mode 100644
index 3e1db2a..0000000
--- a/debian/README.Debian
+++ /dev/null
@@ -1,6 +0,0 @@
-xournal for Debian
-------------------
-
-<possible notes regarding this package - if none, delete this file>
-
- -- unknown <frade@asturlinux.org>, Sun, 19 Mar 2006 14:16:13 +0100
diff --git a/debian/README.source b/debian/README.source
new file mode 100644
index 0000000..0ba81aa
--- /dev/null
+++ b/debian/README.source
@@ -0,0 +1,5 @@
+This package uses quilt to apply changes to the original source and
+consequently the build depends include quilt.  Please see 
+/usr/share/doc/quilt/README.source for details on how to work with the quilt patch system.
+
+October 3, 2009 - Carlo Segre <segre@debian.org>
diff --git a/debian/changelog b/debian/changelog
index 3bd46a5..164cfe3 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,79 @@
-xournal (0.2-1) unstable; urgency=low
+xournal (0.4.5-3) unstable; urgency=low
 
-  * Initial Release.
+  * Add -lz and -X11 to link flags (Closes: #617637, #556718)
+  * Add ${misc:Depends} to debian/control
+  * Upgrade to Standards-Version 3.9.1 (no changes)
 
- -- Ivan Frade et al. <frade@asturlinux.org>  Sun, 19 Mar 2006 14:16:13 +0100
+ -- Carlo Segre <segre@debian.org>  Sat, 26 Mar 2011 14:18:31 -0500
 
+xournal (0.4.5-2) unstable; urgency=low
+
+  * Patch from Gentoo and Ubuntu to xo-print.c (Closes: #552075)
+  * Move html-doc to /usr/share/doc/xournal (Closes: #560076)
+
+ -- Carlo Segre <segre@debian.org>  Tue, 08 Dec 2009 15:39:31 -0600
+
+xournal (0.4.5-1) unstable; urgency=low
+
+  * New upstream release - fixes the following bugs:
+    - Change to gtk+ (>= 2.10) eliminating dependencies on libgnomeprint
+      and libgnomeprintui (Closes: #542571, #539128)
+    - Remove dependency on poppler-utils and replace with poppler-glib which
+      eliminates the problem with xpdf-utils and poppler-utils 
+      (Closes: #499037)
+    - New option available to autoload *.pdf.xoj files (Closes: #410911)
+  * Upgrade to Standards-Version 3.8.3 (no changes)
+  * Change to section "x11"
+  
+
+ -- Carlo Segre <segre@debian.org>  Sat, 03 Oct 2009 00:28:16 -0500
+
+xournal (0.4.2.1-1) unstable; urgency=low
+
+  * Changing Maintainer
+  * Changed dependency from gs to ghostscript-x.
+  * Converted to quilt for source modifications.
+  * Restored UTF support in desktop and mime files.
+  * Modify clean rule to delete leftover configuration files which 
+    were making the diff.gz file significantly larger.
+  * Added patch to src/xo-file.c which fixes the problem that PDF files 
+    cannot be opened for annotation with libgtk2.0-0 version 2.14.7 on 
+    i386 (Closes: #522541).
+  * Install debian/watch from Ubuntu package (Closes: #501323).
+  * Raised debhelper compatibility  level to 7.
+  * Upgraded Standards Version to 3.8.1 (no changes).
+  * Acknowledge NMU (Closes: #478540).
+
+ -- Carlo Segre <segre@debian.org>  Thu, 09 Apr 2009 00:16:08 -0500
+
+xournal (0.4.2.1-0.1) unstable; urgency=low
+
+  * Non-maintainer upload.
+    + Uploaded directly to unstable, as the maintainer seems inactive
+      (no answer to bug reports, no answer to Philipp Kern's intent
+      to NMU in #478540).
+  * New upstream release (Closes: #478540).
+
+ -- Lucas Nussbaum <lucas@lucas-nussbaum.net>  Tue, 03 Jun 2008 11:19:48 +0200
+
+xournal (0.4.1-1) unstable; urgency=low
+
+  * New upstream release (Closes: #410909, #441222, #458684)
+  * Fix FTBFS if build twice in a row (Closes: #442773)
+  * Removed deprecated Encoding key from desktop files
+  * Added Wl,--as-needed as linking options to remove linking to unused
+    libraries
+
+ -- Mathieu Bouchard <mbouchar@bioinfo.ulaval.ca>  Sat, 15 Sep 2007 23:18:10 -0400
+
+xournal (0.3.3-1) unstable; urgency=low
+
+  * New upstream release
+
+ -- Mathieu Bouchard <mbouchar@bioinfo.ulaval.ca>  Wed, 14 Feb 2007 11:49:42 -0500
+
+xournal (0.3.2-1) unstable; urgency=low
+
+  * Initial release (Closes: #406496)
+
+ -- Mathieu Bouchard <mbouchar@bioinfo.ulaval.ca>  Wed, 10 Jan 2007 15:25:09 -0500
diff --git a/debian/compat b/debian/compat
index b8626c4..7f8f011 100644
--- a/debian/compat
+++ b/debian/compat
@@ -1 +1 @@
-4
+7
diff --git a/debian/conffiles.ex b/debian/conffiles.ex
deleted file mode 100644
index 6f77dc6..0000000
--- a/debian/conffiles.ex
+++ /dev/null
@@ -1,7 +0,0 @@
-#
-# If you want to use this conffile, remove all comments and put files that
-# you want dpkg to process here using their absolute pathnames.
-# See the policy manual
-#
-# for example:
-# /etc/xournal/xournal.conf
diff --git a/debian/control b/debian/control
index 1f9ac40..dbe9d1d 100644
--- a/debian/control
+++ b/debian/control
@@ -1,12 +1,16 @@
 Source: xournal
-Section: unknown
+Section: x11
 Priority: optional
-Maintainer: unknown <frade@asturlinux.org>
-Build-Depends: debhelper (>= 4.0.0)
-Standards-Version: 3.6.0
+Maintainer: Carlo Segre <segre@debian.org>
+Build-Depends: debhelper (>= 7), autoconf, automake, libgtk2.0-dev (>= 2.10),
+     libgnomecanvas2-dev, libpoppler-glib-dev (>= 0.5.4)
+Standards-Version: 3.9.1
+Homepage: http://xournal.sourceforge.net/
 
 Package: xournal
 Architecture: any
-Depends: maemo
-Description: xournal application
- Application to take notes over a PDF
+Depends: ${shlibs:Depends}, ${misc:Depends}, ghostscript-x
+Description: GTK+ Application for note taking
+ Xournal is a GTK+ application for notetaking, sketching and
+ keeping a journal using a stylus. It can also be used to
+ add annotations to PDF files.
diff --git a/debian/copyright b/debian/copyright
index 59dcae8..7d04095 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -1,10 +1,34 @@
-This package was debianized by unknown <frade@asturlinux.org> on
-Sun, 19 Mar 2006 14:16:13 +0100.
+This package was debianized by Mathieu Bouchard <mbouchar@bioinfo.ulaval.ca> on
+Mon, 27 Feb 2006 11:35:09 -0500.
 
-It was downloaded from <fill in ftp site>
+It was downloaded from <http://xournal.sourceforge.net/>
 
-Upstream Author(s): <put author(s) name and email here>
+Upstream Author:
+
+    Denis Auroux <auroux@math.mit.edu>
 
 Copyright:
 
-<Must follow here>
+    <Copyright (C) 2007 Denis Auroux>
+
+License:
+
+    This package is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This package is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this package; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+On Debian systems, the complete text of the GNU General
+Public License can be found in `/usr/share/common-licenses/GPL'.
+
+The Debian packaging is (C) 2007, Mathieu Bouchard <mbouchar@bioinfo.ulaval.ca> and
+is licensed under the GPL, see above.
diff --git a/debian/cron.d.ex b/debian/cron.d.ex
deleted file mode 100644
index bb66274..0000000
--- a/debian/cron.d.ex
+++ /dev/null
@@ -1,4 +0,0 @@
-#
-# Regular cron jobs for the xournal package
-#
-0 4	* * *	root	xournal_maintenance
diff --git a/debian/dirs b/debian/dirs
deleted file mode 100644
index ca882bb..0000000
--- a/debian/dirs
+++ /dev/null
@@ -1,2 +0,0 @@
-usr/bin
-usr/sbin
diff --git a/debian/docs b/debian/docs
index 50bd824..6fa41fc 100644
--- a/debian/docs
+++ b/debian/docs
@@ -1,2 +1,6 @@
-NEWS
 README
+debian/README.source
+src/TODO
+html-doc/manual.html
+html-doc/screenshot.png
+
diff --git a/debian/emacsen-install.ex b/debian/emacsen-install.ex
deleted file mode 100644
index bc88ce9..0000000
--- a/debian/emacsen-install.ex
+++ /dev/null
@@ -1,45 +0,0 @@
-#! /bin/sh -e
-# /usr/lib/emacsen-common/packages/install/xournal
-
-# Written by Jim Van Zandt <jrv@vanzandt.mv.com>, borrowing heavily
-# from the install scripts for gettext by Santiago Vila
-# <sanvila@ctv.es> and octave by Dirk Eddelbuettel <edd@debian.org>.
-
-FLAVOR=$1
-PACKAGE=xournal
-
-if [ ${FLAVOR} = emacs ]; then exit 0; fi
-
-echo install/${PACKAGE}: Handling install for emacsen flavor ${FLAVOR}
-
-#FLAVORTEST=`echo $FLAVOR | cut -c-6`
-#if [ ${FLAVORTEST} = xemacs ] ; then
-#    SITEFLAG="-no-site-file"
-#else
-#    SITEFLAG="--no-site-file"
-#fi
-FLAGS="${SITEFLAG} -q -batch -l path.el -f batch-byte-compile"
-
-ELDIR=/usr/share/emacs/site-lisp/${PACKAGE}
-ELCDIR=/usr/share/${FLAVOR}/site-lisp/${PACKAGE}
-
-# Install-info-altdir does not actually exist. 
-# Maybe somebody will write it.
-if test -x /usr/sbin/install-info-altdir; then
-    echo install/${PACKAGE}: install Info links for ${FLAVOR}
-    install-info-altdir --quiet --section "" "" --dirname=${FLAVOR} /usr/info/${PACKAGE}.info.gz
-fi
-
-install -m 755 -d ${ELCDIR}
-cd ${ELDIR}
-FILES=`echo *.el`
-cp ${FILES} ${ELCDIR}
-cd ${ELCDIR}
-
-cat << EOF > path.el
-(setq load-path (cons "." load-path) byte-compile-warnings nil)
-EOF
-${FLAVOR} ${FLAGS} ${FILES}
-rm -f *.el path.el
-
-exit 0
diff --git a/debian/emacsen-remove.ex b/debian/emacsen-remove.ex
deleted file mode 100644
index a1582be..0000000
--- a/debian/emacsen-remove.ex
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/sh -e
-# /usr/lib/emacsen-common/packages/remove/xournal
-
-FLAVOR=$1
-PACKAGE=xournal
-
-if [ ${FLAVOR} != emacs ]; then
-    if test -x /usr/sbin/install-info-altdir; then
-        echo remove/${PACKAGE}: removing Info links for ${FLAVOR}
-        install-info-altdir --quiet --remove --dirname=${FLAVOR} /usr/info/xournal.info.gz
-    fi
-
-    echo remove/${PACKAGE}: purging byte-compiled files for ${FLAVOR}
-    rm -rf /usr/share/${FLAVOR}/site-lisp/${PACKAGE}
-fi
diff --git a/debian/emacsen-startup.ex b/debian/emacsen-startup.ex
deleted file mode 100644
index 7e3799c..0000000
--- a/debian/emacsen-startup.ex
+++ /dev/null
@@ -1,19 +0,0 @@
-;; -*-emacs-lisp-*-
-;;
-;; Emacs startup file for the Debian xournal package
-;;
-;; Originally contributed by Nils Naumann <naumann@unileoben.ac.at>
-;; Modified by Dirk Eddelbuettel <edd@debian.org>
-;; Adapted for dh-make by Jim Van Zandt <jrv@vanzandt.mv.com>
-
-;; The xournal package follows the Debian/GNU Linux 'emacsen' policy and
-;; byte-compiles its elisp files for each 'emacs flavor' (emacs19,
-;; xemacs19, emacs20, xemacs20...).  The compiled code is then
-;; installed in a subdirectory of the respective site-lisp directory.
-;; We have to add this to the load-path:
-(let ((package-dir (concat "/usr/share/"
-                           (symbol-name flavor)
-                           "/site-lisp/xournal")))
-  (when (file-directory-p package-dir)
-        (setq load-path (cons package-dir load-path))))
-
diff --git a/debian/files b/debian/files
deleted file mode 100644
index b446481..0000000
--- a/debian/files
+++ /dev/null
@@ -1 +0,0 @@
-xournal_0.2-1_arm.deb unknown optional
diff --git a/debian/init.d.ex b/debian/init.d.ex
deleted file mode 100644
index c4fd7aa..0000000
--- a/debian/init.d.ex
+++ /dev/null
@@ -1,74 +0,0 @@
-#! /bin/sh
-#
-# skeleton	example file to build /etc/init.d/ scripts.
-#		This file should be used to construct scripts for /etc/init.d.
-#
-#		Written by Miquel van Smoorenburg <miquels@cistron.nl>.
-#		Modified for Debian 
-#		by Ian Murdock <imurdock@gnu.ai.mit.edu>.
-#
-# Version:	@(#)skeleton  1.9  26-Feb-2001  miquels@cistron.nl
-#
-
-PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
-DAEMON=/usr/sbin/xournal
-NAME=xournal
-DESC=xournal
-
-test -x $DAEMON || exit 0
-
-# Include xournal defaults if available
-if [ -f /etc/default/xournal ] ; then
-	. /etc/default/xournal
-fi
-
-set -e
-
-case "$1" in
-  start)
-	echo -n "Starting $DESC: "
-	start-stop-daemon --start --quiet --pidfile /var/run/$NAME.pid \
-		--exec $DAEMON -- $DAEMON_OPTS
-	echo "$NAME."
-	;;
-  stop)
-	echo -n "Stopping $DESC: "
-	start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
-		--exec $DAEMON
-	echo "$NAME."
-	;;
-  #reload)
-	#
-	#	If the daemon can reload its config files on the fly
-	#	for example by sending it SIGHUP, do it here.
-	#
-	#	If the daemon responds to changes in its config file
-	#	directly anyway, make this a do-nothing entry.
-	#
-	# echo "Reloading $DESC configuration files."
-	# start-stop-daemon --stop --signal 1 --quiet --pidfile \
-	#	/var/run/$NAME.pid --exec $DAEMON
-  #;;
-  restart|force-reload)
-	#
-	#	If the "reload" option is implemented, move the "force-reload"
-	#	option to the "reload" entry above. If not, "force-reload" is
-	#	just the same as "restart".
-	#
-	echo -n "Restarting $DESC: "
-	start-stop-daemon --stop --quiet --pidfile \
-		/var/run/$NAME.pid --exec $DAEMON
-	sleep 1
-	start-stop-daemon --start --quiet --pidfile \
-		/var/run/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
-	echo "$NAME."
-	;;
-  *)
-	N=/etc/init.d/$NAME
-	# echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
-	echo "Usage: $N {start|stop|restart|force-reload}" >&2
-	exit 1
-	;;
-esac
-
-exit 0
diff --git a/debian/links b/debian/links
new file mode 100644
index 0000000..73a19f2
--- /dev/null
+++ b/debian/links
@@ -0,0 +1 @@
+usr/share/xournal/pixmaps usr/share/doc/xournal/pixmaps
diff --git a/debian/manpage.1.ex b/debian/manpage.1.ex
deleted file mode 100644
index 573e1c9..0000000
--- a/debian/manpage.1.ex
+++ /dev/null
@@ -1,60 +0,0 @@
-.\"                                      Hey, EMACS: -*- nroff -*-
-.\" First parameter, NAME, should be all caps
-.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection
-.\" other parameters are allowed: see man(7), man(1)
-.TH XOURNAL SECTION "March 19, 2006"
-.\" Please adjust this date whenever revising the manpage.
-.\"
-.\" Some roff macros, for reference:
-.\" .nh        disable hyphenation
-.\" .hy        enable hyphenation
-.\" .ad l      left justify
-.\" .ad b      justify to both left and right margins
-.\" .nf        disable filling
-.\" .fi        enable filling
-.\" .br        insert line break
-.\" .sp <n>    insert n+1 empty lines
-.\" for manpage-specific macros, see man(7)
-.SH NAME
-xournal \- program to do something
-.SH SYNOPSIS
-.B xournal
-.RI [ options ] " files" ...
-.br
-.B bar
-.RI [ options ] " files" ...
-.SH DESCRIPTION
-This manual page documents briefly the
-.B xournal
-and
-.B bar
-commands.
-This manual page was written for the Debian distribution
-because the original program does not have a manual page.
-Instead, it has documentation in the GNU Info format; see below.
-.PP
-.\" TeX users may be more comfortable with the \fB<whatever>\fP and
-.\" \fI<whatever>\fP escape sequences to invode bold face and italics, 
-.\" respectively.
-\fBxournal\fP is a program that...
-.SH OPTIONS
-These programs follow the usual GNU command line syntax, with long
-options starting with two dashes (`-').
-A summary of options is included below.
-For a complete description, see the Info files.
-.TP
-.B \-h, \-\-help
-Show summary of options.
-.TP
-.B \-v, \-\-version
-Show version of program.
-.SH SEE ALSO
-.BR bar (1),
-.BR baz (1).
-.br
-The programs are documented fully by
-.IR "The Rise and Fall of a Fooish Bar" ,
-available via the Info system.
-.SH AUTHOR
-This manual page was written by unknown <frade@asturlinux.org>,
-for the Debian project (but may be used by others).
diff --git a/debian/manpage.sgml.ex b/debian/manpage.sgml.ex
deleted file mode 100644
index 7dac20e..0000000
--- a/debian/manpage.sgml.ex
+++ /dev/null
@@ -1,156 +0,0 @@
-<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
-
-<!-- Process this file with docbook-to-man to generate an nroff manual
-     page: `docbook-to-man manpage.sgml > manpage.1'.  You may view
-     the manual page with: `docbook-to-man manpage.sgml | nroff -man |
-     less'.  A typical entry in a Makefile or Makefile.am is:
-
-manpage.1: manpage.sgml
-	docbook-to-man $< > $@
-
-    
-	The docbook-to-man binary is found in the docbook-to-man package.
-	Please remember that if you create the nroff version in one of the
-	debian/rules file targets (such as build), you will need to include
-	docbook-to-man in your Build-Depends control field.
-
-  -->
-
-  <!-- Fill in your name for FIRSTNAME and SURNAME. -->
-  <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
-  <!ENTITY dhsurname   "<surname>SURNAME</surname>">
-  <!-- Please adjust the date whenever revising the manpage. -->
-  <!ENTITY dhdate      "<date>March 19, 2006</date>">
-  <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
-       allowed: see man(7), man(1). -->
-  <!ENTITY dhsection   "<manvolnum>SECTION</manvolnum>">
-  <!ENTITY dhemail     "<email>frade@asturlinux.org</email>">
-  <!ENTITY dhusername  "unknown">
-  <!ENTITY dhucpackage "<refentrytitle>XOURNAL</refentrytitle>">
-  <!ENTITY dhpackage   "xournal">
-
-  <!ENTITY debian      "<productname>Debian</productname>">
-  <!ENTITY gnu         "<acronym>GNU</acronym>">
-  <!ENTITY gpl         "&gnu; <acronym>GPL</acronym>">
-]>
-
-<refentry>
-  <refentryinfo>
-    <address>
-      &dhemail;
-    </address>
-    <author>
-      &dhfirstname;
-      &dhsurname;
-    </author>
-    <copyright>
-      <year>2003</year>
-      <holder>&dhusername;</holder>
-    </copyright>
-    &dhdate;
-  </refentryinfo>
-  <refmeta>
-    &dhucpackage;
-
-    &dhsection;
-  </refmeta>
-  <refnamediv>
-    <refname>&dhpackage;</refname>
-
-    <refpurpose>program to do something</refpurpose>
-  </refnamediv>
-  <refsynopsisdiv>
-    <cmdsynopsis>
-      <command>&dhpackage;</command>
-
-      <arg><option>-e <replaceable>this</replaceable></option></arg>
-
-      <arg><option>--example <replaceable>that</replaceable></option></arg>
-    </cmdsynopsis>
-  </refsynopsisdiv>
-  <refsect1>
-    <title>DESCRIPTION</title>
-
-    <para>This manual page documents briefly the
-      <command>&dhpackage;</command> and <command>bar</command>
-      commands.</para>
-
-    <para>This manual page was written for the &debian; distribution
-      because the original program does not have a manual page.
-      Instead, it has documentation in the &gnu;
-      <application>Info</application> format; see below.</para>
-
-    <para><command>&dhpackage;</command> is a program that...</para>
-
-  </refsect1>
-  <refsect1>
-    <title>OPTIONS</title>
-
-    <para>These programs follow the usual &gnu; command line syntax,
-      with long options starting with two dashes (`-').  A summary of
-      options is included below.  For a complete description, see the
-      <application>Info</application> files.</para>
-
-    <variablelist>
-      <varlistentry>
-        <term><option>-h</option>
-          <option>--help</option>
-        </term>
-        <listitem>
-          <para>Show summary of options.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><option>-v</option>
-          <option>--version</option>
-        </term>
-        <listitem>
-          <para>Show version of program.</para>
-        </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
-  <refsect1>
-    <title>SEE ALSO</title>
-
-    <para>bar (1), baz (1).</para>
-
-    <para>The programs are documented fully by <citetitle>The Rise and
-      Fall of a Fooish Bar</citetitle> available via the
-      <application>Info</application> system.</para>
-  </refsect1>
-  <refsect1>
-    <title>AUTHOR</title>
-
-    <para>This manual page was written by &dhusername; &dhemail; for
-      the &debian; system (but may be used by others).  Permission is
-      granted to copy, distribute and/or modify this document under
-      the terms of the &gnu; General Public License, Version 2 any 
-	  later version published by the Free Software Foundation.
-    </para>
-	<para>
-	  On Debian systems, the complete text of the GNU General Public
-	  License can be found in /usr/share/common-licenses/GPL.
-	</para>
-
-  </refsect1>
-</refentry>
-
-<!-- Keep this comment at the end of the file
-Local variables:
-mode: sgml
-sgml-omittag:t
-sgml-shorttag:t
-sgml-minimize-attributes:nil
-sgml-always-quote-attributes:t
-sgml-indent-step:2
-sgml-indent-data:t
-sgml-parent-document:nil
-sgml-default-dtd-file:nil
-sgml-exposed-tags:nil
-sgml-local-catalogs:nil
-sgml-local-ecat-files:nil
-End:
--->
-
-
diff --git a/debian/manpage.xml.ex b/debian/manpage.xml.ex
deleted file mode 100644
index 905a816..0000000
--- a/debian/manpage.xml.ex
+++ /dev/null
@@ -1,148 +0,0 @@
-<?xml version='1.0' encoding='ISO-8859-1'?>
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
-"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
-
-<!--
-
-Process this file with an XSLT processor: `xsltproc \
--''-nonet /usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
-manpages/docbook.xsl manpage.dbk'.  A manual page
-<package>.<section> will be generated.  You may view the
-manual page with: nroff -man <package>.<section> | less'.  A
-typical entry in a Makefile or Makefile.am is:
-
-DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\
-manpages/docbook.xsl
-XP=xsltproc -''-nonet
-
-manpage.1: manpage.dbk
-        $(XP) $(DB2MAN) $<
-    
-The xsltproc binary is found in the xsltproc package.  The
-XSL files are in docbook-xsl.  Please remember that if you
-create the nroff version in one of the debian/rules file
-targets (such as build), you will need to include xsltproc
-and docbook-xsl in your Build-Depends control field.
-
--->
-
-  <!-- Fill in your name for FIRSTNAME and SURNAME. -->
-  <!ENTITY dhfirstname "<firstname>FIRSTNAME</firstname>">
-  <!ENTITY dhsurname   "<surname>SURNAME</surname>">
-  <!-- Please adjust the date whenever revising the manpage. -->
-  <!ENTITY dhdate      "<date>March 19, 2006</date>">
-  <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
-       allowed: see man(7), man(1). -->
-  <!ENTITY dhsection   "<manvolnum>SECTION</manvolnum>">
-  <!ENTITY dhemail     "<email>frade@asturlinux.org</email>">
-  <!ENTITY dhusername  "unknown">
-  <!ENTITY dhucpackage "<refentrytitle>XOURNAL</refentrytitle>">
-  <!ENTITY dhpackage   "xournal">
-
-  <!ENTITY debian      "<productname>Debian</productname>">
-  <!ENTITY gnu         "<acronym>GNU</acronym>">
-  <!ENTITY gpl         "&gnu; <acronym>GPL</acronym>">
-]>
-
-<refentry>
-  <refentryinfo>
-    <address>
-      &dhemail;
-    </address>
-    <author>
-      &dhfirstname;
-      &dhsurname;
-    </author>
-    <copyright>
-      <year>2003</year>
-      <holder>&dhusername;</holder>
-    </copyright>
-    &dhdate;
-  </refentryinfo>
-  <refmeta>
-    &dhucpackage;
-
-    &dhsection;
-  </refmeta>
-  <refnamediv>
-    <refname>&dhpackage;</refname>
-
-    <refpurpose>program to do something</refpurpose>
-  </refnamediv>
-  <refsynopsisdiv>
-    <cmdsynopsis>
-      <command>&dhpackage;</command>
-
-      <arg><option>-e <replaceable>this</replaceable></option></arg>
-
-      <arg><option>--example <replaceable>that</replaceable></option></arg>
-    </cmdsynopsis>
-  </refsynopsisdiv>
-  <refsect1>
-    <title>DESCRIPTION</title>
-
-    <para>This manual page documents briefly the
-      <command>&dhpackage;</command> and <command>bar</command>
-      commands.</para>
-
-    <para>This manual page was written for the &debian; distribution
-      because the original program does not have a manual page.
-      Instead, it has documentation in the &gnu;
-      <application>Info</application> format; see below.</para>
-
-    <para><command>&dhpackage;</command> is a program that...</para>
-
-  </refsect1>
-  <refsect1>
-    <title>OPTIONS</title>
-
-    <para>These programs follow the usual &gnu; command line syntax,
-      with long options starting with two dashes (`-').  A summary of
-      options is included below.  For a complete description, see the
-      <application>Info</application> files.</para>
-
-    <variablelist>
-      <varlistentry>
-        <term><option>-h</option>
-          <option>--help</option>
-        </term>
-        <listitem>
-          <para>Show summary of options.</para>
-        </listitem>
-      </varlistentry>
-      <varlistentry>
-        <term><option>-v</option>
-          <option>--version</option>
-        </term>
-        <listitem>
-          <para>Show version of program.</para>
-        </listitem>
-      </varlistentry>
-    </variablelist>
-  </refsect1>
-  <refsect1>
-    <title>SEE ALSO</title>
-
-    <para>bar (1), baz (1).</para>
-
-    <para>The programs are documented fully by <citetitle>The Rise and
-      Fall of a Fooish Bar</citetitle> available via the
-      <application>Info</application> system.</para>
-  </refsect1>
-  <refsect1>
-    <title>AUTHOR</title>
-
-    <para>This manual page was written by &dhusername; &dhemail; for
-      the &debian; system (but may be used by others).  Permission is
-      granted to copy, distribute and/or modify this document under
-      the terms of the &gnu; General Public License, Version 2 any 
-	  later version published by the Free Software Foundation.
-    </para>
-	<para>
-	  On Debian systems, the complete text of the GNU General Public
-	  License can be found in /usr/share/common-licenses/GPL.
-	</para>
-
-  </refsect1>
-</refentry>
-
diff --git a/debian/menu b/debian/menu
new file mode 100644
index 0000000..6a587a3
--- /dev/null
+++ b/debian/menu
@@ -0,0 +1,2 @@
+?package(xournal):needs="X11" section="Applications/Editors"\
+  title="xournal" command="/usr/bin/xournal"
diff --git a/debian/menu.ex b/debian/menu.ex
deleted file mode 100644
index 88f3521..0000000
--- a/debian/menu.ex
+++ /dev/null
@@ -1,2 +0,0 @@
-?package(xournal):needs=X11|text|vc|wm section=Apps/see-menu-manual\
-  title="xournal" command="/usr/bin/xournal"
diff --git a/debian/patches/add_ldflags b/debian/patches/add_ldflags
new file mode 100644
index 0000000..f647ff9
--- /dev/null
+++ b/debian/patches/add_ldflags
@@ -0,0 +1,10 @@
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -20,5 +20,6 @@
+ 	xo-callbacks.c xo-callbacks.h \
+ 	xo-shapes.c xo-shapes.h
+ 
+-xournal_LDADD = ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS)
++xournal_LDADD = ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS) -lX11 -lz
+ 
++xournal_LDFLAGS = -Wl,--as-needed
diff --git a/debian/patches/compilation_flags b/debian/patches/compilation_flags
new file mode 100644
index 0000000..6bf7eca
--- /dev/null
+++ b/debian/patches/compilation_flags
@@ -0,0 +1,26 @@
+--- a/po/Makefile.in.in
++++ b/po/Makefile.in.in
+@@ -95,6 +95,13 @@
+ $(srcdir)/$(GETTEXT_PACKAGE).pot: $(POTFILES)
+ 	$(XGETTEXT) --default-domain=$(GETTEXT_PACKAGE) --directory=$(top_srcdir) \
+ 	  --add-comments --keyword=_ --keyword=N_ \
++	  --keyword=C_:1c,2 \
++	  --keyword=NC_:1c,2 \
++	  --keyword=g_dngettext:2,3 \
++	  --flag=N_:1:pass-c-format \
++	  --flag=C_:2:pass-c-format \
++	  --flag=NC_:2:pass-c-format \
++	  --flag=g_dngettext:2:pass-c-format \
+           --flag=g_strdup_printf:1:c-format \
+           --flag=g_string_printf:2:c-format \
+           --flag=g_string_append_printf:2:c-format \
+--- a/src/ttsubset/Makefile.in
++++ b/src/ttsubset/Makefile.in
+@@ -113,6 +113,7 @@
+ 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@
diff --git a/debian/patches/correct_gtk_usage b/debian/patches/correct_gtk_usage
new file mode 100644
index 0000000..c9100a7
--- /dev/null
+++ b/debian/patches/correct_gtk_usage
@@ -0,0 +1,22 @@
+--- a/src/xo-file.c
++++ b/src/xo-file.c
+@@ -987,7 +987,18 @@
+   for (npad = 6; npad>0; npad--) {
+      ppm_name = g_strdup_printf("%s/p-%0*d.ppm", bgpdf.tmpdir, npad, req->pageno);
+      if (bgpdf.status != STATUS_ABORTED && bgpdf.status != STATUS_SHUTDOWN)
+-       pixbuf = gdk_pixbuf_new_from_file(ppm_name, NULL);
++     { // workaround for PPM loading issue in recent GTK
++       gchar *buf;
++       gsize count;
++       GdkPixbufLoader *loader = gdk_pixbuf_loader_new_with_type("pnm", NULL);
++       if (loader!=NULL && g_file_get_contents(ppm_name, &buf, &count, NULL))
++       {
++         gdk_pixbuf_loader_write(loader, buf, count, NULL);
++         pixbuf = gdk_pixbuf_loader_get_pixbuf(loader);
++         gdk_pixbuf_loader_close(loader, NULL);
++         g_free(buf);
++       }
++     }
+      ret = unlink(ppm_name);
+      g_free(ppm_name);
+      if (pixbuf != NULL || ret == 0) break;
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..9064dea
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,3 @@
+add_ldflags
+compilation_flags
+xoprint-len_fix
diff --git a/debian/patches/xoprint-len_fix b/debian/patches/xoprint-len_fix
new file mode 100644
index 0000000..65576bb
--- /dev/null
+++ b/debian/patches/xoprint-len_fix
@@ -0,0 +1,88 @@
+--- a/src/xo-print.c
++++ b/src/xo-print.c
+@@ -761,7 +761,7 @@
+ 
+   make_xref(xref, xref->last+1, pdfbuf->len);
+   g_string_append_printf(pdfbuf, 
+-    "%d 0 obj\n<< /Length %d /Filter /FlateDecode /Type /Xobject "
++    "%d 0 obj\n<< /Length %zu /Filter /FlateDecode /Type /Xobject "
+     "/Subtype /Image /Width %d /Height %d /ColorSpace /DeviceRGB "
+     "/BitsPerComponent 8 >> stream\n",
+     xref->last, zpix->len, width, height);
+@@ -840,8 +840,10 @@
+   gboolean fallback, is_binary;
+   guchar encoding[256];
+   gushort glyphs[256];
+-  int i, j, num, len1, len2;
+-  gsize len;
++  int i, j, num;
++  guint32 len1, len2;
++  guint32 tt_len;
++  gsize t1_len;
+   TrueTypeFont *ttfnt;
+   char *seg1, *seg2;
+   char *fontdata, *p;
+@@ -862,14 +864,14 @@
+       }
+     font->num_glyphs_used = num-1;
+     if (OpenTTFont(font->filename, 0, &ttfnt) == SF_OK) {
+-      if (CreateTTFromTTGlyphs_tomemory(ttfnt, (guint8**)&fontdata, &len, glyphs, encoding, num, 
++      if (CreateTTFromTTGlyphs_tomemory(ttfnt, (guint8**)&fontdata, &tt_len, glyphs, encoding, num,
+                    0, NULL, TTCF_AutoName | TTCF_IncludeOS2) == SF_OK) {
+         make_xref(xref, xref->last+1, pdfbuf->len);
+         nobj_fontprog = xref->last;
+         g_string_append_printf(pdfbuf, 
+-          "%d 0 obj\n<< /Length %d /Length1 %d >> stream\n",
+-          nobj_fontprog, (int)len, (int)len);
+-        g_string_append_len(pdfbuf, fontdata, len);
++          "%d 0 obj\n<< /Length %u /Length1 %u >> stream\n",
++          nobj_fontprog, tt_len, tt_len);
++        g_string_append_len(pdfbuf, fontdata, tt_len);
+         g_string_append(pdfbuf, "endstream\nendobj\n");
+         g_free(fontdata);
+       }
+@@ -879,7 +881,7 @@
+     else fallback = TRUE;
+   } else {
+   // embed the font file: Type1 case
+-    if (g_file_get_contents(font->filename, &fontdata, &len, NULL) && len>=8) {
++    if (g_file_get_contents(font->filename, &fontdata, &t1_len, NULL) && t1_len>=8) {
+       if (fontdata[0]==(char)0x80 && fontdata[1]==(char)0x01) {
+         is_binary = TRUE;
+         len1 = pfb_get_length((unsigned char *)fontdata+2);
+@@ -898,7 +900,7 @@
+           if (*p=='\n' || *p=='\r') p++;
+           if (*p=='\n' || *p=='\r') p++;
+           len1 = p-fontdata;
+-          p = g_strrstr_len(fontdata, len, T1_SEGMENT_3_END);
++          p = g_strrstr_len(fontdata, t1_len, T1_SEGMENT_3_END);
+           if (p==NULL) fallback = TRUE;
+           else {
+             // rewind 512 zeros
+@@ -936,7 +938,7 @@
+         make_xref(xref, xref->last+1, pdfbuf->len);
+         nobj_fontprog = xref->last;
+         g_string_append_printf(pdfbuf, 
+-          "%d 0 obj\n<< /Length %d /Length1 %d /Length2 %d /Length3 0 >> stream\n",
++          "%d 0 obj\n<< /Length %u /Length1 %u /Length2 %u /Length3 0 >> stream\n",
+           nobj_fontprog, len1+len2, len1, len2);
+         g_string_append_len(pdfbuf, seg1, len1);
+         g_string_append_len(pdfbuf, seg2, len2);
+@@ -1258,7 +1260,7 @@
+       tmpstr = make_pdfprefix(pdfinfo.pages+(pg->bg->file_page_seq-1),
+                               pg->width, pg->height);
+       g_string_append_printf(pdfbuf,
+-        "%d 0 obj\n<< /Length %d >> stream\n%s\nendstream\nendobj\n",
++        "%d 0 obj\n<< /Length %zu >> stream\n%s\nendstream\nendobj\n",
+         n_obj_prefix, tmpstr->len, tmpstr->str);
+       g_string_free(tmpstr, TRUE);
+       g_string_prepend(pgstrm, "Q Q Q ");
+@@ -1276,7 +1278,7 @@
+     
+     make_xref(&xref, xref.last+1, pdfbuf->len);
+     g_string_append_printf(pdfbuf, 
+-      "%d 0 obj\n<< /Length %d /Filter /FlateDecode>> stream\n",
++      "%d 0 obj\n<< /Length %zu /Filter /FlateDecode>> stream\n",
+       xref.last, zpgstrm->len);
+     g_string_append_len(pdfbuf, zpgstrm->str, zpgstrm->len);
+     g_string_free(zpgstrm, TRUE);
diff --git a/debian/postinst.ex b/debian/postinst.ex
deleted file mode 100644
index 8627d18..0000000
--- a/debian/postinst.ex
+++ /dev/null
@@ -1,42 +0,0 @@
-#! /bin/sh
-# postinst script for xournal
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <postinst> `configure' <most-recently-configured-version>
-#        * <old-postinst> `abort-upgrade' <new version>
-#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
-#          <new-version>
-#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
-#          <failed-install-package> <version> `removing'
-#          <conflicting-package> <version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-#
-
-case "$1" in
-    configure)
-
-    ;;
-
-    abort-upgrade|abort-remove|abort-deconfigure)
-
-    ;;
-
-    *)
-        echo "postinst called with unknown argument \`$1'" >&2
-        exit 1
-    ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/postrm.ex b/debian/postrm.ex
deleted file mode 100644
index a464e2c..0000000
--- a/debian/postrm.ex
+++ /dev/null
@@ -1,38 +0,0 @@
-#! /bin/sh
-# postrm script for xournal
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <postrm> `remove'
-#        * <postrm> `purge'
-#        * <old-postrm> `upgrade' <new-version>
-#        * <new-postrm> `failed-upgrade' <old-version>
-#        * <new-postrm> `abort-install'
-#        * <new-postrm> `abort-install' <old-version>
-#        * <new-postrm> `abort-upgrade' <old-version>
-#        * <disappearer's-postrm> `disappear' <r>overwrit>r> <new-version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
-       purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
-
-
-        ;;
-
-    *)
-        echo "postrm called with unknown argument \`$1'" >&2
-        exit 1
-
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
diff --git a/debian/preinst.ex b/debian/preinst.ex
deleted file mode 100644
index d25e1d6..0000000
--- a/debian/preinst.ex
+++ /dev/null
@@ -1,44 +0,0 @@
-#! /bin/sh
-# preinst script for xournal
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <new-preinst> `install'
-#        * <new-preinst> `install' <old-version>
-#        * <new-preinst> `upgrade' <old-version>
-#        * <old-preinst> `abort-upgrade' <new-version>
-#
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
-    install|upgrade)
-#        if [ "$1" = "upgrade" ]
-#        then
-#            start-stop-daemon --stop --quiet --oknodo  \
-#                --pidfile /var/run/xournal.pid  \
-#                --exec /usr/sbin/xournal 2>/dev/null || true
-#        fi
-    ;;
-
-    abort-upgrade)
-    ;;
-
-    *)
-        echo "preinst called with unknown argument \`$1'" >&2
-        exit 1
-    ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/prerm.ex b/debian/prerm.ex
deleted file mode 100644
index aa7d145..0000000
--- a/debian/prerm.ex
+++ /dev/null
@@ -1,39 +0,0 @@
-#! /bin/sh
-# prerm script for xournal
-#
-# see: dh_installdeb(1)
-
-set -e
-
-# summary of how this script can be called:
-#        * <prerm> `remove'
-#        * <old-prerm> `upgrade' <new-version>
-#        * <new-prerm> `failed-upgrade' <old-version>
-#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
-#        * <deconfigured's-prerm> `deconfigure' `in-favour'
-#          <package-being-installed> <version> `removing'
-#          <conflicting-package> <version>
-# for details, see http://www.debian.org/doc/debian-policy/ or
-# the debian-policy package
-
-
-case "$1" in
-    remove|upgrade|deconfigure)
-#       install-info --quiet --remove /usr/info/xournal.info.gz
-        ;;
-    failed-upgrade)
-        ;;
-    *)
-        echo "prerm called with unknown argument \`$1'" >&2
-        exit 1
-    ;;
-esac
-
-# dh_installdeb will replace this with shell code automatically
-# generated by other debhelper scripts.
-
-#DEBHELPER#
-
-exit 0
-
-
diff --git a/debian/rules b/debian/rules
index e56132e..5bc0fa1 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,18 +1,14 @@
 #!/usr/bin/make -f
 # -*- makefile -*-
 # Sample debian/rules that uses debhelper.
-# GNU copyright 1997 to 1999 by Joey Hess.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
 
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
 
-
-# These are used for cross-compiling and for saving the configure script
-# from having to guess our platform (since we know it already)
-DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
-DEB_BUILD_GNU_TYPE  ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE)
-
-
 CFLAGS = -Wall -g
 
 ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
@@ -20,53 +16,52 @@ ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
 else
 	CFLAGS += -O2
 endif
-ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
-	INSTALL_PROGRAM += -s
-endif
 
-config.status: configure
+configure: configure-stamp
+configure-stamp:
 	dh_testdir
-	# Add here commands to configure the package.
-	CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info
+	# Configure the package.
+	./autogen.sh --prefix=/usr
 
+	touch configure-stamp
 
 build: build-stamp
-
-build-stamp:  config.status
+build-stamp: configure-stamp 
 	dh_testdir
 
-	# Add here commands to compile the package.
+	# Compile the package.
 	$(MAKE)
-	#/usr/bin/docbook-to-man debian/xournal.sgml > xournal.1
 
 	touch build-stamp
 
-clean:
+clean: 
 	dh_testdir
 	dh_testroot
-	rm -f build-stamp 
 
-	# Add here commands to clean up after the build process.
-	-$(MAKE) distclean
-ifneq "$(wildcard /usr/share/misc/config.sub)" ""
-	cp -f /usr/share/misc/config.sub config.sub
-endif
-ifneq "$(wildcard /usr/share/misc/config.guess)" ""
-	cp -f /usr/share/misc/config.guess config.guess
-endif
+	# Clean up after the build process.
+	if test -f Makefile; then \
+		$(MAKE) distclean; \
+	else \
+		rm -f src/xournal; \
+        fi
 
+	rm -f aclocal.m4 config.h.in Makefile.in src/Makefile.in
+	rm -f configure-stamp build-stamp
+	rm -f depcomp install-sh missing configure
 
 	dh_clean 
 
 install: build
 	dh_testdir
 	dh_testroot
-	dh_clean -k 
+	dh_prep
 	dh_installdirs
 
-	# Add here commands to install the package into debian/xournal.
+	# Install the package into debian/xournal.
 	$(MAKE) install DESTDIR=$(CURDIR)/debian/xournal
-
+	$(MAKE) desktop-install DESTDIR=$(CURDIR)/debian/xournal
+	# Remove HTML manual from /usr/share/xournal/html-doc
+	rm -rf $(CURDIR)/debian/xournal/usr/share/xournal/html-doc
 
 # Build architecture-independent files here.
 binary-indep: build install
@@ -78,25 +73,12 @@ binary-arch: build install
 	dh_testroot
 	dh_installchangelogs ChangeLog
 	dh_installdocs
-	dh_installexamples
-#	dh_install
-#	dh_installmenu
-#	dh_installdebconf	
-#	dh_installlogrotate
-#	dh_installemacsen
-#	dh_installpam
-#	dh_installmime
-#	dh_installinit
-#	dh_installcron
-#	dh_installinfo
-	dh_installman
+	dh_installman debian/xournal.1
+	dh_installmenu
 	dh_link
 	dh_strip
 	dh_compress
 	dh_fixperms
-#	dh_perl
-#	dh_python
-#	dh_makeshlibs
 	dh_installdeb
 	dh_shlibdeps
 	dh_gencontrol
@@ -104,4 +86,4 @@ binary-arch: build install
 	dh_builddeb
 
 binary: binary-indep binary-arch
-.PHONY: build clean binary-indep binary-arch binary install 
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/debian/source/format b/debian/source/format
new file mode 100644
index 0000000..163aaf8
--- /dev/null
+++ b/debian/source/format
@@ -0,0 +1 @@
+3.0 (quilt)
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..959ae26
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,3 @@
+version=3
+
+http://sf.net/xournal/xournal-(.*)\.tar\.gz
diff --git a/debian/watch.ex b/debian/watch.ex
deleted file mode 100644
index 1ddcf3b..0000000
--- a/debian/watch.ex
+++ /dev/null
@@ -1,6 +0,0 @@
-# Example watch control file for uscan
-# Rename this file to "watch" and then you can run the "uscan" command
-# to check for upstream updates and more.
-# Site		Directory		Pattern			Version	Script
-version=2
-sunsite.unc.edu	/pub/Linux/Incoming	xournal-(.*)\.tar\.gz	debian	uupdate
diff --git a/debian/xournal-default.ex b/debian/xournal-default.ex
deleted file mode 100644
index 7cbd177..0000000
--- a/debian/xournal-default.ex
+++ /dev/null
@@ -1,10 +0,0 @@
-# Defaults for xournal initscript
-# sourced by /etc/init.d/xournal
-# installed at /etc/default/xournal by the maintainer scripts
-
-#
-# This is a POSIX shell fragment
-#
-
-# Additional options that are passed to the Daemon.
-DAEMON_OPTS=""
diff --git a/debian/xournal.1 b/debian/xournal.1
new file mode 100644
index 0000000..a43ebf6
--- /dev/null
+++ b/debian/xournal.1
@@ -0,0 +1,25 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.TH XOURNAL 1 "November 8, 2009"
+.SH NAME
+xournal \- GTK+ Application for note taking
+.SH SYNOPSIS
+.B xournal
+.RI [ file ]
+.br
+.SH DESCRIPTION
+This manual page briefly documents the
+.B xournal
+command.
+.PP
+\fBXournal\fP is a GTK+ application for notetaking, sketching and
+keeping a journal using a stylus. It can also be used to
+add annotations to PDF files and graphics files.  It takes no options.
+.PP
+The Xournal HTML manual may be found at
+file://usr/share/doc/xournal/manual.html
+.SH AUTHOR
+xournal was written by Denis Auroux <auroux@math.mit.edu>.
+.PP
+This manual page was originally written by 
+Mathieu Bouchard <mbouchar@bioinfo.ulaval.ca>,
+for the Debian project (but may be used by others).
diff --git a/debian/xournal.doc-base.EX b/debian/xournal.doc-base.EX
deleted file mode 100644
index 708e2ea..0000000
--- a/debian/xournal.doc-base.EX
+++ /dev/null
@@ -1,22 +0,0 @@
-Document: xournal
-Title: Debian xournal Manual
-Author: <insert document author here>
-Abstract: This manual describes what xournal is
- and how it can be used to
- manage online manuals on Debian systems.
-Section: unknown
-
-Format: debiandoc-sgml
-Files: /usr/share/doc/xournal/xournal.sgml.gz
-
-Format: postscript
-Files: /usr/share/doc/xournal/xournal.ps.gz
-
-Format: text
-Files: /usr/share/doc/xournal/xournal.text.gz
-
-Format: HTML
-Index: /usr/share/doc/xournal/html/index.html
-Files: /usr/share/doc/xournal/html/*.html
-
-  
diff --git a/debian/xournal.links b/debian/xournal.links
deleted file mode 100644
index 26e4e29..0000000
--- a/debian/xournal.links
+++ /dev/null
@@ -1 +0,0 @@
-/var/lib/install/usr/share/applications/hildon/xournal.desktop /etc/others-menu/extra_applications/0020_xournal.desktop
diff --git a/debian/xournal.substvars b/debian/xournal.substvars
deleted file mode 100644
index 8c4b451..0000000
--- a/debian/xournal.substvars
+++ /dev/null
@@ -1 +0,0 @@
-shlibs:Depends=dbus-1 (>= 0.23.4), dbus-glib-1 (>= 0.23.4), hildon-fm1 (>= 0.9.47-1), hildon-lgpl0 (>= 0.9.59-1), hildon-libs0 (>= 0.9.53-1), libart-2.0-2 (>= 2.3.16), libatk1.0-0 (>= 1.9.0), libc6 (>= 2.3.2.ds1-4), libglib2.0-0 (>= 2.6.0), libgnomecanvas2-0 (>= 2.6.0), libgnomeprint2.2-0 (>= 2.10.2), libgnomeprintui2.2-0 (>= 2.10.0), libgtk2.0-0 (>= 2:2.6.4-1.osso76), libosso1 (>= 0.9.19-1), libpango1.0-0 (>= 1.8.1), libx11-6 | xlibs (>> 4.1.0), libxml2 (>= 2.6.16), zlib1g (>= 1:1.2.1)
diff --git a/po/ca.po b/po/ca.po
index 5451320..194004b 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -142,8 +142,8 @@ msgid "_Hide Layer"
 msgstr "_Oculta la capa"
 
 #: src/xo-interface.c:665
-msgid "_Journal"
-msgstr "_Diari"
+msgid "_Page"
+msgstr "_Pàgina"
 
 #: src/xo-interface.c:672
 msgid "New Page _Before"
diff --git a/po/cs.po b/po/cs.po
index d997cf1..1d81508 100644
--- a/po/cs.po
+++ b/po/cs.po
@@ -143,8 +143,8 @@ msgid "_Hide Layer"
 msgstr "S_krýt vrstvu"
 
 #: src/xo-interface.c:665
-msgid "_Journal"
-msgstr "_Deník"
+msgid "_Page"
+msgstr "_Stránka"
 
 #: src/xo-interface.c:672
 msgid "New Page _Before"
diff --git a/po/de.po b/po/de.po
index 30837f6..7c981e8 100644
--- a/po/de.po
+++ b/po/de.po
@@ -140,8 +140,8 @@ msgid "_Hide Layer"
 msgstr "Ebene _verbergen"
 
 #: src/xo-interface.c:666
-msgid "_Journal"
-msgstr ""
+msgid "_Page"
+msgstr "_Seite"
 
 #: src/xo-interface.c:673
 msgid "New Page _Before"
diff --git a/po/es.po b/po/es.po
index 13a0bfd..f905436 100644
--- a/po/es.po
+++ b/po/es.po
@@ -145,8 +145,8 @@ msgid "_Hide Layer"
 msgstr "_Ocultar la capa"
 
 #: src/xo-interface.c:665
-msgid "_Journal"
-msgstr "_Diario"
+msgid "_Page"
+msgstr "_Página"
 
 #: src/xo-interface.c:672
 msgid "New Page _Before"
diff --git a/po/it.po b/po/it.po
index fd1dd94..099ba63 100644
--- a/po/it.po
+++ b/po/it.po
@@ -144,7 +144,7 @@ msgid "_Hide Layer"
 msgstr "_Nascondi livello"
 
 #: src/xo-interface.c:665
-msgid "_Journal"
+msgid "_Page"
 msgstr "_Pagina"
 
 #: src/xo-interface.c:672
diff --git a/po/nl.po b/po/nl.po
index d40b49e..615db8f 100644
--- a/po/nl.po
+++ b/po/nl.po
@@ -146,8 +146,8 @@ msgid "_Hide Layer"
 msgstr "_Laag verbergen"
 
 #: src/xo-interface.c:665
-msgid "_Journal"
-msgstr "_Schrift"
+msgid "_Page"
+msgstr "_Pagina"
 
 #: src/xo-interface.c:672
 msgid "New Page _Before"
diff --git a/po/pt_BR.po b/po/pt_BR.po
index d33ddb9..beccd8b 100644
--- a/po/pt_BR.po
+++ b/po/pt_BR.po
@@ -150,8 +150,8 @@ msgid "_Hide Layer"
 msgstr "_Ocultar camada"
 
 #: src/xo-interface.c:665
-msgid "_Journal"
-msgstr "_Diário"
+msgid "_Page"
+msgstr "_Página"
 
 #: src/xo-interface.c:672
 msgid "New Page _Before"
diff --git a/src/Makefile.am b/src/Makefile.am
index 03ecd35..80395d8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -18,6 +18,8 @@ xournal_SOURCES = \
 	xo-misc.c xo-misc.h \
 	xo-file.c xo-file.h \
 	xo-paint.c xo-paint.h \
+	xo-clipboard.c xo-clipboard.h \
+	xo-image.c xo-image.h \
 	xo-print.c xo-print.h \
 	xo-support.c xo-support.h \
 	xo-interface.c xo-interface.h \
@@ -26,8 +28,7 @@ xournal_SOURCES = \
 
 if WIN32
   xournal_LDFLAGS = -mwindows
-  xournal_LDADD = win32/xournal.res ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS)
+  xournal_LDADD = win32/xournal.res ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS) -lz
 else
-  xournal_LDADD = ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS) -lX11
+  xournal_LDADD = ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS) -lX11 -lz -lm
 endif
-
diff --git a/src/Makefile.in b/src/Makefile.in
index 45ebffa..f42ab2a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
+# Makefile.in generated by automake 1.11 from Makefile.am.
 # @configure_input@
 
 # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -48,9 +48,10 @@ CONFIG_CLEAN_VPATH_FILES =
 am__installdirs = "$(DESTDIR)$(bindir)"
 PROGRAMS = $(bin_PROGRAMS)
 am_xournal_OBJECTS = main.$(OBJEXT) xo-misc.$(OBJEXT) \
-	xo-file.$(OBJEXT) xo-paint.$(OBJEXT) xo-print.$(OBJEXT) \
-	xo-support.$(OBJEXT) xo-interface.$(OBJEXT) \
-	xo-callbacks.$(OBJEXT) xo-shapes.$(OBJEXT)
+	xo-file.$(OBJEXT) xo-paint.$(OBJEXT) xo-clipboard.$(OBJEXT) \
+	xo-image.$(OBJEXT) xo-print.$(OBJEXT) xo-support.$(OBJEXT) \
+	xo-interface.$(OBJEXT) xo-callbacks.$(OBJEXT) \
+	xo-shapes.$(OBJEXT)
 xournal_OBJECTS = $(am_xournal_OBJECTS)
 am__DEPENDENCIES_1 =
 @WIN32_FALSE@xournal_DEPENDENCIES = ttsubset/libttsubset.a \
@@ -161,7 +162,6 @@ PACKAGE_LIBS = @PACKAGE_LIBS@
 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@
@@ -240,6 +240,8 @@ xournal_SOURCES = \
 	xo-misc.c xo-misc.h \
 	xo-file.c xo-file.h \
 	xo-paint.c xo-paint.h \
+	xo-clipboard.c xo-clipboard.h \
+	xo-image.c xo-image.h \
 	xo-print.c xo-print.h \
 	xo-support.c xo-support.h \
 	xo-interface.c xo-interface.h \
@@ -247,8 +249,8 @@ xournal_SOURCES = \
 	xo-shapes.c xo-shapes.h
 
 @WIN32_TRUE@xournal_LDFLAGS = -mwindows
-@WIN32_FALSE@xournal_LDADD = ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS) -lX11
-@WIN32_TRUE@xournal_LDADD = win32/xournal.res ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS)
+@WIN32_FALSE@xournal_LDADD = ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS) -lX11 -lz
+@WIN32_TRUE@xournal_LDADD = win32/xournal.res ttsubset/libttsubset.a @PACKAGE_LIBS@ $(INTLLIBS) -lz
 all: all-recursive
 
 .SUFFIXES:
@@ -332,7 +334,9 @@ distclean-compile:
 
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xo-callbacks.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xo-clipboard.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xo-file.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xo-image.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xo-interface.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xo-misc.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xo-paint.Po@am__quote@
@@ -361,7 +365,7 @@ distclean-compile:
 #     (which will cause the Makefiles to be regenerated when you run `make');
 # (2) otherwise, pass the desired values on the `make' command line.
 $(RECURSIVE_TARGETS):
-	@fail= failcom='exit 1'; \
+	@failcom='exit 1'; \
 	for f in x $$MAKEFLAGS; do \
 	  case $$f in \
 	    *=* | --[!k]*);; \
@@ -386,7 +390,7 @@ $(RECURSIVE_TARGETS):
 	fi; test -z "$$fail"
 
 $(RECURSIVE_CLEAN_TARGETS):
-	@fail= failcom='exit 1'; \
+	@failcom='exit 1'; \
 	for f in x $$MAKEFLAGS; do \
 	  case $$f in \
 	    *=* | --[!k]*);; \
diff --git a/src/TODO b/src/TODO
index e6d19ed..01bdcd9 100644
--- a/src/TODO
+++ b/src/TODO
@@ -20,6 +20,12 @@ List of features to be implemented (not in any particular order)
   xournal). (cf #2944459). Recalibration probably requires talking directly 
   to X server to query input device geometry and compensate for GTK.
 
+TODO WITH IMAGE PATCH:
+TODO: paste and selresize don't put rectangle at top
+TODO: select click in image selects it
+TODO: option for image mode to revert to previous tool
+TODO: direct paste text
+
 BUGS:
 - lingering issues with synaptics touchpads? (#2872667)
  (todo) - set device to Absolute mode at startup? (GDK doesn't expose API,
@@ -29,6 +35,11 @@ BUGS:
 - export to PDF should see cropbox size if smaller, and map the
    cropbox -- not the entire page -- to the page area! (2009-11-18 forum)
 
+BEHAVIOR TODO:
+- option to have "Save Prefs" save current brushes as settings, not defaults
+- method to map more general devices to specific tools or to Ignore
+  (e.g.: X220T ignore trackpoint; map touchscreen to Hand, eraser to Eraser)
+
 WIN32:
 - test further
 - write an installer
@@ -150,10 +161,9 @@ https://sourceforge.net/tracker/index.php?func=detail&aid=3447356&group_id=16343
 - proximity detection: eraser proximity switches mapping? 
   proximity out removes cursor until next motionnotify?
 
-
 - render page to bitmap: for export, preview, and copy-paste
     (render using libart, see how gnomecanvas does it?)
-    NO: render using Cairo !!! then can switch to GtkPrint as well.
+    NO: render using Cairo !!!
     (copy-paste: config option to render only current layer or all below?)
 - cut-and-paste of selection into other apps (as bitmap; as SVG?)
 
@@ -184,10 +194,6 @@ https://sourceforge.net/tracker/index.php?func=detail&aid=3447356&group_id=16343
 - add config option to limit total memory usage for PDF bitmaps
 - ability to select entire page for copy-paste (as bitmap / reorder xournal)
 - copy/paste of an entire page (beware if PDF bg is not compatible!)
-- rewrite printing using GtkPrint + Cairo as GnomePrint replacement
-   (keep GnomePrint option for compatibility with GTK+ <2.10)
-- insert images (screen capture or from file or from clipboard), 
-  not as full-page backgrounds (new ITEM type)
 
 - convert to/from Jarnal format; to/from MS Journal format???
 - export as SVG, as bitmap (use Cairo for this)
diff --git a/src/main.c b/src/main.c
index 20d48fd..6ad515f 100644
--- a/src/main.c
+++ b/src/main.c
@@ -349,7 +349,6 @@ main (int argc, char *argv[])
   
   if (bgpdf.status != STATUS_NOT_INIT) shutdown_bgpdf();
 
-  save_mru_list();
   if (ui.auto_save_prefs) save_config_to_file();
   
   return 0;
diff --git a/src/xo-callbacks.c b/src/xo-callbacks.c
index 3b2b319..076ec82 100644
--- a/src/xo-callbacks.c
+++ b/src/xo-callbacks.c
@@ -468,7 +468,7 @@ on_editUndo_activate                   (GtkMenuItem     *menuitem,
   if (undo == NULL) return; // nothing to undo!
   reset_selection(); // safer
   reset_recognizer(); // safer
-  if (undo->type == ITEM_STROKE || undo->type == ITEM_TEXT) {
+  if (undo->type == ITEM_STROKE || undo->type == ITEM_TEXT || undo->type == ITEM_IMAGE) {
     // we're keeping the stroke info, but deleting the canvas item
     gtk_object_destroy(GTK_OBJECT(undo->item->canvas_item));
     undo->item->canvas_item = NULL;
@@ -682,7 +682,7 @@ on_editRedo_activate                   (GtkMenuItem     *menuitem,
   if (redo == NULL) return; // nothing to redo!
   reset_selection(); // safer
   reset_recognizer(); // safer
-  if (redo->type == ITEM_STROKE || redo->type == ITEM_TEXT) {
+  if (redo->type == ITEM_STROKE || redo->type == ITEM_TEXT || redo->type == ITEM_IMAGE) {
     // re-create the canvas_item
     make_canvas_item_one(redo->layer->group, redo->item);
     // reinsert the item on its layer
@@ -840,6 +840,12 @@ on_editRedo_activate                   (GtkMenuItem     *menuitem,
       if (it->type == ITEM_TEXT && it->canvas_item != NULL)
         gnome_canvas_item_set(it->canvas_item, 
           "fill-color-rgba", it->brush.color_rgba, NULL);
+      if (it->type == ITEM_IMAGE && it->canvas_item != NULL) {
+        // remark: a variable-width item might have lost its variable-width
+        group = (GnomeCanvasGroup *) it->canvas_item->parent;
+        gtk_object_destroy(GTK_OBJECT(it->canvas_item));
+        make_canvas_item_one(group, it);
+      }
     }
   }
   else if (redo->type == ITEM_TEXT_EDIT) {
@@ -962,6 +968,7 @@ on_viewZoomIn_activate                 (GtkMenuItem     *menuitem,
   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
   rescale_text_items();
   rescale_bg_pixmaps();
+  rescale_images();
 }
 
 
@@ -974,6 +981,7 @@ on_viewZoomOut_activate                (GtkMenuItem     *menuitem,
   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
   rescale_text_items();
   rescale_bg_pixmaps();
+  rescale_images();
 }
 
 
@@ -985,6 +993,7 @@ on_viewNormalSize_activate             (GtkMenuItem     *menuitem,
   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
   rescale_text_items();
   rescale_bg_pixmaps();
+  rescale_images();
 }
 
 
@@ -996,6 +1005,7 @@ on_viewPageWidth_activate              (GtkMenuItem     *menuitem,
   gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
   rescale_text_items();
   rescale_bg_pixmaps();
+  rescale_images();
 }
 
 
@@ -1100,7 +1110,7 @@ on_journalNewPageAfter_activate        (GtkMenuItem     *menuitem,
   pg = new_page(ui.cur_page);
   journal.pages = g_list_insert(journal.pages, pg, ui.pageno+1);
   journal.npages++;
-  do_switch_page(ui.pageno+1, TRUE, TRUE);
+  do_switch_page_and_scroll(ui.pageno+1, TRUE, TRUE, -1/2.);
 
   prepare_new_undo();
   undo->type = ITEM_NEW_PAGE;
@@ -1120,7 +1130,7 @@ on_journalNewPageEnd_activate          (GtkMenuItem     *menuitem,
   pg = new_page((struct Page *)g_list_last(journal.pages)->data);
   journal.pages = g_list_append(journal.pages, pg);
   journal.npages++;
-  do_switch_page(journal.npages-1, TRUE, TRUE);
+  do_switch_page_and_scroll(journal.npages-1, TRUE, TRUE, -1/2.);
 
   prepare_new_undo();
   undo->type = ITEM_NEW_PAGE;
@@ -1246,7 +1256,6 @@ on_journalFlatten_activate             (GtkMenuItem     *menuitem,
 
 }
 
-
 // the paper sizes dialog
 
 GtkWidget *papersize_dialog;
@@ -1555,6 +1564,7 @@ on_journalLoadBackground_activate      (GtkMenuItem     *menuitem,
     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
     rescale_text_items();
     rescale_bg_pixmaps();
+    rescale_images();
   }
   do_switch_page(ui.pageno, TRUE, TRUE);
 }
@@ -1601,6 +1611,7 @@ on_journalScreenshot_activate          (GtkMenuItem     *menuitem,
     gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
     rescale_text_items();
     rescale_bg_pixmaps();
+    rescale_images();
   }
   do_switch_page(ui.pageno, TRUE, TRUE);
 }
@@ -1765,6 +1776,33 @@ on_toolsText_activate                  (GtkMenuItem     *menuitem,
 
 
 void
+on_toolsImage_activate                 (GtkMenuItem *menuitem,
+                                        gpointer         user_data)
+{
+  if (GTK_OBJECT_TYPE(menuitem) == GTK_TYPE_RADIO_MENU_ITEM) {
+    if (!gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem)))
+      return;
+  } else {
+    if (!gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON (menuitem)))
+      return;
+  }
+  
+  if (ui.cur_mapping != 0 && !ui.button_switch_mapping) return; // not user-generated
+  if (ui.toolno[ui.cur_mapping] == TOOL_IMAGE) return;
+  
+  ui.cur_mapping = 0; // don't use switch_mapping() (refreshes buttons too soon)
+  end_text();
+  reset_selection();
+  ui.toolno[ui.cur_mapping] = TOOL_IMAGE;
+  update_mapping_linkings(-1);
+  update_tool_buttons();
+  update_tool_menu();
+  update_color_menu();
+  update_cursor();
+}
+
+
+void
 on_toolsSelectRegion_activate          (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
@@ -2337,8 +2375,6 @@ on_canvas_button_press_event           (GtkWidget       *widget,
                                         gpointer         user_data)
 {
   double pt[2];
-  gboolean page_change;
-  struct Page *tmppage;
   GtkWidget *dialog;
   int mapping;
   gboolean is_core;
@@ -2425,24 +2461,8 @@ on_canvas_button_press_event           (GtkWidget       *widget,
   else mapping = event->button-1;
 
   // check whether we're in a page
-  page_change = FALSE;
-  tmppage = ui.cur_page;
   get_pointer_coords((GdkEvent *)event, pt);
-  while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
-    if (ui.pageno == 0) break;
-    page_change = TRUE;
-    ui.pageno--;
-    tmppage = g_list_nth_data(journal.pages, ui.pageno);
-    pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
-  }
-  while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
-    if (ui.pageno == journal.npages-1) break;
-    pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
-    page_change = TRUE;
-    ui.pageno++;
-    tmppage = g_list_nth_data(journal.pages, ui.pageno);
-  }
-  if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
+  set_current_page(pt);
   
   // can't paint on the background...
 
@@ -2508,6 +2528,9 @@ on_canvas_button_press_event           (GtkWidget       *widget,
   else if (ui.toolno[mapping] == TOOL_TEXT) {
     start_text((GdkEvent *)event, NULL);
   }
+  else if (ui.toolno[mapping] == TOOL_IMAGE) {
+    insert_image((GdkEvent *)event);
+  }
   return FALSE;
 }
 
@@ -2697,7 +2720,7 @@ on_canvas_motion_notify_event          (GtkWidget       *widget,
      or if there's a selection (then we might want to change the mouse
      cursor to indicate the possibility of resizing) */  
   if (ui.cur_item_type == ITEM_NONE && ui.selection==NULL) return FALSE;
-  if (ui.cur_item_type == ITEM_TEXT) return FALSE;
+  if (ui.cur_item_type == ITEM_TEXT || ui.cur_item_type == ITEM_IMAGE) return FALSE;
 
   is_core = (event->device == gdk_device_get_core_pointer());
   if (!ui.use_xinput && !is_core) return FALSE;
@@ -3142,32 +3165,36 @@ on_optionsProgressiveBG_activate       (GtkMenuItem     *menuitem,
 
 
 void
-on_mru_activate                        (GtkMenuItem     *menuitem,
+on_mru_activate                        (GtkRecentChooser *recentChooser,
                                         gpointer         user_data)
 {
-  int which;
   gboolean success;
+  gchar *uri, *name;
   GtkWidget *dialog;
   
   end_text();
   if (!ok_to_close()) return; // user aborted on save confirmation
   
-  for (which = 0 ; which < MRU_SIZE; which++) {
-    if (ui.mrumenu[which] == GTK_WIDGET(menuitem)) break;
-  }
-  if (which == MRU_SIZE || ui.mru[which] == NULL) return; // not found...
-
+  uri = gtk_recent_chooser_get_current_uri (recentChooser);
+  name = g_filename_from_uri (uri, NULL, NULL);
   set_cursor_busy(TRUE);
-  success = open_journal(ui.mru[which]);
+  success = open_journal(name);
   set_cursor_busy(FALSE);
-  if (success) return;
+  if (success) {
+    g_free(uri);
+    g_free(name);
+    return;
+  }
 
   /* open failed */
   dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_DESTROY_WITH_PARENT,
-    GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), ui.mru[which]);
+    GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening file '%s'"), name);
   gtk_dialog_run(GTK_DIALOG(dialog));
   gtk_widget_destroy(dialog);
-  delete_mru_entry(which);
+
+  delete_mru_entry(name);
+  g_free(uri);
+  g_free(name);
 }
 
 
@@ -3204,6 +3231,14 @@ on_button2Text_activate                (GtkMenuItem     *menuitem,
 
 
 void
+on_button2Image_activate               (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  process_mapping_activate(menuitem, 1, TOOL_IMAGE);
+}
+
+
+void
 on_button2SelectRegion_activate        (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
@@ -3289,6 +3324,14 @@ on_button3Text_activate                (GtkMenuItem     *menuitem,
 
 
 void
+on_button3Image_activate               (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  process_mapping_activate(menuitem, 2, TOOL_IMAGE);
+}
+
+
+void
 on_button3SelectRegion_activate        (GtkMenuItem     *menuitem,
                                         gpointer         user_data)
 {
@@ -3381,6 +3424,7 @@ on_viewSetZoom_activate                (GtkMenuItem     *menuitem,
       gnome_canvas_set_pixels_per_unit(canvas, ui.zoom);
       rescale_text_items();
       rescale_bg_pixmaps();
+      rescale_images();
     }
   } while (response == GTK_RESPONSE_APPLY);
   
@@ -3604,3 +3648,272 @@ on_optionsButtonsSwitchMappings_activate(GtkMenuItem    *menuitem,
   ui.button_switch_mapping = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM (menuitem));
 }
 
+// the ruling parameters dialog
+void
+on_journalRulingParams_activate        (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  GtkWidget *ruling_dialog;
+  GtkEntry *rd_margin_color, *rd_ruling_color;
+  GtkSpinButton *rd_left_margin, *rd_top_margin, *rd_bottom_margin;
+  GtkSpinButton *rd_thickness, *rd_spacing, *rd_graph_spacing;
+  int response;
+  char entry_text[9];
+
+  struct Background *bg = ui.cur_page->bg;
+
+  end_text();
+  ruling_dialog = create_rulingDialog();
+
+  // Set values in widgets to be those from current page.
+  rd_margin_color = GTK_ENTRY(lookup_widget (ruling_dialog, "rd_margin_color"));
+  snprintf (entry_text, 9, "%08x", bg->ruling_margin_color);
+  gtk_entry_set_text (rd_margin_color, entry_text);
+
+  rd_ruling_color = GTK_ENTRY(lookup_widget (ruling_dialog, "rd_ruling_color"));
+  snprintf (entry_text, 9, "%08x", bg->ruling_color);
+  gtk_entry_set_text (rd_ruling_color, entry_text);
+
+  rd_thickness = GTK_SPIN_BUTTON(lookup_widget (ruling_dialog, "rd_thickness" ));
+  gtk_spin_button_set_value (rd_thickness, bg->ruling_thickness);
+  gtk_spin_button_set_range (rd_thickness, RULING_THICKNESS_MIN, RULING_THICKNESS_MAX);
+
+  rd_left_margin = GTK_SPIN_BUTTON(lookup_widget (ruling_dialog, "rd_left_margin" ));
+  gtk_spin_button_set_value (rd_left_margin, bg->ruling_leftmargin);
+  gtk_spin_button_set_range (rd_left_margin, RULING_MARGIN_MIN, RULING_MARGIN_MAX);
+
+  rd_top_margin = GTK_SPIN_BUTTON(lookup_widget (ruling_dialog, "rd_top_margin" ));
+  gtk_spin_button_set_value (rd_top_margin, bg->ruling_topmargin);
+  gtk_spin_button_set_range (rd_top_margin, RULING_MARGIN_MIN, RULING_MARGIN_MAX);
+
+  rd_spacing = GTK_SPIN_BUTTON(lookup_widget (ruling_dialog, "rd_spacing" ));
+  gtk_spin_button_set_value (rd_spacing, bg->ruling_spacing);
+  gtk_spin_button_set_range (rd_spacing, RULING_SPACING_MIN, RULING_SPACING_MAX);
+
+  rd_bottom_margin = GTK_SPIN_BUTTON(lookup_widget (ruling_dialog, "rd_bottom_margin" ));
+  gtk_spin_button_set_value (rd_bottom_margin, bg->ruling_bottommargin);
+  gtk_spin_button_set_range (rd_bottom_margin, RULING_MARGIN_MIN, RULING_MARGIN_MAX);
+
+  rd_graph_spacing = GTK_SPIN_BUTTON(lookup_widget (ruling_dialog, "rd_graph_spacing" ));
+  gtk_spin_button_set_value (rd_graph_spacing, bg->ruling_graphspacing);
+  gtk_spin_button_set_range (rd_graph_spacing, RULING_SPACING_MIN, RULING_SPACING_MAX);
+
+  // Run the dialog
+  gtk_dialog_set_default_response(GTK_DIALOG(ruling_dialog), GTK_RESPONSE_OK);
+  gtk_widget_show(ruling_dialog);
+  response = gtk_dialog_run(GTK_DIALOG(ruling_dialog));
+
+  if (response == GTK_RESPONSE_OK) {
+    struct Page *pg;
+    GList *pglist;
+    guint val;
+    gchar *ptr;
+
+    pg = ui.cur_page;
+    for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
+      if (ui.bg_apply_all_pages) pg = (struct Page *)pglist->data;
+      prepare_new_undo();
+      if (ui.bg_apply_all_pages) {
+	if (pglist->next!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
+	if (pglist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
+      }
+      undo->type = ITEM_NEW_BG_ONE;
+      undo->page = pg;
+      undo->bg = (struct Background *)g_memdup(pg->bg, sizeof(struct Background));
+      undo->bg->canvas_item = NULL;
+
+      // Set values here
+      val = strtoul( gtk_entry_get_text (rd_margin_color), &ptr, 16);
+      if( *ptr == 0 ) pg->bg->ruling_margin_color = val;
+      val = strtoul( gtk_entry_get_text (rd_ruling_color), &ptr, 16);
+      if( *ptr == 0 ) pg->bg->ruling_color = val;
+      pg->bg->ruling_thickness = gtk_spin_button_get_value (rd_thickness);
+      pg->bg->ruling_leftmargin = gtk_spin_button_get_value (rd_left_margin);
+      pg->bg->ruling_topmargin = gtk_spin_button_get_value (rd_top_margin);
+      pg->bg->ruling_spacing = gtk_spin_button_get_value (rd_spacing);
+      pg->bg->ruling_bottommargin = gtk_spin_button_get_value (rd_bottom_margin);
+      pg->bg->ruling_graphspacing = gtk_spin_button_get_value (rd_graph_spacing);
+      
+      update_canvas_bg(pg);
+      if (!ui.bg_apply_all_pages) break;
+    }
+    do_switch_page(ui.pageno, TRUE, TRUE);
+  }
+  gtk_widget_destroy(ruling_dialog);
+}
+
+
+/*
+ * Simple color inversion, without preserving hue.
+ */
+//#define INVERT_COLOR( c ) c = ((c) ^ 0xffffff00)
+
+/*
+ * HLS color inversion. This preserves the nature of the color, and only tries
+ * to invert the brightness. The next few functions are helper functions to
+ * do this.
+ *
+ * NOTE: In theory inverting twice should get back the original. However there
+ * are round off errors that might change the colors slightly. I've tested for
+ * 1,000,000 randomly generated colors that inverting twice is the identity.
+ *
+ * -- gi1242 2010-02-13.
+ */
+#define INVERT_COLOR( c ) c = rgba_invert_color(c)
+
+#define intcolor( f ) ((f) >= 1.0 ? 255 : (guint) ((f) * 256) & 0xff)
+
+static double
+hue_to_rgb(const double m1, const double m2, double h )
+{
+  if (h<0) h+=1.0;
+  if (h>1) h-=1.0;
+  if (6.0*h < 1  ) return (m1+(m2-m1)*h*6.0);
+  if (2.0*h < 1  ) return m2;
+  if (3.0*h < 2.0) return (m1+(m2-m1)*((2.0/3.0)-h)*6.0);
+  return m1;
+}
+
+guint
+hls_to_rgb(const double H, const double L, const double S )
+{
+  double r,g,b;
+  double m1, m2;
+
+  if (S==0) r=g=b=L;
+  else {
+    if (L <=0.5) m2 = L*(1.0+S);
+    else         m2 = L+S-L*S;
+    m1 = 2.0*L-m2;
+    r = hue_to_rgb(m1,m2,H+1.0/3.0);
+    g = hue_to_rgb(m1,m2,H);
+    b = hue_to_rgb(m1,m2,H-1.0/3.0);
+  }
+  return ( intcolor(r) << 16 ) | (intcolor(g) << 8) | (intcolor(b));
+}
+
+void
+rgba_to_hls( const guint rgba, double *H, double *L, double *S )
+{
+  double delta;
+  double r = ( ( ( rgba >> 24 ) & 0xff ) + .5 ) / 256.0;
+  double g = ( ( ( rgba >> 16 ) & 0xff ) + .5 ) / 256.0;
+  double b = ( ( ( rgba >>  8 ) & 0xff ) + .5 ) / 256.0;
+  double cmax;
+  double cmin;
+
+  cmax = (r > g) ? r : g; if( b > cmax ) cmax = b;
+  cmin = (r < g) ? r : g; if( b < cmin ) cmin = b;
+
+  *L=(cmax+cmin)/2.0;
+  if(cmax==cmin) *S = *H = 0; // it's really undefined
+  else {
+    if(*L < 0.5)	*S = (cmax-cmin)/(cmax+cmin);
+    else			*S = (cmax-cmin)/(2.0-cmax-cmin);
+    delta = cmax - cmin;
+    if (r==cmax) *H = (g-b)/delta;
+    else 
+      if(g==cmax) *H = 2.0 +(b-r)/delta;
+      else        *H = 4.0+(r-g)/delta;
+    *H /= 6.0;
+    if (*H < 0.0) *H += 1;
+  }
+}
+
+guint
+rgba_invert_color( guint c )
+{
+  double h, l, s;
+  guint inv;
+
+  rgba_to_hls( c, &h, &l, &s );
+  inv = (hls_to_rgb( h, 1.0-l, s ) << 8) | (c & 0xff);
+
+  return inv;
+}
+
+void
+on_invert_colors_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data)
+{
+  GList *pagelist, *layerlist, *itemlist;
+  struct Page *pg;
+  struct Layer *layer;
+  struct Item *item;
+
+  // NOTE: If it wasn't for color_no of all colors, we could simply store undo
+  // info by "redoing" an invert journal. Unfortunately, info on color_no
+  // (necessarily) gets lost when inverting colors, so we can't do this (or risk
+  // possible side effects).
+  for (pagelist = journal.pages; pagelist!=NULL; pagelist = pagelist->next) {
+    pg = (struct Page *)pagelist->data;
+
+    // First set MULTIOP_CONT_REDO if the undo info was generated by this
+    // function.
+    if (pagelist->prev!=NULL) undo->multiop |= MULTIOP_CONT_REDO;
+
+    // Now prepare undo info for page background.
+    prepare_new_undo();
+    if (pagelist->prev!=NULL) undo->multiop |= MULTIOP_CONT_UNDO;
+    undo->type = ITEM_NEW_BG_ONE;
+    undo->page = pg;
+    undo->bg = (struct Background *)g_memdup(pg->bg, sizeof(struct Background));
+    undo->bg->canvas_item = NULL;
+
+    // Invert page/ruling colors. NOTE: Color names are lost when inverting. We
+    // can search against predef_bgcolors_rgba etc., but that only wastes CPU
+    // cycles.
+    INVERT_COLOR (pg->bg->color_rgba);
+    pg->bg->color_no = -1;
+    INVERT_COLOR (pg->bg->ruling_margin_color);
+    INVERT_COLOR (pg->bg->ruling_color);
+
+    update_canvas_bg(pg);
+
+    for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) {
+      layer = (struct Layer *)layerlist->data;
+
+      if (layer->items!=NULL) {
+	// Current undo item is necessarily generated by this function. Set
+	// MULTIOP_CONT_REDO.
+	undo->multiop |= MULTIOP_CONT_REDO;
+
+	// Now prepare undo information for items on this page.
+	prepare_new_undo();
+	undo->multiop |= MULTIOP_CONT_UNDO;
+	undo->type = ITEM_REPAINTSEL;
+	undo->itemlist = NULL;
+	undo->auxlist = NULL;
+
+	for (itemlist = layer->items; itemlist!=NULL; itemlist = itemlist->next)
+	{
+	  struct Brush *brush;
+
+	  item = (struct Item *)itemlist->data;
+
+	  // Store undo info for this stroke (as in recolor_selection())
+	  undo->itemlist = g_list_append(undo->itemlist, item);
+	  brush = (struct Brush *)g_malloc(sizeof(struct Brush));
+	  g_memmove(brush, &(item->brush), sizeof(struct Brush));
+	  undo->auxlist = g_list_append(undo->auxlist, brush);
+
+	  // Invert colors for this stroke.
+	  INVERT_COLOR( item->brush.color_rgba );
+	  item->brush.color_no = -1;
+	  if (item->canvas_item!=NULL) {
+	    if (!item->brush.variable_width)
+	      gnome_canvas_item_set(item->canvas_item, 
+		  "fill-color-rgba", item->brush.color_rgba, NULL);
+	    else {
+	      GnomeCanvasGroup *group;
+
+	      group = (GnomeCanvasGroup *) item->canvas_item->parent;
+	      gtk_object_destroy(GTK_OBJECT(item->canvas_item));
+	      make_canvas_item_one(group, item);
+	    }
+	  } /* if (item->canvas_item...) */
+	} /* for (itemlist...) */
+      } /* if (layer->items!=NULL) */
+    } /* for (layerlist...) */
+  } /* for (pagelist...) */
+}
diff --git a/src/xo-callbacks.h b/src/xo-callbacks.h
index d3d173e..f6b9e22 100644
--- a/src/xo-callbacks.h
+++ b/src/xo-callbacks.h
@@ -497,7 +497,7 @@ on_optionsProgressiveBG_activate       (GtkMenuItem     *menuitem,
                                         gpointer         user_data);
 
 void
-on_mru_activate                        (GtkMenuItem     *menuitem,
+on_mru_activate                        (GtkRecentChooser *recentChooser,
                                         gpointer         user_data);
 
 void
@@ -648,3 +648,23 @@ on_buttonColorChooser_set              (GtkColorButton  *colorbutton,
 void
 on_optionsButtonsSwitchMappings_activate(GtkMenuItem    *menuitem,
                                         gpointer         user_data);
+
+void
+on_journalRulingParams_activate        (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_invert_colors_activate              (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_toolsImage_activate                 (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_button2Image_activate               (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
+
+void
+on_button3Image_activate               (GtkMenuItem     *menuitem,
+                                        gpointer         user_data);
diff --git a/src/xo-clipboard.c b/src/xo-clipboard.c
new file mode 100644
index 0000000..3aa3653
--- /dev/null
+++ b/src/xo-clipboard.c
@@ -0,0 +1,304 @@
+/*
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of  
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <string.h>
+#include <gtk/gtk.h>
+
+#include "xournal.h"
+#include "xo-callbacks.h"
+#include "xo-interface.h"
+#include "xo-support.h"
+#include "xo-misc.h"
+#include "xo-paint.h"
+#include "xo-image.h"
+
+
+void callback_clipboard_get(GtkClipboard *clipboard,
+                            GtkSelectionData *selection_data,
+                            guint info, gpointer user_data)
+{
+  int length;
+  
+  g_memmove(&length, user_data, sizeof(int));
+  gtk_selection_data_set(selection_data,
+     gdk_atom_intern("_XOURNAL", FALSE), 8, user_data, length);
+}
+
+void callback_clipboard_clear(GtkClipboard *clipboard, gpointer user_data)
+{
+  g_free(user_data);
+}
+
+void selection_to_clip(void)
+{
+  int bufsz, nitems, val;
+  char *buf, *p;
+  GList *list;
+  struct Item *item;
+  GtkTargetEntry target;
+  
+  if (ui.selection == NULL) return;
+  bufsz = 2*sizeof(int) // bufsz, nitems
+        + sizeof(struct BBox); // bbox
+  nitems = 0;
+  for (list = ui.selection->items; list != NULL; list = list->next) {
+    item = (struct Item *)list->data;
+    nitems++;
+    if (item->type == ITEM_STROKE) {
+      bufsz+= sizeof(int) // type
+            + sizeof(struct Brush) // brush
+            + sizeof(int) // num_points
+            + 2*item->path->num_points*sizeof(double); // the points
+      if (item->brush.variable_width)
+        bufsz += (item->path->num_points-1)*sizeof(double); // the widths
+    }
+    else if (item->type == ITEM_TEXT) {
+      bufsz+= sizeof(int) // type
+            + sizeof(struct Brush) // brush
+            + 2*sizeof(double) // bbox upper-left
+            + sizeof(int) // text len
+            + strlen(item->text)+1 // text
+            + sizeof(int) // font_name len
+            + strlen(item->font_name)+1 // font_name
+            + sizeof(double); // font_size
+    }
+    else if (item->type == ITEM_IMAGE) {
+      if (item->image_png == NULL) {
+        set_cursor_busy(TRUE);
+        if (!gdk_pixbuf_save_to_buffer(item->image, &item->image_png, &item->image_png_len, "png", NULL, NULL))
+          item->image_png_len = 0;       // failed for some reason, so forget it
+        set_cursor_busy(FALSE);
+      }
+      bufsz+= sizeof(int) // type
+        + sizeof(struct BBox)
+        + sizeof(gsize) // png_buflen
+        + item->image_png_len;
+    }
+    else bufsz+= sizeof(int); // type
+  }
+  p = buf = g_malloc(bufsz);
+  g_memmove(p, &bufsz, sizeof(int)); p+= sizeof(int);
+  g_memmove(p, &nitems, sizeof(int)); p+= sizeof(int);
+  g_memmove(p, &ui.selection->bbox, sizeof(struct BBox)); p+= sizeof(struct BBox);
+  for (list = ui.selection->items; list != NULL; list = list->next) {
+    item = (struct Item *)list->data;
+    g_memmove(p, &item->type, sizeof(int)); p+= sizeof(int);
+    if (item->type == ITEM_STROKE) {
+      g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
+      g_memmove(p, &item->path->num_points, sizeof(int)); p+= sizeof(int);
+      g_memmove(p, item->path->coords, 2*item->path->num_points*sizeof(double));
+      p+= 2*item->path->num_points*sizeof(double);
+      if (item->brush.variable_width) {
+        g_memmove(p, item->widths, (item->path->num_points-1)*sizeof(double));
+        p+= (item->path->num_points-1)*sizeof(double);
+      }
+    }
+    if (item->type == ITEM_TEXT) {
+      g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
+      g_memmove(p, &item->bbox.left, sizeof(double)); p+= sizeof(double);
+      g_memmove(p, &item->bbox.top, sizeof(double)); p+= sizeof(double);
+      val = strlen(item->text);
+      g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
+      g_memmove(p, item->text, val+1); p+= val+1;
+      val = strlen(item->font_name);
+      g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
+      g_memmove(p, item->font_name, val+1); p+= val+1;
+      g_memmove(p, &item->font_size, sizeof(double)); p+= sizeof(double);
+    }
+    if (item->type == ITEM_IMAGE) {
+      g_memmove(p, &item->bbox, sizeof(struct BBox)); p+= sizeof(struct BBox);
+      g_memmove(p, &item->image_png_len, sizeof(gsize)); p+= sizeof(gsize);
+      if (item->image_png_len > 0) {
+        g_memmove(p, item->image_png, item->image_png_len); p+= item->image_png_len;
+      }
+    }
+  }
+  
+  target.target = "_XOURNAL";
+  target.flags = 0;
+  target.info = 0;
+  
+  gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), 
+       &target, 1,
+       callback_clipboard_get, callback_clipboard_clear, buf);
+}
+
+// local paste within xournal
+void clipboard_paste_from_xournal(GtkSelectionData *sel_data)
+{
+  unsigned char *p;
+  int nitems, npts, i, len;
+  struct Item *item;
+  double hoffset, voffset, cx, cy;
+  double *pf;
+  int sx, sy, wx, wy;
+  
+  reset_selection();
+  
+  ui.selection = g_new(struct Selection, 1);
+  p = sel_data->data + sizeof(int);
+  g_memmove(&nitems, p, sizeof(int)); p+= sizeof(int);
+  ui.selection->type = ITEM_SELECTRECT;
+  ui.selection->layer = ui.cur_layer;
+  g_memmove(&ui.selection->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
+  ui.selection->items = NULL;
+  
+  // find by how much we translate the pasted selection
+  gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
+  gdk_window_get_geometry(GTK_WIDGET(canvas)->window, NULL, NULL, &wx, &wy, NULL);
+  gnome_canvas_window_to_world(canvas, sx + wx/2, sy + wy/2, &cx, &cy);
+  cx -= ui.cur_page->hoffset;
+  cy -= ui.cur_page->voffset;
+  if (cx + (ui.selection->bbox.right-ui.selection->bbox.left)/2 > ui.cur_page->width)
+    cx = ui.cur_page->width - (ui.selection->bbox.right-ui.selection->bbox.left)/2;
+  if (cx - (ui.selection->bbox.right-ui.selection->bbox.left)/2 < 0)
+    cx = (ui.selection->bbox.right-ui.selection->bbox.left)/2;
+  if (cy + (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 > ui.cur_page->height)
+    cy = ui.cur_page->height - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
+  if (cy - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 < 0)
+    cy = (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
+  hoffset = cx - (ui.selection->bbox.right+ui.selection->bbox.left)/2;
+  voffset = cy - (ui.selection->bbox.top+ui.selection->bbox.bottom)/2;
+  ui.selection->bbox.left += hoffset;
+  ui.selection->bbox.right += hoffset;
+  ui.selection->bbox.top += voffset;
+  ui.selection->bbox.bottom += voffset;
+
+  ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
+      gnome_canvas_rect_get_type(), "width-pixels", 1,
+      "outline-color-rgba", 0x000000ff,
+      "fill-color-rgba", 0x80808040,
+      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, 
+      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
+  make_dashed(ui.selection->canvas_item);
+
+  while (nitems-- > 0) {
+    item = g_new(struct Item, 1);
+    ui.selection->items = g_list_append(ui.selection->items, item);
+    ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
+    ui.cur_layer->nitems++;
+    g_memmove(&item->type, p, sizeof(int)); p+= sizeof(int);
+    if (item->type == ITEM_STROKE) {
+      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
+      g_memmove(&npts, p, sizeof(int)); p+= sizeof(int);
+      item->path = gnome_canvas_points_new(npts);
+      pf = (double *)p;
+      for (i=0; i<npts; i++) {
+        item->path->coords[2*i] = pf[2*i] + hoffset;
+        item->path->coords[2*i+1] = pf[2*i+1] + voffset;
+      }
+      p+= 2*item->path->num_points*sizeof(double);
+      if (item->brush.variable_width) {
+        item->widths = g_memdup(p, (item->path->num_points-1)*sizeof(double));
+        p+= (item->path->num_points-1)*sizeof(double);
+      }
+      else item->widths = NULL;
+      update_item_bbox(item);
+      make_canvas_item_one(ui.cur_layer->group, item);
+    }
+    if (item->type == ITEM_TEXT) {
+      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
+      g_memmove(&item->bbox.left, p, sizeof(double)); p+= sizeof(double);
+      g_memmove(&item->bbox.top, p, sizeof(double)); p+= sizeof(double);
+      item->bbox.left += hoffset;
+      item->bbox.top += voffset;
+      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
+      item->text = g_malloc(len+1);
+      g_memmove(item->text, p, len+1); p+= len+1;
+      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
+      item->font_name = g_malloc(len+1);
+      g_memmove(item->font_name, p, len+1); p+= len+1;
+      g_memmove(&item->font_size, p, sizeof(double)); p+= sizeof(double);
+      make_canvas_item_one(ui.cur_layer->group, item);
+    }
+    if (item->type == ITEM_IMAGE) {
+      item->canvas_item = NULL;
+      item->image_png = NULL;
+      item->image_png_len = 0;
+      g_memmove(&item->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
+      item->bbox.left += hoffset;
+      item->bbox.right += hoffset;
+      item->bbox.top += voffset;
+      item->bbox.bottom += voffset;
+      g_memmove(&item->image_png_len, p, sizeof(gsize)); p+= sizeof(gsize);
+      if (item->image_png_len > 0) {
+        item->image_png = g_memdup(p, item->image_png_len);
+        item->image = pixbuf_from_buffer(item->image_png, item->image_png_len);
+        p+= item->image_png_len;
+      } else {
+        item->image = NULL;
+      }
+      make_canvas_item_one(ui.cur_layer->group, item);
+    }
+  }
+
+  prepare_new_undo();
+  undo->type = ITEM_PASTE;
+  undo->layer = ui.cur_layer;
+  undo->itemlist = g_list_copy(ui.selection->items);  
+  
+  gtk_selection_data_free(sel_data);
+  update_copy_paste_enabled();
+  update_color_menu();
+  update_thickness_buttons();
+  update_color_buttons();
+  update_font_button();  
+  update_cursor(); // FIXME: can't know if pointer is within selection!
+}
+
+// paste an external image
+void clipboard_paste_image(GdkPixbuf *pixbuf)
+{
+  double pt[2];
+
+  reset_selection();
+
+  get_current_pointer_coords(pt);
+  set_current_page(pt);  
+
+  create_image_from_pixbuf(pixbuf, pt);
+}
+
+// work out what format the clipboard data is in, and paste accordingly
+void clipboard_paste(void)
+{
+  GtkSelectionData *sel_data;
+  GtkClipboard *clipboard;
+  GdkPixbuf *pixbuf;
+
+  if (ui.cur_layer == NULL) return;
+  
+  ui.cur_item_type = ITEM_PASTE;
+  clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
+  // try xournal data
+  sel_data = gtk_clipboard_wait_for_contents(
+      clipboard,
+      gdk_atom_intern("_XOURNAL", FALSE));
+  ui.cur_item_type = ITEM_NONE;
+  if (sel_data != NULL) { 
+    clipboard_paste_from_xournal(sel_data);
+    return;
+  } 
+  // try image data
+  pixbuf = gtk_clipboard_wait_for_image(clipboard);
+  if (pixbuf != NULL) {
+    clipboard_paste_image(pixbuf);
+    return;
+  }
+}
diff --git a/src/xo-clipboard.h b/src/xo-clipboard.h
new file mode 100644
index 0000000..4007fa5
--- /dev/null
+++ b/src/xo-clipboard.h
@@ -0,0 +1,17 @@
+/*
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of  
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+void selection_to_clip(void);
+void clipboard_paste(void);
diff --git a/src/xo-file.c b/src/xo-file.c
index 81ce156..c0e74e1 100644
--- a/src/xo-file.c
+++ b/src/xo-file.c
@@ -43,8 +43,9 @@
 #include "xo-misc.h"
 #include "xo-file.h"
 #include "xo-paint.h"
+#include "xo-image.h"
 
-const char *tool_names[NUM_TOOLS] = {"pen", "eraser", "highlighter", "text", "", "selectrect", "vertspace", "hand"};
+const char *tool_names[NUM_TOOLS] = {"pen", "eraser", "highlighter", "text", "", "selectrect", "vertspace", "hand", "image"};
 const char *color_names[COLOR_MAX] = {"black", "blue", "red", "green",
    "gray", "lightblue", "lightgreen", "magenta", "orange", "yellow", "white"};
 const char *bgtype_names[3] = {"solid", "pixmap", "pdf"};
@@ -86,6 +87,47 @@ void chk_attach_names(void)
   }
 }
 
+/* Write image to file: returns true on success, false on error.
+   The image is written as a base64 encoded PNG. */
+
+gboolean write_image(gzFile f, Item *item)
+{
+  gchar *base64_str;
+
+  if (item->image_png == NULL) {
+    if (!gdk_pixbuf_save_to_buffer(item->image, &item->image_png, &item->image_png_len, "png", NULL, NULL)) {
+      item->image_png_len = 0;       // failed for some reason, so forget it
+      return FALSE;
+    }
+  }
+
+  base64_str = g_base64_encode(item->image_png, item->image_png_len);
+  gzputs(f, base64_str);
+  g_free(base64_str);
+  return TRUE;
+}
+
+// create pixbuf from base64 encoded PNG, or return NULL on failure
+
+GdkPixbuf *read_pixbuf(const gchar *base64_str, gsize base64_strlen)
+{
+  gchar *base64_str2;
+  gchar *png_buf;
+  gsize png_buflen;
+  GdkPixbuf *pixbuf;
+
+  // We have to copy the string in order to null terminate it, sigh.
+  base64_str2 = g_memdup(base64_str, base64_strlen+1);
+  base64_str2[base64_strlen] = 0;
+  png_buf = g_base64_decode(base64_str2, &png_buflen);
+
+  pixbuf = pixbuf_from_buffer(png_buf, png_buflen);
+
+  g_free(png_buf);
+  g_free(base64_str2);
+  return pixbuf;
+}
+
 // saves the journal to a file: returns true on success, false on error
 
 gboolean save_journal(const char *filename)
@@ -183,6 +225,7 @@ gboolean save_journal(const char *filename)
       gzprintf(f, "pageno=\"%d\" ", pg->bg->file_page_seq);
     }
     gzprintf(f, "/>\n");
+    gzprintf(f, "<rulingstyle margin_color=\"#%08x\" color=\"#%08x\" thickness=\"%f\" leftmargin=\"%f\" topmargin=\"%f\" spacing=\"%f\" bottommargin=\"%f\" graphspacing=\"%f\" />\n", pg->bg->ruling_margin_color, pg->bg->ruling_color, pg->bg->ruling_thickness, pg->bg->ruling_leftmargin, pg->bg->ruling_topmargin, pg->bg->ruling_spacing, pg->bg->ruling_bottommargin, pg->bg->ruling_graphspacing);
     for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) {
       layer = (struct Layer *)layerlist->data;
       gzprintf(f, "<layer>\n");
@@ -219,6 +262,12 @@ gboolean save_journal(const char *filename)
           gzputs(f, "</text>\n");
           g_free(tmpstr);
         }
+        if (item->type == ITEM_IMAGE) {
+          gzprintf(f, "<image left=\"%.2f\" top=\"%.2f\" right=\"%.2f\" bottom=\"%.2f\">", 
+            item->bbox.left, item->bbox.top, item->bbox.right, item->bbox.bottom);
+          if (!write_image(f, item)) success = FALSE;
+          gzprintf(f, "</image>\n");
+        }
       }
       gzprintf(f, "</layer>\n");
     }
@@ -310,6 +359,19 @@ void xoj_parser_start_element(GMarkupParseContext *context,
     tmpPage->bg->canvas_item = NULL;
     tmpPage->bg->pixbuf = NULL;
     tmpPage->bg->filename = NULL;
+
+    // When loading journals which don't have the <rulingstyle ...> tag, we
+    // should use the compiled in defaults from xournal-0.4.5 for backward
+    // compatibility.
+    tmpPage->bg->ruling_margin_color = RULING_MARGIN_COLOR;
+    tmpPage->bg->ruling_color = RULING_COLOR;
+    tmpPage->bg->ruling_thickness = RULING_THICKNESS;
+    tmpPage->bg->ruling_leftmargin = RULING_LEFTMARGIN;
+    tmpPage->bg->ruling_topmargin = RULING_TOPMARGIN;
+    tmpPage->bg->ruling_spacing = RULING_SPACING;
+    tmpPage->bg->ruling_bottommargin = RULING_BOTTOMMARGIN;
+    tmpPage->bg->ruling_graphspacing = RULING_GRAPHSPACING;
+
     tmpJournal.pages = g_list_append(tmpJournal.pages, tmpPage);
     tmpJournal.npages++;
     // scan for height and width attributes
@@ -453,6 +515,62 @@ void xoj_parser_start_element(GMarkupParseContext *context,
     if (tmpPage->bg->type == BG_PIXMAP && has_attr != 25) *error = xoj_invalid();
     if (tmpPage->bg->type == BG_PDF && has_attr != 57) *error = xoj_invalid();
   }
+  else if (!strcmp(element_name, "rulingstyle")) {
+    // TODO: Check if we're inside a background element.
+    if (tmpPage == NULL || tmpLayer !=NULL) {
+      *error = xoj_invalid();
+      return;
+    }
+    while (*attribute_names!=NULL) {
+      if (!strcmp(*attribute_names, "margin_color")) {
+        if (**attribute_values == '#') {
+          tmpPage->bg->ruling_margin_color = strtoul(*attribute_values + 1, &ptr, 16);
+          if (*ptr!=0) *error = xoj_invalid();
+        }
+	else *error = xoj_invalid();
+      }
+      else if (!strcmp(*attribute_names, "color")) {
+        if (**attribute_values == '#') {
+          tmpPage->bg->ruling_color = strtoul(*attribute_values + 1, &ptr, 16);
+          if (*ptr!=0) *error = xoj_invalid();
+        }
+	else *error = xoj_invalid();
+      }
+      else if (!strcmp(*attribute_names, "thickness")) {
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpPage->bg->ruling_thickness = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+      }
+      else if (!strcmp(*attribute_names, "leftmargin")) {
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpPage->bg->ruling_leftmargin = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+      }
+      else if (!strcmp(*attribute_names, "topmargin")) {
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpPage->bg->ruling_topmargin = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+      }
+      else if (!strcmp(*attribute_names, "spacing")) {
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpPage->bg->ruling_spacing = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+      }
+      else if (!strcmp(*attribute_names, "bottommargin")) {
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpPage->bg->ruling_bottommargin = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+      }
+      else if (!strcmp(*attribute_names, "graphspacing")) {
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpPage->bg->ruling_graphspacing = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+      }
+      else *error = xoj_invalid();
+      attribute_names++;
+      attribute_values++;
+    }
+  }
   else if (!strcmp(element_name, "layer")) { // start of a layer
     if (tmpPage == NULL || tmpLayer != NULL) {
       *error = xoj_invalid();
@@ -601,6 +719,56 @@ void xoj_parser_start_element(GMarkupParseContext *context,
     }
     if (has_attr!=31) *error = xoj_invalid();
   }
+  else if (!strcmp(element_name, "image")) { // start of a image item
+    if (tmpLayer == NULL || tmpItem != NULL) {
+      *error = xoj_invalid();
+      return;
+    }
+    tmpItem = (struct Item *)g_malloc0(sizeof(struct Item));
+    tmpItem->type = ITEM_IMAGE;
+    tmpItem->canvas_item = NULL;
+    tmpItem->image=NULL;
+    tmpItem->image_png = NULL;
+    tmpItem->image_png_len = 0;
+    tmpLayer->items = g_list_append(tmpLayer->items, tmpItem);
+    tmpLayer->nitems++;
+    // scan for x, y
+    has_attr = 0;
+    while (*attribute_names!=NULL) {
+      if (!strcmp(*attribute_names, "left")) {
+        if (has_attr & 1) *error = xoj_invalid();
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpItem->bbox.left = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+        has_attr |= 1;
+      }
+      else if (!strcmp(*attribute_names, "top")) {
+        if (has_attr & 2) *error = xoj_invalid();
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpItem->bbox.top = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+        has_attr |= 2;
+      }
+      else if (!strcmp(*attribute_names, "right")) {
+        if (has_attr & 4) *error = xoj_invalid();
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpItem->bbox.right = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+        has_attr |= 4;
+      }
+      else if (!strcmp(*attribute_names, "bottom")) {
+        if (has_attr & 8) *error = xoj_invalid();
+        cleanup_numeric((gchar *)*attribute_values);
+        tmpItem->bbox.bottom = g_ascii_strtod(*attribute_values, &ptr);
+        if (ptr == *attribute_values) *error = xoj_invalid();
+        has_attr |= 8;
+      }
+      else *error = xoj_invalid();
+      attribute_names++;
+      attribute_values++;
+    }
+    if (has_attr!=15) *error = xoj_invalid();
+  }
 }
 
 void xoj_parser_end_element(GMarkupParseContext *context,
@@ -636,6 +804,13 @@ void xoj_parser_end_element(GMarkupParseContext *context,
     }
     tmpItem = NULL;
   }
+  if (!strcmp(element_name, "image")) {
+    if (tmpItem == NULL) {
+      *error = xoj_invalid();
+      return;
+    }
+    tmpItem = NULL;
+  }
 }
 
 void xoj_parser_text(GMarkupParseContext *context,
@@ -673,6 +848,9 @@ void xoj_parser_text(GMarkupParseContext *context,
     g_memmove(tmpItem->text, text, text_len);
     tmpItem->text[text_len]=0;
   }
+  if (!strcmp(element_name, "image")) {
+    tmpItem->image = read_pixbuf(text, text_len);
+  }
 }
 
 gboolean user_wants_second_chance(char **filename)
@@ -1259,109 +1437,66 @@ void bgpdf_update_bg(int pageno, struct BgPdfPage *bgpg)
   }
 }
 
-// initialize the recent files list
+// initialize GtkRecentManager. Also backwards compatibility: import recent files into GtkRecentManager
 void init_mru(void)
 {
-  int i;
+  GtkRecentFilter *recentFilter = gtk_recent_filter_new ();
+  gtk_recent_filter_add_application ( recentFilter, "xournal");
+  gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (GET_COMPONENT("fileRecentFiles_menu")), recentFilter);
+
   gsize lfptr;
-  char s[5];
   GIOChannel *f;
-  gchar *str;
+  gchar *str, *uri;
   GIOStatus status;
+  GtkRecentManager *recentManager = gtk_recent_manager_get_default ();
   
-  g_strlcpy(s, "mru0", 5);
-  for (s[3]='0', i=0; i<MRU_SIZE; s[3]++, i++) {
-    ui.mrumenu[i] = GET_COMPONENT(s);
-    ui.mru[i] = NULL;
-  }
   f = g_io_channel_new_file(ui.mrufile, "r", NULL);
   if (f) status = G_IO_STATUS_NORMAL;
   else status = G_IO_STATUS_ERROR;
-  i = 0;
-  while (status == G_IO_STATUS_NORMAL && i<MRU_SIZE) {
+  while (status == G_IO_STATUS_NORMAL) {
     lfptr = 0;
     status = g_io_channel_read_line(f, &str, NULL, &lfptr, NULL);
     if (status == G_IO_STATUS_NORMAL && lfptr>0) {
       str[lfptr] = 0;
-      ui.mru[i] = str;
-      i++;
+      uri = g_filename_to_uri (str, NULL, NULL);
+      gtk_recent_manager_add_item (recentManager, uri);
+      g_free(uri);
+      g_free(str);
     }
   }
   if (f) {
     g_io_channel_shutdown(f, FALSE, NULL);
     g_io_channel_unref(f);
   }
-  update_mru_menu();
-}
-
-void update_mru_menu(void)
-{
-  int i;
-  gboolean anyone = FALSE;
-  gchar *tmp;
   
-  for (i=0; i<MRU_SIZE; i++) {
-    if (ui.mru[i]!=NULL) {
-      tmp = g_strdup_printf("_%d %s", i+1,
-               g_strjoinv("__", g_strsplit_set(g_basename(ui.mru[i]),"_",-1)));
-      gtk_label_set_text_with_mnemonic(GTK_LABEL(gtk_bin_get_child(GTK_BIN(ui.mrumenu[i]))),
-          tmp);
-      g_free(tmp);
-      gtk_widget_show(ui.mrumenu[i]);
-      anyone = TRUE;
-    }
-    else gtk_widget_hide(ui.mrumenu[i]);
-  }
-  gtk_widget_set_sensitive(GET_COMPONENT("fileRecentFiles"), anyone);
+  g_unlink (ui.mrufile);
 }
 
 void new_mru_entry(char *name)
 {
-  int i, j;
-  
-  for (i=0;i<MRU_SIZE;i++) 
-    if (ui.mru[i]!=NULL && !strcmp(ui.mru[i], name)) {
-      g_free(ui.mru[i]);
-      for (j=i+1; j<MRU_SIZE; j++) ui.mru[j-1] = ui.mru[j];
-      ui.mru[MRU_SIZE-1]=NULL;
-    }
-  if (ui.mru[MRU_SIZE-1]!=NULL) g_free(ui.mru[MRU_SIZE-1]);
-  for (j=MRU_SIZE-1; j>=1; j--) ui.mru[j] = ui.mru[j-1];
-  ui.mru[0] = g_strdup(name);
-  update_mru_menu();
-}
-
-void delete_mru_entry(int which)
-{
-  int i;
-  
-  if (ui.mru[which]!=NULL) g_free(ui.mru[which]);
-  for (i=which+1;i<MRU_SIZE;i++) 
-    ui.mru[i-1] = ui.mru[i];
-  ui.mru[MRU_SIZE-1] = NULL;
-  update_mru_menu();
+  gchar *uri = g_filename_to_uri (name, NULL, NULL);
+  gtk_recent_manager_add_item (gtk_recent_manager_get_default(), uri);
+  g_free(uri);
 }
 
-void save_mru_list(void)
+void delete_mru_entry(char *name)
 {
-  FILE *f;
-  int i;
-  
-  f = fopen(ui.mrufile, "w");
-  if (f==NULL) return;
-  for (i=0; i<MRU_SIZE; i++)
-    if (ui.mru[i]!=NULL) fprintf(f, "%s\n", ui.mru[i]);
-  fclose(f);
+  gchar *uri = g_filename_to_uri(name, NULL, NULL);
+  gtk_recent_manager_remove_item(gtk_recent_manager_get_default(), uri, NULL);
+  g_free(uri);
 }
 
 void init_config_default(void)
 {
   int i, j;
-
+  GtkPaperSize *size;
   DEFAULT_ZOOM = DISPLAY_DPI_DEFAULT/72.0;
   ui.zoom = ui.startup_zoom = 1.0*DEFAULT_ZOOM;
-  ui.default_page.height = 792.0;
-  ui.default_page.width = 612.0;
+  // passing NULL gives system's default paper size
+  size = gtk_paper_size_new (NULL);
+  ui.default_page.height = gtk_paper_size_get_height (size,GTK_UNIT_POINTS);
+  ui.default_page.width = gtk_paper_size_get_width (size,GTK_UNIT_POINTS);
+  gtk_paper_size_free(size);
   ui.default_page.bg->type = BG_SOLID;
   ui.default_page.bg->color_no = COLOR_WHITE;
   ui.default_page.bg->color_rgba = predef_bgcolors_rgba[COLOR_WHITE];
@@ -1384,8 +1519,17 @@ void init_config_default(void)
   ui.zoom_step_factor = 1.5;
   ui.progressive_bg = TRUE;
   ui.print_ruling = TRUE;
+  ui.default_page.bg->ruling_margin_color = RULING_MARGIN_COLOR;
+  ui.default_page.bg->ruling_color = RULING_COLOR;
+  ui.default_page.bg->ruling_thickness = RULING_THICKNESS;
+  ui.default_page.bg->ruling_leftmargin = RULING_LEFTMARGIN;
+  ui.default_page.bg->ruling_topmargin = RULING_TOPMARGIN;
+  ui.default_page.bg->ruling_spacing = RULING_SPACING;
+  ui.default_page.bg->ruling_bottommargin = RULING_SPACING;
+  ui.default_page.bg->ruling_graphspacing = RULING_GRAPHSPACING;
   ui.default_unit = UNIT_CM;
   ui.default_path = NULL;
+  ui.default_image = NULL;
   ui.default_font_name = g_strdup(DEFAULT_FONT);
   ui.default_font_size = DEFAULT_FONT_SIZE;
   ui.pressure_sensitivity = FALSE;
@@ -1580,6 +1724,30 @@ void save_config_to_file(void)
   update_keyval("paper", "style",
     _(" the default paper style (plain, lined, ruled, or graph)"),
     g_strdup(bgstyle_names[ui.default_page.bg->ruling]));
+  update_keyval("paper", "ruling_margin_color",
+    _(" default ruling margin color"),
+    g_strdup_printf("#%08x", ui.default_page.bg->ruling_margin_color));
+  update_keyval("paper", "ruling_color",
+    _(" default ruling color"),
+    g_strdup_printf("#%08x", ui.default_page.bg->ruling_color));
+  update_keyval("paper", "ruling_thickness",
+    _(" default ruling thickness"),
+    g_strdup_printf("%.3f", ui.default_page.bg->ruling_thickness));
+  update_keyval("paper", "ruling_leftmargin",
+    _(" default ruling left margin"),
+    g_strdup_printf("%.3f", ui.default_page.bg->ruling_leftmargin));
+  update_keyval("paper", "ruling_topmargin",
+    _(" default ruling top margin"),
+    g_strdup_printf("%.3f", ui.default_page.bg->ruling_topmargin));
+  update_keyval("paper", "ruling_spacing",
+    _(" default ruling spacing"),
+    g_strdup_printf("%.3f", ui.default_page.bg->ruling_spacing));
+  update_keyval("paper", "ruling_bottommargin",
+    _(" default ruling bottom margin"),
+    g_strdup_printf("%.3f", ui.default_page.bg->ruling_bottommargin));
+  update_keyval("paper", "ruling_graphspacing",
+    _(" default ruling graph spacing"),
+    g_strdup_printf("%.3f", ui.default_page.bg->ruling_graphspacing));
   update_keyval("paper", "apply_all",
     _(" apply paper style changes to all pages (true/false)"),
     g_strdup(ui.bg_apply_all_pages?"true":"false"));
@@ -1881,6 +2049,7 @@ void load_config_from_file(void)
   gboolean b;
   int i, j;
   gchar *str;
+  int discard_colorno;
   
 #if GLIB_CHECK_VERSION(2,6,0)
   // no support for keyval files before Glib 2.6.0
@@ -1937,6 +2106,14 @@ void load_config_from_file(void)
      &(ui.default_page.bg->color_no), &(ui.default_page.bg->color_rgba), 
      bgcolor_names, predef_bgcolors_rgba, COLOR_MAX);
   parse_keyval_enum("paper", "style", &(ui.default_page.bg->ruling), bgstyle_names, 4);
+  parse_keyval_enum_color("paper", "ruling_margin_color", &discard_colorno, &ui.default_page.bg->ruling_margin_color, color_names, predef_colors_rgba, COLOR_MAX);
+  parse_keyval_enum_color("paper", "ruling_color", &discard_colorno, &ui.default_page.bg->ruling_color, color_names, predef_colors_rgba, COLOR_MAX);
+  parse_keyval_float("paper", "ruling_thickness", &ui.default_page.bg->ruling_thickness, RULING_THICKNESS_MIN, RULING_THICKNESS_MAX );
+  parse_keyval_float("paper", "ruling_leftmargin", &ui.default_page.bg->ruling_leftmargin, RULING_MARGIN_MIN, RULING_MARGIN_MAX );
+  parse_keyval_float("paper", "ruling_topmargin", &ui.default_page.bg->ruling_topmargin, RULING_MARGIN_MIN, RULING_MARGIN_MAX );
+  parse_keyval_float("paper", "ruling_spacing", &ui.default_page.bg->ruling_spacing, RULING_SPACING_MIN, RULING_SPACING_MAX );
+  parse_keyval_float("paper", "ruling_bottommargin", &ui.default_page.bg->ruling_bottommargin, RULING_MARGIN_MIN, RULING_MARGIN_MAX );
+  parse_keyval_float("paper", "ruling_graphspacing", &ui.default_page.bg->ruling_graphspacing, RULING_SPACING_MIN, RULING_SPACING_MAX );
   parse_keyval_boolean("paper", "apply_all", &ui.bg_apply_all_pages);
   parse_keyval_enum("paper", "default_unit", &ui.default_unit, unit_names, 4);
   parse_keyval_boolean("paper", "progressive_bg", &ui.progressive_bg);
diff --git a/src/xo-file.h b/src/xo-file.h
index 01f7116..fac10db 100644
--- a/src/xo-file.h
+++ b/src/xo-file.h
@@ -43,10 +43,8 @@ void bgpdf_create_page_with_bg(int pageno, struct BgPdfPage *bgpg);
 void bgpdf_update_bg(int pageno, struct BgPdfPage *bgpg);
 
 void init_mru(void);
-void update_mru_menu(void);
 void new_mru_entry(char *name);
-void delete_mru_entry(int which);
-void save_mru_list(void);
+void delete_mru_entry(char *name);
 
 void init_config_default(void);
 void load_config_from_file(void);
diff --git a/src/xo-image.c b/src/xo-image.c
new file mode 100644
index 0000000..884bf23
--- /dev/null
+++ b/src/xo-image.c
@@ -0,0 +1,167 @@
+/*
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of  
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <math.h>
+#include <string.h>
+#include <gtk/gtk.h>
+#include <gio/gio.h>
+
+#include "xournal.h"
+#include "xo-support.h"
+#include "xo-image.h"
+
+// create pixbuf from buffer, or return NULL on failure
+GdkPixbuf *pixbuf_from_buffer(const gchar *buf, gsize buflen)
+{
+  GInputStream *istream;
+  GdkPixbuf *pixbuf;
+  GError *error;
+
+  error = NULL;
+
+  istream = g_memory_input_stream_new_from_data (buf, buflen, NULL);
+  pixbuf = gdk_pixbuf_new_from_stream(istream, NULL, &error); 
+  g_input_stream_close(istream, NULL, &error);
+  return pixbuf;
+}
+
+void create_image_from_pixbuf(GdkPixbuf *pixbuf, double *pt)
+{
+  double scale;
+  struct Item *item;
+
+  item = g_new(struct Item, 1);
+  item->type = ITEM_IMAGE;
+  item->canvas_item = NULL;
+  item->bbox.left = pt[0];
+  item->bbox.top = pt[1];
+  item->image = pixbuf;
+  item->image_png = NULL;
+  item->image_png_len = 0;
+
+  // Scale at native size, unless that won't fit, in which case we shrink it down.
+  scale = 1 / ui.zoom;
+  if ((scale * gdk_pixbuf_get_width(item->image)) > ui.cur_page->width - item->bbox.left)
+    scale = (ui.cur_page->width - item->bbox.left) / gdk_pixbuf_get_width(item->image);
+  if ((scale * gdk_pixbuf_get_height(item->image)) > ui.cur_page->height - item->bbox.top)
+    scale = (ui.cur_page->height - item->bbox.top) / gdk_pixbuf_get_height(item->image);
+
+  item->bbox.right = item->bbox.left + scale * gdk_pixbuf_get_width(item->image);
+  item->bbox.bottom = item->bbox.top + scale * gdk_pixbuf_get_height(item->image);
+  ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
+  ui.cur_layer->nitems++;
+  
+  make_canvas_item_one(ui.cur_layer->group, item);
+
+  // add undo information
+  prepare_new_undo();
+  undo->type = ITEM_IMAGE;
+  undo->item = item;
+  undo->layer = ui.cur_layer;
+  ui.cur_item = NULL;
+  ui.cur_item_type = ITEM_NONE;
+
+  // select image
+  reset_selection();
+  ui.selection = g_new0(struct Selection, 1);
+  ui.selection->type = ITEM_SELECTRECT;
+  ui.selection->layer = ui.cur_layer;
+  ui.selection->bbox = item->bbox;
+  ui.selection->items = g_list_append(ui.selection->items, item);
+  ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
+      gnome_canvas_rect_get_type(), "width-pixels", 1,
+      "outline-color-rgba", 0x000000ff,
+      "fill-color-rgba", 0x80808040,
+      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, 
+      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
+  make_dashed(ui.selection->canvas_item);
+  update_copy_paste_enabled();
+}
+
+void insert_image(GdkEvent *event)
+{
+  GtkTextBuffer *buffer;
+  GnomeCanvasItem *canvas_item;
+  GdkColor color;
+  GtkWidget *dialog;
+  GtkFileFilter *filt_all;
+  GtkFileFilter *filt_gdkimage;
+  char *filename;
+  GdkPixbuf *pixbuf;
+  double scale=1;
+  double pt[2];
+  
+  dialog = gtk_file_chooser_dialog_new(_("Insert Image"), GTK_WINDOW (winMain),
+     GTK_FILE_CHOOSER_ACTION_OPEN, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+     GTK_STOCK_OPEN, GTK_RESPONSE_OK, NULL);
+#ifdef FILE_DIALOG_SIZE_BUGFIX
+  gtk_window_set_default_size(GTK_WINDOW(dialog), 500, 400);
+#endif
+     
+  filt_all = gtk_file_filter_new();
+  gtk_file_filter_set_name(filt_all, _("All files"));
+  gtk_file_filter_add_pattern(filt_all, "*");
+  filt_gdkimage = gtk_file_filter_new();
+  gtk_file_filter_set_name(filt_gdkimage, _("Image files"));
+  gtk_file_filter_add_pixbuf_formats(filt_gdkimage);
+  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_gdkimage);
+  gtk_file_chooser_add_filter(GTK_FILE_CHOOSER (dialog), filt_all);
+
+  if (ui.default_image != NULL) gtk_file_chooser_set_filename(GTK_FILE_CHOOSER (dialog), ui.default_image);
+
+  if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_OK) {
+    gtk_widget_destroy(dialog);
+    return;
+  }
+  filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER (dialog));
+  gtk_widget_destroy(dialog);
+
+  if (filename == NULL) return; /* nothing selected */
+
+  if (ui.default_image != NULL) g_free(ui.default_image);
+  ui.default_image = g_strdup(filename);
+  
+  set_cursor_busy(TRUE);
+  pixbuf=gdk_pixbuf_new_from_file(filename, NULL);
+  set_cursor_busy(FALSE);
+  
+  if(pixbuf==NULL) { /* open failed */
+    dialog = gtk_message_dialog_new(GTK_WINDOW (winMain), GTK_DIALOG_MODAL,
+      GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Error opening image '%s'"), filename);
+    gtk_dialog_run(GTK_DIALOG(dialog));
+    gtk_widget_destroy(dialog);
+    g_free(filename);
+    ui.cur_item = NULL;
+    ui.cur_item_type = ITEM_NONE;
+    return;
+  }
+
+  ui.cur_item_type = ITEM_IMAGE;
+
+  get_pointer_coords(event, pt);
+  set_current_page(pt);  
+
+  create_image_from_pixbuf(pixbuf, pt);
+}
+
+void rescale_images(void)
+{
+  // nothing needed in this implementation
+}
+
diff --git a/src/xo-image.h b/src/xo-image.h
new file mode 100644
index 0000000..e0cb8fa
--- /dev/null
+++ b/src/xo-image.h
@@ -0,0 +1,19 @@
+/*
+ *  This program is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2 of the License, or (at your option) any later version.
+ *
+ *  This software is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of  
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+GdkPixbuf *pixbuf_from_buffer(const gchar *buf, gsize buflen);
+void create_image_from_pixbuf(GdkPixbuf *pixbuf, double *pt);
+void insert_image(GdkEvent *event);
+void rescale_images(void);
diff --git a/src/xo-interface.c b/src/xo-interface.c
index f6022ea..5d74730 100644
--- a/src/xo-interface.c
+++ b/src/xo-interface.c
@@ -43,14 +43,6 @@ create_winMain (void)
   GtkWidget *separator1;
   GtkWidget *fileRecentFiles;
   GtkWidget *fileRecentFiles_menu;
-  GtkWidget *mru0;
-  GtkWidget *mru1;
-  GtkWidget *mru2;
-  GtkWidget *mru3;
-  GtkWidget *mru4;
-  GtkWidget *mru5;
-  GtkWidget *mru6;
-  GtkWidget *mru7;
   GtkWidget *separator22;
   GtkWidget *filePrintOptions;
   GtkWidget *image624;
@@ -108,6 +100,8 @@ create_winMain (void)
   GtkWidget *journalDeleteLayer;
   GtkWidget *journalFlatten;
   GtkWidget *separator8;
+  GtkWidget *journalRulingParams;
+  GtkWidget *invert_colors;
   GtkWidget *journalPaperSize;
   GtkWidget *journalPaperColor;
   GtkWidget *journalPaperColor_menu;
@@ -143,6 +137,7 @@ create_winMain (void)
   GtkWidget *toolsEraser;
   GtkWidget *toolsHighlighter;
   GtkWidget *toolsText;
+  GtkWidget *toolsImage;
   GtkWidget *separator15;
   GtkWidget *toolsReco;
   GtkWidget *toolsRuler;
@@ -215,6 +210,7 @@ create_winMain (void)
   GtkWidget *button2Eraser;
   GtkWidget *button2Highlighter;
   GtkWidget *button2Text;
+  GtkWidget *button2Image;
   GtkWidget *button2SelectRegion;
   GtkWidget *button2SelectRectangle;
   GtkWidget *button2VerticalSpace;
@@ -231,6 +227,7 @@ create_winMain (void)
   GtkWidget *button3Eraser;
   GtkWidget *button3Highlighter;
   GtkWidget *button3Text;
+  GtkWidget *button3Image;
   GtkWidget *button3SelectRegion;
   GtkWidget *button3SelectRectangle;
   GtkWidget *button3VerticalSpace;
@@ -289,6 +286,7 @@ create_winMain (void)
   GtkWidget *buttonEraser;
   GtkWidget *buttonHighlighter;
   GtkWidget *buttonText;
+  GtkWidget *buttonImage;
   GtkWidget *buttonReco;
   GtkWidget *buttonRuler;
   GtkWidget *toolitem15;
@@ -397,41 +395,9 @@ create_winMain (void)
   gtk_widget_show (fileRecentFiles);
   gtk_container_add (GTK_CONTAINER (menuFile_menu), fileRecentFiles);
 
-  fileRecentFiles_menu = gtk_menu_new ();
+  fileRecentFiles_menu = gtk_recent_chooser_menu_new_for_manager (gtk_recent_manager_get_default ());
   gtk_menu_item_set_submenu (GTK_MENU_ITEM (fileRecentFiles), fileRecentFiles_menu);
-
-  mru0 = gtk_menu_item_new_with_mnemonic (_("0"));
-  gtk_widget_show (mru0);
-  gtk_container_add (GTK_CONTAINER (fileRecentFiles_menu), mru0);
-
-  mru1 = gtk_menu_item_new_with_mnemonic (_("1"));
-  gtk_widget_show (mru1);
-  gtk_container_add (GTK_CONTAINER (fileRecentFiles_menu), mru1);
-
-  mru2 = gtk_menu_item_new_with_mnemonic (_("2"));
-  gtk_widget_show (mru2);
-  gtk_container_add (GTK_CONTAINER (fileRecentFiles_menu), mru2);
-
-  mru3 = gtk_menu_item_new_with_mnemonic (_("3"));
-  gtk_widget_show (mru3);
-  gtk_container_add (GTK_CONTAINER (fileRecentFiles_menu), mru3);
-
-  mru4 = gtk_menu_item_new_with_mnemonic (_("4"));
-  gtk_widget_show (mru4);
-  gtk_container_add (GTK_CONTAINER (fileRecentFiles_menu), mru4);
-
-  mru5 = gtk_menu_item_new_with_mnemonic (_("5"));
-  gtk_widget_show (mru5);
-  gtk_container_add (GTK_CONTAINER (fileRecentFiles_menu), mru5);
-
-  mru6 = gtk_menu_item_new_with_mnemonic (_("6"));
-  gtk_widget_show (mru6);
-  gtk_container_add (GTK_CONTAINER (fileRecentFiles_menu), mru6);
-
-  mru7 = gtk_menu_item_new_with_mnemonic (_("7"));
-  gtk_widget_show (mru7);
-  gtk_container_add (GTK_CONTAINER (fileRecentFiles_menu), mru7);
-
+    
   separator22 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator22);
   gtk_container_add (GTK_CONTAINER (menuFile_menu), separator22);
@@ -662,7 +628,7 @@ create_winMain (void)
   gtk_widget_show (image631);
   gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (viewHideLayer), image631);
 
-  menuJournal = gtk_menu_item_new_with_mnemonic (_("_Journal"));
+  menuJournal = gtk_menu_item_new_with_mnemonic (_("_Page"));
   gtk_widget_show (menuJournal);
   gtk_container_add (GTK_CONTAINER (menubar), menuJournal);
 
@@ -707,6 +673,17 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), separator8);
   gtk_widget_set_sensitive (separator8, FALSE);
 
+  journalRulingParams = gtk_menu_item_new_with_mnemonic (_("_Ruling Parameters"));
+  gtk_widget_show (journalRulingParams);
+  gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalRulingParams);
+
+  invert_colors = gtk_menu_item_new_with_mnemonic (_("_Invert Colors (all pages)"));
+  gtk_widget_show (invert_colors);
+  gtk_container_add (GTK_CONTAINER (menuJournal_menu), invert_colors);
+  gtk_widget_add_accelerator (invert_colors, "activate", accel_group,
+                              GDK_I, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
+
   journalPaperSize = gtk_menu_item_new_with_mnemonic (_("Paper Si_ze"));
   gtk_widget_show (journalPaperSize);
   gtk_container_add (GTK_CONTAINER (menuJournal_menu), journalPaperSize);
@@ -876,6 +853,15 @@ create_winMain (void)
                               GTK_ACCEL_VISIBLE);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsText), TRUE);
 
+  toolsImage = gtk_radio_menu_item_new_with_mnemonic (toolsPen_group, _("_Image"));
+  toolsPen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (toolsImage));
+  gtk_widget_show (toolsImage);
+  gtk_container_add (GTK_CONTAINER (menuTools_menu), toolsImage);
+  gtk_widget_add_accelerator (toolsImage, "activate", accel_group,
+                              GDK_I, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
+                              GTK_ACCEL_VISIBLE);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsImage), TRUE);
+
   separator15 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator15);
   gtk_container_add (GTK_CONTAINER (menuTools_menu), separator15);
@@ -934,6 +920,7 @@ create_winMain (void)
   gtk_widget_add_accelerator (toolsHand, "activate", accel_group,
                               GDK_A, (GdkModifierType) GDK_CONTROL_MASK | GDK_SHIFT_MASK,
                               GTK_ACCEL_VISIBLE);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (toolsHand), TRUE);
 
   separator16 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator16);
@@ -1227,6 +1214,12 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2Text);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2Text), TRUE);
 
+  button2Image = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, _("_Image"));
+  button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2Image));
+  gtk_widget_show (button2Image);
+  gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2Image);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2Image), TRUE);
+
   button2SelectRegion = gtk_radio_menu_item_new_with_mnemonic (button2Pen_group, _("Select Re_gion"));
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2SelectRegion));
   gtk_widget_show (button2SelectRegion);
@@ -1249,6 +1242,7 @@ create_winMain (void)
   button2Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button2Hand));
   gtk_widget_show (button2Hand);
   gtk_container_add (GTK_CONTAINER (button2_mapping_menu), button2Hand);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button2Hand), TRUE);
 
   separator24 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator24);
@@ -1303,6 +1297,12 @@ create_winMain (void)
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3Text);
   gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3Text), TRUE);
 
+  button3Image = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, _("_Image"));
+  button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3Image));
+  gtk_widget_show (button3Image);
+  gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3Image);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3Image), TRUE);
+
   button3SelectRegion = gtk_radio_menu_item_new_with_mnemonic (button3Pen_group, _("Select Re_gion"));
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3SelectRegion));
   gtk_widget_show (button3SelectRegion);
@@ -1325,6 +1325,7 @@ create_winMain (void)
   button3Pen_group = gtk_radio_menu_item_get_group (GTK_RADIO_MENU_ITEM (button3Hand));
   gtk_widget_show (button3Hand);
   gtk_container_add (GTK_CONTAINER (button3_mapping_menu), button3Hand);
+  gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (button3Hand), TRUE);
 
   separator25 = gtk_separator_menu_item_new ();
   gtk_widget_show (separator25);
@@ -1588,6 +1589,17 @@ create_winMain (void)
   gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonText), buttonPen_group);
   buttonPen_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (buttonText));
 
+  buttonImage = (GtkWidget*) gtk_radio_tool_button_new (NULL);
+  gtk_tool_button_set_label (GTK_TOOL_BUTTON (buttonImage), _("Text"));
+  tmp_image = gtk_image_new_from_stock ("gtk-orientation-portrait", tmp_toolbar_icon_size);
+  gtk_widget_show (tmp_image);
+  gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (buttonImage), tmp_image);
+  gtk_widget_show (buttonImage);
+  gtk_container_add (GTK_CONTAINER (toolbarPen), buttonImage);
+  gtk_tool_item_set_tooltip (GTK_TOOL_ITEM (buttonImage), tooltips, _("Text"), NULL);
+  gtk_radio_tool_button_set_group (GTK_RADIO_TOOL_BUTTON (buttonImage), buttonPen_group);
+  buttonPen_group = gtk_radio_tool_button_get_group (GTK_RADIO_TOOL_BUTTON (buttonImage));
+
   buttonReco = (GtkWidget*) gtk_toggle_tool_button_new ();
   gtk_tool_button_set_label (GTK_TOOL_BUTTON (buttonReco), _("Shape Recognizer"));
   tmp_image = create_pixmap (winMain, "shapes.png");
@@ -1967,28 +1979,7 @@ create_winMain (void)
   g_signal_connect ((gpointer) fileSaveAs, "activate",
                     G_CALLBACK (on_fileSaveAs_activate),
                     NULL);
-  g_signal_connect ((gpointer) mru0, "activate",
-                    G_CALLBACK (on_mru_activate),
-                    NULL);
-  g_signal_connect ((gpointer) mru1, "activate",
-                    G_CALLBACK (on_mru_activate),
-                    NULL);
-  g_signal_connect ((gpointer) mru2, "activate",
-                    G_CALLBACK (on_mru_activate),
-                    NULL);
-  g_signal_connect ((gpointer) mru3, "activate",
-                    G_CALLBACK (on_mru_activate),
-                    NULL);
-  g_signal_connect ((gpointer) mru4, "activate",
-                    G_CALLBACK (on_mru_activate),
-                    NULL);
-  g_signal_connect ((gpointer) mru5, "activate",
-                    G_CALLBACK (on_mru_activate),
-                    NULL);
-  g_signal_connect ((gpointer) mru6, "activate",
-                    G_CALLBACK (on_mru_activate),
-                    NULL);
-  g_signal_connect ((gpointer) mru7, "activate",
+  g_signal_connect ((gpointer) fileRecentFiles_menu, "item-activated",
                     G_CALLBACK (on_mru_activate),
                     NULL);
   g_signal_connect ((gpointer) filePrintOptions, "activate",
@@ -2084,6 +2075,12 @@ create_winMain (void)
   g_signal_connect ((gpointer) journalFlatten, "activate",
                     G_CALLBACK (on_journalFlatten_activate),
                     NULL);
+  g_signal_connect ((gpointer) journalRulingParams, "activate",
+                    G_CALLBACK (on_journalRulingParams_activate),
+                    NULL);
+  g_signal_connect ((gpointer) invert_colors, "activate",
+                    G_CALLBACK (on_invert_colors_activate),
+                    NULL);
   g_signal_connect ((gpointer) journalPaperSize, "activate",
                     G_CALLBACK (on_journalPaperSize_activate),
                     NULL);
@@ -2147,6 +2144,9 @@ create_winMain (void)
   g_signal_connect ((gpointer) toolsText, "toggled",
                     G_CALLBACK (on_toolsText_activate),
                     NULL);
+  g_signal_connect ((gpointer) toolsImage, "toggled",
+                    G_CALLBACK (on_toolsImage_activate),
+                    NULL);
   g_signal_connect ((gpointer) toolsReco, "toggled",
                     G_CALLBACK (on_toolsReco_activate),
                     NULL);
@@ -2282,6 +2282,9 @@ create_winMain (void)
   g_signal_connect ((gpointer) button2Text, "activate",
                     G_CALLBACK (on_button2Text_activate),
                     NULL);
+  g_signal_connect ((gpointer) button2Image, "activate",
+                    G_CALLBACK (on_button2Image_activate),
+                    NULL);
   g_signal_connect ((gpointer) button2SelectRegion, "activate",
                     G_CALLBACK (on_button2SelectRegion_activate),
                     NULL);
@@ -2312,6 +2315,9 @@ create_winMain (void)
   g_signal_connect ((gpointer) button3Text, "activate",
                     G_CALLBACK (on_button3Text_activate),
                     NULL);
+  g_signal_connect ((gpointer) button3Image, "activate",
+                    G_CALLBACK (on_button3Image_activate),
+                    NULL);
   g_signal_connect ((gpointer) button3SelectRegion, "activate",
                     G_CALLBACK (on_button3SelectRegion_activate),
                     NULL);
@@ -2426,6 +2432,9 @@ create_winMain (void)
   g_signal_connect ((gpointer) buttonText, "toggled",
                     G_CALLBACK (on_toolsText_activate),
                     NULL);
+  g_signal_connect ((gpointer) buttonImage, "toggled",
+                    G_CALLBACK (on_toolsImage_activate),
+                    NULL);
   g_signal_connect ((gpointer) buttonReco, "toggled",
                     G_CALLBACK (on_toolsReco_activate),
                     NULL);
@@ -2520,14 +2529,6 @@ create_winMain (void)
   GLADE_HOOKUP_OBJECT (winMain, separator1, "separator1");
   GLADE_HOOKUP_OBJECT (winMain, fileRecentFiles, "fileRecentFiles");
   GLADE_HOOKUP_OBJECT (winMain, fileRecentFiles_menu, "fileRecentFiles_menu");
-  GLADE_HOOKUP_OBJECT (winMain, mru0, "mru0");
-  GLADE_HOOKUP_OBJECT (winMain, mru1, "mru1");
-  GLADE_HOOKUP_OBJECT (winMain, mru2, "mru2");
-  GLADE_HOOKUP_OBJECT (winMain, mru3, "mru3");
-  GLADE_HOOKUP_OBJECT (winMain, mru4, "mru4");
-  GLADE_HOOKUP_OBJECT (winMain, mru5, "mru5");
-  GLADE_HOOKUP_OBJECT (winMain, mru6, "mru6");
-  GLADE_HOOKUP_OBJECT (winMain, mru7, "mru7");
   GLADE_HOOKUP_OBJECT (winMain, separator22, "separator22");
   GLADE_HOOKUP_OBJECT (winMain, filePrintOptions, "filePrintOptions");
   GLADE_HOOKUP_OBJECT (winMain, image624, "image624");
@@ -2584,6 +2585,8 @@ create_winMain (void)
   GLADE_HOOKUP_OBJECT (winMain, journalDeleteLayer, "journalDeleteLayer");
   GLADE_HOOKUP_OBJECT (winMain, journalFlatten, "journalFlatten");
   GLADE_HOOKUP_OBJECT (winMain, separator8, "separator8");
+  GLADE_HOOKUP_OBJECT (winMain, journalRulingParams, "journalRulingParams");
+  GLADE_HOOKUP_OBJECT (winMain, invert_colors, "invert_colors");
   GLADE_HOOKUP_OBJECT (winMain, journalPaperSize, "journalPaperSize");
   GLADE_HOOKUP_OBJECT (winMain, journalPaperColor, "journalPaperColor");
   GLADE_HOOKUP_OBJECT (winMain, journalPaperColor_menu, "journalPaperColor_menu");
@@ -2616,6 +2619,7 @@ create_winMain (void)
   GLADE_HOOKUP_OBJECT (winMain, toolsEraser, "toolsEraser");
   GLADE_HOOKUP_OBJECT (winMain, toolsHighlighter, "toolsHighlighter");
   GLADE_HOOKUP_OBJECT (winMain, toolsText, "toolsText");
+  GLADE_HOOKUP_OBJECT (winMain, toolsImage, "toolsImage");
   GLADE_HOOKUP_OBJECT (winMain, separator15, "separator15");
   GLADE_HOOKUP_OBJECT (winMain, toolsReco, "toolsReco");
   GLADE_HOOKUP_OBJECT (winMain, toolsRuler, "toolsRuler");
@@ -2682,6 +2686,7 @@ create_winMain (void)
   GLADE_HOOKUP_OBJECT (winMain, button2Eraser, "button2Eraser");
   GLADE_HOOKUP_OBJECT (winMain, button2Highlighter, "button2Highlighter");
   GLADE_HOOKUP_OBJECT (winMain, button2Text, "button2Text");
+  GLADE_HOOKUP_OBJECT (winMain, button2Image, "button2Image");
   GLADE_HOOKUP_OBJECT (winMain, button2SelectRegion, "button2SelectRegion");
   GLADE_HOOKUP_OBJECT (winMain, button2SelectRectangle, "button2SelectRectangle");
   GLADE_HOOKUP_OBJECT (winMain, button2VerticalSpace, "button2VerticalSpace");
@@ -2696,6 +2701,7 @@ create_winMain (void)
   GLADE_HOOKUP_OBJECT (winMain, button3Eraser, "button3Eraser");
   GLADE_HOOKUP_OBJECT (winMain, button3Highlighter, "button3Highlighter");
   GLADE_HOOKUP_OBJECT (winMain, button3Text, "button3Text");
+  GLADE_HOOKUP_OBJECT (winMain, button3Image, "button3Image");
   GLADE_HOOKUP_OBJECT (winMain, button3SelectRegion, "button3SelectRegion");
   GLADE_HOOKUP_OBJECT (winMain, button3SelectRectangle, "button3SelectRectangle");
   GLADE_HOOKUP_OBJECT (winMain, button3VerticalSpace, "button3VerticalSpace");
@@ -2750,6 +2756,7 @@ create_winMain (void)
   GLADE_HOOKUP_OBJECT (winMain, buttonEraser, "buttonEraser");
   GLADE_HOOKUP_OBJECT (winMain, buttonHighlighter, "buttonHighlighter");
   GLADE_HOOKUP_OBJECT (winMain, buttonText, "buttonText");
+  GLADE_HOOKUP_OBJECT (winMain, buttonImage, "buttonImage");
   GLADE_HOOKUP_OBJECT (winMain, buttonReco, "buttonReco");
   GLADE_HOOKUP_OBJECT (winMain, buttonRuler, "buttonRuler");
   GLADE_HOOKUP_OBJECT (winMain, toolitem15, "toolitem15");
@@ -3110,3 +3117,227 @@ create_zoomDialog (void)
   return zoomDialog;
 }
 
+GtkWidget*
+create_rulingDialog (void)
+{
+  GtkWidget *rulingDialog;
+  GtkWidget *dialog_vbox4;
+  GtkWidget *hbox5;
+  GtkWidget *table1;
+  GtkWidget *rd_margin_color;
+  GtkWidget *rd_ruling_color;
+  GtkObject *rd_thickness_adj;
+  GtkWidget *rd_thickness;
+  GtkObject *rd_left_margin_adj;
+  GtkWidget *rd_left_margin;
+  GtkObject *rd_top_margin_adj;
+  GtkWidget *rd_top_margin;
+  GtkObject *rd_spacing_adj;
+  GtkWidget *rd_spacing;
+  GtkObject *rd_bottom_margin_adj;
+  GtkWidget *rd_bottom_margin;
+  GtkObject *rd_graph_spacing_adj;
+  GtkWidget *rd_graph_spacing;
+  GtkWidget *label2;
+  GtkWidget *label3;
+  GtkWidget *label4;
+  GtkWidget *label5;
+  GtkWidget *label6;
+  GtkWidget *label7;
+  GtkWidget *label8;
+  GtkWidget *label9;
+  GtkWidget *dialog_action_area4;
+  GtkWidget *cancelbutton3;
+  GtkWidget *okbutton2;
+  GtkTooltips *tooltips;
+
+  tooltips = gtk_tooltips_new ();
+
+  rulingDialog = gtk_dialog_new ();
+  gtk_window_set_title (GTK_WINDOW (rulingDialog), _("Set ruling parameters"));
+  gtk_window_set_type_hint (GTK_WINDOW (rulingDialog), GDK_WINDOW_TYPE_HINT_DIALOG);
+
+  dialog_vbox4 = GTK_DIALOG (rulingDialog)->vbox;
+  gtk_widget_show (dialog_vbox4);
+
+  hbox5 = gtk_hbox_new (FALSE, 0);
+  gtk_widget_show (hbox5);
+  gtk_box_pack_start (GTK_BOX (dialog_vbox4), hbox5, TRUE, FALSE, 10);
+
+  table1 = gtk_table_new (8, 2, FALSE);
+  gtk_widget_show (table1);
+  gtk_box_pack_start (GTK_BOX (hbox5), table1, TRUE, FALSE, 10);
+  gtk_table_set_row_spacings (GTK_TABLE (table1), 5);
+  gtk_table_set_col_spacings (GTK_TABLE (table1), 6);
+
+  rd_margin_color = gtk_entry_new ();
+  gtk_widget_show (rd_margin_color);
+  gtk_table_attach (GTK_TABLE (table1), rd_margin_color, 1, 2, 0, 1,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, rd_margin_color, _("RGBA color of the left margin"), NULL);
+  gtk_entry_set_max_length (GTK_ENTRY (rd_margin_color), 8);
+  gtk_entry_set_width_chars (GTK_ENTRY (rd_margin_color), 8);
+
+  rd_ruling_color = gtk_entry_new ();
+  gtk_widget_show (rd_ruling_color);
+  gtk_table_attach (GTK_TABLE (table1), rd_ruling_color, 1, 2, 1, 2,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, rd_ruling_color, _("RGBA color of ruling lines"), NULL);
+  gtk_entry_set_max_length (GTK_ENTRY (rd_ruling_color), 8);
+  gtk_entry_set_width_chars (GTK_ENTRY (rd_ruling_color), 8);
+
+  rd_thickness_adj = gtk_adjustment_new (1, 0, 100, 0.10000000149, 10, 0);
+  rd_thickness = gtk_spin_button_new (GTK_ADJUSTMENT (rd_thickness_adj), 1, 3);
+  gtk_widget_show (rd_thickness);
+  gtk_table_attach (GTK_TABLE (table1), rd_thickness, 1, 2, 2, 3,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, rd_thickness, _("Thickness (points) of ruling lines"), NULL);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (rd_thickness), TRUE);
+
+  rd_left_margin_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 0);
+  rd_left_margin = gtk_spin_button_new (GTK_ADJUSTMENT (rd_left_margin_adj), 1, 3);
+  gtk_widget_show (rd_left_margin);
+  gtk_table_attach (GTK_TABLE (table1), rd_left_margin, 1, 2, 3, 4,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, rd_left_margin, _("Thickness (points) of left margin"), NULL);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (rd_left_margin), TRUE);
+
+  rd_top_margin_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 0);
+  rd_top_margin = gtk_spin_button_new (GTK_ADJUSTMENT (rd_top_margin_adj), 1, 3);
+  gtk_widget_show (rd_top_margin);
+  gtk_table_attach (GTK_TABLE (table1), rd_top_margin, 1, 2, 4, 5,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, rd_top_margin, _("Thickness (points) of top margin"), NULL);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (rd_top_margin), TRUE);
+
+  rd_spacing_adj = gtk_adjustment_new (1, 0, 100, 0.5, 10, 0);
+  rd_spacing = gtk_spin_button_new (GTK_ADJUSTMENT (rd_spacing_adj), 1, 3);
+  gtk_widget_show (rd_spacing);
+  gtk_table_attach (GTK_TABLE (table1), rd_spacing, 1, 2, 5, 6,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, rd_spacing, _("Spacing (points) between lines"), NULL);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (rd_spacing), TRUE);
+
+  rd_bottom_margin_adj = gtk_adjustment_new (1, 0, 100, 1, 10, 0);
+  rd_bottom_margin = gtk_spin_button_new (GTK_ADJUSTMENT (rd_bottom_margin_adj), 1, 3);
+  gtk_widget_show (rd_bottom_margin);
+  gtk_table_attach (GTK_TABLE (table1), rd_bottom_margin, 1, 2, 6, 7,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, rd_bottom_margin, _("Bottom margin (points)"), NULL);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (rd_bottom_margin), TRUE);
+
+  rd_graph_spacing_adj = gtk_adjustment_new (1, 0, 100, 0.10000000149, 10, 0);
+  rd_graph_spacing = gtk_spin_button_new (GTK_ADJUSTMENT (rd_graph_spacing_adj), 1, 3);
+  gtk_widget_show (rd_graph_spacing);
+  gtk_table_attach (GTK_TABLE (table1), rd_graph_spacing, 1, 2, 7, 8,
+                    (GtkAttachOptions) (GTK_FILL),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_tooltips_set_tip (tooltips, rd_graph_spacing, _("Size of graph squares (points). Divide paper dimensions by the number of squares to get this"), NULL);
+  gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (rd_graph_spacing), TRUE);
+
+  label2 = gtk_label_new (_("Margin color"));
+  gtk_widget_show (label2);
+  gtk_table_attach (GTK_TABLE (table1), label2, 0, 1, 0, 1,
+                    (GtkAttachOptions) (GTK_EXPAND),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label2), 0, 0.5);
+
+  label3 = gtk_label_new (_("Ruling color"));
+  gtk_widget_show (label3);
+  gtk_table_attach (GTK_TABLE (table1), label3, 0, 1, 1, 2,
+                    (GtkAttachOptions) (GTK_EXPAND),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label3), 0, 0.5);
+
+  label4 = gtk_label_new (_("Thickness"));
+  gtk_widget_show (label4);
+  gtk_table_attach (GTK_TABLE (table1), label4, 0, 1, 2, 3,
+                    (GtkAttachOptions) (GTK_EXPAND),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label4), 0, 0.5);
+
+  label5 = gtk_label_new (_("Left margin"));
+  gtk_widget_show (label5);
+  gtk_table_attach (GTK_TABLE (table1), label5, 0, 1, 3, 4,
+                    (GtkAttachOptions) (GTK_EXPAND),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label5), 0, 0.5);
+
+  label6 = gtk_label_new (_("Top margin"));
+  gtk_widget_show (label6);
+  gtk_table_attach (GTK_TABLE (table1), label6, 0, 1, 4, 5,
+                    (GtkAttachOptions) (GTK_EXPAND),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label6), 0, 0.5);
+
+  label7 = gtk_label_new (_("Spacing"));
+  gtk_widget_show (label7);
+  gtk_table_attach (GTK_TABLE (table1), label7, 0, 1, 5, 6,
+                    (GtkAttachOptions) (GTK_EXPAND),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label7), 0, 0.5);
+
+  label8 = gtk_label_new (_("Bottom margin"));
+  gtk_widget_show (label8);
+  gtk_table_attach (GTK_TABLE (table1), label8, 0, 1, 6, 7,
+                    (GtkAttachOptions) (GTK_EXPAND),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label8), 0, 0.5);
+
+  label9 = gtk_label_new (_("Graph spacing"));
+  gtk_widget_show (label9);
+  gtk_table_attach (GTK_TABLE (table1), label9, 0, 1, 7, 8,
+                    (GtkAttachOptions) (GTK_EXPAND),
+                    (GtkAttachOptions) (0), 0, 0);
+  gtk_misc_set_alignment (GTK_MISC (label9), 0, 0.5);
+
+  dialog_action_area4 = GTK_DIALOG (rulingDialog)->action_area;
+  gtk_widget_show (dialog_action_area4);
+  gtk_button_box_set_layout (GTK_BUTTON_BOX (dialog_action_area4), GTK_BUTTONBOX_END);
+
+  cancelbutton3 = gtk_button_new_from_stock ("gtk-cancel");
+  gtk_widget_show (cancelbutton3);
+  gtk_dialog_add_action_widget (GTK_DIALOG (rulingDialog), cancelbutton3, GTK_RESPONSE_CANCEL);
+  GTK_WIDGET_SET_FLAGS (cancelbutton3, GTK_CAN_DEFAULT);
+
+  okbutton2 = gtk_button_new_from_stock ("gtk-ok");
+  gtk_widget_show (okbutton2);
+  gtk_dialog_add_action_widget (GTK_DIALOG (rulingDialog), okbutton2, GTK_RESPONSE_OK);
+  GTK_WIDGET_SET_FLAGS (okbutton2, GTK_CAN_DEFAULT);
+
+  /* Store pointers to all widgets, for use by lookup_widget(). */
+  GLADE_HOOKUP_OBJECT_NO_REF (rulingDialog, rulingDialog, "rulingDialog");
+  GLADE_HOOKUP_OBJECT_NO_REF (rulingDialog, dialog_vbox4, "dialog_vbox4");
+  GLADE_HOOKUP_OBJECT (rulingDialog, hbox5, "hbox5");
+  GLADE_HOOKUP_OBJECT (rulingDialog, table1, "table1");
+  GLADE_HOOKUP_OBJECT (rulingDialog, rd_margin_color, "rd_margin_color");
+  GLADE_HOOKUP_OBJECT (rulingDialog, rd_ruling_color, "rd_ruling_color");
+  GLADE_HOOKUP_OBJECT (rulingDialog, rd_thickness, "rd_thickness");
+  GLADE_HOOKUP_OBJECT (rulingDialog, rd_left_margin, "rd_left_margin");
+  GLADE_HOOKUP_OBJECT (rulingDialog, rd_top_margin, "rd_top_margin");
+  GLADE_HOOKUP_OBJECT (rulingDialog, rd_spacing, "rd_spacing");
+  GLADE_HOOKUP_OBJECT (rulingDialog, rd_bottom_margin, "rd_bottom_margin");
+  GLADE_HOOKUP_OBJECT (rulingDialog, rd_graph_spacing, "rd_graph_spacing");
+  GLADE_HOOKUP_OBJECT (rulingDialog, label2, "label2");
+  GLADE_HOOKUP_OBJECT (rulingDialog, label3, "label3");
+  GLADE_HOOKUP_OBJECT (rulingDialog, label4, "label4");
+  GLADE_HOOKUP_OBJECT (rulingDialog, label5, "label5");
+  GLADE_HOOKUP_OBJECT (rulingDialog, label6, "label6");
+  GLADE_HOOKUP_OBJECT (rulingDialog, label7, "label7");
+  GLADE_HOOKUP_OBJECT (rulingDialog, label8, "label8");
+  GLADE_HOOKUP_OBJECT (rulingDialog, label9, "label9");
+  GLADE_HOOKUP_OBJECT_NO_REF (rulingDialog, dialog_action_area4, "dialog_action_area4");
+  GLADE_HOOKUP_OBJECT (rulingDialog, cancelbutton3, "cancelbutton3");
+  GLADE_HOOKUP_OBJECT (rulingDialog, okbutton2, "okbutton2");
+  GLADE_HOOKUP_OBJECT_NO_REF (rulingDialog, tooltips, "tooltips");
+
+  return rulingDialog;
+}
+
diff --git a/src/xo-interface.h b/src/xo-interface.h
index 1e86792..d0e04b4 100644
--- a/src/xo-interface.h
+++ b/src/xo-interface.h
@@ -6,3 +6,4 @@ GtkWidget* create_winMain (void);
 GtkWidget* create_papersizeDialog (void);
 GtkWidget* create_aboutDialog (void);
 GtkWidget* create_zoomDialog (void);
+GtkWidget* create_rulingDialog (void);
diff --git a/src/xo-misc.c b/src/xo-misc.c
index bc4747c..4387858 100644
--- a/src/xo-misc.c
+++ b/src/xo-misc.c
@@ -31,6 +31,7 @@
 #include "xo-file.h"
 #include "xo-paint.h"
 #include "xo-shapes.h"
+#include "xo-image.h"
 
 // some global constants
 
@@ -104,6 +105,31 @@ struct Page *new_page_with_bg(struct Background *bg, double width, double height
   return pg;
 }
 
+// change the current page if necessary for pointer at pt
+void set_current_page(gdouble *pt)
+{
+  gboolean page_change;
+  struct Page *tmppage;
+
+  page_change = FALSE;
+  tmppage = ui.cur_page;
+  while (ui.view_continuous && (pt[1] < - VIEW_CONTINUOUS_SKIP)) {
+    if (ui.pageno == 0) break;
+    page_change = TRUE;
+    ui.pageno--;
+    tmppage = g_list_nth_data(journal.pages, ui.pageno);
+    pt[1] += tmppage->height + VIEW_CONTINUOUS_SKIP;
+  }
+  while (ui.view_continuous && (pt[1] > tmppage->height + VIEW_CONTINUOUS_SKIP)) {
+    if (ui.pageno == journal.npages-1) break;
+    pt[1] -= tmppage->height + VIEW_CONTINUOUS_SKIP;
+    page_change = TRUE;
+    ui.pageno++;
+    tmppage = g_list_nth_data(journal.pages, ui.pageno);
+  }
+  if (page_change) do_switch_page(ui.pageno, FALSE, FALSE);
+}
+
 void realloc_cur_path(int n)
 {
   if (n <= ui.cur_path_storage_alloc) return;
@@ -156,6 +182,11 @@ void clear_redo_stack(void)
       g_free(redo->item->font_name);
       g_free(redo->item);
     }
+    else if (redo->type == ITEM_IMAGE) {
+      g_object_unref(redo->item->image);
+      g_free(redo->item->image_png);
+      g_free(redo->item);
+    }
     else if (redo->type == ITEM_ERASURE || redo->type == ITEM_RECOGNIZER) {
       for (list = redo->erasurelist; list!=NULL; list=list->next) {
         erasure = (struct UndoErasureData *)list->data;
@@ -232,6 +263,10 @@ void clear_undo_stack(void)
         }
         if (erasure->item->type == ITEM_TEXT)
           { g_free(erasure->item->text); g_free(erasure->item->font_name); }
+        if (erasure->item->type == ITEM_IMAGE) {
+          g_object_unref(erasure->item->image);
+          g_free(erasure->item->image_png);
+        }
         g_free(erasure->item);
         g_list_free(erasure->replacement_items);
         g_free(erasure);
@@ -316,6 +351,10 @@ void delete_layer(struct Layer *l)
     if (item->type == ITEM_TEXT) {
       g_free(item->font_name); g_free(item->text);
     }
+    if (item->type == ITEM_IMAGE) {
+      g_object_unref(item->image);
+      g_free(item->image_png);
+    }
     // don't need to delete the canvas_item, as it's part of the group destroyed below
     g_free(item);
     l->items = g_list_delete_link(l->items, l->items);
@@ -370,6 +409,17 @@ void get_pointer_coords(GdkEvent *event, gdouble *ret)
   ret[1] -= ui.cur_page->voffset;
 }
 
+void get_current_pointer_coords(gdouble *ret)
+{
+  gint wx, wy, sx, sy;
+
+  gtk_widget_get_pointer((GtkWidget *)canvas, &wx, &wy);
+  gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
+  gnome_canvas_window_to_world(canvas, (double)(wx + sx), (double)(wy + sy), ret, ret+1);
+  ret[0] -= ui.cur_page->hoffset;
+  ret[1] -= ui.cur_page->voffset;
+}
+
 void fix_xinput_coords(GdkEvent *event)
 {
   double *axes, *px, *py, axis_width;
@@ -533,6 +583,16 @@ void make_canvas_item_one(GnomeCanvasGroup *group, struct Item *item)
           "text", item->text, NULL);
     update_item_bbox(item);
   }
+  if (item->type == ITEM_IMAGE) {
+    item->canvas_item = gnome_canvas_item_new(group,
+          gnome_canvas_pixbuf_get_type(),
+          "pixbuf", item->image,
+          "x", item->bbox.left, "y", item->bbox.top,
+          "width", item->bbox.right - item->bbox.left,
+          "height", item->bbox.bottom - item->bbox.top,
+          "width-set", TRUE, "height-set", TRUE,
+          NULL);
+  }
 }
 
 void make_canvas_items(void)
@@ -592,35 +652,35 @@ void update_canvas_bg(struct Page *pg)
     pt = seg->coords;
     if (pg->bg->ruling == RULING_GRAPH) {
       pt[1] = 0; pt[3] = pg->height;
-      for (x=RULING_GRAPHSPACING; x<pg->width-1; x+=RULING_GRAPHSPACING) {
+      for (x=pg->bg->ruling_graphspacing; x<pg->width-1; x+=pg->bg->ruling_graphspacing) {
         pt[0] = pt[2] = x;
         gnome_canvas_item_new(group, gnome_canvas_line_get_type(),
-           "points", seg, "fill-color-rgba", RULING_COLOR,
-           "width-units", RULING_THICKNESS, NULL);
+           "points", seg, "fill-color-rgba", pg->bg->ruling_color,
+           "width-units", pg->bg->ruling_thickness, NULL);
       }      
       pt[0] = 0; pt[2] = pg->width;
-      for (y=RULING_GRAPHSPACING; y<pg->height-1; y+=RULING_GRAPHSPACING) {
+      for (y=pg->bg->ruling_graphspacing; y<pg->height-1; y+=pg->bg->ruling_graphspacing) {
         pt[1] = pt[3] = y;
         gnome_canvas_item_new(group, gnome_canvas_line_get_type(),
-           "points", seg, "fill-color-rgba", RULING_COLOR,
-           "width-units", RULING_THICKNESS, NULL);
+           "points", seg, "fill-color-rgba", pg->bg->ruling_color,
+           "width-units", pg->bg->ruling_thickness, NULL);
       }      
       gnome_canvas_points_free(seg);
       return;
     }
     pt[0] = 0; pt[2] = pg->width;
-    for (y=RULING_TOPMARGIN; y<pg->height-1; y+=RULING_SPACING) {
+    for (y=pg->bg->ruling_topmargin; y<pg->height-1; y+=pg->bg->ruling_spacing) {
       pt[1] = pt[3] = y;
       gnome_canvas_item_new(group, gnome_canvas_line_get_type(),
-         "points", seg, "fill-color-rgba", RULING_COLOR,
-         "width-units", RULING_THICKNESS, NULL);
+         "points", seg, "fill-color-rgba", pg->bg->ruling_color,
+         "width-units", pg->bg->ruling_thickness, NULL);
     }      
     if (pg->bg->ruling == RULING_LINED) {
-      pt[0] = pt[2] = RULING_LEFTMARGIN;
+      pt[0] = pt[2] = pg->bg->ruling_leftmargin;
       pt[1] = 0; pt[3] = pg->height;
       gnome_canvas_item_new(group, gnome_canvas_line_get_type(),
-         "points", seg, "fill-color-rgba", RULING_MARGIN_COLOR,
-         "width-units", RULING_THICKNESS, NULL);
+         "points", seg, "fill-color-rgba", pg->bg->ruling_margin_color,
+         "width-units", pg->bg->ruling_thickness, NULL);
     }
     gnome_canvas_points_free(seg);
     return;
@@ -881,6 +941,10 @@ void update_tool_buttons(void)
       gtk_toggle_tool_button_set_active(
         GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonText")), TRUE);
       break;
+    case TOOL_IMAGE:
+      gtk_toggle_tool_button_set_active(
+        GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonImage")), TRUE);
+      break;
     case TOOL_SELECTREGION:
       gtk_toggle_tool_button_set_active(
         GTK_TOGGLE_TOOL_BUTTON(GET_COMPONENT("buttonSelectRegion")), TRUE);
@@ -929,6 +993,10 @@ void update_tool_menu(void)
       gtk_check_menu_item_set_active(
         GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsText")), TRUE);
       break;
+    case TOOL_IMAGE:
+      gtk_check_menu_item_set_active(
+        GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsImage")), TRUE);
+      break;
     case TOOL_SELECTREGION:
       gtk_check_menu_item_set_active(
         GTK_CHECK_MENU_ITEM(GET_COMPONENT("toolsSelectRegion")), TRUE);
@@ -1159,6 +1227,10 @@ void update_mappings_menu(void)
       gtk_check_menu_item_set_active(
         GTK_CHECK_MENU_ITEM(GET_COMPONENT("button2Text")), TRUE);
       break;
+    case TOOL_IMAGE:
+      gtk_check_menu_item_set_active(
+        GTK_CHECK_MENU_ITEM(GET_COMPONENT("button2Image")), TRUE);
+      break;
     case TOOL_SELECTREGION:
       gtk_check_menu_item_set_active(
         GTK_CHECK_MENU_ITEM(GET_COMPONENT("button2SelectRegion")), TRUE);
@@ -1189,6 +1261,10 @@ void update_mappings_menu(void)
       gtk_check_menu_item_set_active(
         GTK_CHECK_MENU_ITEM(GET_COMPONENT("button3Text")), TRUE);
       break;
+    case TOOL_IMAGE:
+      gtk_check_menu_item_set_active(
+        GTK_CHECK_MENU_ITEM(GET_COMPONENT("button3Image")), TRUE);
+      break;
     case TOOL_SELECTREGION:
       gtk_check_menu_item_set_active(
         GTK_CHECK_MENU_ITEM(GET_COMPONENT("button3SelectRegion")), TRUE);
@@ -1207,7 +1283,13 @@ void update_mappings_menu(void)
 
 void do_switch_page(int pg, gboolean rescroll, gboolean refresh_all)
 {
-  int i, cx, cy;
+  do_switch_page_and_scroll(pg, rescroll, refresh_all, 0.0);
+}
+
+void do_switch_page_and_scroll(int pg, gboolean rescroll, gboolean refresh_all, gdouble scroll_pagefraction)
+{
+  int i, cx, cy, visibleheight;
+  GtkAdjustment *adjust;
   struct Layer *layer;
   GList *list;
   
@@ -1232,7 +1314,9 @@ void do_switch_page(int pg, gboolean rescroll, gboolean refresh_all)
     gtk_adjustment_set_value(gtk_layout_get_vadjustment(GTK_LAYOUT(canvas)),
       ui.cur_page->voffset*ui.zoom);  */
     gnome_canvas_get_scroll_offsets(canvas, &cx, &cy);
-    cy = ui.cur_page->voffset*ui.zoom;
+    adjust = gtk_layout_get_vadjustment (GTK_LAYOUT(canvas));
+    visibleheight = gtk_adjustment_get_page_size (adjust);
+    cy = ui.cur_page->voffset*ui.zoom + visibleheight*scroll_pagefraction;
     gnome_canvas_scroll_to(canvas, cx, cy);
     
     if (refresh_all) 
@@ -1244,7 +1328,7 @@ void do_switch_page(int pg, gboolean rescroll, gboolean refresh_all)
 
 void update_page_stuff(void)
 {
-  gchar tmp[10];
+  gchar *tmp;
   GtkComboBox *layerbox;
   int i;
   GList *pglist;
@@ -1291,9 +1375,9 @@ void update_page_stuff(void)
   gtk_spin_button_set_range(spin, 1, journal.npages+1);
     /* npages+1 will be used to create a new page at end */
   gtk_spin_button_set_value(spin, ui.pageno+1);
-  g_snprintf(tmp, 10, _(" of %d"), journal.npages);
+  tmp = g_strdup_printf(_(" of %d"), journal.npages);
   gtk_label_set_text(GTK_LABEL(GET_COMPONENT("labelNumpages")), tmp);
-
+  g_free(tmp);
   layerbox = GTK_COMBO_BOX(GET_COMPONENT("comboLayer"));
   if (ui.layerbox_length == 0) {
     gtk_combo_box_prepend_text(layerbox, _("Background"));
@@ -1304,8 +1388,9 @@ void update_page_stuff(void)
     ui.layerbox_length--;
   }
   while (ui.layerbox_length < ui.cur_page->nlayers+1) {
-    g_snprintf(tmp, 10, _("Layer %d"), ui.layerbox_length++);
+    tmp = g_strdup_printf(_("Layer %d"), ui.layerbox_length++);
     gtk_combo_box_prepend_text(layerbox, tmp);
+    g_free(tmp);
   }
   gtk_combo_box_set_active(layerbox, ui.cur_page->nlayers-1-ui.layerno);
   ui.in_update_page_stuff = FALSE;
@@ -1418,7 +1503,7 @@ void update_toolbar_and_menu(void)
 
 void update_file_name(char *filename)
 {
-  gchar tmp[100], *p;
+  gchar *tmp, *p;
   if (ui.filename != NULL) g_free(ui.filename);
   ui.filename = filename;
   if (filename == NULL) {
@@ -1428,8 +1513,9 @@ void update_file_name(char *filename)
   p = g_utf8_strrchr(filename, -1, '/');
   if (p == NULL) p = filename; 
   else p = g_utf8_next_char(p);
-  g_snprintf(tmp, 100, _("Xournal - %s"), p);
+  tmp = g_strdup_printf( _("%s - Xournal"), p);
   gtk_window_set_title(GTK_WINDOW (winMain), tmp);
+  g_free(tmp);
   new_mru_entry(filename);
 
   if (filename[0]=='/') {
@@ -1743,7 +1829,8 @@ void move_journal_items_by(GList *itemlist, double dx, double dy,
     if (item->type == ITEM_STROKE)
       for (pt=item->path->coords, i=0; i<item->path->num_points; i++, pt+=2)
         { pt[0] += dx; pt[1] += dy; }
-    if (item->type == ITEM_STROKE || item->type == ITEM_TEXT || item->type == ITEM_TEMP_TEXT) {
+    if (item->type == ITEM_STROKE || item->type == ITEM_TEXT || 
+        item->type == ITEM_TEMP_TEXT || item->type == ITEM_IMAGE) {
       item->bbox.left += dx;
       item->bbox.right += dx;
       item->bbox.top += dy;
@@ -1826,6 +1913,22 @@ void resize_journal_items_by(GList *itemlist, double scaling_x, double scaling_y
       item->bbox.left = item->bbox.left*scaling_x + offset_x;
       item->bbox.top = item->bbox.top*scaling_y + offset_y;
     }
+    if (item->type == ITEM_IMAGE) {
+      item->bbox.left = item->bbox.left*scaling_x + offset_x;
+      item->bbox.right = item->bbox.right*scaling_x + offset_x;
+      item->bbox.top = item->bbox.top*scaling_y + offset_y;
+      item->bbox.bottom = item->bbox.bottom*scaling_y + offset_y;
+      if (item->bbox.left > item->bbox.right) {
+        temp = item->bbox.left;
+        item->bbox.left = item->bbox.right;
+        item->bbox.right = temp;
+      }
+      if (item->bbox.top > item->bbox.bottom) {
+        temp = item->bbox.top;
+        item->bbox.top = item->bbox.bottom;
+        item->bbox.bottom = temp;
+      }
+    }
     // redraw the item
     if (item->canvas_item!=NULL) {
       group = (GnomeCanvasGroup *) item->canvas_item->parent;
diff --git a/src/xo-misc.h b/src/xo-misc.h
index da1433d..407df9e 100644
--- a/src/xo-misc.h
+++ b/src/xo-misc.h
@@ -17,6 +17,7 @@
 
 struct Page *new_page(struct Page *template);
 struct Page *new_page_with_bg(struct Background *bg, double width, double height);
+void set_current_page(gdouble *pt);
 void realloc_cur_path(int n);
 void realloc_cur_widths(int n);
 void clear_redo_stack(void);
@@ -36,6 +37,7 @@ void refstring_unref(struct Refstring *rs);
 
 int finite_sized(double x);
 void get_pointer_coords(GdkEvent *event, double *ret);
+void get_current_pointer_coords(double *ret);
 double get_pressure_multiplier(GdkEvent *event);
 void fix_xinput_coords(GdkEvent *event);
 void update_item_bbox(struct Item *item);
@@ -76,7 +78,9 @@ gchar *make_cur_font_name(void);
 void update_font_button(void);
 
 void update_mapping_linkings(int toolno);
+void do_switch_page_and_scroll(int pg, gboolean rescroll, gboolean refresh_all, gdouble scroll_pagefraction);
 void do_switch_page(int pg, gboolean rescroll, gboolean refresh_all);
+
 void set_cur_color(int color_no, guint color_rgba);
 void recolor_temp_text(int color_no, guint color_rgba);
 void process_color_activate(GtkMenuItem *menuitem, int color_no, guint color_rgba);
@@ -132,8 +136,7 @@ wrapper_poppler_page_render_to_pixbuf (PopplerPage *page,
 			       int rotation,
 			       GdkPixbuf *pixbuf);
 
-// defines for paper rulings
-
+// Compiled in defaults for paper rulings
 #define RULING_MARGIN_COLOR 0xff0080ff
 #define RULING_COLOR 0x40a0ffff
 #define RULING_THICKNESS 0.5
@@ -142,3 +145,11 @@ wrapper_poppler_page_render_to_pixbuf (PopplerPage *page,
 #define RULING_SPACING 24.0
 #define RULING_BOTTOMMARGIN RULING_SPACING
 #define RULING_GRAPHSPACING 14.17
+
+// Bounds for page ruling
+#define RULING_THICKNESS_MIN (0.1)
+#define RULING_THICKNESS_MAX (2.0)
+#define RULING_MARGIN_MIN (0.0)
+#define RULING_MARGIN_MAX (216.0)
+#define RULING_SPACING_MIN (6.0)
+#define RULING_SPACING_MAX (96.0)
diff --git a/src/xo-paint.c b/src/xo-paint.c
index c777482..9d006c6 100644
--- a/src/xo-paint.c
+++ b/src/xo-paint.c
@@ -694,6 +694,12 @@ gboolean start_resizesel(GdkEvent *event)
     ui.selection->new_x2 = ui.selection->bbox.right;
     gnome_canvas_item_set(ui.selection->canvas_item, "dash", NULL, NULL);
     update_cursor_for_resize(pt);
+
+    // Check whether we should preserve the aspect ratio
+    if (event->button.button == 3)
+    	ui.cur_brush->tool_options |= TOOLOPT_SELECT_PRESERVE;
+    else
+    	ui.cur_brush->tool_options &= ~TOOLOPT_SELECT_PRESERVE;
     return TRUE;
   }
   return FALSE;
@@ -825,6 +831,38 @@ void continue_resizesel(GdkEvent *event)
   if (ui.selection->resizing_left) ui.selection->new_x1 = pt[0];
   if (ui.selection->resizing_right) ui.selection->new_x2 = pt[0];
 
+  if (ui.cur_brush->tool_options & TOOLOPT_SELECT_PRESERVE) {
+	  double aspectratio = (ui.selection->bbox.top - ui.selection->bbox.bottom)/(ui.selection->bbox.right - ui.selection->bbox.left);
+	  double newheight = ui.selection->new_y1 - ui.selection->new_y2;
+	  double newwidth = ui.selection->new_x2 - ui.selection->new_x1;
+	  gboolean boundheight;
+
+	  // Resizing from top or bottom only
+	  if ((ui.selection->resizing_top || ui.selection->resizing_bottom) && !(ui.selection->resizing_left || ui.selection->resizing_right))
+		  boundheight = 0;
+	  // Resizing from right or left only
+	  else if (!(ui.selection->resizing_top || ui.selection->resizing_bottom) && (ui.selection->resizing_left || ui.selection->resizing_right))
+		  boundheight = 1;
+	  // Resizing from a corner
+	  else if (newheight/aspectratio > newwidth)
+		  boundheight = 0;
+	  else
+		  boundheight = 1;
+
+	  if (boundheight) {
+		  // Bound the height
+		  newheight = newwidth*aspectratio;
+		  if (ui.selection->resizing_top) ui.selection->new_y1 = ui.selection->new_y2 + newheight;
+		  else ui.selection->new_y2 = ui.selection->new_y1 - newheight;
+	  }
+	  else {
+		  // Bound the width
+		  newwidth = newheight/aspectratio;
+		  if (ui.selection->resizing_left) ui.selection->new_x1 = ui.selection->new_x2 - newwidth;
+		  else ui.selection->new_x2 = ui.selection->new_x1 + newwidth;
+	  }
+  }
+
   gnome_canvas_item_set(ui.selection->canvas_item, 
     "x1", ui.selection->new_x1, "x2", ui.selection->new_x2,
     "y1", ui.selection->new_y1, "y2", ui.selection->new_y2, NULL);
@@ -964,211 +1002,6 @@ void selection_delete(void)
      the forward direction */
 }
 
-void callback_clipboard_get(GtkClipboard *clipboard,
-                            GtkSelectionData *selection_data,
-                            guint info, gpointer user_data)
-{
-  int length;
-  
-  g_memmove(&length, user_data, sizeof(int));
-  gtk_selection_data_set(selection_data,
-     gdk_atom_intern("_XOURNAL", FALSE), 8, user_data, length);
-}
-
-void callback_clipboard_clear(GtkClipboard *clipboard, gpointer user_data)
-{
-  g_free(user_data);
-}
-
-void selection_to_clip(void)
-{
-  int bufsz, nitems, val;
-  char *buf, *p;
-  GList *list;
-  struct Item *item;
-  GtkTargetEntry target;
-  
-  if (ui.selection == NULL) return;
-  bufsz = 2*sizeof(int) // bufsz, nitems
-        + sizeof(struct BBox); // bbox
-  nitems = 0;
-  for (list = ui.selection->items; list != NULL; list = list->next) {
-    item = (struct Item *)list->data;
-    nitems++;
-    if (item->type == ITEM_STROKE) {
-      bufsz+= sizeof(int) // type
-            + sizeof(struct Brush) // brush
-            + sizeof(int) // num_points
-            + 2*item->path->num_points*sizeof(double); // the points
-      if (item->brush.variable_width)
-        bufsz += (item->path->num_points-1)*sizeof(double); // the widths
-    }
-    else if (item->type == ITEM_TEXT) {
-      bufsz+= sizeof(int) // type
-            + sizeof(struct Brush) // brush
-            + 2*sizeof(double) // bbox upper-left
-            + sizeof(int) // text len
-            + strlen(item->text)+1 // text
-            + sizeof(int) // font_name len
-            + strlen(item->font_name)+1 // font_name
-            + sizeof(double); // font_size
-    }
-    else bufsz+= sizeof(int); // type
-  }
-  p = buf = g_malloc(bufsz);
-  g_memmove(p, &bufsz, sizeof(int)); p+= sizeof(int);
-  g_memmove(p, &nitems, sizeof(int)); p+= sizeof(int);
-  g_memmove(p, &ui.selection->bbox, sizeof(struct BBox)); p+= sizeof(struct BBox);
-  for (list = ui.selection->items; list != NULL; list = list->next) {
-    item = (struct Item *)list->data;
-    g_memmove(p, &item->type, sizeof(int)); p+= sizeof(int);
-    if (item->type == ITEM_STROKE) {
-      g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
-      g_memmove(p, &item->path->num_points, sizeof(int)); p+= sizeof(int);
-      g_memmove(p, item->path->coords, 2*item->path->num_points*sizeof(double));
-      p+= 2*item->path->num_points*sizeof(double);
-      if (item->brush.variable_width) {
-        g_memmove(p, item->widths, (item->path->num_points-1)*sizeof(double));
-        p+= (item->path->num_points-1)*sizeof(double);
-      }
-    }
-    if (item->type == ITEM_TEXT) {
-      g_memmove(p, &item->brush, sizeof(struct Brush)); p+= sizeof(struct Brush);
-      g_memmove(p, &item->bbox.left, sizeof(double)); p+= sizeof(double);
-      g_memmove(p, &item->bbox.top, sizeof(double)); p+= sizeof(double);
-      val = strlen(item->text);
-      g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
-      g_memmove(p, item->text, val+1); p+= val+1;
-      val = strlen(item->font_name);
-      g_memmove(p, &val, sizeof(int)); p+= sizeof(int);
-      g_memmove(p, item->font_name, val+1); p+= val+1;
-      g_memmove(p, &item->font_size, sizeof(double)); p+= sizeof(double);
-    }
-  }
-  
-  target.target = "_XOURNAL";
-  target.flags = 0;
-  target.info = 0;
-  
-  gtk_clipboard_set_with_data(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), 
-       &target, 1,
-       callback_clipboard_get, callback_clipboard_clear, buf);
-}
-
-
-void clipboard_paste(void)
-{
-  GtkSelectionData *sel_data;
-  unsigned char *p;
-  int nitems, npts, i, len;
-  struct Item *item;
-  double hoffset, voffset, cx, cy;
-  double *pf;
-  int sx, sy, wx, wy;
-  
-  if (ui.cur_layer == NULL) return;
-  
-  ui.cur_item_type = ITEM_PASTE;
-  sel_data = gtk_clipboard_wait_for_contents(
-      gtk_clipboard_get(GDK_SELECTION_CLIPBOARD),
-      gdk_atom_intern("_XOURNAL", FALSE));
-  ui.cur_item_type = ITEM_NONE;
-  if (sel_data == NULL) return; // paste failed
-  
-  reset_selection();
-  
-  ui.selection = g_new(struct Selection, 1);
-  p = sel_data->data + sizeof(int);
-  g_memmove(&nitems, p, sizeof(int)); p+= sizeof(int);
-  ui.selection->type = ITEM_SELECTRECT;
-  ui.selection->layer = ui.cur_layer;
-  g_memmove(&ui.selection->bbox, p, sizeof(struct BBox)); p+= sizeof(struct BBox);
-  ui.selection->items = NULL;
-  
-  // find by how much we translate the pasted selection
-  gnome_canvas_get_scroll_offsets(canvas, &sx, &sy);
-  gdk_window_get_geometry(GTK_WIDGET(canvas)->window, NULL, NULL, &wx, &wy, NULL);
-  gnome_canvas_window_to_world(canvas, sx + wx/2, sy + wy/2, &cx, &cy);
-  cx -= ui.cur_page->hoffset;
-  cy -= ui.cur_page->voffset;
-  if (cx + (ui.selection->bbox.right-ui.selection->bbox.left)/2 > ui.cur_page->width)
-    cx = ui.cur_page->width - (ui.selection->bbox.right-ui.selection->bbox.left)/2;
-  if (cx - (ui.selection->bbox.right-ui.selection->bbox.left)/2 < 0)
-    cx = (ui.selection->bbox.right-ui.selection->bbox.left)/2;
-  if (cy + (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 > ui.cur_page->height)
-    cy = ui.cur_page->height - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
-  if (cy - (ui.selection->bbox.bottom-ui.selection->bbox.top)/2 < 0)
-    cy = (ui.selection->bbox.bottom-ui.selection->bbox.top)/2;
-  hoffset = cx - (ui.selection->bbox.right+ui.selection->bbox.left)/2;
-  voffset = cy - (ui.selection->bbox.top+ui.selection->bbox.bottom)/2;
-  ui.selection->bbox.left += hoffset;
-  ui.selection->bbox.right += hoffset;
-  ui.selection->bbox.top += voffset;
-  ui.selection->bbox.bottom += voffset;
-
-  ui.selection->canvas_item = gnome_canvas_item_new(ui.cur_layer->group,
-      gnome_canvas_rect_get_type(), "width-pixels", 1,
-      "outline-color-rgba", 0x000000ff,
-      "fill-color-rgba", 0x80808040,
-      "x1", ui.selection->bbox.left, "x2", ui.selection->bbox.right, 
-      "y1", ui.selection->bbox.top, "y2", ui.selection->bbox.bottom, NULL);
-  make_dashed(ui.selection->canvas_item);
-
-  while (nitems-- > 0) {
-    item = g_new(struct Item, 1);
-    ui.selection->items = g_list_append(ui.selection->items, item);
-    ui.cur_layer->items = g_list_append(ui.cur_layer->items, item);
-    ui.cur_layer->nitems++;
-    g_memmove(&item->type, p, sizeof(int)); p+= sizeof(int);
-    if (item->type == ITEM_STROKE) {
-      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
-      g_memmove(&npts, p, sizeof(int)); p+= sizeof(int);
-      item->path = gnome_canvas_points_new(npts);
-      pf = (double *)p;
-      for (i=0; i<npts; i++) {
-        item->path->coords[2*i] = pf[2*i] + hoffset;
-        item->path->coords[2*i+1] = pf[2*i+1] + voffset;
-      }
-      p+= 2*item->path->num_points*sizeof(double);
-      if (item->brush.variable_width) {
-        item->widths = g_memdup(p, (item->path->num_points-1)*sizeof(double));
-        p+= (item->path->num_points-1)*sizeof(double);
-      }
-      else item->widths = NULL;
-      update_item_bbox(item);
-      make_canvas_item_one(ui.cur_layer->group, item);
-    }
-    if (item->type == ITEM_TEXT) {
-      g_memmove(&item->brush, p, sizeof(struct Brush)); p+= sizeof(struct Brush);
-      g_memmove(&item->bbox.left, p, sizeof(double)); p+= sizeof(double);
-      g_memmove(&item->bbox.top, p, sizeof(double)); p+= sizeof(double);
-      item->bbox.left += hoffset;
-      item->bbox.top += voffset;
-      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
-      item->text = g_malloc(len+1);
-      g_memmove(item->text, p, len+1); p+= len+1;
-      g_memmove(&len, p, sizeof(int)); p+= sizeof(int);
-      item->font_name = g_malloc(len+1);
-      g_memmove(item->font_name, p, len+1); p+= len+1;
-      g_memmove(&item->font_size, p, sizeof(double)); p+= sizeof(double);
-      make_canvas_item_one(ui.cur_layer->group, item);
-    }
-  }
-
-  prepare_new_undo();
-  undo->type = ITEM_PASTE;
-  undo->layer = ui.cur_layer;
-  undo->itemlist = g_list_copy(ui.selection->items);  
-  
-  gtk_selection_data_free(sel_data);
-  update_copy_paste_enabled();
-  update_color_menu();
-  update_thickness_buttons();
-  update_color_buttons();
-  update_font_button();  
-  update_cursor(); // FIXME: can't know if pointer is within selection!
-}
-
 // modify the color or thickness of pen strokes in a selection
 
 void recolor_selection(int color_no, guint color_rgba)
diff --git a/src/xo-paint.h b/src/xo-paint.h
index 4ee4e40..8d69bd6 100644
--- a/src/xo-paint.h
+++ b/src/xo-paint.h
@@ -38,8 +38,6 @@ void continue_resizesel(GdkEvent *event);
 void finalize_resizesel(void);
 
 void selection_delete(void);
-void selection_to_clip(void);
-void clipboard_paste(void);
 
 void recolor_selection(int color_no, guint color_rgba);
 void rethicken_selection(int val);
diff --git a/src/xo-print.c b/src/xo-print.c
index 2cfc18e..942716d 100644
--- a/src/xo-print.c
+++ b/src/xo-print.c
@@ -704,24 +704,24 @@ void pdf_draw_solid_background(struct Page *pg, GString *str)
   if (pg->bg->ruling == RULING_NONE) return;
   g_string_append_printf(str,
     "%.2f %.2f %.2f RG %.2f w ",
-    RGBA_RGB(RULING_COLOR), RULING_THICKNESS);
+    RGBA_RGB(pg->bg->ruling_color), pg->bg->ruling_thickness);
   if (pg->bg->ruling == RULING_GRAPH) {
-    for (x=RULING_GRAPHSPACING; x<pg->width-1; x+=RULING_GRAPHSPACING)
+    for (x=pg->bg->ruling_graphspacing; x<pg->width-1; x+=pg->bg->ruling_graphspacing)
       g_string_append_printf(str, "%.2f 0 m %.2f %.2f l S ",
         x, x, pg->height);
-    for (y=RULING_GRAPHSPACING; y<pg->height-1; y+=RULING_GRAPHSPACING)
+    for (y=pg->bg->ruling_graphspacing; y<pg->height-1; y+=pg->bg->ruling_graphspacing)
       g_string_append_printf(str, "0 %.2f m %.2f %.2f l S ",
         y, pg->width, y);
     return;
   }
-  for (y=RULING_TOPMARGIN; y<pg->height-1; y+=RULING_SPACING)
+  for (y=pg->bg->ruling_topmargin; y<pg->height-1; y+=pg->bg->ruling_spacing)
     g_string_append_printf(str, "0 %.2f m %.2f %.2f l S ",
       y, pg->width, y);
   if (pg->bg->ruling == RULING_LINED)
     g_string_append_printf(str, 
       "%.2f %.2f %.2f RG %.2f 0 m %.2f %.2f l S ",
-      RGBA_RGB(RULING_MARGIN_COLOR), 
-      RULING_LEFTMARGIN, RULING_LEFTMARGIN, pg->height);
+      RGBA_RGB(pg->bg->ruling_margin_color), 
+      pg->bg->ruling_leftmargin, pg->bg->ruling_leftmargin, pg->height);
 }
 
 int pdf_draw_bitmap_background(struct Page *pg, GString *str, 
@@ -787,6 +787,81 @@ int pdf_draw_bitmap_background(struct Page *pg, GString *str,
   return xref->last;
 }
 
+gboolean pdf_draw_image(PdfImage *image, struct XrefTable *xref, GString *pdfbuf)
+{
+  char *buf, *p1, *p2;
+  int height, width, stride, x, y, chan;
+  GString *zpix;
+
+  if (gdk_pixbuf_get_bits_per_sample(image->pixbuf) != 8 ||
+      gdk_pixbuf_get_colorspace(image->pixbuf) != GDK_COLORSPACE_RGB) {
+    return FALSE;
+  }
+
+  width = gdk_pixbuf_get_width(image->pixbuf);
+  height = gdk_pixbuf_get_height(image->pixbuf);
+  stride = gdk_pixbuf_get_rowstride(image->pixbuf);
+  chan = gdk_pixbuf_get_n_channels(image->pixbuf);
+  if (!((chan==3 && !image->has_alpha) || (chan==4 && image->has_alpha))) {
+    return FALSE;
+  }
+
+  p2 = buf = (char *)g_malloc(3*width*height);
+  for (y=0; y<height; y++) {
+    p1 = (char *)gdk_pixbuf_get_pixels(image->pixbuf)+stride*y;
+    for (x=0; x<width; x++) {
+      *(p2++)=*(p1++); *(p2++)=*(p1++); *(p2++)=*(p1++);
+      if (chan==4) p1++;
+    }
+  }
+  zpix = do_deflate(buf, 3*width*height);
+  g_free(buf);
+
+  xref->data[image->n_obj] = pdfbuf->len;
+  g_string_append_printf(pdfbuf, 
+    "%d 0 obj\n<< /Length %d /Filter /FlateDecode /Type /Xobject "
+    "/Subtype /Image /Width %d /Height %d /ColorSpace /DeviceRGB "
+    "/BitsPerComponent 8 ",
+    image->n_obj, zpix->len, width, height);
+  if (image->has_alpha) {
+    g_string_append_printf(pdfbuf, 
+      "/SMask %d 0 R ",
+      image->n_obj_smask);
+  }
+  g_string_append_printf(pdfbuf, " >> stream\n");
+
+  g_string_append_len(pdfbuf, zpix->str, zpix->len);
+  g_string_free(zpix, TRUE);
+  g_string_append(pdfbuf, "endstream\nendobj\n");
+
+  if (image->has_alpha) {
+    p2 = buf = (char *)g_malloc(width*height);
+    for (y=0; y<height; y++) {
+      p1 = (char *)gdk_pixbuf_get_pixels(image->pixbuf)+stride*y;
+      for (x=0; x<width; x++) {
+        p1+=3;                  /* skip the RGB */
+        *(p2++)=*(p1++);        /* just copy the alpha */
+      }
+    }
+    zpix = do_deflate(buf, width*height);
+    g_free(buf);
+    
+    xref->data[image->n_obj_smask] = pdfbuf->len;
+    g_string_append_printf(pdfbuf, 
+      "%d 0 obj\n<< /Length %d /Filter /FlateDecode /Type /Xobject "
+      "/Subtype /Image /Width %d /Height %d /ColorSpace /DeviceGray "
+      "/BitsPerComponent 8 >> stream\n",
+      image->n_obj_smask, zpix->len, width, height);
+
+    g_string_append_len(pdfbuf, zpix->str, zpix->len);
+    g_string_free(zpix, TRUE);
+    g_string_append(pdfbuf, "endstream\nendobj\n");
+  }
+
+  return TRUE;
+}
+
+
 // manipulate Pdf fonts
 
 struct PdfFont *new_pdffont(struct XrefTable *xref, GList **fonts,
@@ -1023,10 +1098,31 @@ void embed_pdffont(GString *pdfbuf, struct XrefTable *xref, struct PdfFont *font
   g_string_append(pdfbuf, ">> endobj\n");
 }
 
+// Pdf images
+
+struct PdfImage *new_pdfimage(struct XrefTable *xref, GList **images, GdkPixbuf *pixbuf)
+{
+  GList *list;
+  struct PdfImage *image;
+  
+  image = g_malloc(sizeof(struct PdfImage));
+  *images = g_list_append(*images, image);
+  image->n_obj = xref->last+1;
+  make_xref(xref, xref->last+1, 0); // will give it a value later
+  image->has_alpha = gdk_pixbuf_get_has_alpha(pixbuf);
+  if (image->has_alpha) {
+    image->n_obj_smask = xref->last+1;
+    make_xref(xref, xref->last+1, 0); // will give it a value later
+  }
+  image->pixbuf = pixbuf;
+
+  return image;
+}
+
 // draw a page's graphics
 
 void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter, 
-                  struct XrefTable *xref, GList **pdffonts)
+                   struct XrefTable *xref, GList **pdffonts, GList **pdfimages)
 {
   GList *layerlist, *itemlist, *tmplist;
   struct Layer *l;
@@ -1051,6 +1147,7 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter,
   int font_id;
   FT_Face ftface;
   struct PdfFont *cur_font;
+  struct PdfImage *cur_image;
   gboolean in_string;
   
   old_rgba = old_text_rgba = 0x12345678;    // not any values we use, so we'll reset them
@@ -1059,6 +1156,10 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter,
     cur_font = (struct PdfFont *)tmplist->data;
     cur_font->used_in_this_page = FALSE;
   }
+  for (tmplist = *pdfimages; tmplist!=NULL; tmplist = tmplist->next) {
+    cur_image = (struct PdfImage *)tmplist->data;
+    cur_image->used_in_this_page = FALSE;
+  }
 
   for (layerlist = pg->layers; layerlist!=NULL; layerlist = layerlist->next) {
     l = (struct Layer *)layerlist->data;
@@ -1178,6 +1279,14 @@ void pdf_draw_page(struct Page *pg, GString *str, gboolean *use_hiliter,
         pango_layout_iter_free(iter);
         g_object_unref(layout);
       }
+      else if  (item->type == ITEM_IMAGE) {
+        cur_image = new_pdfimage(xref, pdfimages, item->image);
+	cur_image->used_in_this_page = TRUE;
+        g_string_append_printf(str, "\nq 1 0 0 1 %.2f %.2f cm %.2f 0 0 %.2f 0 %.2f cm /Im%d Do Q ",
+           item->bbox.left, item->bbox.top, // translation
+           item->bbox.right-item->bbox.left, item->bbox.top-item->bbox.bottom, item->bbox.bottom-item->bbox.top, // scaling
+           cur_image->n_obj);
+      }
     }
   }
 }
@@ -1204,8 +1313,9 @@ gboolean print_to_pdf(char *filename)
   gboolean use_hiliter;
   struct PdfInfo pdfinfo;
   struct PdfObj *obj;
-  GList *pdffonts, *list;
+  GList *pdffonts, *pdfimages, *list;
   struct PdfFont *font;
+  struct PdfImage *image;
   char *tmpbuf;
   
   f = fopen(filename, "wb");
@@ -1215,6 +1325,7 @@ gboolean print_to_pdf(char *filename)
   xref.data = NULL;
   uses_pdf = FALSE;
   pdffonts = NULL;
+  pdfimages = NULL;
   for (pglist = journal.pages; pglist!=NULL; pglist = pglist->next) {
     pg = (struct Page *)pglist->data;
     if (pg->bg->type == BG_PDF) uses_pdf = TRUE;
@@ -1284,7 +1395,7 @@ gboolean print_to_pdf(char *filename)
       n_obj_bgpix = pdf_draw_bitmap_background(pg, pgstrm, &xref, pdfbuf);
     // draw the page contents
     use_hiliter = FALSE;
-    pdf_draw_page(pg, pgstrm, &use_hiliter, &xref, &pdffonts);
+    pdf_draw_page(pg, pgstrm, &use_hiliter, &xref, &pdffonts, &pdfimages);
     g_string_append_printf(pgstrm, "Q\n");
     
     // deflate pgstrm and write it
@@ -1340,7 +1451,7 @@ gboolean print_to_pdf(char *filename)
     }
     add_dict_subentry(pdfbuf, &xref,
         obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/PDF"));
-    if (n_obj_bgpix>0)
+    if (n_obj_bgpix>0 || pdfimages!=NULL)
       add_dict_subentry(pdfbuf, &xref,
         obj, "/ProcSet", PDFTYPE_ARRAY, NULL, mk_pdfname("/ImageC"));
     if (use_hiliter)
@@ -1360,12 +1471,21 @@ gboolean print_to_pdf(char *filename)
         g_free(tmpbuf);
       }
     }
+    for (list=pdfimages; list!=NULL; list = list->next) {
+      image = (struct PdfImage *)list->data;
+      if (image->used_in_this_page) {
+        tmpbuf = g_strdup_printf("/Im%d", image->n_obj);
+        add_dict_subentry(pdfbuf, &xref,
+          obj, "/XObject", PDFTYPE_DICT, tmpbuf, mk_pdfref(image->n_obj));
+        g_free(tmpbuf);
+      }
+    }
     show_pdfobj(obj, pdfbuf);
     free_pdfobj(obj);
     g_string_append(pdfbuf, " >> endobj\n");
   }
   
-  // after the pages, we insert fonts
+  // after the pages, we insert fonts and images
   for (list = pdffonts; list!=NULL; list = list->next) {
     font = (struct PdfFont *)list->data;
     embed_pdffont(pdfbuf, &xref, font);
@@ -1374,6 +1494,14 @@ gboolean print_to_pdf(char *filename)
     g_free(font);
   }
   g_list_free(pdffonts);
+  for (list = pdfimages; list!=NULL; list = list->next) {
+    image = (struct PdfImage *)list->data;
+    if (!pdf_draw_image(image, &xref, pdfbuf)) {
+      return FALSE;
+    }
+    g_free(image);
+  }
+  g_list_free(pdfimages);
   
   // PDF trailer
   startxref = pdfbuf->len;
@@ -1443,25 +1571,25 @@ void print_background(cairo_t *cr, struct Page *pg)
     cairo_fill(cr);
     if (!ui.print_ruling) return;
     if (pg->bg->ruling == RULING_NONE) return;
-    cairo_set_source_rgb(cr, RGBA_RGB(RULING_COLOR));
-    cairo_set_line_width(cr, RULING_THICKNESS);
+    cairo_set_source_rgb(cr, RGBA_RGB(pg->bg->ruling_color));
+    cairo_set_line_width(cr, pg->bg->ruling_thickness);
 
     if (pg->bg->ruling == RULING_GRAPH) {
-      for (x=RULING_GRAPHSPACING; x<pg->width-1; x+=RULING_GRAPHSPACING)
+      for (x=pg->bg->ruling_graphspacing; x<pg->width-1; x+=pg->bg->ruling_graphspacing)
         { cairo_move_to(cr, x, 0); cairo_line_to(cr, x, pg->height); }
-      for (y=RULING_GRAPHSPACING; y<pg->height-1; y+=RULING_GRAPHSPACING)
+      for (y=pg->bg->ruling_graphspacing; y<pg->height-1; y+=pg->bg->ruling_graphspacing)
         { cairo_move_to(cr, 0, y); cairo_line_to(cr, pg->width, y); }
       cairo_stroke(cr);
       return;
     }
     
-    for (y=RULING_TOPMARGIN; y<pg->height-1; y+=RULING_SPACING)
+    for (y=pg->bg->ruling_topmargin; y<pg->height-1; y+=pg->bg->ruling_spacing)
       { cairo_move_to(cr, 0, y); cairo_line_to(cr, pg->width, y); }
     cairo_stroke(cr);
     if (pg->bg->ruling == RULING_LINED) {
-      cairo_set_source_rgb(cr, RGBA_RGB(RULING_MARGIN_COLOR));
-      cairo_move_to(cr, RULING_LEFTMARGIN, 0);
-      cairo_line_to(cr, RULING_LEFTMARGIN, pg->height);
+      cairo_set_source_rgb(cr, RGBA_RGB(pg->bg->ruling_margin_color));
+      cairo_move_to(cr, pg->bg->ruling_leftmargin, 0);
+      cairo_line_to(cr, pg->bg->ruling_leftmargin, pg->height);
       cairo_stroke(cr);
     }
     return;
@@ -1565,6 +1693,16 @@ void print_job_render_page(GtkPrintOperation *print, GtkPrintContext *context, g
         pango_cairo_show_layout(cr, layout);
         g_object_unref(layout);
       }
+      if (item->type == ITEM_IMAGE) {
+        double scalex = (item->bbox.right-item->bbox.left)/gdk_pixbuf_get_width(item->image);
+        double scaley = (item->bbox.bottom-item->bbox.top)/gdk_pixbuf_get_height(item->image);
+        cairo_scale(cr, scalex, scaley);
+        gdk_cairo_set_source_pixbuf(cr,item->image, item->bbox.left/scalex, item->bbox.top/scaley);
+        cairo_scale(cr, 1/scalex, 1/scaley);
+        cairo_paint(cr);
+        old_rgba = predef_colors_rgba[COLOR_BLACK];
+        cairo_set_source_rgb(cr, 0, 0, 0);
+      }
     }
   }
 }
diff --git a/src/xo-print.h b/src/xo-print.h
index 95a96f7..498be84 100644
--- a/src/xo-print.h
+++ b/src/xo-print.h
@@ -60,6 +60,15 @@ typedef struct PdfFont {
   int flags;
 } PdfFont;
 
+typedef struct PdfImage {
+  int n_obj;
+  gboolean has_alpha;
+  int n_obj_smask;              /* only if has_alpha */
+  GdkPixbuf *pixbuf;
+  gboolean used_in_this_page;
+} PdfImage;
+
+
 #define PDFTYPE_CST 0    // intval: true=1, false=0, null=-1
 #define PDFTYPE_INT 1    // intval
 #define PDFTYPE_REAL 2   // realval
diff --git a/src/xournal.h b/src/xournal.h
index 605c823..c3b3852 100644
--- a/src/xournal.h
+++ b/src/xournal.h
@@ -86,6 +86,15 @@ typedef struct Background {
   double pixbuf_scale; // for PIXMAP, this is the *current* zoom value
                        // for PDF, this is the *requested* zoom value
   int pixel_height, pixel_width; // PDF only: pixel size of current pixbuf
+
+  guint ruling_margin_color;
+  guint ruling_color;
+  double ruling_thickness;
+  double ruling_leftmargin;
+  double ruling_topmargin;
+  double ruling_spacing;
+  double ruling_bottommargin;
+  double ruling_graphspacing;
 } Background;
 
 #define BG_SOLID 0
@@ -143,13 +152,15 @@ extern guint predef_bgcolors_rgba[COLOR_MAX];
 #define TOOL_SELECTRECT   5
 #define TOOL_VERTSPACE    6
 #define TOOL_HAND         7
+#define TOOL_IMAGE        8
 #define NUM_STROKE_TOOLS  3
-#define NUM_TOOLS         8
+#define NUM_TOOLS         9
 #define NUM_BUTTONS       3
 
 #define TOOLOPT_ERASER_STANDARD     0
 #define TOOLOPT_ERASER_WHITEOUT     1
 #define TOOLOPT_ERASER_STROKES      2
+#define TOOLOPT_SELECT_PRESERVE     1 // Preserve the aspect ratio of the selection when resizing
 
 extern double predef_thickness[NUM_STROKE_TOOLS][THICKNESS_MAX];
 
@@ -173,6 +184,10 @@ typedef struct Item {
   gchar *font_name;
   gdouble font_size;
   GtkWidget *widget; // the widget while text is being edited (ITEM_TEMP_TEXT)
+  // the following fields for ITEM_IMAGE:
+  GdkPixbuf *image;  // the image
+  gchar *image_png;  // PNG of original image, for save and clipboard
+  gsize image_png_len;
 } Item;
 
 // item type values for Item.type, UndoItem.type, ui.cur_item_type ...
@@ -201,6 +216,7 @@ typedef struct Item {
 #define ITEM_TEXT_ATTRIB 21
 #define ITEM_RESIZESEL 22
 #define ITEM_RECOGNIZER 23
+#define ITEM_IMAGE 24
 
 typedef struct Layer {
   GList *items; // the items on the layer, from bottom to top
@@ -275,14 +291,13 @@ typedef struct UIData {
   gboolean hand_scrollto_pending;
   char *filename;
   gchar *default_path; // default path for new notes
+  gchar *default_image; // path for previous image
   gboolean view_continuous, fullscreen, maximize_at_start;
   gboolean in_update_page_stuff; // semaphore to avoid scrollbar retroaction
   struct Selection *selection;
   GdkCursor *cursor;
   gboolean progressive_bg; // update PDF bg's one at a time
   char *mrufile, *configfile; // file names for MRU & config
-  char *mru[MRU_SIZE]; // MRU data
-  GtkWidget *mrumenu[MRU_SIZE];
   gboolean bg_apply_all_pages;
   int window_default_width, window_default_height, scrollbar_step_increment;
   gboolean print_ruling; // print the paper ruling ?
@@ -326,8 +341,8 @@ typedef struct UndoErasureData {
 
 typedef struct UndoItem {
   int type;
-  struct Item *item; // for ITEM_STROKE, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_TEXT_ATTRIB
-  struct Layer *layer; // for ITEM_STROKE, ITEM_ERASURE, ITEM_PASTE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_MOVESEL, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_RECOGNIZER
+  struct Item *item; // for ITEM_STROKE, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_TEXT_ATTRIB, ITEM_IMAGE
+  struct Layer *layer; // for ITEM_STROKE, ITEM_ERASURE, ITEM_PASTE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_MOVESEL, ITEM_TEXT, ITEM_TEXT_EDIT, ITEM_RECOGNIZER, ITEM_IMAGE
   struct Layer *layer2; // for ITEM_DELETE_LAYER with val=-1, ITEM_MOVESEL
   struct Page *page;  // for ITEM_NEW_BG_ONE/RESIZE, ITEM_NEW_PAGE, ITEM_NEW_LAYER, ITEM_DELETE_LAYER, ITEM_DELETE_PAGE
   GList *erasurelist; // for ITEM_ERASURE, ITEM_RECOGNIZER
diff --git a/xournal.glade b/xournal.glade
index cebf20f..5bcf327 100644
--- a/xournal.glade
+++ b/xournal.glade
@@ -58,7 +58,7 @@
 		      <signal name="activate" handler="on_fileNewBackground_activate" last_modification_time="Wed, 30 Nov 2005 18:39:59 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image623">
+			<widget class="GtkImage" id="image656">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-open</property>
 			  <property name="icon_size">1</property>
@@ -203,7 +203,7 @@
 		      <signal name="activate" handler="on_filePrintOptions_activate" last_modification_time="Wed, 30 Nov 2005 18:44:18 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image624">
+			<widget class="GtkImage" id="image657">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-preferences</property>
 			  <property name="icon_size">1</property>
@@ -432,7 +432,7 @@
 			      <accelerator key="equal" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 			      <child internal-child="image">
-				<widget class="GtkImage" id="image625">
+				<widget class="GtkImage" id="image658">
 				  <property name="visible">True</property>
 				  <property name="stock">gtk-zoom-fit</property>
 				  <property name="icon_size">1</property>
@@ -473,7 +473,7 @@
 		      <accelerator key="Home" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image626">
+			<widget class="GtkImage" id="image659">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-goto-first</property>
 			  <property name="icon_size">1</property>
@@ -495,7 +495,7 @@
 		      <accelerator key="Left" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image627">
+			<widget class="GtkImage" id="image660">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-go-back</property>
 			  <property name="icon_size">1</property>
@@ -517,7 +517,7 @@
 		      <accelerator key="Right" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image628">
+			<widget class="GtkImage" id="image661">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-go-forward</property>
 			  <property name="icon_size">1</property>
@@ -539,7 +539,7 @@
 		      <accelerator key="End" modifiers="GDK_CONTROL_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image629">
+			<widget class="GtkImage" id="image662">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-goto-last</property>
 			  <property name="icon_size">1</property>
@@ -566,7 +566,7 @@
 		      <signal name="activate" handler="on_viewShowLayer_activate" last_modification_time="Wed, 30 Nov 2005 19:40:23 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image630">
+			<widget class="GtkImage" id="image663">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-add</property>
 			  <property name="icon_size">1</property>
@@ -587,7 +587,7 @@
 		      <signal name="activate" handler="on_viewHideLayer_activate" last_modification_time="Wed, 30 Nov 2005 19:40:23 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image631">
+			<widget class="GtkImage" id="image664">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-remove</property>
 			  <property name="icon_size">1</property>
@@ -607,7 +607,7 @@
 	  <child>
 	    <widget class="GtkMenuItem" id="menuJournal">
 	      <property name="visible">True</property>
-	      <property name="label" translatable="yes">_Journal</property>
+	      <property name="label" translatable="yes">_Page</property>
 	      <property name="use_underline">True</property>
 
 	      <child>
@@ -689,6 +689,25 @@
 		  </child>
 
 		  <child>
+		    <widget class="GtkMenuItem" id="journalRulingParams">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Ruling Parameters</property>
+		      <property name="use_underline">True</property>
+		      <signal name="activate" handler="on_journalRulingParams_activate" last_modification_time="Sun, 29 Nov 2009 06:11:08 GMT"/>
+		    </widget>
+		  </child>
+
+		  <child>
+		    <widget class="GtkMenuItem" id="invert_colors">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Invert Colors (all pages)</property>
+		      <property name="use_underline">True</property>
+		      <signal name="activate" handler="on_invert_colors_activate" last_modification_time="Sat, 26 Dec 2009 23:44:59 GMT"/>
+		      <accelerator key="I" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
+		    </widget>
+		  </child>
+
+		  <child>
 		    <widget class="GtkMenuItem" id="journalPaperSize">
 		      <property name="visible">True</property>
 		      <property name="label" translatable="yes">Paper Si_ze</property>
@@ -882,7 +901,7 @@
 		      <signal name="activate" handler="on_journalLoadBackground_activate" last_modification_time="Wed, 30 Nov 2005 20:06:31 GMT"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image632">
+			<widget class="GtkImage" id="image665">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-open</property>
 			  <property name="icon_size">1</property>
@@ -989,6 +1008,18 @@
 		  </child>
 
 		  <child>
+		    <widget class="GtkRadioMenuItem" id="toolsImage">
+		      <property name="visible">True</property>
+		      <property name="label" translatable="yes">_Image</property>
+		      <property name="use_underline">True</property>
+		      <property name="active">True</property>
+		      <property name="group">toolsPen</property>
+		      <signal name="toggled" handler="on_toolsImage_activate" last_modification_time="Wed, 27 Jun 2012 20:54:08 GMT"/>
+		      <accelerator key="I" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
+		    </widget>
+		  </child>
+
+		  <child>
 		    <widget class="GtkSeparatorMenuItem" id="separator15">
 		      <property name="visible">True</property>
 		    </widget>
@@ -1063,7 +1094,7 @@
 		      <property name="visible">True</property>
 		      <property name="label" translatable="yes">H_and Tool</property>
 		      <property name="use_underline">True</property>
-		      <property name="active">False</property>
+		      <property name="active">True</property>
 		      <property name="group">toolsPen</property>
 		      <signal name="activate" handler="on_toolsHand_activate" last_modification_time="Wed, 20 Sep 2006 02:20:48 GMT"/>
 		      <accelerator key="A" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
@@ -1083,7 +1114,7 @@
 		      <property name="use_underline">True</property>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image633">
+			<widget class="GtkImage" id="image666">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-select-color</property>
 			  <property name="icon_size">1</property>
@@ -1449,7 +1480,7 @@
 		      <accelerator key="F" modifiers="GDK_CONTROL_MASK | GDK_SHIFT_MASK" signal="activate"/>
 
 		      <child internal-child="image">
-			<widget class="GtkImage" id="image634">
+			<widget class="GtkImage" id="image667">
 			  <property name="visible">True</property>
 			  <property name="stock">gtk-select-font</property>
 			  <property name="icon_size">1</property>
@@ -1609,6 +1640,17 @@
 			  </child>
 
 			  <child>
+			    <widget class="GtkRadioMenuItem" id="button2Image">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">_Image</property>
+			      <property name="use_underline">True</property>
+			      <property name="active">True</property>
+			      <property name="group">button2Pen</property>
+			      <signal name="activate" handler="on_button2Image_activate" last_modification_time="Wed, 27 Jun 2012 14:33:10 GMT"/>
+			    </widget>
+			  </child>
+
+			  <child>
 			    <widget class="GtkRadioMenuItem" id="button2SelectRegion">
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">Select Re_gion</property>
@@ -1646,7 +1688,7 @@
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">H_and Tool</property>
 			      <property name="use_underline">True</property>
-			      <property name="active">False</property>
+			      <property name="active">True</property>
 			      <property name="group">button2Pen</property>
 			      <signal name="activate" handler="on_button2Hand_activate" last_modification_time="Wed, 20 Sep 2006 02:20:48 GMT"/>
 			    </widget>
@@ -1745,6 +1787,17 @@
 			  </child>
 
 			  <child>
+			    <widget class="GtkRadioMenuItem" id="button3Image">
+			      <property name="visible">True</property>
+			      <property name="label" translatable="yes">_Image</property>
+			      <property name="use_underline">True</property>
+			      <property name="active">True</property>
+			      <property name="group">button3Pen</property>
+			      <signal name="activate" handler="on_button3Image_activate" last_modification_time="Wed, 27 Jun 2012 14:33:10 GMT"/>
+			    </widget>
+			  </child>
+
+			  <child>
 			    <widget class="GtkRadioMenuItem" id="button3SelectRegion">
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">Select Re_gion</property>
@@ -1782,7 +1835,7 @@
 			      <property name="visible">True</property>
 			      <property name="label" translatable="yes">H_and Tool</property>
 			      <property name="use_underline">True</property>
-			      <property name="active">False</property>
+			      <property name="active">True</property>
 			      <property name="group">button3Pen</property>
 			      <signal name="activate" handler="on_button3Hand_activate" last_modification_time="Wed, 20 Sep 2006 02:20:48 GMT"/>
 			    </widget>
@@ -2431,6 +2484,26 @@
 	  </child>
 
 	  <child>
+	    <widget class="GtkRadioToolButton" id="buttonImage">
+	      <property name="visible">True</property>
+	      <property name="tooltip" translatable="yes">Image</property>
+	      <property name="label" translatable="yes">Image</property>
+	      <property name="use_underline">True</property>
+	      <property name="stock_id">gtk-orientation-portrait</property>
+	      <property name="visible_horizontal">True</property>
+	      <property name="visible_vertical">True</property>
+	      <property name="is_important">False</property>
+	      <property name="active">False</property>
+	      <property name="group">buttonPen</property>
+	      <signal name="toggled" handler="on_toolsImage_activate" last_modification_time="Wed, 27 Jun 2012 20:49:10 GMT"/>
+	    </widget>
+	    <packing>
+	      <property name="expand">False</property>
+	      <property name="homogeneous">True</property>
+	    </packing>
+	  </child>
+
+	  <child>
 	    <widget class="GtkToggleToolButton" id="buttonReco">
 	      <property name="visible">True</property>
 	      <property name="tooltip" translatable="yes">Shape Recognizer</property>
@@ -3820,4 +3893,508 @@ and other contributors
   </child>
 </widget>
 
+<widget class="GtkDialog" id="rulingDialog">
+  <property name="visible">True</property>
+  <property name="title" translatable="yes">Set ruling parameters</property>
+  <property name="type">GTK_WINDOW_TOPLEVEL</property>
+  <property name="window_position">GTK_WIN_POS_NONE</property>
+  <property name="modal">False</property>
+  <property name="resizable">True</property>
+  <property name="destroy_with_parent">False</property>
+  <property name="decorated">True</property>
+  <property name="skip_taskbar_hint">False</property>
+  <property name="skip_pager_hint">False</property>
+  <property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
+  <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
+  <property name="focus_on_map">True</property>
+  <property name="urgency_hint">False</property>
+  <property name="has_separator">True</property>
+
+  <child internal-child="vbox">
+    <widget class="GtkVBox" id="dialog-vbox4">
+      <property name="visible">True</property>
+      <property name="homogeneous">False</property>
+      <property name="spacing">0</property>
+
+      <child internal-child="action_area">
+	<widget class="GtkHButtonBox" id="dialog-action_area4">
+	  <property name="visible">True</property>
+	  <property name="layout_style">GTK_BUTTONBOX_END</property>
+
+	  <child>
+	    <widget class="GtkButton" id="cancelbutton3">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-cancel</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-6</property>
+	    </widget>
+	  </child>
+
+	  <child>
+	    <widget class="GtkButton" id="okbutton2">
+	      <property name="visible">True</property>
+	      <property name="can_default">True</property>
+	      <property name="can_focus">True</property>
+	      <property name="label">gtk-ok</property>
+	      <property name="use_stock">True</property>
+	      <property name="relief">GTK_RELIEF_NORMAL</property>
+	      <property name="focus_on_click">True</property>
+	      <property name="response_id">-5</property>
+	    </widget>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">0</property>
+	  <property name="expand">False</property>
+	  <property name="fill">True</property>
+	  <property name="pack_type">GTK_PACK_END</property>
+	</packing>
+      </child>
+
+      <child>
+	<widget class="GtkHBox" id="hbox5">
+	  <property name="visible">True</property>
+	  <property name="homogeneous">False</property>
+	  <property name="spacing">0</property>
+
+	  <child>
+	    <widget class="GtkTable" id="table1">
+	      <property name="visible">True</property>
+	      <property name="n_rows">8</property>
+	      <property name="n_columns">2</property>
+	      <property name="homogeneous">False</property>
+	      <property name="row_spacing">5</property>
+	      <property name="column_spacing">6</property>
+
+	      <child>
+		<widget class="GtkEntry" id="rd_margin_color">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">RGBA color of the left margin</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">8</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">8</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkEntry" id="rd_ruling_color">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">RGBA color of ruling lines</property>
+		  <property name="can_focus">True</property>
+		  <property name="editable">True</property>
+		  <property name="visibility">True</property>
+		  <property name="max_length">8</property>
+		  <property name="text" translatable="yes"></property>
+		  <property name="has_frame">True</property>
+		  <property name="invisible_char">*</property>
+		  <property name="activates_default">False</property>
+		  <property name="width_chars">8</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkSpinButton" id="rd_thickness">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">Thickness (points) of ruling lines</property>
+		  <property name="can_focus">True</property>
+		  <property name="climb_rate">1</property>
+		  <property name="digits">3</property>
+		  <property name="numeric">True</property>
+		  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+		  <property name="snap_to_ticks">False</property>
+		  <property name="wrap">False</property>
+		  <property name="adjustment">1 0 100 0.10000000149 10 0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkSpinButton" id="rd_left_margin">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">Thickness (points) of left margin</property>
+		  <property name="can_focus">True</property>
+		  <property name="climb_rate">1</property>
+		  <property name="digits">3</property>
+		  <property name="numeric">True</property>
+		  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+		  <property name="snap_to_ticks">False</property>
+		  <property name="wrap">False</property>
+		  <property name="adjustment">1 0 100 1 10 0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkSpinButton" id="rd_top_margin">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">Thickness (points) of top margin</property>
+		  <property name="can_focus">True</property>
+		  <property name="climb_rate">1</property>
+		  <property name="digits">3</property>
+		  <property name="numeric">True</property>
+		  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+		  <property name="snap_to_ticks">False</property>
+		  <property name="wrap">False</property>
+		  <property name="adjustment">1 0 100 1 10 0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">4</property>
+		  <property name="bottom_attach">5</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkSpinButton" id="rd_spacing">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">Spacing (points) between lines</property>
+		  <property name="can_focus">True</property>
+		  <property name="climb_rate">1</property>
+		  <property name="digits">3</property>
+		  <property name="numeric">True</property>
+		  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+		  <property name="snap_to_ticks">False</property>
+		  <property name="wrap">False</property>
+		  <property name="adjustment">1 0 100 0.5 10 0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">5</property>
+		  <property name="bottom_attach">6</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkSpinButton" id="rd_bottom_margin">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">Bottom margin (points)</property>
+		  <property name="can_focus">True</property>
+		  <property name="climb_rate">1</property>
+		  <property name="digits">3</property>
+		  <property name="numeric">True</property>
+		  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+		  <property name="snap_to_ticks">False</property>
+		  <property name="wrap">False</property>
+		  <property name="adjustment">1 0 100 1 10 0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">6</property>
+		  <property name="bottom_attach">7</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkSpinButton" id="rd_graph_spacing">
+		  <property name="visible">True</property>
+		  <property name="tooltip" translatable="yes">Size of graph squares (points). Divide paper dimensions by the number of squares to get this</property>
+		  <property name="can_focus">True</property>
+		  <property name="climb_rate">1</property>
+		  <property name="digits">3</property>
+		  <property name="numeric">True</property>
+		  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
+		  <property name="snap_to_ticks">False</property>
+		  <property name="wrap">False</property>
+		  <property name="adjustment">1 0 100 0.10000000149 10 0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">1</property>
+		  <property name="right_attach">2</property>
+		  <property name="top_attach">7</property>
+		  <property name="bottom_attach">8</property>
+		  <property name="x_options">fill</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label2">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Margin color</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">0</property>
+		  <property name="bottom_attach">1</property>
+		  <property name="x_options">expand</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label3">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Ruling color</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">1</property>
+		  <property name="bottom_attach">2</property>
+		  <property name="x_options">expand</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label4">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Thickness</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">2</property>
+		  <property name="bottom_attach">3</property>
+		  <property name="x_options">expand</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label5">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Left margin</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">3</property>
+		  <property name="bottom_attach">4</property>
+		  <property name="x_options">expand</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label6">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Top margin</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">4</property>
+		  <property name="bottom_attach">5</property>
+		  <property name="x_options">expand</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label7">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Spacing</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">5</property>
+		  <property name="bottom_attach">6</property>
+		  <property name="x_options">expand</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label8">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Bottom margin</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">6</property>
+		  <property name="bottom_attach">7</property>
+		  <property name="x_options">expand</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+
+	      <child>
+		<widget class="GtkLabel" id="label9">
+		  <property name="visible">True</property>
+		  <property name="label" translatable="yes">Graph spacing</property>
+		  <property name="use_underline">False</property>
+		  <property name="use_markup">False</property>
+		  <property name="justify">GTK_JUSTIFY_LEFT</property>
+		  <property name="wrap">False</property>
+		  <property name="selectable">False</property>
+		  <property name="xalign">0</property>
+		  <property name="yalign">0.5</property>
+		  <property name="xpad">0</property>
+		  <property name="ypad">0</property>
+		  <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
+		  <property name="width_chars">-1</property>
+		  <property name="single_line_mode">False</property>
+		  <property name="angle">0</property>
+		</widget>
+		<packing>
+		  <property name="left_attach">0</property>
+		  <property name="right_attach">1</property>
+		  <property name="top_attach">7</property>
+		  <property name="bottom_attach">8</property>
+		  <property name="x_options">expand</property>
+		  <property name="y_options"></property>
+		</packing>
+	      </child>
+	    </widget>
+	    <packing>
+	      <property name="padding">10</property>
+	      <property name="expand">True</property>
+	      <property name="fill">False</property>
+	    </packing>
+	  </child>
+	</widget>
+	<packing>
+	  <property name="padding">10</property>
+	  <property name="expand">True</property>
+	  <property name="fill">False</property>
+	</packing>
+      </child>
+    </widget>
+  </child>
+</widget>
+
 </glade-interface>
