[Xfce4-commits] <mousepad:master> * Import my Mousepad rewrite

Nick Schermer noreply at xfce.org
Sat May 5 21:30:02 CEST 2012


Updating branch refs/heads/master
         to 8a402ec2206b15649d4bc1a50621d3a52f11dd2b (commit)
       from 1bd002d711d108435b12b0cf7aa694b908cd63ed (commit)

commit 8a402ec2206b15649d4bc1a50621d3a52f11dd2b
Author: Nick Schermer <nick at xfce.org>
Date:   Tue Feb 27 17:02:14 2007 +0000

    * Import my Mousepad rewrite
    
    
    (Old svn revision: 25036)

 AUTHORS                          |    3 +
 COPYING                          |  340 ++++++++
 INSTALL                          |  231 +++++
 Makefile.am                      |   40 +
 Mousepad.desktop.in.in           |   13 +
 NEWS                             |   29 +
 TODO                             |   27 +
 autogen.sh                       |   37 +
 configure.in.in                  |  238 +++++
 icons/16x16/Makefile.am          |   10 +
 icons/16x16/Mousepad.png         |  Bin 0 -> 574 bytes
 icons/24x24/Makefile.am          |   10 +
 icons/24x24/Mousepad.png         |  Bin 0 -> 972 bytes
 icons/Makefile.am                |   21 +
 icons/scalable/Makefile.am       |   10 +
 icons/scalable/Mousepad.svg      |  552 ++++++++++++
 mousepad/Makefile.am             |   93 ++
 mousepad/main.c                  |  182 ++++
 mousepad/mousepad-application.c  |  239 +++++
 mousepad/mousepad-application.h  |   52 ++
 mousepad/mousepad-dbus-infos.xml |   15 +
 mousepad/mousepad-dbus.c         |  247 ++++++
 mousepad/mousepad-dbus.h         |   44 +
 mousepad/mousepad-file.c         |  331 +++++++
 mousepad/mousepad-file.h         |   46 +
 mousepad/mousepad-preferences.c  |  544 ++++++++++++
 mousepad/mousepad-preferences.h  |   43 +
 mousepad/mousepad-private.h      |   75 ++
 mousepad/mousepad-screen.c       |  607 +++++++++++++
 mousepad/mousepad-screen.h       |   67 ++
 mousepad/mousepad-tab-label.c    |  265 ++++++
 mousepad/mousepad-tab-label.h    |   41 +
 mousepad/mousepad-view.c         |  554 ++++++++++++
 mousepad/mousepad-view.h         |   45 +
 mousepad/mousepad-window-ui.xml  |   65 ++
 mousepad/mousepad-window.c       | 1779 ++++++++++++++++++++++++++++++++++++++
 mousepad/mousepad-window.h       |   48 +
 po/LINGUAS                       |    1 +
 po/Mousepad.pot                  |  225 +++++
 po/POTFILES.in                   |    6 +
 40 files changed, 7175 insertions(+), 0 deletions(-)

diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..e39278b
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Erik Harrison <erikharrison at xfce.org>
+Nick Schermer <nick at xfce.org>
+Benedikt Meurer <benny at xfce.org>
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..d60c31a
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..095b1eb
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,231 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
+Software Foundation, Inc.
+
+This file is free documentation; the Free Software Foundation gives
+unlimited permission to copy, distribute and modify it.
+
+Basic Installation
+==================
+
+These are generic installation instructions.
+
+   The `configure' shell script attempts to guess correct values for
+various system-dependent variables used during compilation.  It uses
+those values to create a `Makefile' in each directory of the package.
+It may also create one or more `.h' files containing system-dependent
+definitions.  Finally, it creates a shell script `config.status' that
+you can run in the future to recreate the current configuration, and a
+file `config.log' containing compiler output (useful mainly for
+debugging `configure').
+
+   It can also use an optional file (typically called `config.cache'
+and enabled with `--cache-file=config.cache' or simply `-C') that saves
+the results of its tests to speed up reconfiguring.  (Caching is
+disabled by default to prevent problems with accidental use of stale
+cache files.)
+
+   If you need to do unusual things to compile the package, please try
+to figure out how `configure' could check whether to do them, and mail
+diffs or instructions to the address given in the `README' so they can
+be considered for the next release.  If you are using the cache, and at
+some point `config.cache' contains results you don't want to keep, you
+may remove or edit it.
+
+   The file `configure.ac' (or `configure.in') is used to create
+`configure' by a program called `autoconf'.  You only need
+`configure.ac' if you want to change it or regenerate `configure' using
+a newer version of `autoconf'.
+
+The simplest way to compile this package is:
+
+  1. `cd' to the directory containing the package's source code and type
+     `./configure' to configure the package for your system.  If you're
+     using `csh' on an old version of System V, you might need to type
+     `sh ./configure' instead to prevent `csh' from trying to execute
+     `configure' itself.
+
+     Running `configure' takes awhile.  While running, it prints some
+     messages telling which features it is checking for.
+
+  2. Type `make' to compile the package.
+
+  3. Optionally, type `make check' to run any self-tests that come with
+     the package.
+
+  4. Type `make install' to install the programs and any data files and
+     documentation.
+
+  5. You can remove the program binaries and object files from the
+     source code directory by typing `make clean'.  To also remove the
+     files that `configure' created (so you can compile the package for
+     a different kind of computer), type `make distclean'.  There is
+     also a `make maintainer-clean' target, but that is intended mainly
+     for the package's developers.  If you use it, you may have to get
+     all sorts of other programs in order to regenerate files that came
+     with the distribution.
+
+Compilers and Options
+=====================
+
+Some systems require unusual options for compilation or linking that the
+`configure' script does not know about.  Run `./configure --help' for
+details on some of the pertinent environment variables.
+
+   You can give `configure' initial values for configuration parameters
+by setting variables in the command line or in the environment.  Here
+is an example:
+
+     ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
+
+   *Note Defining Variables::, for more details.
+
+Compiling For Multiple Architectures
+====================================
+
+You can compile the package for more than one kind of computer at the
+same time, by placing the object files for each architecture in their
+own directory.  To do this, you must use a version of `make' that
+supports the `VPATH' variable, such as GNU `make'.  `cd' to the
+directory where you want the object files and executables to go and run
+the `configure' script.  `configure' automatically checks for the
+source code in the directory that `configure' is in and in `..'.
+
+   If you have to use a `make' that does not support the `VPATH'
+variable, you have to compile the package for one architecture at a
+time in the source code directory.  After you have installed the
+package for one architecture, use `make distclean' before reconfiguring
+for another architecture.
+
+Installation Names
+==================
+
+By default, `make install' will install the package's files in
+`/usr/local/bin', `/usr/local/man', etc.  You can specify an
+installation prefix other than `/usr/local' by giving `configure' the
+option `--prefix=PREFIX'.
+
+   You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files.  If you
+give `configure' the option `--exec-prefix=PREFIX', the package will
+use PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files will still use the regular prefix.
+
+   In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' to specify different values for particular
+kinds of files.  Run `configure --help' for a list of the directories
+you can set and what kinds of files go in them.
+
+   If the package supports it, you can cause programs to be installed
+with an extra prefix or suffix on their names by giving `configure' the
+option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
+
+Optional Features
+=================
+
+Some packages pay attention to `--enable-FEATURE' options to
+`configure', where FEATURE indicates an optional part of the package.
+They may also pay attention to `--with-PACKAGE' options, where PACKAGE
+is something like `gnu-as' or `x' (for the X Window System).  The
+`README' should mention any `--enable-' and `--with-' options that the
+package recognizes.
+
+   For packages that use the X Window System, `configure' can usually
+find the X include and library files automatically, but if it doesn't,
+you can use the `configure' options `--x-includes=DIR' and
+`--x-libraries=DIR' to specify their locations.
+
+Specifying the System Type
+==========================
+
+There may be some features `configure' cannot figure out automatically,
+but needs to determine by the type of machine the package will run on.
+Usually, assuming the package is built to be run on the _same_
+architectures, `configure' can figure that out, but if it prints a
+message saying it cannot guess the machine type, give it the
+`--build=TYPE' option.  TYPE can either be a short name for the system
+type, such as `sun4', or a canonical name which has the form:
+
+     CPU-COMPANY-SYSTEM
+
+where SYSTEM can have one of these forms:
+
+     OS KERNEL-OS
+
+   See the file `config.sub' for the possible values of each field.  If
+`config.sub' isn't included in this package, then this package doesn't
+need to know the machine type.
+
+   If you are _building_ compiler tools for cross-compiling, you should
+use the `--target=TYPE' option to select the type of system they will
+produce code for.
+
+   If you want to _use_ a cross compiler, that generates code for a
+platform different from the build platform, you should specify the
+"host" platform (i.e., that on which the generated programs will
+eventually be run) with `--host=TYPE'.
+
+Sharing Defaults
+================
+
+If you want to set default values for `configure' scripts to share, you
+can create a site shell script called `config.site' that gives default
+values for variables like `CC', `cache_file', and `prefix'.
+`configure' looks for `PREFIX/share/config.site' if it exists, then
+`PREFIX/etc/config.site' if it exists.  Or, you can set the
+`CONFIG_SITE' environment variable to the location of the site script.
+A warning: not all `configure' scripts look for a site script.
+
+Defining Variables
+==================
+
+Variables not defined in a site shell script can be set in the
+environment passed to `configure'.  However, some packages may run
+configure again during the build, and the customized values of these
+variables may be lost.  In order to avoid this problem, you should set
+them in the `configure' command line, using `VAR=value'.  For example:
+
+     ./configure CC=/usr/local2/bin/gcc
+
+will cause the specified gcc to be used as the C compiler (unless it is
+overridden in the site shell script).
+
+`configure' Invocation
+======================
+
+`configure' recognizes the following options to control how it operates.
+
+`--help'
+`-h'
+     Print a summary of the options to `configure', and exit.
+
+`--version'
+`-V'
+     Print the version of Autoconf used to generate the `configure'
+     script, and exit.
+
+`--cache-file=FILE'
+     Enable the cache: use and save the results of the tests in FILE,
+     traditionally `config.cache'.  FILE defaults to `/dev/null' to
+     disable caching.
+
+`--config-cache'
+`-C'
+     Alias for `--cache-file=config.cache'.
+
+`--quiet'
+`--silent'
+`-q'
+     Do not print messages saying which checks are being made.  To
+     suppress all normal output, redirect it to `/dev/null' (any error
+     messages will still be shown).
+
+`--srcdir=DIR'
+     Look for the package's source code in directory DIR.  Usually
+     `configure' can determine that directory automatically.
+
+`configure' also accepts some other, not widely useful, options.  Run
+`configure --help' for more details.
+
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..039c6a0
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,40 @@
+# $Id$
+
+SUBDIRS =								\
+	icons								\
+	mousepad                                                        \
+	po
+
+distclean-local:
+	rm -rf *.spec *.cache *~
+
+rpm: dist
+	rpmbuild -ta $(PACKAGE)-$(VERSION).tar.gz
+	@rm -f $(PACKAGE)-$(VERSION).tar.gz
+
+desktopdir = $(datadir)/applications
+desktop_in_in_files = 							\
+	Mousepad.desktop.in.in
+desktop_in_files = $(desktop_in_in_files:.desktop.in.in=.desktop.in)
+%.desktop.in: %.desktop.in.in
+	sed -e "s,\@libexecdir\@,$(libexecdir),g" < $< > $@
+desktop_DATA = $(desktop_in_files:.desktop.in=.desktop)
+ at INTLTOOL_DESKTOP_RULE@
+
+EXTRA_DIST =								\
+	intltool-extract.in						\
+	intltool-merge.in						\
+	intltool-update.in						\
+	$(desktop_in_in_files)
+
+DISTCLEANFILES =							\
+	intltool-extract						\
+	intltool-merge							\
+	intltool-update							\
+	$(desktop_in_files)						\
+	$(desktop_DATA)
+
+DISTCHECK_CONFIGURE_FLAGS =						\
+	--enable-gtk-doc
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/Mousepad.desktop.in.in b/Mousepad.desktop.in.in
new file mode 100644
index 0000000..875f1b7
--- /dev/null
+++ b/Mousepad.desktop.in.in
@@ -0,0 +1,13 @@
+
+[Desktop Entry]
+Encoding=UTF-8
+_Name=Mousepad
+_Comment=Simple Text Editor
+_GenericName=Text Editor
+Exec=Mousepad %F
+Icon=Mousepad
+Terminal=false
+StartupNotify=true
+Type=Application
+Categories=Application;Office;
+
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..4109058
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,29 @@
+Mousepad 0.3.x
+==============
+New core features:
+  - Everything is written in GObjects.
+  - Run multiple windows in one instance.
+  - Tab support.
+  - Loading multiple files at once (in new tabs). Both multiple
+    select in the open dialog and by using the command line is supported.
+  - Hidden settings
+    - Set the recent menu limit.
+  - Support for editable menu accelerators.
+  - Using MMAP for loading files.
+  - Items in the recent menu are removed when Mousepad was unable
+    to open it.
+
+
+Bug that can be closed:
+  2941 - Save button is now default response in the dialog.
+  2720 - No font is set as long the user doesn't defined any.
+  1697 - No compiler warnings.
+  2945 - Windows geometry is now properly saved.
+  2896 - Hidden option to show to full path in the window title.
+  2397 - Basic command line options.
+  2786 - The MousepadPreferences object uses XfceRc for saving the settings.
+  2784 - No crashes when there is no rc file.
+
+Bug that won't be fixed:
+  956  - Xfce About dialog. This allows us to depend on libxfcegui4 for one
+         dialog, so we're going to do that and use the Gtk about dialog.
diff --git a/README b/README
new file mode 100644
index 0000000..e69de29
diff --git a/THANKS b/THANKS
new file mode 100644
index 0000000..e69de29
diff --git a/TODO b/TODO
new file mode 100644
index 0000000..a6464bb
--- /dev/null
+++ b/TODO
@@ -0,0 +1,27 @@
+- Interface
+  - Implement the Go menu and acceleartors.
+  - Dialog when closing multiple (modified) tabs.
+  - Statusbar (not a priority).
+  - Right-click menu for the tab label.
+  - Credits dialog.
+  - Change tabs position.
+
+- Text View
+  - Search and Replace. Maybe also text highlighting.
+  - GObject for undo/redo that is used by MousepadView.
+  - Support for encoding.
+
+- Saving and loading
+  - Save All option.
+  - Reload option. Maybe also stat the source file when switching
+    tabs and tell the user if the source was modified.
+
+- Other
+  - Implement Gtk print support.
+  - Maybe add support for gtksourceview and/or gtkspell.
+
+- Testing
+  - Profiling the startup time.
+  - Profiling loading large files (Gtk has a problem here). This also
+    locks some dialogs.
+  - Checking for memory leaks.
diff --git a/autogen.sh b/autogen.sh
new file mode 100755
index 0000000..ef7bfb2
--- /dev/null
+++ b/autogen.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+#
+# $Id$
+#
+# Copyright (c) 2007
+#         The Xfce development team. All rights reserved.
+#
+
+(type xdt-autogen) >/dev/null 2>&1 || {
+  cat >&2 <<EOF
+autogen.sh: You don't seem to have the Xfce development tools installed on
+            your system, which are required to build this software.
+            Please install the xfce4-dev-tools package first, it is available
+            from http://www.xfce.org/.
+EOF
+  exit 1
+}
+
+# verify that po/LINGUAS is present
+(test -f po/LINGUAS) >/dev/null 2>&1 || {
+  cat >&2 <<EOF
+autogen.sh: The file po/LINGUAS could not be found. Please check your snapshot
+            or try to checkout again.
+EOF
+  exit 1
+}
+
+# substitute
+linguas=`sed -e '/^#/d' po/LINGUAS`
+revision=`LC_ALL=C svn info | awk '/^Revision: / {printf "%d\n", $2}'`
+sed -e "s/@LINGUAS@/${linguas}/g" \
+    -e "s/@REVISION@/${revision}/g" \
+    < "configure.in.in" > "configure.in"
+
+exec xdt-autogen $@
+
+# vi:set ts=2 sw=2 et ai:
diff --git a/configure.in.in b/configure.in.in
new file mode 100644
index 0000000..6cbd2a5
--- /dev/null
+++ b/configure.in.in
@@ -0,0 +1,238 @@
+dnl $Id$
+dnl
+dnl Copyright (c) 2007
+dnl         The Xfce development team. All rights reserved.
+dnl
+
+dnl ***************************
+dnl *** Version information ***
+dnl ***************************
+m4_define([mousepad_version_major], [0])
+m4_define([mousepad_version_minor], [3])
+m4_define([mousepad_version_micro], [0])
+m4_define([mousepad_version_build], [r at REVISION@])
+m4_define([mousepad_version_tag], [svn])
+m4_define([mousepad_version], [mousepad_version_major().mousepad_version_minor().mousepad_version_micro()ifelse(mousepad_version_tag(), [svn], [mousepad_version_tag()-mousepad_version_build()], [mousepad_version_tag()])])
+
+dnl *******************************************
+dnl *** Debugging support for SVN snapshots ***
+dnl *******************************************
+m4_define([mousepad_debug_default], [ifelse(mousepad_version_tag(), [svn], [yes], [minimum])])
+
+dnl ***************************
+dnl *** Initialize autoconf ***
+dnl ***************************
+AC_COPYRIGHT([Copyright (c) 2007
+        The Xfce development team. All rights reserved.])
+AC_INIT([Mousepad], [mousepad_version()], [http://bugzilla.xfce.org/], [Mousepad])
+AC_PREREQ([2.50])
+AC_CANONICAL_TARGET()
+AC_REVISION([$Id$])
+
+dnl ***************************
+dnl *** Initialize automake ***
+dnl ***************************
+AM_INIT_AUTOMAKE([1.8 dist-bzip2 tar-ustar])
+AM_CONFIG_HEADER([config.h])
+AM_MAINTAINER_MODE()
+
+dnl *******************************
+dnl *** Check for UNIX variants ***
+dnl *******************************
+AC_AIX()
+AC_ISC_POSIX()
+AC_MINIX()
+
+dnl ********************************
+dnl *** Check for basic programs ***
+dnl ********************************
+AC_PROG_CC()
+AC_PROG_LD()
+AC_PROG_INSTALL()
+AC_PROG_INTLTOOL()
+
+dnl **************************
+dnl *** Initialize libtool ***
+dnl **************************
+AC_PROG_LIBTOOL()
+
+dnl **************************************
+dnl *** Substitute version information ***
+dnl **************************************
+MOUSEPAD_VERSION_MAJOR=mousepad_version_major()
+MOUSEPAD_VERSION_MINOR=mousepad_version_minor()
+MOUSEPAD_VERSION_MICRO=mousepad_version_micro()
+AC_SUBST([MOUSEPAD_VERSION_MAJOR])
+AC_SUBST([MOUSEPAD_VERSION_MINOR])
+AC_SUBST([MOUSEPAD_VERSION_MICRO])
+
+dnl **********************************
+dnl *** Check for standard headers ***
+dnl **********************************
+AC_CHECK_HEADERS([errno.h fcntl.h memory.h stdlib.h string.h \
+                  sys/mman.h sys/types.h sys/stat.h time.h unistd.h])
+
+dnl ************************************
+dnl *** Check for standard functions ***
+dnl ************************************
+AC_FUNC_MMAP()
+AC_CHECK_FUNCS([posix_madvise])
+
+dnl ******************************
+dnl *** Check for i18n support ***
+dnl ******************************
+XDT_I18N([@LINGUAS@])
+
+dnl ***********************************
+dnl *** Check for required packages ***
+dnl ***********************************
+XDT_CHECK_PACKAGE([EXO], [exo-0.3], [0.3.2])
+XDT_CHECK_PACKAGE([GLIB], [glib-2.0], [2.12.0])
+XDT_CHECK_PACKAGE([GTHREAD], [gthread-2.0], [2.12.0])
+XDT_CHECK_PACKAGE([GTK], [gtk+-2.0], [2.10.0])
+XDT_CHECK_PACKAGE([LIBXFCE4UTIL], [libxfce4util-1.0], [4.4.0])
+
+dnl ********************************************
+dnl *** Check for session management support ***
+dnl ********************************************
+XDT_CHECK_LIBSM()
+
+dnl **********************************
+dnl *** Optional support for D-BUS ***
+dnl **********************************
+XDT_CHECK_OPTIONAL_PACKAGE([DBUS], [dbus-glib-1],
+                           [0.34], [dbus], [D-BUS support])
+
+dnl *************************************************
+dnl *** Optional support for startup notification ***
+dnl *************************************************
+XDT_CHECK_OPTIONAL_PACKAGE([LIBSTARTUP_NOTIFICATION],
+                           [libstartup-notification-1.0],
+                           [0.4], [startup-notification],
+                           [startup notification library])
+
+dnl *************************
+dnl *** Check for gtk-doc ***
+dnl *************************
+GTK_DOC_CHECK([1.0])
+
+dnl ***********************************
+dnl *** Check for debugging support ***
+dnl ***********************************
+AC_ARG_ENABLE([debug],
+AC_HELP_STRING([--enable-debug=@<:@no/minimum/yes/full@:>@], [Turn on debugging @<:@default=mousepad_debug_default@:>@]),
+  [], [enable_debug=mousepad_debug_default])
+AC_MSG_CHECKING([whether to enable debugging support])
+if test x"$enable_debug" = x"full" -o x"$enable_debug" = x"yes"; then
+  dnl Print the result
+  AC_MSG_RESULT([$enable_debug])
+
+  dnl Make sure we detect possible errors (if supported)
+  save_CFLAGS="$CFLAGS"
+  CFLAGS="$CFLAGS -Wall -Werror"
+  AC_MSG_CHECKING([whether $CC accepts -Wall -Werror])
+  AC_COMPILE_IFELSE(AC_LANG_SOURCE([int x;]), [
+    AC_MSG_RESULT([yes])
+    PLATFORM_CFLAGS="$PLATFORM_CFLAGS -Wall -Werror"
+  ], [
+    AC_MSG_RESULT([no])
+  ])
+  CFLAGS="$save_CFLAGS"
+
+  dnl Paranoia for --enable-debug=full
+  if test x"$enable_debug" = x"full"; then
+    dnl Enable extensive debugging
+    PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_ENABLE_DEBUG"
+
+    dnl Use -O0 -g3 if the compiler supports it
+    save_CFLAGS="$CFLAGS"
+    CFLAGS="$CFLAGS -O0 -g3"
+    AC_MSG_CHECKING([whether $CC accepts -O0 -g3])
+    AC_COMPILE_IFELSE(AC_LANG_SOURCE([int x;]), [
+      AC_MSG_RESULT([yes])
+      PLATFORM_CFLAGS="$PLATFORM_CFLAGS -O0 -g3"
+    ], [
+      AC_MSG_RESULT([no])
+    ])
+    CFLAGS="$save_CFLAGS"
+  fi
+else
+  dnl Print the result
+  AC_MSG_RESULT([$enable_debug])
+
+  dnl Disable debugging (release build)
+  PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DNDEBUG"
+
+  dnl Disable object cast checks
+  PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_DISABLE_CAST_CHECKS"
+
+  dnl Disable all checks for --enable-debug=no
+  if test x"$enable_debug" = x"no"; then
+    PLATFORM_CPPFLAGS="$PLATFORM_CPPFLAGS -DG_DISABLE_ASSERT -DG_DISABLE_CHECKS"
+  fi
+fi
+
+dnl **************************************
+dnl *** Check for linker optimizations ***
+dnl **************************************
+AC_MSG_CHECKING([whether $LD accepts --as-needed])
+case `$LD --as-needed -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  LDFLAGS="$LDFLAGS -Wl,--as-needed"
+  AC_MSG_RESULT([yes])
+  ;;
+*)
+  AC_MSG_RESULT([no])
+  ;;
+esac
+AC_MSG_CHECKING([whether $LD accepts -O1])
+case `$LD -O1 -v 2>&1 </dev/null` in
+*GNU* | *'with BFD'*)
+  PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -Wl,-O1"
+  AC_MSG_RESULT([yes])
+  ;;
+*)
+  AC_MSG_RESULT([no])
+  ;;
+esac
+
+dnl *********************************
+dnl *** Substitute platform flags ***
+dnl *********************************
+AC_MSG_CHECKING([PLATFORM_CPPFLAGS])
+AC_MSG_RESULT([$PLATFORM_CPPFLAGS])
+AC_SUBST([PLATFORM_CPPFLAGS])
+AC_MSG_CHECKING([PLATFORM_CFLAGS])
+AC_MSG_RESULT([$PLATFORM_CFLAGS])
+AC_SUBST([PLATFORM_CFLAGS])
+AC_MSG_CHECKING([PLATFORM_LDFLAGS])
+AC_MSG_RESULT([$PLATFORM_LDFLAGS])
+AC_SUBST([PLATFORM_LDFLAGS])
+
+AC_OUTPUT([
+Makefile
+icons/Makefile
+icons/16x16/Makefile
+icons/24x24/Makefile
+icons/scalable/Makefile
+mousepad/Makefile
+po/Makefile.in
+])
+
+dnl ***************************
+dnl *** Print configuration ***
+dnl ***************************
+echo
+echo "Build Configuration:"
+echo
+if test x"$DBUS_FOUND" = x"yes"; then
+echo "* D-BUS support:             yes"
+else
+echo "* D-BUS support:             no"
+fi
+if test x"$LIBSTARTUP_NOTIFICATION_FOUND" = x"yes"; then
+echo "* Startup Notification:      yes"
+else
+echo "* Startup Notification:      no"
+fi
+echo
diff --git a/icons/16x16/Makefile.am b/icons/16x16/Makefile.am
new file mode 100644
index 0000000..4fe130f
--- /dev/null
+++ b/icons/16x16/Makefile.am
@@ -0,0 +1,10 @@
+# $Id$
+
+appsdir = $(datadir)/icons/hicolor/16x16/apps
+apps_DATA =								\
+	Mousepad.png
+
+EXTRA_DIST =								\
+	$(apps_DATA)
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/icons/16x16/Mousepad.png b/icons/16x16/Mousepad.png
new file mode 100644
index 0000000..188e1c1
Binary files /dev/null and b/icons/16x16/Mousepad.png differ
diff --git a/icons/24x24/Makefile.am b/icons/24x24/Makefile.am
new file mode 100644
index 0000000..2608272
--- /dev/null
+++ b/icons/24x24/Makefile.am
@@ -0,0 +1,10 @@
+# $Id$
+
+iconsdir = $(datadir)/icons/hicolor/24x24/apps
+icons_DATA =								\
+	Mousepad.png
+
+EXTRA_DIST =								\
+	$(icons_DATA)
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/icons/24x24/Mousepad.png b/icons/24x24/Mousepad.png
new file mode 100644
index 0000000..bdbb88e
Binary files /dev/null and b/icons/24x24/Mousepad.png differ
diff --git a/icons/Makefile.am b/icons/Makefile.am
new file mode 100644
index 0000000..e6cdc99
--- /dev/null
+++ b/icons/Makefile.am
@@ -0,0 +1,21 @@
+# $Id$
+
+SUBDIRS =								\
+	16x16								\
+	24x24								\
+	scalable
+
+gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
+
+install-data-hook:
+	@-if test -z "$(DESTDIR)"; then					\
+                echo "Updating Gtk icon cache.";			\
+                $(gtk_update_icon_cache);				\
+        else								\
+                echo "*** Icon cache not updated. Remember to run:";	\
+		echo "***";						\
+                echo "***   $(gtk_update_icon_cache)";			\
+		echo "***";						\
+        fi
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/icons/scalable/Makefile.am b/icons/scalable/Makefile.am
new file mode 100644
index 0000000..305a62c
--- /dev/null
+++ b/icons/scalable/Makefile.am
@@ -0,0 +1,10 @@
+# $Id$
+
+iconsdir = $(datadir)/icons/hicolor/scalable/apps
+icons_DATA =								\
+	Mousepad.svg
+
+EXTRA_DIST =								\
+	$(icons_DATA)
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/icons/scalable/Mousepad.svg b/icons/scalable/Mousepad.svg
new file mode 100644
index 0000000..aa7188e
--- /dev/null
+++ b/icons/scalable/Mousepad.svg
@@ -0,0 +1,552 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   inkscape:export-ydpi="90.000000"
+   inkscape:export-xdpi="90.000000"
+   inkscape:export-filename="/home/jimmac/Desktop/wi-fi.png"
+   width="48px"
+   height="48px"
+   id="svg11300"
+   sodipodi:version="0.32"
+   inkscape:version="0.43+devel"
+   sodipodi:docbase="/home/jimmac/src/cvs/tango-icon-theme/scalable/apps"
+   sodipodi:docname="accessories-text-editor.svg">
+  <defs
+     id="defs3">
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5060"
+       id="radialGradient6719"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
+       cx="605.71429"
+       cy="486.64789"
+       fx="605.71429"
+       fy="486.64789"
+       r="117.14286" />
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient5060">
+      <stop
+         style="stop-color:black;stop-opacity:1;"
+         offset="0"
+         id="stop5062" />
+      <stop
+         style="stop-color:black;stop-opacity:0;"
+         offset="1"
+         id="stop5064" />
+    </linearGradient>
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5060"
+       id="radialGradient6717"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
+       cx="605.71429"
+       cy="486.64789"
+       fx="605.71429"
+       fy="486.64789"
+       r="117.14286" />
+    <linearGradient
+       id="linearGradient5048">
+      <stop
+         style="stop-color:black;stop-opacity:0;"
+         offset="0"
+         id="stop5050" />
+      <stop
+         id="stop5056"
+         offset="0.5"
+         style="stop-color:black;stop-opacity:1;" />
+      <stop
+         style="stop-color:black;stop-opacity:0;"
+         offset="1"
+         id="stop5052" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient5048"
+       id="linearGradient6715"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
+       x1="302.85715"
+       y1="366.64789"
+       x2="302.85715"
+       y2="609.50507" />
+    <linearGradient
+       id="linearGradient2994">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop2996" />
+      <stop
+         style="stop-color:#c9c9c9;stop-opacity:1;"
+         offset="1"
+         id="stop2998" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2984">
+      <stop
+         style="stop-color:#e7e2b8;stop-opacity:1;"
+         offset="0"
+         id="stop2986" />
+      <stop
+         style="stop-color:#e7e2b8;stop-opacity:0;"
+         offset="1"
+         id="stop2988" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2974">
+      <stop
+         style="stop-color:#c1c1c1;stop-opacity:1;"
+         offset="0"
+         id="stop2976" />
+      <stop
+         style="stop-color:#acacac;stop-opacity:1;"
+         offset="1"
+         id="stop2978" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2966">
+      <stop
+         style="stop-color:#ffd1d1;stop-opacity:1;"
+         offset="0"
+         id="stop2968" />
+      <stop
+         id="stop3006"
+         offset="0.5"
+         style="stop-color:#ff1d1d;stop-opacity:1;" />
+      <stop
+         style="stop-color:#6f0000;stop-opacity:1;"
+         offset="1"
+         id="stop2970" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2919">
+      <stop
+         style="stop-color:#a3a4a0;stop-opacity:1;"
+         offset="0"
+         id="stop2921" />
+      <stop
+         style="stop-color:#888a85;stop-opacity:1;"
+         offset="1"
+         id="stop2923" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2873">
+      <stop
+         style="stop-color:#939393;stop-opacity:1;"
+         offset="0"
+         id="stop2875" />
+      <stop
+         style="stop-color:#424242;stop-opacity:1;"
+         offset="1"
+         id="stop2877" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       id="linearGradient2865">
+      <stop
+         style="stop-color:#000000;stop-opacity:1;"
+         offset="0"
+         id="stop2867" />
+      <stop
+         style="stop-color:#000000;stop-opacity:0;"
+         offset="1"
+         id="stop2869" />
+    </linearGradient>
+    <linearGradient
+       id="linearGradient2855">
+      <stop
+         style="stop-color:#dfdfdf;stop-opacity:1;"
+         offset="0"
+         id="stop2857" />
+      <stop
+         style="stop-color:#ffffff;stop-opacity:1;"
+         offset="1"
+         id="stop2859" />
+    </linearGradient>
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2855"
+       id="linearGradient2861"
+       x1="21.043484"
+       y1="42.83337"
+       x2="14.283642"
+       y2="6.8333683"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.137871,0.000000,0.000000,1.000000,-2.660884,0.000000)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2865"
+       id="radialGradient2871"
+       cx="23.5625"
+       cy="40.4375"
+       fx="23.5625"
+       fy="40.4375"
+       r="19.5625"
+       gradientTransform="matrix(1.000000,0.000000,0.000000,0.348243,0.000000,26.35543)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2873"
+       id="linearGradient2879"
+       x1="26.612417"
+       y1="28.083368"
+       x2="26.228401"
+       y2="42.83337"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2919"
+       id="linearGradient2925"
+       x1="6"
+       y1="7.5624999"
+       x2="40.984375"
+       y2="7.5624999"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2966"
+       id="linearGradient2972"
+       x1="48.90625"
+       y1="17.376184"
+       x2="50.988335"
+       y2="22.250591"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-5.669292,0.000000)" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2974"
+       id="linearGradient2980"
+       x1="46"
+       y1="19.8125"
+       x2="47.6875"
+       y2="22.625"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-5.669292,0.000000)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2984"
+       id="radialGradient2990"
+       cx="29.053354"
+       cy="27.640751"
+       fx="29.053354"
+       fy="27.640751"
+       r="3.2408544"
+       gradientTransform="matrix(2.923565,-3.911409e-24,2.471769e-23,2.029717,-61.55532,-27.88417)"
+       gradientUnits="userSpaceOnUse" />
+    <linearGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2994"
+       id="linearGradient3000"
+       x1="25.71875"
+       y1="31.046875"
+       x2="25.514589"
+       y2="30.703125"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="translate(-5.825542,0.125000)" />
+    <radialGradient
+       inkscape:collect="always"
+       xlink:href="#linearGradient2865"
+       id="radialGradient3010"
+       gradientUnits="userSpaceOnUse"
+       gradientTransform="matrix(1.000000,0.000000,0.000000,0.348243,1.439818e-16,26.35543)"
+       cx="23.5625"
+       cy="40.4375"
+       fx="23.5625"
+       fy="40.4375"
+       r="19.5625" />
+  </defs>
+  <sodipodi:namedview
+     stroke="#c4a000"
+     fill="#edd400"
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="0.25490196"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1"
+     inkscape:cx="14.928934"
+     inkscape:cy="7.6822472"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:grid-bbox="true"
+     inkscape:document-units="px"
+     inkscape:showpageshadow="false"
+     inkscape:window-width="872"
+     inkscape:window-height="659"
+     inkscape:window-x="195"
+     inkscape:window-y="221" />
+  <metadata
+     id="metadata4">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:creator>
+          <cc:Agent>
+            <dc:title>Jakub Steiner</dc:title>
+          </cc:Agent>
+        </dc:creator>
+        <dc:source>http://jimmac.musichall.cz</dc:source>
+        <cc:license
+           rdf:resource="http://creativecommons.org/licenses/by-sa/2.0/" />
+        <dc:title>Text Editor</dc:title>
+      </cc:Work>
+      <cc:License
+         rdf:about="http://creativecommons.org/licenses/by-sa/2.0/">
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Reproduction" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/Distribution" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Notice" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/Attribution" />
+        <cc:permits
+           rdf:resource="http://web.resource.org/cc/DerivativeWorks" />
+        <cc:requires
+           rdf:resource="http://web.resource.org/cc/ShareAlike" />
+      </cc:License>
+    </rdf:RDF>
+  </metadata>
+  <g
+     id="layer1"
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer">
+    <g
+       transform="matrix(2.417561e-2,0,0,2.086758e-2,45.12765,40.1536)"
+       id="g6707">
+      <rect
+         style="opacity:0.40206185;color:black;fill:url(#linearGradient6715);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         id="rect6709"
+         width="1339.6335"
+         height="478.35718"
+         x="-1559.2523"
+         y="-150.69685" />
+      <path
+         style="opacity:0.40206185;color:black;fill:url(#radialGradient6717);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         d="M -219.61876,-150.68038 C -219.61876,-150.68038 -219.61876,327.65041 -219.61876,327.65041 C -76.744594,328.55086 125.78146,220.48075 125.78138,88.454235 C 125.78138,-43.572302 -33.655436,-150.68036 -219.61876,-150.68038 z "
+         id="path6711"
+         sodipodi:nodetypes="cccc" />
+      <path
+         sodipodi:nodetypes="cccc"
+         id="path6713"
+         d="M -1559.2523,-150.68038 C -1559.2523,-150.68038 -1559.2523,327.65041 -1559.2523,327.65041 C -1702.1265,328.55086 -1904.6525,220.48075 -1904.6525,88.454235 C -1904.6525,-43.572302 -1745.2157,-150.68036 -1559.2523,-150.68038 z "
+         style="opacity:0.40206185;color:black;fill:url(#radialGradient6719);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+    </g>
+    <path
+       style="color:#000000;fill:url(#linearGradient2861);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient2879);stroke-width:0.99999982;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 7.1638699,4.5063726 L 39.813122,4.5063726 C 40.575699,4.5063726 41.189615,5.0388241 41.189615,5.7002099 C 41.189615,5.7002099 43.590945,39.868907 43.590945,39.868907 C 43.590945,39.868907 43.603403,42.216529 43.603403,42.216529 C 43.603403,42.877915 42.989488,43.410366 42.226911,43.410366 L 4.750081,43.410366 C 3.9875042,43.410366 3.3735887,42.877915 3.3735887,42.216529 L 3.3624173,40.049613 L 5.7873775,5.7002099 C 5.7873775,5.0388241 6.4012931,4.5063726 7.1638699,4.5063726 z "
+       id="rect1975"
+       sodipodi:nodetypes="ccccccccccc" />
+    <path
+       transform="matrix(0.616613,0.000000,0.000000,0.440367,10.61425,13.94266)"
+       d="M 43.125 40.4375 A 19.5625 6.8125 0 1 1  4,40.4375 A 19.5625 6.8125 0 1 1  43.125 40.4375 z"
+       sodipodi:ry="6.8125"
+       sodipodi:rx="19.5625"
+       sodipodi:cy="40.4375"
+       sodipodi:cx="23.5625"
+       id="path3008"
+       style="opacity:0.31578944;color:#000000;fill:url(#radialGradient3010);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       sodipodi:type="arc" />
+    <rect
+       style="opacity:1;color:#000000;fill:#a4a4a4;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       id="rect2851"
+       width="39.048077"
+       height="3.0714951"
+       x="3.9770372"
+       y="39.868271"
+       rx="0.67937863"
+       ry="0.67937863" />
+    <path
+       style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 3.9267507,40.442796 C 3.9267507,40.442796 4.0776125,39.912466 4.6307727,39.868272 L 42.195375,39.868272 C 42.949684,39.868272 42.999971,40.619573 42.999971,40.619573 C 42.999971,40.619573 43.02357,39 41.7161,39 L 5.3042159,39 C 4.2984702,39.088388 3.9267507,39.779883 3.9267507,40.442796 z "
+       id="path2853"
+       sodipodi:nodetypes="ccccccc" />
+    <path
+       style="opacity:1;color:#000000;fill:url(#linearGradient2925);fill-opacity:1.0;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 6.25,5.7343749 L 6,10.125 C 6,10.125 6.3125,8.9999999 7,8.9999999 L 40.125,8.9999999 C 40.828125,8.9843749 40.859375,9.3124999 40.984375,9.8281249 C 40.984375,9.8281249 40.734375,5.9531249 40.734375,5.9531249 C 40.703125,5.4062499 40.515625,4.9999999 39.953125,4.9999999 L 7.0625,4.9999999 C 6.609375,4.9999999 6.296875,5.3437499 6.25,5.7343749 z "
+       id="path2915"
+       sodipodi:nodetypes="ccccccccc" />
+    <path
+       sodipodi:nodetypes="ccccccccccc"
+       id="path2917"
+       d="M 7.8126474,5.5404503 L 38.944983,5.5404503 C 39.66702,5.5404503 40.2483,5.3883462 40.2483,6.014572 C 40.2483,6.014572 42.521973,39.023077 42.521973,39.023077 C 42.521973,39.023077 42.622156,41.732033 42.622156,41.732033 C 42.622156,42.358259 42.48282,42.376269 41.760782,42.376269 L 4.8620444,42.376269 C 4.4493662,42.376269 4.4426114,42.269871 4.4426114,41.864615 L 4.4320338,39.194177 L 6.7280807,6.045822 C 6.7280807,5.4195962 7.09061,5.5404503 7.8126474,5.5404503 z "
+       style="color:#000000;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:0.99999946;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;opacity:0.43859649" />
+    <g
+       id="g2950">
+      <rect
+         ry="1"
+         rx="1"
+         y="2.5"
+         x="8.5"
+         height="5"
+         width="2"
+         id="rect2899"
+         style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <rect
+         style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         id="rect2901"
+         width="2"
+         height="5"
+         x="12.5"
+         y="2.5"
+         rx="1"
+         ry="1" />
+      <rect
+         ry="1"
+         rx="1"
+         y="2.5"
+         x="16.5"
+         height="5"
+         width="2"
+         id="rect2903"
+         style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <rect
+         style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         id="rect2905"
+         width="2"
+         height="5"
+         x="20.5"
+         y="2.5"
+         rx="1"
+         ry="1" />
+      <rect
+         ry="1"
+         rx="1"
+         y="2.5"
+         x="24.5"
+         height="5"
+         width="2"
+         id="rect2907"
+         style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <rect
+         style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         id="rect2909"
+         width="2"
+         height="5"
+         x="28.5"
+         y="2.5"
+         rx="1"
+         ry="1" />
+      <rect
+         ry="1"
+         rx="1"
+         y="2.5"
+         x="32.5"
+         height="5"
+         width="2"
+         id="rect2911"
+         style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <rect
+         style="opacity:1;color:#000000;fill:#fce94f;fill-opacity:1;fill-rule:evenodd;stroke:#886f00;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         id="rect2913"
+         width="2"
+         height="5"
+         x="36.5"
+         y="2.5"
+         rx="1"
+         ry="1" />
+    </g>
+    <g
+       id="g2941">
+      <rect
+         y="12"
+         x="9"
+         height="1"
+         width="29"
+         id="rect2927"
+         style="opacity:0.28070175;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <rect
+         style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         id="rect2929"
+         width="29"
+         height="1"
+         x="9"
+         y="14.981792" />
+      <rect
+         y="18.003939"
+         x="9"
+         height="1"
+         width="13"
+         id="rect2931"
+         style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <rect
+         style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         id="rect2933"
+         width="29"
+         height="1"
+         x="9"
+         y="22.985731" />
+      <rect
+         y="26.007877"
+         x="9"
+         height="1"
+         width="29"
+         id="rect2935"
+         style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+      <rect
+         style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+         id="rect2937"
+         width="29"
+         height="1"
+         x="9"
+         y="29.030024" />
+      <rect
+         y="32.05217"
+         x="9"
+         height="1"
+         width="8"
+         id="rect2939"
+         style="opacity:0.28070176;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+    </g>
+    <path
+       style="opacity:1;color:#000000;fill:#cb9022;fill-opacity:1;fill-rule:evenodd;stroke:#5c410c;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 17.34116,32.5 L 22.96616,26.875 L 43.059909,17.125 C 46.309909,15.875 48.247409,20.5 45.372409,22.125 L 25.34116,31.5 L 17.34116,32.5 z "
+       id="path2960"
+       sodipodi:nodetypes="cccccc" />
+    <path
+       sodipodi:nodetypes="czcczcc"
+       id="path2964"
+       d="M 38.330708,20 C 38.330708,20 39.768208,20.09375 40.330708,21.34375 C 40.910201,22.631511 40.330708,24 40.330708,24 L 45.361958,21.53125 C 45.361958,21.53125 46.81399,20.649883 46.018208,18.6875 C 45.233296,16.751923 43.330708,17.53125 43.330708,17.53125 L 38.330708,20 z "
+       style="opacity:1;color:#000000;fill:url(#linearGradient2972);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible" />
+    <path
+       style="opacity:1;color:#000000;fill:url(#linearGradient2980);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 38.330708,20 C 38.330708,20 39.768208,20.09375 40.330708,21.34375 C 40.910201,22.631511 40.330708,24 40.330708,24 L 42.330708,23 C 42.330708,23 43.15774,21.681133 42.549458,20.3125 C 41.924458,18.90625 40.330708,19 40.330708,19 L 38.330708,20 z "
+       id="path2962"
+       sodipodi:nodetypes="czcczcc" />
+    <path
+       style="opacity:1;color:#000000;fill:url(#radialGradient2990);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 18.768208,31.78125 L 23.268208,27.28125 C 24.768208,28.09375 25.549458,29.4375 25.143208,31 L 18.768208,31.78125 z "
+       id="path2982"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="opacity:1;color:#000000;fill:url(#linearGradient3000);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 20.111958,30.375 L 18.486958,31.96875 L 20.830708,31.65625 C 21.049458,30.9375 20.643208,30.59375 20.111958,30.375 z "
+       id="path2992"
+       sodipodi:nodetypes="cccc" />
+    <path
+       style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:0.36363639;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 23.268208,27.25 L 24.830708,28.5 L 40.218048,21.18133 C 39.773616,20.325286 38.976281,20.096733 38.314669,20.019068 L 23.268208,27.25 z "
+       id="path3002"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="opacity:1;color:#000000;fill:#000000;fill-opacity:0.36363639;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 25.143208,31.0625 L 25.330708,30.3125 L 40.561798,23.1829 C 40.561798,23.1829 40.451638,23.796527 40.345919,23.93225 L 25.143208,31.0625 z "
+       id="path3004"
+       sodipodi:nodetypes="ccccc" />
+  </g>
+</svg>
diff --git a/mousepad/Makefile.am b/mousepad/Makefile.am
new file mode 100644
index 0000000..bb27224
--- /dev/null
+++ b/mousepad/Makefile.am
@@ -0,0 +1,93 @@
+# $Id$
+
+INCLUDES =								\
+	-I$(top_builddir)						\
+	-I$(top_srcdir)							\
+	-DBINDIR=\"$(bindir)\"						\
+	-DDATADIR=\"$(datadir)\"					\
+	-DLIBDIR=\"$(libdir)\"						\
+	-DLIBEXECDIR=\"$(libexecdir)\"					\
+	-DG_LOG_DOMAIN=\"Mousepad\"					\
+	-DLIBEXECDIR=\"$(libexecdir)\"					\
+	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"				\
+	$(PLATFORM_CPPFLAGS)
+
+bin_PROGRAMS = 								\
+	Mousepad
+
+Mousepad_SOURCES =							\
+	main.c								\
+	mousepad-application.c						\
+	mousepad-application.h						\
+	mousepad-file.c							\
+	mousepad-file.h							\
+	mousepad-preferences.c						\
+	mousepad-preferences.h						\
+	mousepad-private.h						\
+	mousepad-screen.c						\
+	mousepad-screen.h						\
+	mousepad-tab-label.c						\
+	mousepad-tab-label.h						\
+	mousepad-view.c							\
+	mousepad-view.h							\
+	mousepad-window.c						\
+	mousepad-window.h						\
+	mousepad-window-ui.h
+
+Mousepad_CFLAGS =							\
+	$(EXO_CFLAGS)							\
+	$(GTHREAD_CFLAGS)						\
+	$(PLATFORM_CFLAGS)
+
+Mousepad_LDFLAGS =							\
+	-no-undefined							\
+	$(LIBSM_LDFLAGS)						\
+	$(PLATFORM_LDFLAGS)
+
+Mousepad_LDADD =							\
+	$(EXO_LIBS)							\
+	$(GTHREAD_LIBS)
+
+if HAVE_DBUS
+mousepad_build_sources =						\
+	mousepad-dbus-infos.h
+
+Mousepad_SOURCES +=							\
+	mousepad-dbus.c							\
+	mousepad-dbus.h
+
+Mousepad_CFLAGS +=							\
+	-DDBUS_API_SUBJECT_TO_CHANGE					\
+	$(DBUS_CFLAGS)
+
+Mousepad_LDADD +=							\
+	$(DBUS_LIBS)
+endif
+
+# install symlink to 'mousepad'
+install-data-local:
+	$(mkinstalldirs) $(DESTDIR)$(bindir)
+	-( cd $(DESTDIR)$(bindir) ; ln -sf Mousepad mousepad )
+
+if MAINTAINER_MODE
+DISTCLEANFILES =							\
+	mousepad-window-ui.h
+
+BUILT_SOURCES =								\
+	$(mousepad_build_sources)                                       \
+	mousepad-window-ui.h
+
+if HAVE_DBUS
+mousepad-dbus-infos.h: $(srcdir)/mousepad-dbus-infos.xml Makefile
+	dbus-binding-tool --prefix=mousepad_dbus_service --mode=glib-server $(srcdir)/mousepad-dbus-infos.xml > mousepad-dbus-infos.h
+endif
+
+mousepad-window-ui.h: Makefile $(srcdir)/mousepad-window-ui.xml
+	exo-csource --static --name=mousepad_window_ui $(srcdir)/mousepad-window-ui.xml > mousepad-window-ui.h
+endif
+
+EXTRA_DIST =								\
+	mousepad-dbus-infos.xml                                         \
+	mousepad-window-ui.xml
+
+# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/mousepad/main.c b/mousepad/main.c
new file mode 100644
index 0000000..88045b7
--- /dev/null
+++ b/mousepad/main.c
@@ -0,0 +1,182 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STDIO_H
+#include <stdio.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-application.h>
+
+#ifdef HAVE_DBUS
+#include <mousepad/mousepad-dbus.h>
+#endif
+
+
+/* globals */
+static gchar    **filenames = NULL;
+static gboolean   opt_version = FALSE;
+#ifdef HAVE_DBUS
+static gboolean   opt_disable_server = FALSE;
+#endif
+
+
+
+/* command line options */
+static GOptionEntry option_entries[] =
+{
+#ifdef HAVE_DBUS
+  { "disable-server", '\0', 0, G_OPTION_ARG_NONE, &opt_disable_server, N_ ("Do not register with the D-BUS session message bus"), NULL, },
+#endif
+  { "version", 'v', 0, G_OPTION_ARG_NONE, &opt_version, N_ ("Print version information and exit"), NULL, },
+  { G_OPTION_REMAINING, '\0', 0, G_OPTION_ARG_FILENAME_ARRAY, &filenames, NULL, NULL },
+  { NULL, },
+};
+
+
+
+gint
+main (gint argc, gchar **argv)
+{
+  MousepadApplication *application;
+#ifdef HAVE_DBUS
+  MousepadDBusService *dbus_service;
+#endif
+  GError              *error = NULL;
+  gchar               *working_directory;
+
+  /* translation domain */
+  xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+
+  /* default application name */
+  g_set_application_name (_("Mousepad"));
+
+#ifdef G_ENABLE_DEBUG
+  /* crash when something went wrong */
+  g_log_set_always_fatal (G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
+#endif
+
+  /* initialize the GThread system */
+  if (!g_thread_supported ())
+    g_thread_init (NULL);
+
+  /* initialize Gtk+ */
+  if (!gtk_init_with_args (&argc, &argv, _("[FILES...]"), option_entries, GETTEXT_PACKAGE, &error))
+    {
+      /* check if we have an error message */
+      if (G_LIKELY (error == NULL))
+        {
+          /* no error message, the GUI initialization failed */
+          g_error ("%s", _("Failed to open display."));
+        }
+      else
+        {
+           /* print the error message */
+           g_error ("%s", error->message);
+           g_error_free (error);
+        }
+
+      return EXIT_FAILURE;
+    }
+
+  /* check if we should print version information */
+  if (G_UNLIKELY (opt_version))
+    {
+      g_print ("%s %s (Xfce %s)\n\n", PACKAGE_NAME, PACKAGE_VERSION, xfce_version_string ());
+      g_print ("%s\n", "Copyright (c) 2007");
+      g_print ("\t%s\n\n", _("The Xfce development team. All rights reserved."));
+      g_print ("%s\n\n", _("Written by Nick Schermer <nick at xfce.org>."));
+      g_print (_("Please report bugs to <%s>."), PACKAGE_BUGREPORT);
+      g_print ("\n");
+
+      return EXIT_SUCCESS;
+    }
+
+  /* get the current working directory */
+  working_directory = g_get_current_dir ();
+
+#ifdef HAVE_DBUS
+  if (G_LIKELY (!opt_disable_server))
+    {
+      /* check if we can reuse an existing instance */
+      if (mousepad_dbus_client_launch_files (filenames, working_directory, &error))
+        {
+          /* stop any running startup notification */
+          gdk_notify_startup_complete ();
+
+          /* cleanup */
+          g_free (working_directory);
+          g_strfreev (filenames);
+
+          /* print errors, if needed */
+          if (G_UNLIKELY (error))
+            {
+              g_error ("Mousepad: %s\n", error->message);
+              g_error_free (error);
+
+              return EXIT_FAILURE;
+            }
+
+          return EXIT_SUCCESS;
+        }
+    }
+#endif /* !HAVE_DBUS */
+
+  /* use the Mousepad icon as default for new windows */
+  gtk_window_set_default_icon_name ("Mousepad");
+
+  /* create a new mousepad application */
+  application = mousepad_application_get ();
+
+  /* open an empty window or the files */
+  mousepad_application_open_window (application, NULL, working_directory, filenames);
+
+  /* cleanup */
+  g_free (working_directory);
+  g_strfreev (filenames);
+
+  /* do not enter the main loop, unless we have atleast one window */
+  if (G_LIKELY (mousepad_application_has_windows (application)))
+    {
+#ifdef HAVE_DBUS
+      /* register with dbus */
+      dbus_service = g_object_new (MOUSEPAD_TYPE_DBUS_SERVICE, NULL);
+#endif
+
+      /* enter the main loop */
+      gtk_main ();
+
+#ifdef HAVE_DBUS
+      /* release dbus service reference */
+      g_object_unref (G_OBJECT (dbus_service));
+#endif
+    }
+
+  /* release application reference */
+  g_object_unref (G_OBJECT (application));
+
+  return EXIT_SUCCESS;
+}
diff --git a/mousepad/mousepad-application.c b/mousepad/mousepad-application.c
new file mode 100644
index 0000000..755348b
--- /dev/null
+++ b/mousepad/mousepad-application.c
@@ -0,0 +1,239 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-application.h>
+#include <mousepad/mousepad-window.h>
+
+
+
+static void mousepad_application_class_init       (MousepadApplicationClass  *klass);
+static void mousepad_application_init             (MousepadApplication       *application);
+static void mousepad_application_window_destroyed (GtkWidget                 *window,
+                                                   MousepadApplication       *application);
+static void mousepad_application_finalize         (GObject                   *object);
+
+
+
+struct _MousepadApplicationClass
+{
+  GObjectClass __parent__;
+};
+
+struct _MousepadApplication
+{
+  GObject  __parent__;
+
+  GList   *windows;
+};
+
+
+
+static GObjectClass *mousepad_application_parent_class;
+
+
+
+MousepadApplication*
+mousepad_application_get (void)
+{
+  static MousepadApplication *application = NULL;
+
+  if (G_UNLIKELY (application == NULL))
+    {
+      application = g_object_new (MOUSEPAD_TYPE_APPLICATION, NULL);
+    }
+  else
+    {
+      g_object_ref (G_OBJECT (application));
+    }
+
+  return application;
+}
+
+
+
+static GObjectClass *mousepad_application_parent_class;
+
+
+
+GType
+mousepad_application_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (G_TYPE_OBJECT,
+                                            I_("MousepadApplication"),
+                                            sizeof (MousepadApplicationClass),
+                                            (GClassInitFunc) mousepad_application_class_init,
+                                            sizeof (MousepadApplication),
+                                            (GInstanceInitFunc) mousepad_application_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_application_class_init (MousepadApplicationClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  mousepad_application_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_application_finalize;
+}
+
+
+
+static void
+mousepad_application_init (MousepadApplication *application)
+{
+  gchar *path;
+
+  /* check if we have a saved accel map */
+  path = xfce_resource_lookup (XFCE_RESOURCE_CONFIG, "Mousepad/accels.scm");
+  if (G_LIKELY (path != NULL))
+    {
+      /* load the accel map */
+      gtk_accel_map_load (path);
+      g_free (path);
+    }
+}
+
+
+
+static void
+mousepad_application_finalize (GObject *object)
+{
+  MousepadApplication *application = MOUSEPAD_APPLICATION (object);
+  GList               *li;
+  gchar               *path;
+
+  /* save the current accel map */
+  path = xfce_resource_save_location (XFCE_RESOURCE_CONFIG, "Mousepad/accels.scm", TRUE);
+  if (G_LIKELY (path != NULL))
+    {
+      /* save the accel map */
+      gtk_accel_map_save (path);
+      g_free (path);
+    }
+
+  for (li = application->windows; li != NULL; li = li->next)
+    {
+      g_signal_handlers_disconnect_by_func (G_OBJECT (li->data), G_CALLBACK (mousepad_application_window_destroyed), application);
+      gtk_widget_destroy (GTK_WIDGET (li->data));
+    }
+
+  g_list_free (application->windows);
+
+  (*G_OBJECT_CLASS (mousepad_application_parent_class)->finalize) (object);
+}
+
+
+
+GList*
+mousepad_application_get_windows (MousepadApplication *application)
+{
+  GList *windows = NULL;
+  GList *li;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_APPLICATION (application), NULL);
+
+  for (li = application->windows; li != NULL; li = li->next)
+    if (G_LIKELY (MOUSEPAD_IS_WINDOW (li->data)))
+      windows = g_list_prepend (windows, li->data);
+
+  return windows;
+}
+
+
+
+gboolean
+mousepad_application_has_windows (MousepadApplication *application)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_APPLICATION (application), FALSE);
+
+  return (application->windows != NULL);
+}
+
+
+
+void
+mousepad_application_open_window (MousepadApplication  *application,
+                                  GdkScreen            *screen,
+                                  const gchar          *working_directory,
+                                  gchar               **filenames)
+{
+  GtkWidget *window;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_APPLICATION (application));
+  _mousepad_return_if_fail (screen == NULL || GDK_IS_SCREEN (screen));
+
+  /* create a new window */
+  window = mousepad_window_new ();
+
+  /* get the screen */
+  if (G_UNLIKELY (screen == NULL))
+    screen = gdk_screen_get_default ();
+
+  /* move to the correct screen */
+  gtk_window_set_screen (GTK_WINDOW (window), screen);
+
+  /* open the filenames or an empty tab */
+  if (filenames != NULL && *filenames != NULL)
+    mousepad_window_open_files (MOUSEPAD_WINDOW (window), working_directory, filenames);
+  else
+    mousepad_window_open_tab (MOUSEPAD_WINDOW (window), NULL);
+
+  /* connect to the "destroy" signal */
+  g_signal_connect (G_OBJECT (window), "destroy",
+                    G_CALLBACK (mousepad_application_window_destroyed), application);
+
+  /* add the window to our internal list */
+  application->windows = g_list_prepend (application->windows, window);
+
+  gtk_widget_show (window);
+}
+
+
+
+static void
+mousepad_application_window_destroyed (GtkWidget           *window,
+                                       MousepadApplication *application)
+{
+  _mousepad_return_if_fail (GTK_IS_WINDOW (window));
+  _mousepad_return_if_fail (MOUSEPAD_IS_APPLICATION (application));
+  _mousepad_return_if_fail (g_list_find (application->windows, window) != NULL);
+
+  /* remove the window from the list */
+  application->windows = g_list_remove (application->windows, window);
+
+  /* quit if there are no windows opened */
+  if (application->windows == NULL)
+    gtk_main_quit ();
+}
diff --git a/mousepad/mousepad-application.h b/mousepad/mousepad-application.h
new file mode 100644
index 0000000..de4dde9
--- /dev/null
+++ b/mousepad/mousepad-application.h
@@ -0,0 +1,52 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_APPLICATION_H__
+#define __MOUSEPAD_APPLICATION_H__
+
+#include <exo/exo.h>
+
+G_BEGIN_DECLS
+
+typedef struct _MousepadApplicationClass MousepadApplicationClass;
+typedef struct _MousepadApplication      MousepadApplication;
+
+#define MOUSEPAD_TYPE_APPLICATION            (mousepad_application_get_type ())
+#define MOUSEPAD_APPLICATION(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_APPLICATION, MousepadApplication))
+#define MOUSEPAD_APPLICATION_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_APPLICATION, MousepadApplicationClass))
+#define MOUSEPAD_IS_APPLICATION(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_APPLICATION))
+#define MOUSEPAD_IS_APPLICATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), MOUSEPAD_TYPE_APPLICATION))
+#define MOUSEPAD_APPLICATION_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_APPLICATION, MousepadApplicationClass))
+
+GType                mousepad_application_get_type    (void) G_GNUC_CONST;
+
+MousepadApplication *mousepad_application_get         (void);
+
+GList               *mousepad_application_get_windows (MousepadApplication  *application);
+
+gboolean             mousepad_application_has_windows (MousepadApplication  *application);
+
+void                 mousepad_application_open_window (MousepadApplication  *application,
+                                                       GdkScreen            *screen,
+                                                       const gchar          *working_directory,
+                                                       gchar               **filenames);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_APPLICATION_H__ */
diff --git a/mousepad/mousepad-dbus-infos.xml b/mousepad/mousepad-dbus-infos.xml
new file mode 100644
index 0000000..27fa116
--- /dev/null
+++ b/mousepad/mousepad-dbus-infos.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<node name="/org/xfce/Mousepad">
+
+  <interface name="org.xfce.Mousepad">
+    <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="mousepad_dbus_service" />
+
+    <method name="LaunchFiles">
+      <arg direction="in" name="working-directory" type="s" />
+      <arg direction="in" name="filenames" type="as" />
+    </method>
+
+  </interface>
+
+</node>
diff --git a/mousepad/mousepad-dbus.c b/mousepad/mousepad-dbus.c
new file mode 100644
index 0000000..9c6f6bd
--- /dev/null
+++ b/mousepad/mousepad-dbus.c
@@ -0,0 +1,247 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2004-2007 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2007      Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <dbus/dbus-glib-lowlevel.h>
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus.h>
+
+#include <mousepad/mousepad-dbus.h>
+#include <mousepad/mousepad-private.h>
+
+
+
+static void      mousepad_dbus_service_class_init     (MousepadDBusServiceClass  *klass);
+static void      mousepad_dbus_service_init           (MousepadDBusService       *dbus_service);
+static void      mousepad_dbus_service_finalize       (GObject                   *object);
+static gboolean  mousepad_dbus_service_launch_files   (MousepadDBusService       *dbus_service,
+                                                       const gchar               *working_directory,
+                                                       gchar                    **filenames,
+                                                       GError                   **error);
+
+
+
+struct _MousepadDBusServiceClass
+{
+  GObjectClass __parent__;
+};
+
+struct _MousepadDBusService
+{
+  GObject __parent__;
+
+  DBusGConnection *connection;
+};
+
+
+
+static GObjectClass *mousepad_dbus_service_parent_class;
+
+
+
+GType
+mousepad_dbus_service_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (G_TYPE_OBJECT,
+                                            I_("MousepadDBusService"),
+                                            sizeof (MousepadDBusServiceClass),
+                                            (GClassInitFunc) mousepad_dbus_service_class_init,
+                                            sizeof (MousepadDBusService),
+                                            (GInstanceInitFunc) mousepad_dbus_service_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_dbus_service_class_init (MousepadDBusServiceClass *klass)
+{
+  extern const DBusGObjectInfo  dbus_glib_mousepad_dbus_service_object_info;
+  GObjectClass                 *gobject_class;
+
+  /* determine the parent type class */
+  mousepad_dbus_service_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_dbus_service_finalize;
+
+  /* install the D-BUS info for our class */
+  dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass), &dbus_glib_mousepad_dbus_service_object_info);
+}
+
+
+
+static void
+mousepad_dbus_service_init (MousepadDBusService *dbus_service)
+{
+  GError *error = NULL;
+
+  /* try to connect to the session bus */
+  dbus_service->connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+  if (G_LIKELY (dbus_service->connection != NULL))
+    {
+      /* register the /org/xfce/TextEditor object for Mousepad */
+      dbus_g_connection_register_g_object (dbus_service->connection, "/org/xfce/Mousepad", G_OBJECT (dbus_service));
+
+      /* request the org.xfce.Mousepad name for Mousepad */
+      dbus_bus_request_name (dbus_g_connection_get_connection (dbus_service->connection), "org.xfce.Mousepad", DBUS_NAME_FLAG_REPLACE_EXISTING, NULL);
+    }
+  else
+    {
+#ifdef NDEBUG
+      /* hide this warning when the user is root and debug is disabled */
+      if (geteuid () != 0)
+#endif
+        {
+          /* notify the user that D-BUS service won't be available */
+          g_message ("Failed to connect to the D-BUS session bus: %s\n", error->message);
+        }
+
+      g_error_free (error);
+    }
+}
+
+
+
+static void
+mousepad_dbus_service_finalize (GObject *object)
+{
+  MousepadDBusService *dbus_service = MOUSEPAD_DBUS_SERVICE (object);
+
+  /* release the D-BUS connection object */
+  if (G_LIKELY (dbus_service->connection != NULL))
+    dbus_g_connection_unref (dbus_service->connection);
+
+  (*G_OBJECT_CLASS (mousepad_dbus_service_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+mousepad_dbus_service_launch_files (MousepadDBusService  *dbus_service,
+                                    const gchar          *working_directory,
+                                    gchar               **filenames,
+                                    GError              **error)
+{
+  MousepadApplication *application;
+   GdkScreen          *screen;
+
+  _mousepad_return_val_if_fail (g_path_is_absolute (working_directory), FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  screen = gdk_screen_get_default ();
+
+  application = mousepad_application_get ();
+  mousepad_application_open_window (application, screen, working_directory, filenames);
+  g_object_unref (G_OBJECT (application));
+
+  return TRUE;
+}
+
+
+
+gboolean
+mousepad_dbus_client_launch_files (gchar       **filenames,
+                                   const gchar  *working_directory,
+                                   GError      **error)
+{
+  DBusConnection *connection;
+  DBusMessage    *message;
+  DBusMessage    *result;
+  DBusError       derror;
+
+  _mousepad_return_val_if_fail (g_path_is_absolute (working_directory), FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  dbus_error_init (&derror);
+
+  /* try to connect to the session bus */
+  connection = dbus_bus_get (DBUS_BUS_SESSION, &derror);
+  if (G_UNLIKELY (connection == NULL))
+    {
+      dbus_set_g_error (error, &derror);
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  /* generate the message */
+  message = dbus_message_new_method_call ("org.xfce.Mousepad", "/org/xfce/Mousepad",
+                                          "org.xfce.Mousepad", "LaunchFiles");
+  dbus_message_set_auto_start (message, FALSE);
+  dbus_message_append_args (message,
+                            DBUS_TYPE_STRING, &working_directory,
+                            DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &filenames, filenames ? g_strv_length (filenames) : 0,
+                            DBUS_TYPE_INVALID);
+
+  /* send the message */
+  result = dbus_connection_send_with_reply_and_block (connection, message, -1, &derror);
+
+  /* release ref */
+  dbus_message_unref (message);
+
+  /* check if no reply was received */
+  if (result == NULL)
+    {
+#ifndef NDEBUG
+      /* set the error when debug is enabled */
+      dbus_set_g_error (error, &derror);
+#endif
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  /* but maybe we received an error */
+  if (dbus_message_get_type (result) == DBUS_MESSAGE_TYPE_ERROR)
+    {
+      dbus_set_error_from_message (&derror, result);
+      dbus_set_g_error (error, &derror);
+      dbus_message_unref (result);
+      dbus_error_free (&derror);
+      return FALSE;
+    }
+
+  /* it seems everything worked */
+  dbus_message_unref (result);
+
+  return TRUE;
+}
+
+
+
+#include <mousepad/mousepad-dbus-infos.h>
+
diff --git a/mousepad/mousepad-dbus.h b/mousepad/mousepad-dbus.h
new file mode 100644
index 0000000..50e5866
--- /dev/null
+++ b/mousepad/mousepad-dbus.h
@@ -0,0 +1,44 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_DBUS_H__
+#define __MOUSEPAD_DBUS_H__
+
+typedef struct _MousepadDBusServiceClass MousepadDBusServiceClass;
+typedef struct _MousepadDBusService      MousepadDBusService;
+
+#include <mousepad/mousepad-application.h>
+
+#define MOUSEPAD_TYPE_DBUS_SERVICE             (mousepad_dbus_service_get_type ())
+#define MOUSEPAD_DBUS_SERVICE(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_DBUS_SERVICE, MousepadDBusService))
+#define MOUSEPAD_DBUS_SERVICE_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_DBUS_SERVICE, MousepadDBusServiceClass))
+#define MOUSEPAD_IS_DBUS_SERVICE(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_DBUS_SERVICE))
+#define MOUSEPAD_IS_DBUS_SERVICE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), MOUSEPAD_TYPE_DBUS_BRIGDE))
+#define MOUSEPAD_DBUS_SERVICE_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_DBUS_SERVICE, MousepadDBusServiceClass))
+
+GType     mousepad_dbus_service_get_type (void) G_GNUC_CONST;
+
+gboolean
+mousepad_dbus_client_launch_files (gchar       **filenames,
+                                   const gchar  *working_directory,
+                                   GError      **error);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_DBUS_H__ */
diff --git a/mousepad/mousepad-file.c b/mousepad/mousepad-file.c
new file mode 100644
index 0000000..6854fa6
--- /dev/null
+++ b/mousepad/mousepad-file.c
@@ -0,0 +1,331 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_MMAN_H
+#include <sys/mman.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-file.h>
+
+
+
+gboolean
+mousepad_file_get_externally_modified (const gchar  *filename,
+                                       gint          mtime,
+                                       GError      **error)
+{
+  gint         fd;
+  struct stat  statb;
+  gboolean     modified = FALSE;
+
+  _mousepad_return_val_if_fail (filename != NULL, FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+
+  /* open the file for reading */
+  fd = open (filename, O_RDONLY);
+  if (G_UNLIKELY (fd < 0))
+    {
+      g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO,
+                   _("Failed to open \"%s\" for reading"), filename);
+      return FALSE;
+    }
+
+  /* check if the file has been modified */
+  if (G_LIKELY (fstat (fd, &statb) == 0))
+    modified = (mtime > 0 && statb.st_mtime != mtime);
+
+  /* close the file */
+  close (fd);
+
+  return modified;
+}
+
+
+
+gboolean
+mousepad_file_save_data (const gchar  *filename,
+                         const gchar  *data,
+                         gsize         bytes,
+                         gint         *new_mtime,
+                         GError      **error)
+{
+  gint         fd;
+  struct stat  statb;
+  gboolean     succeed = FALSE;
+  gint         n, m, l;
+
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _mousepad_return_val_if_fail (filename != NULL, FALSE);
+  _mousepad_return_val_if_fail (data != NULL, FALSE);
+
+  /* try to create the file (this failes if it already exists) */
+  fd = open (filename, O_CREAT | O_EXCL | O_WRONLY, 0666);
+  if (fd < 0)
+    {
+      if (G_LIKELY (errno == EEXIST))
+        {
+          /* try to open an existing file for reading */
+          fd = open (filename, O_RDWR);
+          if (G_UNLIKELY (fd < 0))
+            {
+              g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_IO,
+                           _("Failed to open \"%s\" for writing"), filename);
+              return FALSE;
+             }
+        }
+      else
+        {
+          /* failed to create a file */
+          g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                       _("Failed to create new file \"%s\""), filename);
+          return FALSE;
+        }
+    }
+
+  /* get the file information */
+  if (G_UNLIKELY (fstat (fd, &statb) != 0))
+    goto failed;
+
+  /* an extra check if we are allowed to write */
+  if (G_UNLIKELY ((statb.st_mode & 00222) == 0 && access (filename, W_OK) != 0))
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("You don't have permission to write to \"%s\""), filename);
+      goto failed;
+    }
+
+  /* make sure the document is empty and we're writing at the beginning of the file */
+  if (G_LIKELY (lseek (fd, 0, SEEK_SET) != -1))
+    if (G_UNLIKELY (ftruncate (fd, 0) != 0))
+      {
+        g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                     _("Failed to truncate \"%s\" before writing"), filename);
+        goto failed;
+      }
+
+  /* write the content to the file */
+  for (m = 0, n = bytes; m < n; )
+    {
+      /* write the data piece by piece */
+      l = write (fd, data + m, n - m);
+
+      if (G_UNLIKELY (l < 0))
+        {
+          /* just try again on EAGAIN/EINTR */
+          if (G_LIKELY (errno != EAGAIN && errno != EINTR))
+            {
+              g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                           _("Failed to write data to \"%s\""), filename);
+              goto failed;
+            }
+        }
+      else
+        {
+          /* advance the offset */
+          m += l;
+        }
+    }
+
+  /* re-stat the mtime */
+  if (G_UNLIKELY (fstat (fd, &statb) == 0))
+    *new_mtime = statb.st_mtime;
+
+  /* mm.. it seems everything worked fine */
+  succeed = TRUE;
+
+failed:
+  /* close the file */
+  close (fd);
+
+  return succeed;
+}
+
+
+
+gboolean
+mousepad_file_read_to_buffer (const gchar    *filename,
+                              GtkTextBuffer  *buffer,
+                              gint           *new_mtime,
+                              gboolean       *readonly,
+                              GError        **error)
+{
+  GtkTextIter    start_iter;
+  struct stat    statb;
+  gchar         *content;
+  gint           fd;
+  gboolean       succeed = FALSE;
+
+  _mousepad_return_val_if_fail (GTK_IS_TEXT_BUFFER (buffer), FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _mousepad_return_val_if_fail (filename != NULL, FALSE);
+
+  /* get the start point in the buffer */
+  gtk_text_buffer_get_start_iter (buffer, &start_iter);
+
+  /* open the file for reading */
+  fd = open (filename, O_RDONLY);
+  if (G_UNLIKELY (fd < 0))
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("Failed to open \"%s\" for reading"), filename);
+      return FALSE;
+    }
+
+  /* read the file information */
+  if (G_UNLIKELY (fstat (fd, &statb) < 0))
+    goto failed;
+
+  /* extra check if we're allowed to read the file */
+  if ((statb.st_mode & 00444) == 0 && access (filename, R_OK) != 0)
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("You are not allowed to read \"%s\""), filename);
+      goto failed;
+    }
+
+  /* check if we're allowed to write the file */
+  *readonly = !((statb.st_mode & 00222) != 0 && access (filename, W_OK) == 0);
+
+#ifdef HAVE_MMAP
+  /* try mmap() for files not larger than 8MB */
+  content = (statb.st_size <= 8 * 1024 * 1024)
+            ? (gchar *) mmap (NULL, statb.st_size, PROT_READ, MAP_SHARED, fd, 0)
+            : MAP_FAILED;
+
+  if (G_LIKELY (content != (gchar *) MAP_FAILED))
+    {
+#ifdef HAVE_POSIX_MADVISE
+      /* tell the system that the data will be read sequentially */
+      posix_madvise (content, statb.st_size, POSIX_MADV_SEQUENTIAL);
+#endif
+
+      /* insert the file content */
+      gtk_text_buffer_insert (buffer, &start_iter, content, strlen (content));
+
+      /* unmap */
+      munmap (content, statb.st_size);
+    }
+  else
+#endif /* !HAVE_MMAP */
+    {
+      /* load the file content by using the glib function */
+      if (G_UNLIKELY (g_file_get_contents (filename, &content, NULL, error) == FALSE))
+        goto failed;
+
+      /* insert the file content */
+      gtk_text_buffer_insert (buffer, &start_iter, content, strlen (content));
+
+      /* cleanup */
+      g_free (content);
+    }
+
+  /* set the mtime of the document */
+  *new_mtime = statb.st_mtime;
+
+  /* everything went ok */
+  succeed = TRUE;
+
+failed:
+  /* close the file */
+  close (fd);
+
+  return succeed;
+}
+
+
+
+gboolean
+mousepad_file_is_writable (const gchar  *filename,
+                           GError      **error)
+{
+  struct stat statb;
+  gint        fd;
+  gboolean    writable = FALSE;
+
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _mousepad_return_val_if_fail (filename != NULL, FALSE);
+
+  fd = open (filename, O_RDONLY);
+  if (G_UNLIKELY (fd < 0))
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("Failed to open \"%s\" for reading"), filename);
+      return FALSE;
+    }
+
+  /* read the file information */
+  if (G_UNLIKELY (fstat (fd, &statb) < 0))
+    goto failed;
+
+  /* get the file information */
+  if (G_UNLIKELY (fstat (fd, &statb) != 0))
+    goto failed;
+
+  /* an extra check if we are allowed to write */
+  if ((statb.st_mode & 00222) != 0 && access (filename, W_OK) == 0)
+    {
+      writable = TRUE;
+    }
+  else
+    {
+      g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
+                   _("You don't have permission to write to \"%s\""), filename);
+      goto failed;
+    }
+
+
+failed:
+  /* close the file */
+  close (fd);
+
+  return writable;
+}
+
+
+
diff --git a/mousepad/mousepad-file.h b/mousepad/mousepad-file.h
new file mode 100644
index 0000000..cabfda8
--- /dev/null
+++ b/mousepad/mousepad-file.h
@@ -0,0 +1,46 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_FILE_H__
+#define __MOUSEPAD_FILE_H__
+
+G_BEGIN_DECLS
+
+gboolean   mousepad_file_get_externally_modified   (const gchar    *filename,
+                                                    gint            mtime,
+                                                    GError        **error);
+
+gboolean   mousepad_file_save_data                 (const gchar    *filename,
+                                                    const gchar    *data,
+                                                    gsize           bytes,
+                                                    gint           *new_mtime,
+                                                    GError        **error);
+
+gboolean   mousepad_file_read_to_buffer            (const gchar    *filename,
+                                                    GtkTextBuffer  *buffer,
+                                                    gint           *new_mtime,
+                                                    gboolean       *readonly,
+                                                    GError        **error);
+
+gboolean   mousepad_file_is_writable               (const gchar    *filename,
+                                                    GError        **error);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_FILE_H__ */
diff --git a/mousepad/mousepad-preferences.c b/mousepad/mousepad-preferences.c
new file mode 100644
index 0000000..4a3f1d1
--- /dev/null
+++ b/mousepad/mousepad-preferences.c
@@ -0,0 +1,544 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ * Copyright (c) 2007 Benedikt Meurer <benny at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <glib-object.h>
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-preferences.h>
+
+
+
+enum
+{
+  PROP_0,
+  PROP_AUTO_INDENT,
+  PROP_FONT_NAME,
+  PROP_LAST_WINDOW_HEIGHT,
+  PROP_LAST_WINDOW_WIDTH,
+  PROP_LINE_NUMBERS,
+  PROP_WORD_WRAP,
+  PROP_MISC_ALWAYS_SHOW_TABS,
+  PROP_MISC_CYCLE_TABS,
+  PROP_MISC_SHOW_FULL_PATH_IN_TITLE,
+  PROP_MISC_RECENT_MENU_LIMIT,
+  PROP_MISC_REMEMBER_GEOMETRY,
+  PROP_MISC_TAB_CLOSE_BUTTONS,
+  N_PROPERTIES,
+};
+
+static void     transform_string_to_boolean             (const GValue             *src,
+                                                         GValue                   *dst);
+static void     transform_string_to_int                 (const GValue             *src,
+                                                         GValue                   *dst);
+static void     mousepad_preferences_class_init         (MousepadPreferencesClass *klass);
+static void     mousepad_preferences_init               (MousepadPreferences      *preferences);
+static void     mousepad_preferences_finalize           (GObject                  *object);
+static void     mousepad_preferences_get_property       (GObject                  *object,
+                                                         guint                     prop_id,
+                                                         GValue                   *value,
+                                                         GParamSpec               *pspec);
+static void     mousepad_preferences_set_property       (GObject                  *object,
+                                                         guint                     prop_id,
+                                                         const GValue             *value,
+                                                         GParamSpec               *pspec);
+static void     mousepad_preferences_queue_store        (MousepadPreferences      *preferences);
+static gboolean mousepad_preferences_load_idle          (gpointer                  user_data);
+static gboolean mousepad_preferences_store_idle         (gpointer                  user_data);
+static void     mousepad_preferences_store_idle_destroy (gpointer                  user_data);
+
+struct _MousepadPreferencesClass
+{
+  GObjectClass __parent__;
+};
+
+struct _MousepadPreferences
+{
+  GObject  __parent__;
+
+  GValue   values[N_PROPERTIES];
+
+  gboolean loading_in_progress;
+
+  gint     store_idle_id;
+};
+
+
+
+static GObjectClass *mousepad_preferences_parent_class;
+
+
+
+static void
+transform_string_to_boolean (const GValue *src,
+                             GValue       *dst)
+{
+  g_value_set_boolean (dst, strcmp (g_value_get_string (src), "FALSE") != 0);
+}
+
+
+
+static void
+transform_string_to_int (const GValue *src,
+                         GValue       *dst)
+{
+  g_value_set_int (dst, (gint) strtol (g_value_get_string (src), NULL, 10));
+}
+
+
+
+GType
+mousepad_preferences_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (G_TYPE_OBJECT,
+                                            I_("MousepadPreferences"),
+                                            sizeof (MousepadPreferencesClass),
+                                            (GClassInitFunc) mousepad_preferences_class_init,
+                                            sizeof (MousepadPreferences),
+                                            (GInstanceInitFunc) mousepad_preferences_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_preferences_class_init (MousepadPreferencesClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  /* determine the parent type class */
+  mousepad_preferences_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_preferences_finalize;
+  gobject_class->get_property = mousepad_preferences_get_property;
+  gobject_class->set_property = mousepad_preferences_set_property;
+
+  /* register transformation functions */
+  if (!g_value_type_transformable (G_TYPE_STRING, G_TYPE_BOOLEAN))
+    g_value_register_transform_func (G_TYPE_STRING, G_TYPE_BOOLEAN, transform_string_to_boolean);
+  if (!g_value_type_transformable (G_TYPE_STRING, G_TYPE_INT))
+    g_value_register_transform_func (G_TYPE_STRING, G_TYPE_INT, transform_string_to_int);
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_AUTO_INDENT,
+                                   g_param_spec_boolean ("auto-indent",
+                                                         "auto-indent",
+                                                         "auto-indent",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_FONT_NAME,
+                                   g_param_spec_string ("font-name",
+                                                        "font-name",
+                                                        "font-name",
+                                                        NULL,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_LAST_WINDOW_HEIGHT,
+                                   g_param_spec_int ("last-window-height",
+                                                     "last-window-height",
+                                                     "last-window-height",
+                                                     1, G_MAXINT, 480,
+                                                     EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_LAST_WINDOW_WIDTH,
+                                   g_param_spec_int ("last-window-width",
+                                                     "last-window-width",
+                                                     "last-window-width",
+                                                     1, G_MAXINT, 640,
+                                                     EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_LINE_NUMBERS,
+                                   g_param_spec_boolean ("line-numbers",
+                                                         "line-numbers",
+                                                         "line-numbers",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_WORD_WRAP,
+                                   g_param_spec_boolean ("word-wrap",
+                                                         "word-wrap",
+                                                         "word-wrap",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_ALWAYS_SHOW_TABS,
+                                   g_param_spec_boolean ("misc-always-show-tabs",
+                                                         "misc-always-show-tabs",
+                                                         "misc-always-show-tabs",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_CYCLE_TABS,
+                                   g_param_spec_boolean ("misc-cycle-tabs",
+                                                         "misc-cycle-tabs",
+                                                         "misc-cycle-tabs",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_SHOW_FULL_PATH_IN_TITLE,
+                                   g_param_spec_boolean ("misc-show-full-path-in-title",
+                                                         "misc-show-full-path-in-title",
+                                                         "misc-show-full-path-in-title",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_RECENT_MENU_LIMIT,
+                                   g_param_spec_int ("misc-recent-menu-limit",
+                                                     "misc-recent-menu-limit",
+                                                     "misc-recent-menu-limit",
+                                                     1, G_MAXINT, 10,
+                                                     EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_REMEMBER_GEOMETRY,
+                                   g_param_spec_boolean ("misc-remember-geometry",
+                                                         "misc-remember-geometry",
+                                                         "misc-remember-geometry",
+                                                         TRUE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_MISC_TAB_CLOSE_BUTTONS,
+                                   g_param_spec_boolean ("misc-tab-close-buttons",
+                                                         "misc-tab-close-buttons",
+                                                         "misc-tab-close-buttons",
+                                                         TRUE,
+                                                         EXO_PARAM_READWRITE));
+}
+
+
+
+static void
+mousepad_preferences_init (MousepadPreferences *preferences)
+{
+  /* load the settings */
+  mousepad_preferences_load_idle (preferences);
+}
+
+
+
+static void
+mousepad_preferences_finalize (GObject *object)
+{
+  MousepadPreferences *preferences = MOUSEPAD_PREFERENCES (object);
+  guint                n;
+
+  /* flush preferences */
+  if (G_UNLIKELY (preferences->store_idle_id != 0))
+    {
+      mousepad_preferences_store_idle (preferences);
+      g_source_remove (preferences->store_idle_id);
+    }
+  /* release the property values */
+  for (n = 1; n < N_PROPERTIES; ++n)
+    if (G_IS_VALUE (preferences->values + n))
+      g_value_unset (preferences->values + n);
+
+  (*G_OBJECT_CLASS (mousepad_preferences_parent_class)->finalize) (object);
+}
+
+
+
+static void
+mousepad_preferences_get_property (GObject    *object,
+                                   guint       prop_id,
+                                   GValue     *value,
+                                   GParamSpec *pspec)
+{
+  MousepadPreferences *preferences = MOUSEPAD_PREFERENCES (object);
+  GValue              *src;
+
+  src = preferences->values + prop_id;
+  if (G_IS_VALUE (src))
+    g_value_copy (src, value);
+  else
+    g_param_value_set_default (pspec, value);
+}
+
+
+
+static void
+mousepad_preferences_set_property (GObject      *object,
+                                   guint         prop_id,
+                                   const GValue *value,
+                                   GParamSpec   *pspec)
+{
+  MousepadPreferences *preferences = MOUSEPAD_PREFERENCES (object);
+  GValue              *dst;
+
+  dst = preferences->values + prop_id;
+  if (G_UNLIKELY (!G_IS_VALUE (dst)))
+    g_value_init (dst, pspec->value_type);
+
+  if (g_param_values_cmp (pspec, value, dst) != 0)
+    {
+      g_value_copy (value, dst);
+      mousepad_preferences_queue_store (preferences);
+    }
+}
+
+
+
+static void
+mousepad_preferences_queue_store (MousepadPreferences *preferences)
+{
+  if (preferences->store_idle_id == 0 && !preferences->loading_in_progress)
+    {
+      preferences->store_idle_id = g_idle_add_full (G_PRIORITY_LOW, mousepad_preferences_store_idle,
+                                                    preferences, mousepad_preferences_store_idle_destroy);
+    }
+}
+
+
+
+static gchar*
+property_name_to_option_name (const gchar *property_name)
+{
+  const gchar *s;
+  gboolean     upper = TRUE;
+  gchar       *option;
+  gchar       *t;
+
+  option = g_new (gchar, strlen (property_name) + 1);
+  for (s = property_name, t = option; *s != '\0'; ++s)
+    {
+      if (*s == '-')
+        {
+          upper = TRUE;
+        }
+      else if (upper)
+        {
+          *t++ = g_ascii_toupper (*s);
+          upper = FALSE;
+        }
+      else
+        {
+          *t++ = *s;
+        }
+    }
+  *t = '\0';
+
+  return option;
+}
+
+
+
+static gboolean
+mousepad_preferences_load_idle (gpointer user_data)
+{
+  MousepadPreferences *preferences = MOUSEPAD_PREFERENCES (user_data);
+  const gchar         *string;
+  GParamSpec         **specs;
+  GParamSpec          *spec;
+  XfceRc              *rc;
+  GValue               dst = { 0, };
+  GValue               src = { 0, };
+  gchar               *option;
+  guint                nspecs;
+  guint                n;
+
+  rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, "Mousepad/mousepadrc", TRUE);
+  if (G_UNLIKELY (rc == NULL))
+    {
+      g_warning ("Failed to load mousepad preferences.");
+      return FALSE;
+    }
+
+  g_object_freeze_notify (G_OBJECT (preferences));
+
+  xfce_rc_set_group (rc, "Configuration");
+
+  preferences->loading_in_progress = TRUE;
+
+  specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (preferences), &nspecs);
+
+  for (n = 0; n < nspecs; ++n)
+    {
+      spec = specs[n];
+
+      option = property_name_to_option_name (spec->name);
+      string = xfce_rc_read_entry (rc, option, NULL);
+      g_free (option);
+
+      if (G_UNLIKELY (string == NULL))
+        continue;
+
+      g_value_init (&src, G_TYPE_STRING);
+      g_value_set_static_string (&src, string);
+
+      if (spec->value_type == G_TYPE_STRING)
+        {
+          g_object_set_property (G_OBJECT (preferences), spec->name, &src);
+        }
+      else if (g_value_type_transformable (G_TYPE_STRING, spec->value_type))
+        {
+          g_value_init (&dst, spec->value_type);
+          if (g_value_transform (&src, &dst))
+            g_object_set_property (G_OBJECT (preferences), spec->name, &dst);
+          g_value_unset (&dst);
+        }
+      else
+        {
+          g_warning ("Failed to load property \"%s\"", spec->name);
+        }
+
+      g_value_unset (&src);
+    }
+  g_free (specs);
+
+  preferences->loading_in_progress = FALSE;
+
+  xfce_rc_close (rc);
+
+  g_object_thaw_notify (G_OBJECT (preferences));
+
+  return FALSE;
+}
+
+
+
+static gboolean
+mousepad_preferences_store_idle (gpointer user_data)
+{
+  MousepadPreferences *preferences = MOUSEPAD_PREFERENCES (user_data);
+  const gchar         *string;
+  GParamSpec         **specs;
+  GParamSpec          *spec;
+  XfceRc              *rc;
+  GValue               dst = { 0, };
+  GValue               src = { 0, };
+  gchar               *option;
+  guint                nspecs;
+  guint                n;
+
+  rc = xfce_rc_config_open (XFCE_RESOURCE_CONFIG, "Mousepad/mousepadrc", FALSE);
+  if (G_UNLIKELY (rc == NULL))
+    {
+      g_warning ("Failed to store mousepad preferences.");
+      return FALSE;
+    }
+
+  xfce_rc_set_group (rc, "Configuration");
+
+  specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (preferences), &nspecs);
+
+  for (n = 0; n < nspecs; ++n)
+    {
+      spec = specs[n];
+
+      g_value_init (&dst, G_TYPE_STRING);
+
+      if (spec->value_type == G_TYPE_STRING)
+        {
+          g_object_get_property (G_OBJECT (preferences), spec->name, &dst);
+        }
+      else
+        {
+          g_value_init (&src, spec->value_type);
+          g_object_get_property (G_OBJECT (preferences), spec->name, &src);
+          g_value_transform (&src, &dst);
+          g_value_unset (&src);
+        }
+
+      /* determine the option name for the spec */
+      option = property_name_to_option_name (spec->name);
+
+      /* store the setting */
+      string = g_value_get_string (&dst);
+      if (G_LIKELY (string != NULL))
+        xfce_rc_write_entry (rc, option, string);
+
+      /* cleanup */
+      g_value_unset (&dst);
+      g_free (option);
+    }
+
+  /* cleanup */
+  xfce_rc_close (rc);
+  g_free (specs);
+
+  return FALSE;
+}
+
+
+
+static void
+mousepad_preferences_store_idle_destroy (gpointer user_data)
+{
+  MOUSEPAD_PREFERENCES (user_data)->store_idle_id = 0;
+}
+
+
+
+MousepadPreferences*
+mousepad_preferences_get (void)
+{
+  static MousepadPreferences *preferences = NULL;
+
+  if (G_UNLIKELY (preferences == NULL))
+    {
+      preferences = g_object_new (MOUSEPAD_TYPE_PREFERENCES, NULL);
+      g_object_add_weak_pointer (G_OBJECT (preferences),
+                                 (gpointer) &preferences);
+    }
+  else
+    {
+      g_object_ref (G_OBJECT (preferences));
+    }
+
+  return preferences;
+}
diff --git a/mousepad/mousepad-preferences.h b/mousepad/mousepad-preferences.h
new file mode 100644
index 0000000..c3d9d9b
--- /dev/null
+++ b/mousepad/mousepad-preferences.h
@@ -0,0 +1,43 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_PREFERENCIES_H__
+#define __MOUSEPAD_PREFERENCIES_H__
+
+#include <exo/exo.h>
+
+G_BEGIN_DECLS
+
+#define MOUSEPAD_TYPE_PREFERENCES             (mousepad_preferences_get_type ())
+#define MOUSEPAD_PREFERENCES(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_PREFERENCES, MousepadPreferences))
+#define MOUSEPAD_PREFERENCES_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_PREFERENCES, MousepadPreferencesClass))
+#define MOUSEPAD_IS_PREFERENCES(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_PREFERENCES))
+#define MOUSEPAD_IS_PREFERENCES_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), MOUSEPAD_TYPE_PREFERENCES))
+#define MOUSEPAD_PREFERENCES_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_PREFERENCES, MousepadPreferencesClass))
+
+typedef struct _MousepadPreferencesClass MousepadPreferencesClass;
+typedef struct _MousepadPreferences      MousepadPreferences;
+
+GType                mousepad_preferences_get_type (void) G_GNUC_CONST;
+
+MousepadPreferences *mousepad_preferences_get      (void);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_PREFERENCIES_H__ */
diff --git a/mousepad/mousepad-private.h b/mousepad/mousepad-private.h
new file mode 100644
index 0000000..7ed596e
--- /dev/null
+++ b/mousepad/mousepad-private.h
@@ -0,0 +1,75 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2006 Benedikt Meurer <benny at xfce.org>
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_PRIVATE_H__
+#define __MOUSEPAD_PRIVATE_H__
+
+#include <exo/exo.h>
+
+G_BEGIN_DECLS
+
+/* support macros for debugging */
+#ifndef NDEBUG
+#define _mousepad_assert(expr)                  g_assert (expr)
+#define _mousepad_assert_not_reached()          g_assert_not_reached ()
+#define _mousepad_return_if_fail(expr)          g_return_if_fail (expr)
+#define _mousepad_return_val_if_fail(expr, val) g_return_val_if_fail (expr, (val))
+#else
+#define _mousepad_assert(expr)                  G_STMT_START{ (void)0; }G_STMT_END
+#define _mousepad_assert_not_reached()          G_STMT_START{ (void)0; }G_STMT_END
+#define _mousepad_return_if_fail(expr)          G_STMT_START{ (void)0; }G_STMT_END
+#define _mousepad_return_val_if_fail(expr, val) G_STMT_START{ (void)0; }G_STMT_END
+#endif
+
+
+
+/* avoid trivial g_value_get_*() function calls */
+#ifdef NDEBUG
+#define g_value_get_boolean(v)  (((const GValue *) (v))->data[0].v_int)
+#define g_value_get_char(v)     (((const GValue *) (v))->data[0].v_int)
+#define g_value_get_uchar(v)    (((const GValue *) (v))->data[0].v_uint)
+#define g_value_get_int(v)      (((const GValue *) (v))->data[0].v_int)
+#define g_value_get_uint(v)     (((const GValue *) (v))->data[0].v_uint)
+#define g_value_get_long(v)     (((const GValue *) (v))->data[0].v_long)
+#define g_value_get_ulong(v)    (((const GValue *) (v))->data[0].v_ulong)
+#define g_value_get_int64(v)    (((const GValue *) (v))->data[0].v_int64)
+#define g_value_get_uint64(v)   (((const GValue *) (v))->data[0].v_uint64)
+#define g_value_get_enum(v)     (((const GValue *) (v))->data[0].v_long)
+#define g_value_get_flags(v)    (((const GValue *) (v))->data[0].v_ulong)
+#define g_value_get_float(v)    (((const GValue *) (v))->data[0].v_float)
+#define g_value_get_double(v)   (((const GValue *) (v))->data[0].v_double)
+#define g_value_get_string(v)   (((const GValue *) (v))->data[0].v_pointer)
+#define g_value_get_param(v)    (((const GValue *) (v))->data[0].v_pointer)
+#define g_value_get_boxed(v)    (((const GValue *) (v))->data[0].v_pointer)
+#define g_value_get_pointer(v)  (((const GValue *) (v))->data[0].v_pointer)
+#define g_value_get_object(v)   (((const GValue *) (v))->data[0].v_pointer)
+#endif
+
+
+
+/* don't use the invalid property warning since testing in debug builds is enough */
+#ifndef G_ENABLE_DEBUG
+#undef G_OBJECT_WARN_INVALID_PROPERTY_ID
+#define G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec) G_STMT_START{ (void)0; }G_STMT_END
+#endif
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_PRIVATE_H__ */
diff --git a/mousepad/mousepad-screen.c b/mousepad/mousepad-screen.c
new file mode 100644
index 0000000..73ad87d
--- /dev/null
+++ b/mousepad/mousepad-screen.c
@@ -0,0 +1,607 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_MEMORY_H
+#include <memory.h>
+#endif
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-file.h>
+#include <mousepad/mousepad-view.h>
+#include <mousepad/mousepad-screen.h>
+
+
+
+static void            mousepad_screen_class_init               (MousepadScreenClass  *klass);
+static void            mousepad_screen_init                     (MousepadScreen       *screen);
+static void            mousepad_screen_finalize                 (GObject              *object);
+static void            mousepad_screen_get_property             (GObject              *object,
+                                                                 guint                 prop_id,
+                                                                 GValue               *value,
+                                                                 GParamSpec           *pspec);
+static void            mousepad_screen_set_property             (GObject              *object,
+                                                                 guint                 prop_id,
+                                                                 const GValue         *value,
+                                                                 GParamSpec           *pspec);
+static void            mousepad_screen_set_font                 (MousepadScreen       *screen,
+                                                                 const gchar          *font_name);
+static void            mousepad_screen_set_word_wrap            (MousepadScreen       *screen,
+                                                                 gboolean              word_wrap);
+static void            mousepad_screen_modified_changed         (GtkTextBuffer        *buffer,
+                                                                 MousepadScreen       *screen);
+static void            mousepad_screen_has_selection            (GtkTextBuffer        *buffer,
+                                                                 GParamSpec           *pspec,
+                                                                 MousepadScreen       *screen);
+
+
+
+enum
+{
+  PROP_0,
+  PROP_AUTO_INDENT,
+  PROP_FILENAME,
+  PROP_FONT_NAME,
+  PROP_LINE_NUMBERS,
+  PROP_TITLE,
+  PROP_WORD_WRAP,
+};
+
+enum
+{
+  SELECTION_CHANGED,
+  MODIFIED_CHANGED,
+  LAST_SIGNAL,
+};
+
+struct _MousepadScreenClass
+{
+  GtkScrolledWindowClass __parent__;
+
+  /* signals */
+  void (*selection_changed) (MousepadScreen *screen,
+                             gboolean        selected);
+  void (*modified_changed)  (MousepadScreen *screen,
+                             gboolean        modified);
+};
+
+struct _MousepadScreen
+{
+  GtkScrolledWindow  __parent__;
+
+  GtkWidget         *textview;
+
+  /* file and display name */
+  gchar             *filename;
+  gchar             *display_name;
+
+  /* last document modified time */
+  time_t             mtime;
+};
+
+
+
+static guint         screen_signals[LAST_SIGNAL];
+static GObjectClass *mousepad_screen_parent_class;
+
+
+
+GtkWidget *
+mousepad_screen_new (void)
+{
+  return g_object_new (MOUSEPAD_TYPE_SCREEN, NULL);
+}
+
+
+
+GType
+mousepad_screen_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (GTK_TYPE_SCROLLED_WINDOW,
+                                            I_("MousepadScreen"),
+                                            sizeof (MousepadScreenClass),
+                                            (GClassInitFunc) mousepad_screen_class_init,
+                                            sizeof (MousepadScreen),
+                                            (GInstanceInitFunc) mousepad_screen_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_screen_class_init (MousepadScreenClass *klass)
+{
+  GObjectClass   *gobject_class;
+
+  mousepad_screen_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_screen_finalize;
+  gobject_class->get_property = mousepad_screen_get_property;
+  gobject_class->set_property = mousepad_screen_set_property;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_AUTO_INDENT,
+                                   g_param_spec_boolean ("auto-indent",
+                                                         "auto-indent",
+                                                         "auto-indent",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_FILENAME,
+                                   g_param_spec_string ("filename",
+                                                        "filename",
+                                                        "filename",
+                                                        NULL,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_FONT_NAME,
+                                   g_param_spec_string ("font-name",
+                                                        "font-name",
+                                                        "font-name",
+                                                        "Bitstream Vera Sans Mono 10",
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_LINE_NUMBERS,
+                                   g_param_spec_boolean ("line-numbers",
+                                                         "line-numbers",
+                                                         "line-numbers",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_TITLE,
+                                   g_param_spec_string ("title",
+                                                        "title",
+                                                        "title",
+                                                        NULL,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_WORD_WRAP,
+                                   g_param_spec_boolean ("word-wrap",
+                                                         "word-wrap",
+                                                         "word-wrap",
+                                                         FALSE,
+                                                         EXO_PARAM_READWRITE));
+
+  screen_signals[SELECTION_CHANGED] =
+    g_signal_new (I_("selection-changed"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__BOOLEAN,
+                  G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+  screen_signals[MODIFIED_CHANGED] =
+    g_signal_new (I_("modified-changed"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+}
+
+
+
+static void
+mousepad_screen_init (MousepadScreen *screen)
+{
+  GtkTextBuffer *buffer;
+
+  /* initialize the variables */
+  screen->filename     = NULL;
+  screen->display_name = NULL;
+  screen->mtime        = 0;
+
+  /* setup the scolled window */
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (screen),
+                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_scrolled_window_set_hadjustment (GTK_SCROLLED_WINDOW (screen), NULL);
+  gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW (screen), NULL);
+
+  /* setup the textview */
+  screen->textview = g_object_new (MOUSEPAD_TYPE_VIEW, NULL);
+  gtk_container_add (GTK_CONTAINER (screen), screen->textview);
+  gtk_widget_show (screen->textview);
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (screen->textview));
+  g_signal_connect (G_OBJECT (buffer), "modified-changed",
+                    G_CALLBACK (mousepad_screen_modified_changed), screen);
+  g_signal_connect (G_OBJECT (buffer), "notify::has-selection",
+                    G_CALLBACK (mousepad_screen_has_selection), screen);
+
+}
+
+
+
+static void
+mousepad_screen_finalize (GObject *object)
+{
+  MousepadScreen *screen = MOUSEPAD_SCREEN (object);
+
+  g_free (screen->filename);
+  g_free (screen->display_name);
+
+  (*G_OBJECT_CLASS (mousepad_screen_parent_class)->finalize) (object);
+}
+
+
+
+static void
+mousepad_screen_get_property (GObject    *object,
+                              guint       prop_id,
+                              GValue     *value,
+                              GParamSpec *pspec)
+{
+  MousepadScreen *screen = MOUSEPAD_SCREEN (object);
+
+  switch (prop_id)
+    {
+      case PROP_FILENAME:
+        g_value_set_static_string (value, mousepad_screen_get_filename (screen));
+        break;
+
+      case PROP_TITLE:
+        g_value_set_static_string (value, mousepad_screen_get_title (screen, FALSE));
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
+mousepad_screen_set_property (GObject      *object,
+                              guint         prop_id,
+                              const GValue *value,
+                              GParamSpec   *pspec)
+{
+  MousepadScreen *screen = MOUSEPAD_SCREEN (object);
+
+  switch (prop_id)
+    {
+      case PROP_FONT_NAME:
+        mousepad_screen_set_font (screen, g_value_get_string (value));
+        break;
+
+      case PROP_LINE_NUMBERS:
+        mousepad_view_set_show_line_numbers (MOUSEPAD_VIEW (screen->textview),
+                                             g_value_get_boolean (value));
+        break;
+
+      case PROP_AUTO_INDENT:
+        mousepad_view_set_auto_indent (MOUSEPAD_VIEW (screen->textview),
+                                       g_value_get_boolean (value));
+        break;
+
+      case PROP_WORD_WRAP:
+        mousepad_screen_set_word_wrap (screen, g_value_get_boolean (value));
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
+mousepad_screen_set_font (MousepadScreen *screen,
+                          const gchar    *font_name)
+{
+  PangoFontDescription *font_desc;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_SCREEN (screen));
+
+  if (G_LIKELY (font_name))
+    {
+      font_desc = pango_font_description_from_string (font_name);
+      gtk_widget_modify_font (GTK_WIDGET (screen->textview), font_desc);
+      pango_font_description_free (font_desc);
+    }
+}
+
+
+
+static void
+mousepad_screen_set_word_wrap (MousepadScreen *screen,
+                               gboolean        word_wrap)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_SCREEN (screen));
+
+  gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (screen->textview),
+                               word_wrap ? GTK_WRAP_WORD : GTK_WRAP_NONE);
+}
+
+
+
+static void
+mousepad_screen_modified_changed (GtkTextBuffer  *buffer,
+                                  MousepadScreen *screen)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_SCREEN (screen));
+
+  g_signal_emit (G_OBJECT (screen), screen_signals[MODIFIED_CHANGED], 0);
+}
+
+
+
+static void
+mousepad_screen_has_selection (GtkTextBuffer  *buffer,
+                               GParamSpec     *pspec,
+                               MousepadScreen *screen)
+{
+  gboolean selected;
+
+  _mousepad_return_if_fail (GTK_IS_TEXT_BUFFER (buffer));
+  _mousepad_return_if_fail (MOUSEPAD_IS_SCREEN (screen));
+
+  g_object_get (G_OBJECT (buffer), "has-selection", &selected, NULL);
+
+  g_signal_emit (G_OBJECT (screen), screen_signals[SELECTION_CHANGED], 0, selected);
+}
+
+
+
+void
+mousepad_screen_set_filename (MousepadScreen *screen,
+                              const gchar    *filename)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_SCREEN (screen));
+  _mousepad_return_if_fail (filename != NULL);
+
+  /* cleanup the old names */
+  g_free (screen->filename);
+  g_free (screen->display_name);
+
+  /* create the new names */
+  screen->filename = g_strdup (filename);
+  screen->display_name = g_filename_display_basename (filename);
+
+  /* tell the listeners */
+  g_object_notify (G_OBJECT (screen), "title");
+}
+
+
+
+gboolean
+mousepad_screen_open_file (MousepadScreen  *screen,
+                           const gchar     *filename,
+                           GError         **error)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter    iter;
+  gboolean       succeed = FALSE;
+  gboolean       readonly;
+  gint           new_mtime;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _mousepad_return_val_if_fail (filename != NULL, FALSE);
+
+  /* get the buffer */
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (screen->textview));
+
+  /* we're going to add the file content */
+  gtk_text_buffer_begin_user_action (buffer);
+
+  /* insert the file content */
+  if (mousepad_file_read_to_buffer (filename,
+                                    buffer,
+                                    &new_mtime,
+                                    &readonly,
+                                    error))
+    {
+      /* set the new filename */
+      mousepad_screen_set_filename (screen, filename);
+
+      /* set the new mtime */
+      screen->mtime = new_mtime;
+
+      /* whether the textview is editable */
+      gtk_text_view_set_editable (GTK_TEXT_VIEW (screen->textview), !readonly);
+
+      /* move the cursors to the first place and pretend nothing happend */
+      gtk_text_buffer_get_start_iter (buffer, &iter);
+      gtk_text_buffer_place_cursor (buffer, &iter);
+      gtk_text_buffer_set_modified (buffer, FALSE);
+      gtk_text_view_scroll_to_iter (GTK_TEXT_VIEW (screen->textview), &iter, 0, FALSE, 0, 0);
+
+      /* it worked out very well */
+      succeed = TRUE;
+    }
+
+  /* and we're done */
+  gtk_text_buffer_end_user_action (buffer);
+
+  return succeed;
+}
+
+
+
+gboolean
+mousepad_screen_save_file (MousepadScreen  *screen,
+                           GError         **error)
+{
+  gchar         *content;
+  gchar         *converted = NULL;
+  GtkTextBuffer *buffer;
+  GtkTextIter    start, end;
+  gsize          bytes;
+  gint           new_mtime;
+  gboolean       succeed = FALSE;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), FALSE);
+  _mousepad_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  _mousepad_return_val_if_fail (screen->filename != NULL, FALSE);
+
+  /* get the buffer */
+  buffer = mousepad_screen_get_text_buffer (screen);
+
+  /* get the textview content */
+  gtk_text_buffer_get_bounds (buffer, &start, &end);
+  content = gtk_text_buffer_get_slice (buffer, &start, &end, TRUE);
+
+  if (G_LIKELY (content != NULL))
+    {
+      /* TODO: fix the file encoding here, basic utf8 for testing */
+      converted = g_convert (content,
+                             strlen (content),
+                             "UTF-8",
+                             "UTF-8",
+                             NULL,
+                             &bytes,
+                             error);
+
+      /* cleanup */
+      g_free (content);
+
+      if (G_LIKELY (converted != NULL))
+        {
+          succeed = mousepad_file_save_data (screen->filename, converted, bytes,
+                                             &new_mtime, error);
+
+          /* cleanup */
+          g_free (converted);
+
+          /* saving work w/o problems */
+          if (G_LIKELY (succeed))
+            {
+              /* set the new mtime */
+              screen->mtime = new_mtime;
+
+              /* nothing happend */
+              gtk_text_buffer_set_modified (buffer, FALSE);
+
+              /* we were allowed to write */
+              gtk_text_view_set_editable (GTK_TEXT_VIEW (screen->textview), TRUE);
+
+              /* emit the modified-changed signal */
+              mousepad_screen_modified_changed (NULL, screen);
+            }
+        }
+    }
+
+  return succeed;
+}
+
+
+
+const gchar *
+mousepad_screen_get_title (MousepadScreen *screen,
+                           gboolean        show_full_path)
+{
+  const gchar *title;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), NULL);
+
+  if (G_UNLIKELY (show_full_path && screen->filename))
+    title = screen->filename;
+  else if (screen->display_name)
+    title = screen->display_name;
+  else
+    title = _("Untitled");
+
+  return title;
+}
+
+
+
+const gchar *
+mousepad_screen_get_filename (MousepadScreen *screen)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), NULL);
+
+  return screen->filename;
+}
+
+
+
+gboolean
+mousepad_screen_get_externally_modified (MousepadScreen  *screen,
+                                         GError         **error)
+{
+  gboolean modified;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), FALSE);
+  _mousepad_return_val_if_fail (screen->filename != NULL, FALSE);
+
+  /* check if the file has been modified */
+  modified = mousepad_file_get_externally_modified (screen->filename, screen->mtime, error);
+
+  return modified;
+}
+
+
+
+gboolean
+mousepad_screen_get_modified (MousepadScreen *screen)
+{
+  GtkTextBuffer *buffer;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), FALSE);
+
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (screen->textview));
+
+  return gtk_text_buffer_get_modified (buffer);
+}
+
+
+
+GtkTextView *
+mousepad_screen_get_text_view (MousepadScreen  *screen)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), NULL);
+
+  return GTK_TEXT_VIEW (screen->textview);
+}
+
+
+
+GtkTextBuffer *
+mousepad_screen_get_text_buffer (MousepadScreen  *screen)
+{
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), NULL);
+
+  return gtk_text_view_get_buffer (GTK_TEXT_VIEW (screen->textview));
+}
diff --git a/mousepad/mousepad-screen.h b/mousepad/mousepad-screen.h
new file mode 100644
index 0000000..9017424
--- /dev/null
+++ b/mousepad/mousepad-screen.h
@@ -0,0 +1,67 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_SCREEN_H__
+#define __MOUSEPAD_SCREEN_H__
+
+G_BEGIN_DECLS
+
+#define MOUSEPAD_SCROLL_MARGIN 0.02
+
+#define MOUSEPAD_TYPE_SCREEN            (mousepad_screen_get_type ())
+#define MOUSEPAD_SCREEN(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_SCREEN, MousepadScreen))
+#define MOUSEPAD_SCREEN_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_SCREEN, MousepadScreenClass))
+#define MOUSEPAD_IS_SCREEN(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_SCREEN))
+#define MOUSEPAD_IS_SCREEN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPADL_TYPE_SCREEN))
+#define MOUSEPAD_SCREEN_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_SCREEN, MousepadScreenClass))
+
+typedef struct _MousepadScreenClass MousepadScreenClass;
+typedef struct _MousepadScreen      MousepadScreen;
+
+GType           mousepad_screen_get_type                 (void) G_GNUC_CONST;
+
+GtkWidget      *mousepad_screen_new                      (void);
+
+void            mousepad_screen_set_filename             (MousepadScreen  *screen,
+                                                          const gchar     *filename);
+
+gboolean        mousepad_screen_open_file                (MousepadScreen  *screen,
+                                                          const gchar     *filename,
+                                                          GError         **error);
+
+gboolean        mousepad_screen_save_file                (MousepadScreen  *screen,
+                                                          GError         **error);
+
+const gchar    *mousepad_screen_get_title                (MousepadScreen  *screen,
+                                                          gboolean         show_full_path);
+
+const gchar    *mousepad_screen_get_filename             (MousepadScreen  *screen);
+
+gboolean        mousepad_screen_get_externally_modified  (MousepadScreen  *screen,
+                                                          GError         **error);
+
+GtkTextView    *mousepad_screen_get_text_view            (MousepadScreen  *screen);
+
+GtkTextBuffer  *mousepad_screen_get_text_buffer          (MousepadScreen  *screen);
+
+gboolean        mousepad_screen_get_modified             (MousepadScreen  *screen);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_SCREEN_H__ */
diff --git a/mousepad/mousepad-tab-label.c b/mousepad/mousepad-tab-label.c
new file mode 100644
index 0000000..0a8042f
--- /dev/null
+++ b/mousepad/mousepad-tab-label.c
@@ -0,0 +1,265 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-preferences.h>
+#include <mousepad/mousepad-tab-label.h>
+
+static void              mousepad_tab_label_class_init                   (MousepadTabLabelClass  *klass);
+static void              mousepad_tab_label_init                         (MousepadTabLabel       *window);
+static void              mousepad_tab_label_finalize                     (GObject                *object);
+static void              mousepad_tab_label_get_property                 (GObject                *object,
+                                                                          guint                   prop_id,
+                                                                          GValue                 *value,
+                                                                          GParamSpec             *pspec);
+static void              mousepad_tab_label_set_property                 (GObject                *object,
+                                                                          guint                   prop_id,
+                                                                          const GValue           *value,
+                                                                          GParamSpec             *pspec);
+static void              mousepad_tab_label_close_tab                    (GtkWidget              *widget,
+                                                                          MousepadTabLabel       *label);
+
+
+enum
+{
+  PROP_0,
+  PROP_TITLE,
+  PROP_TOOLTIP,
+};
+
+enum
+{
+  CLOSE_TAB,
+  LAST_SIGNAL,
+};
+
+struct _MousepadTabLabelClass
+{
+  GtkHBoxClass __parent__;
+
+  /* signals */
+  void (*close_tab)   (MousepadTabLabel *label);
+};
+
+struct _MousepadTabLabel
+{
+  GtkHBox              __parent__;
+
+  MousepadPreferences *preferences;
+
+  GtkTooltips         *tooltips;
+  GtkWidget           *ebox;
+  GtkWidget           *label;
+};
+
+
+static GObjectClass *mousepad_tab_label_parent_class;
+static guint         label_signals[LAST_SIGNAL];
+
+
+
+GtkWidget *
+mousepad_tab_label_new (void)
+{
+  return g_object_new (MOUSEPAD_TYPE_TAB_LABEL, NULL);
+}
+
+
+
+GType
+mousepad_tab_label_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (GTK_TYPE_HBOX,
+                                            I_("MousepadTabLabel"),
+                                            sizeof (MousepadTabLabelClass),
+                                            (GClassInitFunc) mousepad_tab_label_class_init,
+                                            sizeof (MousepadTabLabel),
+                                            (GInstanceInitFunc) mousepad_tab_label_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_tab_label_class_init (MousepadTabLabelClass *klass)
+{
+  GObjectClass *gobject_class;
+
+  mousepad_tab_label_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_tab_label_finalize;
+  gobject_class->get_property = mousepad_tab_label_get_property;
+  gobject_class->set_property = mousepad_tab_label_set_property;
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_TITLE,
+                                   g_param_spec_string ("title",
+                                                        "title",
+                                                        "title",
+                                                        NULL,
+                                                        EXO_PARAM_READWRITE));
+
+  g_object_class_install_property (gobject_class,
+                                   PROP_TOOLTIP,
+                                   g_param_spec_string ("tooltip",
+                                                        "tooltip",
+                                                        "tooltip",
+                                                        NULL,
+                                                        EXO_PARAM_READWRITE));
+
+  label_signals[CLOSE_TAB] =
+    g_signal_new ("close-tab",
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  G_STRUCT_OFFSET (MousepadTabLabelClass, close_tab),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+}
+
+
+
+static void
+mousepad_tab_label_init (MousepadTabLabel *label)
+{
+  GtkWidget *button;
+  GtkWidget *image;
+
+  label->preferences = mousepad_preferences_get ();
+
+  label->tooltips = gtk_tooltips_new ();
+  g_object_ref (G_OBJECT (label->tooltips));
+  gtk_object_sink (GTK_OBJECT (label->tooltips));
+
+  gtk_widget_push_composite_child ();
+
+  label->ebox = g_object_new (GTK_TYPE_EVENT_BOX, "border-width", 2, NULL);
+  GTK_WIDGET_SET_FLAGS (label->ebox, GTK_NO_WINDOW);
+  gtk_box_pack_start (GTK_BOX (label), label->ebox, TRUE, TRUE, 0);
+  gtk_widget_show (label->ebox);
+
+  label->label = g_object_new (GTK_TYPE_LABEL,
+                                "selectable", FALSE,
+                                "xalign", 0.0, NULL);
+  gtk_container_add (GTK_CONTAINER (label->ebox), label->label);
+  gtk_widget_show (label->label);
+
+  button = gtk_button_new ();
+  gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+  gtk_container_set_border_width (GTK_CONTAINER (button), 0);
+  gtk_button_set_focus_on_click (GTK_BUTTON (button), FALSE);
+  GTK_WIDGET_UNSET_FLAGS (button, GTK_CAN_DEFAULT|GTK_CAN_FOCUS);
+  gtk_tooltips_set_tip (label->tooltips, button, _("Close this tab"), NULL);
+  gtk_box_pack_start (GTK_BOX (label), button, FALSE, FALSE, 0);
+  exo_binding_new (G_OBJECT (label->preferences), "misc-tab-close-buttons", G_OBJECT (button), "visible");
+
+  image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
+  gtk_container_add (GTK_CONTAINER (button), image);
+  gtk_widget_show (image);
+
+  g_signal_connect (G_OBJECT (button), "clicked",
+                    G_CALLBACK (mousepad_tab_label_close_tab), label);
+
+  gtk_widget_pop_composite_child ();
+}
+
+
+
+static void
+mousepad_tab_label_finalize (GObject *object)
+{
+  MousepadTabLabel *label = MOUSEPAD_TAB_LABEL (object);
+
+  g_object_unref (G_OBJECT (label->preferences));
+  g_object_unref (G_OBJECT (label->tooltips));
+
+  (*G_OBJECT_CLASS (mousepad_tab_label_parent_class)->finalize) (object);
+}
+
+
+
+static void
+mousepad_tab_label_get_property (GObject    *object,
+                                 guint       prop_id,
+                                 GValue     *value,
+                                 GParamSpec *pspec)
+{
+  MousepadTabLabel *label = MOUSEPAD_TAB_LABEL (object);
+
+  switch (prop_id)
+    {
+    case PROP_TITLE:
+      g_object_get_property (G_OBJECT (label->label), "label", value);
+      break;
+
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+    }
+}
+
+
+
+static void
+mousepad_tab_label_set_property (GObject      *object,
+                                 guint         prop_id,
+                                 const GValue *value,
+                                 GParamSpec   *pspec)
+{
+  MousepadTabLabel *label = MOUSEPAD_TAB_LABEL (object);
+  const gchar      *title;
+
+  switch (prop_id)
+    {
+      case PROP_TITLE:
+        title = g_value_get_string (value);
+        gtk_label_set_text (GTK_LABEL (label->label), title);
+        break;
+
+      case PROP_TOOLTIP:
+        title = g_value_get_string (value);
+        gtk_tooltips_set_tip (label->tooltips, label->ebox, title, NULL);
+        break;
+
+      default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+
+
+static void
+mousepad_tab_label_close_tab (GtkWidget        *widget,
+                              MousepadTabLabel *label)
+{
+  g_signal_emit (G_OBJECT (label), label_signals[CLOSE_TAB], 0);
+}
diff --git a/mousepad/mousepad-tab-label.h b/mousepad/mousepad-tab-label.h
new file mode 100644
index 0000000..1ce64d5
--- /dev/null
+++ b/mousepad/mousepad-tab-label.h
@@ -0,0 +1,41 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_TAB_LABEL_H__
+#define __MOUSEPAD_TAB_LABEL_H__
+
+G_BEGIN_DECLS
+
+#define MOUSEPAD_TYPE_TAB_LABEL            (mousepad_tab_label_get_type ())
+#define MOUSEPAD_TAB_LABEL(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_TAB_LABEL, MousepadTabLabel))
+#define MOUSEPAD_TAB_LABEL_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_TAB_LABEL, MousepadTabLabelClass))
+#define MOUSEPAD_IS_TAB_LABEL(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_TAB_LABEL))
+#define MOUSEPAD_IS_TAB_LABEL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPADL_TYPE_TAB_LABEL))
+#define MOUSEPAD_TAB_LABEL_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_TAB_LABEL, MousepadTabLabelClass))
+
+typedef struct _MousepadTabLabelClass MousepadTabLabelClass;
+typedef struct _MousepadTabLabel      MousepadTabLabel;
+
+GType      mousepad_tab_label_get_type (void) G_GNUC_CONST;
+
+GtkWidget *mousepad_tab_label_new      (void);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_TAB_LABEL_H__ */
diff --git a/mousepad/mousepad-view.c b/mousepad/mousepad-view.c
new file mode 100644
index 0000000..d4f3ce0
--- /dev/null
+++ b/mousepad/mousepad-view.c
@@ -0,0 +1,554 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_STRING_H
+#include <string.h>
+#endif
+
+#include <gdk/gdkkeysyms.h>
+
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-view.h>
+
+
+
+static void            mousepad_view_class_init               (MousepadViewClass  *klass);
+static void            mousepad_view_init                     (MousepadView       *view);
+static void            mousepad_view_finalize                 (GObject            *object);
+static gboolean        mousepad_view_key_press_event          (GtkWidget          *widget,
+                                                               GdkEventKey        *event);
+static void            mousepad_view_indent_lines             (MousepadView       *view,
+                                                               GtkTextIter        *start,
+                                                               GtkTextIter        *end,
+                                                               gboolean            indent);
+static gchar          *mousepad_view_compute_indentation      (MousepadView       *view,
+                                                               GtkTextIter        *iter);
+static gint            mousepad_view_expose                   (GtkWidget          *widget,
+                                                               GdkEventExpose     *event);
+static void            mousepad_view_get_lines                (GtkTextView        *text_view,
+                                                               gint                first_y,
+                                                               gint                last_y,
+                                                               GArray            **pixels,
+                                                               GArray            **numbers,
+                                                               gint               *countp);
+
+
+
+struct _MousepadViewClass
+{
+  GtkTextViewClass __parent__;
+};
+
+struct _MousepadView
+{
+  GtkTextView  __parent__;
+
+  gboolean     auto_indent;
+  gboolean     line_numbers;
+};
+
+
+
+static GObjectClass *mousepad_view_parent_class;
+
+
+
+GType
+mousepad_view_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (GTK_TYPE_TEXT_VIEW,
+                                            I_("MousepadView"),
+                                            sizeof (MousepadViewClass),
+                                            (GClassInitFunc) mousepad_view_class_init,
+                                            sizeof (MousepadView),
+                                            (GInstanceInitFunc) mousepad_view_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_view_class_init (MousepadViewClass *klass)
+{
+  GObjectClass   *gobject_class;
+  GtkWidgetClass *widget_class;
+
+  mousepad_view_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->finalize = mousepad_view_finalize;
+
+  widget_class = GTK_WIDGET_CLASS (klass);
+  widget_class->key_press_event = mousepad_view_key_press_event;
+  widget_class->expose_event = mousepad_view_expose;
+}
+
+
+
+static void
+mousepad_view_init (MousepadView *view)
+{
+  /* empty */
+}
+
+
+
+static void
+mousepad_view_finalize (GObject *object)
+{
+  (*G_OBJECT_CLASS (mousepad_view_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+mousepad_view_key_press_event (GtkWidget   *widget,
+                               GdkEventKey *event)
+{
+  MousepadView  *view = MOUSEPAD_VIEW (widget);
+  GtkTextBuffer *buffer;
+  GtkTextIter    start, end;
+  GtkTextMark   *mark;
+  guint          modifiers;
+  guint          key = event->keyval;
+  gchar         *string;
+  gboolean       has_selection;
+
+  /* get the textview buffer */
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget));
+
+  /* check if we have to indent when the user pressed enter */
+  if ((key == GDK_Return || key == GDK_KP_Enter) &&
+      !(event->state & GDK_SHIFT_MASK) && view->auto_indent)
+    {
+      /* get the iter */
+      mark = gtk_text_buffer_get_insert (buffer);
+      gtk_text_buffer_get_iter_at_mark (buffer, &start, mark);
+
+      /* get the string of tabs and spaces we're going to indent */
+      string = mousepad_view_compute_indentation (view, &start);
+
+      if (string != NULL)
+        {
+          /* tell others we're going to change the buffer */
+          gtk_text_buffer_begin_user_action (buffer);
+
+          /* insert the indent characters */
+          gtk_text_buffer_insert (buffer, &start, "\n", 1);
+          gtk_text_buffer_insert (buffer, &start, string, strlen (string));
+          g_free (string);
+
+          /* we're finished */
+          gtk_text_buffer_end_user_action (buffer);
+
+          /* make sure the new string is visible for the user */
+          gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (widget), mark);
+
+          return TRUE;
+        }
+    }
+
+  /* get the modifiers state */
+  modifiers = gtk_accelerator_get_default_mod_mask ();
+
+  /* check if the user pressed the tab button for indenting lines */
+  if ((key == GDK_Tab || key == GDK_KP_Tab || key == GDK_ISO_Left_Tab) &&
+      ((event->state & modifiers) == 0 || (event->state & modifiers) == GDK_SHIFT_MASK))
+        {
+          /* get the selected text */
+          has_selection = gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
+
+          /* Shift + Tab */
+          if (event->state & GDK_SHIFT_MASK)
+            {
+              /* unindent */
+              mousepad_view_indent_lines (view, &start, &end, FALSE);
+
+              return TRUE;
+            }
+
+          if (has_selection &&
+              ((gtk_text_iter_starts_line (&start) && gtk_text_iter_ends_line (&end)) ||
+               (gtk_text_iter_get_line (&start) != gtk_text_iter_get_line (&end))))
+            {
+              /* indent */
+              mousepad_view_indent_lines (view, &start, &end, TRUE);
+
+              return TRUE;
+            }
+        }
+
+  return (*GTK_WIDGET_CLASS (mousepad_view_parent_class)->key_press_event) (widget, event);
+}
+
+
+
+static void
+mousepad_view_indent_lines (MousepadView *view,
+                            GtkTextIter  *start,
+                            GtkTextIter  *end,
+                            gboolean      indent)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter    iter, iter2;
+  gint           start_line, end_line;
+  gint           i, spaces, tabs;
+
+  /* get the textview buffer */
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  /* get the line numbers for the start and end iter */
+  start_line = gtk_text_iter_get_line (start);
+  end_line = gtk_text_iter_get_line (end);
+
+  /* check if the last line does not exist of 'invisible' characters */
+  if ((gtk_text_iter_get_visible_line_offset (end) == 0) && (end_line > start_line))
+    end_line--;
+
+  /* tell everybody we're going to change the buffer */
+  gtk_text_buffer_begin_user_action (buffer);
+
+  /* insert a tab in front of each line */
+  for (i = start_line; i <= end_line; i++)
+    {
+      /* get the iter of the line we're going to indent */
+      gtk_text_buffer_get_iter_at_line (buffer, &iter, i);
+
+      /* don't (un)indent empty lines */
+      if (gtk_text_iter_ends_line (&iter))
+        continue;
+
+      if (indent)
+        {
+          /* insert the tab */
+          gtk_text_buffer_insert (buffer, &iter, "\t", -1);
+        }
+      else /* unindent */
+        {
+          if (gtk_text_iter_get_char (&iter) == '\t')
+            {
+              /* remove the tab */
+              iter2 = iter;
+              gtk_text_iter_forward_char (&iter2);
+              gtk_text_buffer_delete (buffer, &iter, &iter2);
+            }
+          else if (gtk_text_iter_get_char (&iter) == ' ')
+            {
+              spaces = 0;
+
+              iter2 = iter;
+
+              /* count the number of spaces before the text */
+              while (!gtk_text_iter_ends_line (&iter2))
+                {
+                  if (gtk_text_iter_get_char (&iter2) == ' ')
+                    spaces++;
+                  else
+                    break;
+
+                  gtk_text_iter_forward_char (&iter2);
+                }
+
+              if (spaces > 0)
+                {
+                  /* the number of tabs in the spaces */
+                  tabs = spaces / 8;
+
+                  /* the number of spaces after the 'tabs' */
+                  spaces = spaces - (tabs * 8);
+
+                  /* we're going to remove the number of spaces after the 'tabs'
+                   * or 1 'tab' */
+                  if (spaces == 0)
+                    spaces = 8;
+
+                  iter2 = iter;
+
+                  /* delete the spaces */
+                  gtk_text_iter_forward_chars (&iter2, spaces);
+                  gtk_text_buffer_delete (buffer, &iter, &iter2);
+                }
+            }
+        }
+    }
+
+  /* we're done */
+  gtk_text_buffer_end_user_action (buffer);
+
+  /* scroll */
+  gtk_text_view_scroll_mark_onscreen (GTK_TEXT_VIEW (view),
+                                      gtk_text_buffer_get_insert (buffer));
+}
+
+
+
+static gchar *
+mousepad_view_compute_indentation (MousepadView *view,
+                                   GtkTextIter  *iter)
+{
+  GtkTextBuffer *buffer;
+  GtkTextIter    start, end;
+  gint           line;
+  gunichar       ch;
+
+  /* get the buffer */
+  buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
+
+  /* get the line of the iter */
+  line = gtk_text_iter_get_line (iter);
+
+  /* get the iter of the beginning of this line */
+  gtk_text_buffer_get_iter_at_line (buffer, &start, line);
+
+  /* clone baby */
+  end = start;
+
+  /* get the first character */
+  ch = gtk_text_iter_get_char (&end);
+
+  /* keep walking till we hit text or a new line */
+  while (g_unichar_isspace (ch) &&
+         (ch != '\n') && (ch != '\r') &&
+         (gtk_text_iter_compare (&end, iter) < 0))
+    {
+      /* break if we can't step forward */
+      if (!gtk_text_iter_forward_char (&end))
+        break;
+
+      /* get the next character */
+      ch = gtk_text_iter_get_char (&end);
+    }
+
+  /* return NULL if the iters are the same */
+  if (gtk_text_iter_equal (&start, &end))
+    return NULL;
+
+  /* return the text between the iters */
+  return gtk_text_iter_get_slice (&start, &end);
+}
+
+
+
+static void
+mousepad_view_get_lines (GtkTextView  *text_view,
+                         gint          first_y,
+                         gint          last_y,
+                         GArray      **pixels,
+                         GArray      **numbers,
+                         gint         *countp)
+{
+  GtkTextIter iter;
+  gint        count = 0;
+  gint        y, height;
+  gint        line_number = 0, last_line_number;
+
+  g_array_set_size (*pixels, 0);
+  g_array_set_size (*numbers, 0);
+
+  /* get iter at first y */
+  gtk_text_view_get_line_at_y (text_view, &iter, first_y, NULL);
+
+  /* for each iter, get its location and add it to the arrays.
+   * Stop when we pass last_y */
+  while (!gtk_text_iter_is_end (&iter))
+    {
+      /* get the y position of the iter */
+      gtk_text_view_get_line_yrange (text_view, &iter, &y, &height);
+
+      /* get the number of the line */
+      line_number = gtk_text_iter_get_line (&iter);
+
+      /* append both values to the array */
+      g_array_append_val (*pixels, y);
+      g_array_append_val (*numbers, line_number);
+
+      ++count;
+
+      /* stop when we reached last_y */
+      if ((y + height) >= last_y)
+        break;
+
+      /* jump to the next line */
+      gtk_text_iter_forward_line (&iter);
+    }
+
+  if (gtk_text_iter_is_end (&iter))
+    {
+      gtk_text_view_get_line_yrange (text_view, &iter, &y, &height);
+
+      last_line_number = gtk_text_iter_get_line (&iter);
+
+      if (last_line_number != line_number)
+        {
+          g_array_append_val (*pixels, y);
+          g_array_append_val (*numbers, last_line_number);
+          ++count;
+        }
+    }
+
+  /* not lines in the buffer? weird, there is atleast one... */
+  if (G_UNLIKELY (count == 0))
+    {
+      y = 0;
+      g_array_append_val (*pixels, y);
+      g_array_append_val (*numbers, y);
+
+      ++count;
+    }
+
+  *countp = count;
+}
+
+
+
+static gboolean
+mousepad_view_expose (GtkWidget      *widget,
+                      GdkEventExpose *event)
+{
+  GdkWindow   *window;
+  GtkTextView *view = GTK_TEXT_VIEW (widget);
+  gint         y1, y2;
+  GArray      *numbers, *pixels;
+  gint         count, i;
+  PangoLayout *layout;
+  gchar        str[8]; /* maximum of 10e6 lines */
+  gint         width;
+  gint         position;
+  gint         line_number;
+
+  /* get the left window */
+  window = gtk_text_view_get_window (view, GTK_TEXT_WINDOW_LEFT);
+
+  /* check if the event if for the left window */
+  if (event->window == window)
+    {
+      /* get the expose event area */
+      y1 = event->area.y;
+      y2 = y1 + event->area.height;
+
+      /* correct then to the size of the textview window */
+      gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_LEFT,
+                                             0, y1, NULL, &y1);
+      gtk_text_view_window_to_buffer_coords (view, GTK_TEXT_WINDOW_LEFT,
+                                             0, y2, NULL, &y2);
+
+      /* create new arrays */
+      pixels  = g_array_new (FALSE, FALSE, sizeof (gint));
+      numbers = g_array_new (FALSE, FALSE, sizeof (gint));
+
+      /* get the line numbers and y coordinates. */
+      mousepad_view_get_lines (view,
+                               y1, y2,
+                               &pixels,
+                               &numbers,
+                               &count);
+
+      /* create the pango layout */
+      g_snprintf (str, sizeof (str), "%d",
+                  MAX (99, gtk_text_buffer_get_line_count (view->buffer)));
+      layout = gtk_widget_create_pango_layout (widget, str);
+      pango_layout_get_pixel_size (layout, &width, NULL);
+      pango_layout_set_width (layout, width);
+      pango_layout_set_alignment (layout, PANGO_ALIGN_RIGHT);
+
+      /* set the width of the left window border */
+      gtk_text_view_set_border_window_size (view, GTK_TEXT_WINDOW_LEFT,
+                                            width + 6);
+
+      for (i = 0; i < count; i++)
+        {
+          gtk_text_view_buffer_to_window_coords (view,
+                                                 GTK_TEXT_WINDOW_LEFT, 0,
+                                                 g_array_index (pixels, gint, i),
+                                                 NULL,
+                                                 &position);
+
+          /* get the line number */
+          line_number = g_array_index (numbers, gint, i) + 1;
+
+          /* create the pango layout */
+          g_snprintf (str, sizeof (str), "%d", line_number);
+          pango_layout_set_markup (layout, str, strlen (str));
+
+          /* time to draw the layout in the window */
+          gtk_paint_layout (widget->style, window,
+                            GTK_WIDGET_STATE (widget),
+                            FALSE, NULL,
+                            widget, NULL,
+                            width + 2,
+                            position,
+                            layout);
+        }
+
+      /* cleanup */
+      g_array_free (pixels, TRUE);
+      g_array_free (numbers, TRUE);
+
+      g_object_unref (G_OBJECT (layout));
+    }
+
+  /* Gtk can draw the text now */
+  return (*GTK_WIDGET_CLASS (mousepad_view_parent_class)->expose_event) (widget, event);
+}
+
+
+
+void
+mousepad_view_set_show_line_numbers (MousepadView *view,
+                                     gboolean      visible)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_VIEW (view));
+
+  if (view->line_numbers != visible)
+    {
+      /* set the boolean */
+      view->line_numbers = visible;
+
+      /* set the left border size */
+      gtk_text_view_set_border_window_size (GTK_TEXT_VIEW (view),
+                                            GTK_TEXT_WINDOW_LEFT,
+                                            visible ? 20 : 0);
+
+      /* make sure there is an expose event */
+      gtk_widget_queue_draw (GTK_WIDGET (view));
+    }
+}
+
+
+
+void
+mousepad_view_set_auto_indent (MousepadView *view,
+                               gboolean      enable)
+{
+   _mousepad_return_if_fail (MOUSEPAD_IS_VIEW (view));
+
+   /* set the boolean */
+   view->auto_indent = enable;
+}
diff --git a/mousepad/mousepad-view.h b/mousepad/mousepad-view.h
new file mode 100644
index 0000000..f18da6e
--- /dev/null
+++ b/mousepad/mousepad-view.h
@@ -0,0 +1,45 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_VIEW_H__
+#define __MOUSEPAD_VIEW_H__
+
+G_BEGIN_DECLS
+
+#define MOUSEPAD_TYPE_VIEW            (mousepad_view_get_type ())
+#define MOUSEPAD_VIEW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_VIEW, MousepadView))
+#define MOUSEPAD_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_VIEW, MousepadViewClass))
+#define MOUSEPAD_IS_VIEW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_VIEW))
+#define MOUSEPAD_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPADL_TYPE_VIEW))
+#define MOUSEPAD_VIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_VIEW, MousepadViewClass))
+
+typedef struct _MousepadViewClass MousepadViewClass;
+typedef struct _MousepadView      MousepadView;
+
+GType           mousepad_view_get_type                  (void) G_GNUC_CONST;
+
+void            mousepad_view_set_show_line_numbers     (MousepadView *view,
+                                                         gboolean      visible);
+
+void            mousepad_view_set_auto_indent           (MousepadView *view,
+                                                         gboolean      enable);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_VIEW_H__ */
diff --git a/mousepad/mousepad-window-ui.xml b/mousepad/mousepad-window-ui.xml
new file mode 100644
index 0000000..b1e94b7
--- /dev/null
+++ b/mousepad/mousepad-window-ui.xml
@@ -0,0 +1,65 @@
+<ui>
+  <!--
+    $Id$
+
+    Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+  -->
+
+  <menubar name="main-menu">
+    <menu action="file-menu">
+      <menuitem action="new-tab" />
+      <menuitem action="new-window" />
+      <separator />
+      <menuitem action="open-file" />
+      <menuitem action="recent-menu" />
+      <separator />
+      <menuitem action="save-file" />
+      <menuitem action="save-file-as" />
+      <separator />
+      <menuitem action="close-tab" />
+      <menuitem action="close-window" />
+      <menuitem action="close-all-windows" />
+    </menu>
+
+    <menu action="edit-menu">
+      <menuitem action="undo" />
+      <menuitem action="redo" />
+      <separator />
+      <menuitem action="cut" />
+      <menuitem action="copy" />
+      <menuitem action="paste" />
+      <menuitem action="delete" />
+      <separator />
+      <menuitem action="select-all" />
+    </menu>
+
+    <menu action="search-menu">
+      <menuitem action="find" />
+      <menuitem action="find-next" />
+      <menuitem action="find-previous" />
+      <menuitem action="replace" />
+      <separator />
+      <menuitem action="jump-to" />
+    </menu>
+
+    <menu action="view-menu">
+      <menuitem action="font" />
+      <separator />
+      <menuitem action="word-wrap" />
+      <menuitem action="line-numbers" />
+      <separator />
+      <menuitem action="auto-indent" />
+    </menu>
+
+    <menu action="go-menu">
+      <menuitem action="back" />
+      <menuitem action="forward" />
+      <separator />
+      <placeholder name="placeholder-go-items" />
+    </menu>
+
+    <menu action="help-menu">
+      <menuitem action="about" />
+    </menu>
+  </menubar>
+</ui>
diff --git a/mousepad/mousepad-window.c b/mousepad/mousepad-window.c
new file mode 100644
index 0000000..1f7a669
--- /dev/null
+++ b/mousepad/mousepad-window.c
@@ -0,0 +1,1779 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ * Copyright (c) 2007 Benedikt Meurer <benny at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include <mousepad/mousepad-application.h>
+#include <mousepad/mousepad-preferences.h>
+#include <mousepad/mousepad-private.h>
+#include <mousepad/mousepad-file.h>
+#include <mousepad/mousepad-screen.h>
+#include <mousepad/mousepad-view.h>
+#include <mousepad/mousepad-tab-label.h>
+#include <mousepad/mousepad-window.h>
+#include <mousepad/mousepad-window-ui.h>
+
+
+
+static void              mousepad_window_class_init                   (MousepadWindowClass    *klass);
+static void              mousepad_window_init                         (MousepadWindow         *window);
+static void              mousepad_window_dispose                      (GObject                *object);
+static void              mousepad_window_finalize                     (GObject                *object);
+static gboolean          mousepad_window_configure_event              (GtkWidget              *widget,
+                                                                       GdkEventConfigure      *event);
+static gboolean          mousepad_window_save_geometry_timer          (gpointer                user_data);
+static void              mousepad_window_save_geometry_timer_destroy  (gpointer                user_data);
+static MousepadScreen   *mousepad_window_get_active                   (MousepadWindow         *window);
+static gboolean          mousepad_window_save_as                      (MousepadWindow         *window,
+                                                                       MousepadScreen         *screen);
+static void              mousepad_window_add                          (MousepadWindow         *window,
+                                                                       MousepadScreen         *screen);
+static gboolean          mousepad_window_close_screen                 (MousepadWindow         *window,
+                                                                       MousepadScreen         *screen);
+static void              mousepad_window_create_recent_menu           (MousepadWindow         *window);
+static void              mousepad_window_add_recent                   (const gchar            *filename);
+static void              mousepad_window_set_title                    (MousepadWindow         *window,
+                                                                       MousepadScreen         *screen);
+static void              mousepad_window_notify_title                 (MousepadScreen         *screen,
+                                                                       GParamSpec             *pspec,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_page_notified                (GtkNotebook            *notebook,
+                                                                       GParamSpec             *pspec,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_tab_removed                  (GtkNotebook            *notebook,
+                                                                       MousepadScreen         *screen,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_error_dialog                 (GtkWindow              *window,
+                                                                       GError                 *error,
+                                                                       const gchar            *message);
+static void              mousepad_window_update_actions               (MousepadWindow         *window);
+static void              mousepad_window_rebuild_gomenu               (MousepadWindow         *window);
+static void              mousepad_window_selection_changed            (MousepadScreen         *screen,
+                                                                       gboolean                selected,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_open_new_window       (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_open_file             (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_open_recent           (GtkRecentChooser       *chooser,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_save_file             (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_save_file_as          (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_close_tab             (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_button_close_tab             (MousepadScreen         *screen);
+static gboolean          mousepad_window_delete_event                 (MousepadWindow         *window,
+                                                                       GdkEvent               *event);
+static void              mousepad_window_action_close                 (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_close_all_windows     (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_open_new_tab          (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_cut                   (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_copy                  (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_paste                 (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_delete                (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_select_all            (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_jump_to               (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_select_font           (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_prev_tab              (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_next_tab              (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+static void              mousepad_window_action_about                 (GtkAction              *action,
+                                                                       MousepadWindow         *window);
+
+
+
+
+struct _MousepadWindowClass
+{
+  GtkWindowClass __parent__;
+};
+
+struct _MousepadWindow
+{
+  GtkWindow            __parent__;
+
+  MousepadPreferences *preferences;
+
+  GtkActionGroup      *action_group;
+  GtkUIManager        *ui_manager;
+
+  GtkWidget           *notebook;
+
+  /* support to remember window geometry */
+  gint                 save_geometry_timer_id;
+};
+
+
+
+static const GtkActionEntry action_entries[] =
+{
+  { "file-menu", NULL, N_ ("_File"), NULL, NULL, NULL, },
+  { "new-tab", "tab-new", N_ ("New _Tab"), "<control>T", N_ ("Open a new Mousepad tab"), G_CALLBACK (mousepad_window_action_open_new_tab), },
+  { "new-window", "window-new", N_ ("_New Window"), "<control>N", N_ ("Open a new Mousepad window"), G_CALLBACK (mousepad_window_action_open_new_window), },
+  { "open-file", GTK_STOCK_OPEN, N_ ("_Open File"), NULL, N_ ("Open a new document"), G_CALLBACK (mousepad_window_action_open_file), },
+  { "recent-menu", NULL, N_ ("Open _Recent"), NULL, NULL, NULL, },
+  { "save-file", GTK_STOCK_SAVE, N_ ("_Save"), NULL, N_ ("Save current document"), G_CALLBACK (mousepad_window_action_save_file), },
+  { "save-file-as", GTK_STOCK_SAVE_AS, N_ ("Save _As"), NULL, N_ ("Save current document as another file"), G_CALLBACK (mousepad_window_action_save_file_as), },
+  { "close-tab", GTK_STOCK_CLOSE, N_ ("C_lose Tab"), "<control>W", N_ ("Close the current Mousepad tab"), G_CALLBACK (mousepad_window_action_close_tab), },
+  { "close-window", GTK_STOCK_QUIT, N_ ("_Close Window"), "<control>Q", N_ ("Close the Mousepad window"), G_CALLBACK (mousepad_window_action_close), },
+  { "close-all-windows", NULL, N_ ("Close _All Windows"), "<control><shift>W", N_ ("Close all Mousepad windows"), G_CALLBACK (mousepad_window_action_close_all_windows), },
+
+  { "edit-menu", NULL, N_ ("_Edit"), NULL, NULL, NULL, },
+  { "undo", GTK_STOCK_UNDO, N_ ("_Undo"), NULL, NULL, NULL, },
+  { "redo", GTK_STOCK_REDO, N_ ("_Redo"), NULL, NULL, NULL, },
+  { "cut", GTK_STOCK_CUT, N_ ("Cu_t"), NULL, NULL, G_CALLBACK (mousepad_window_action_cut), },
+  { "copy", GTK_STOCK_COPY, N_ ("_Copy"), NULL, NULL, G_CALLBACK (mousepad_window_action_copy), },
+  { "paste", GTK_STOCK_PASTE, N_ ("_Paste"), NULL, NULL, G_CALLBACK (mousepad_window_action_paste), },
+  { "delete", GTK_STOCK_DELETE, N_ ("_Delete"), NULL, NULL, G_CALLBACK (mousepad_window_action_delete), },
+  { "select-all", GTK_STOCK_SELECT_ALL, N_ ("Select _All"), NULL, NULL, G_CALLBACK (mousepad_window_action_select_all), },
+
+  { "search-menu", NULL, N_ ("_Search"), NULL, NULL, NULL, },
+  { "find", GTK_STOCK_FIND, N_ ("_Find"), NULL, NULL, NULL, },
+  { "find-next", NULL, N_ ("Find _Next"), NULL, NULL, NULL, },
+  { "find-previous", NULL, N_ ("Find _Previous"), NULL, NULL, NULL, },
+  { "replace", GTK_STOCK_FIND_AND_REPLACE, N_ ("_Replace"), NULL, NULL, NULL, },
+  { "jump-to", GTK_STOCK_JUMP_TO, N_ ("_Jump To"), NULL, NULL, G_CALLBACK (mousepad_window_action_jump_to), },
+
+  { "view-menu", NULL, N_ ("_View"), NULL, NULL, NULL, },
+  { "font", GTK_STOCK_SELECT_FONT, N_ ("_Font"), NULL, N_ ("Choose Mousepad font"), G_CALLBACK (mousepad_window_action_select_font), },
+
+  { "go-menu", NULL, N_ ("_Go"), NULL, },
+  { "back", GTK_STOCK_GO_BACK, N_ ("Back"), NULL, N_ ("Select the previous tab"), G_CALLBACK (mousepad_window_action_prev_tab), },
+  { "forward", GTK_STOCK_GO_FORWARD, N_ ("Forward"), NULL, N_ ("Select the next tab"), G_CALLBACK (mousepad_window_action_next_tab), },
+
+  { "help-menu", NULL, N_ ("_Help"), NULL, },
+  { "about", GTK_STOCK_ABOUT, N_ ("_About"), NULL,N_  ("Display information about Mousepad"), G_CALLBACK (mousepad_window_action_about), },
+};
+
+static const GtkToggleActionEntry toggle_action_entries[] =
+{
+  { "word-wrap", NULL, N_ ("_Word Wrap"), NULL, NULL, NULL, FALSE, },
+  { "line-numbers", NULL, N_ ("_Line Numbers"), NULL, NULL, NULL, FALSE, },
+  { "auto-indent", NULL, N_ ("_Auto Indent"), NULL, NULL, NULL, FALSE, },
+};
+
+
+
+static GObjectClass *mousepad_window_parent_class;
+
+
+
+GtkWidget *
+mousepad_window_new (void)
+{
+  return g_object_new (MOUSEPAD_TYPE_WINDOW, NULL);
+}
+
+
+
+GType
+mousepad_window_get_type (void)
+{
+  static GType type = G_TYPE_INVALID;
+
+  if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+      type = g_type_register_static_simple (GTK_TYPE_WINDOW,
+                                            I_("MousepadWindow"),
+                                            sizeof (MousepadWindowClass),
+                                            (GClassInitFunc) mousepad_window_class_init,
+                                            sizeof (MousepadWindow),
+                                            (GInstanceInitFunc) mousepad_window_init,
+                                            0);
+    }
+
+  return type;
+}
+
+
+
+static void
+mousepad_window_class_init (MousepadWindowClass *klass)
+{
+  GObjectClass   *gobject_class;
+  GtkWidgetClass *gtkwidget_class;
+
+  mousepad_window_parent_class = g_type_class_peek_parent (klass);
+
+  gobject_class = G_OBJECT_CLASS (klass);
+  gobject_class->dispose = mousepad_window_dispose;
+  gobject_class->finalize = mousepad_window_finalize;
+
+  gtkwidget_class = GTK_WIDGET_CLASS (klass);
+  gtkwidget_class->configure_event = mousepad_window_configure_event;
+}
+
+
+static void
+mousepad_window_init (MousepadWindow *window)
+{
+  GtkAccelGroup *accel_group;
+  GtkWidget     *menubar;
+  GtkWidget     *vbox;
+  GtkWidget     *label;
+  GtkWidget     *separator;
+  GtkWidget     *ebox;
+  GtkAction     *action;
+  gint           width, height;
+
+  window->preferences = mousepad_preferences_get ();
+
+  /* signal for monitoring */
+  g_signal_connect (G_OBJECT (window), "delete-event",
+                    G_CALLBACK (mousepad_window_delete_event), NULL);
+
+  /* read settings from the preferences */
+  g_object_get (G_OBJECT (window->preferences),
+                "last-window-width", &width,
+                "last-window-height", &height,
+                NULL);
+
+  /* set the default window size */
+  gtk_window_set_default_size (GTK_WINDOW (window), width, height);
+
+  /* the action group for this window */
+  window->action_group = gtk_action_group_new ("MousepadActionGroup");
+  gtk_action_group_set_translation_domain (window->action_group, GETTEXT_PACKAGE);
+  gtk_action_group_add_actions (window->action_group, action_entries, G_N_ELEMENTS (action_entries), GTK_WIDGET (window));
+  gtk_action_group_add_toggle_actions (window->action_group, toggle_action_entries, G_N_ELEMENTS (toggle_action_entries), GTK_WIDGET (window));
+
+  /* create mutual bindings for the toggle buttons */
+  action = gtk_action_group_get_action (window->action_group, "line-numbers");
+  exo_mutual_binding_new (G_OBJECT (window->preferences), "line-numbers", G_OBJECT (action), "active");
+  action = gtk_action_group_get_action (window->action_group, "auto-indent");
+  exo_mutual_binding_new (G_OBJECT (window->preferences), "auto-indent", G_OBJECT (action), "active");
+  action = gtk_action_group_get_action (window->action_group, "word-wrap");
+  exo_mutual_binding_new (G_OBJECT (window->preferences), "word-wrap", G_OBJECT (action), "active");
+
+  window->ui_manager = gtk_ui_manager_new ();
+  gtk_ui_manager_insert_action_group (window->ui_manager, window->action_group, 0);
+  gtk_ui_manager_add_ui_from_string (window->ui_manager, mousepad_window_ui, mousepad_window_ui_length, NULL);
+
+  /* append the recent-menu items */
+  mousepad_window_create_recent_menu (window);
+
+  accel_group = gtk_ui_manager_get_accel_group (window->ui_manager);
+  gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
+
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_widget_show (vbox);
+
+  menubar = gtk_ui_manager_get_widget (window->ui_manager, "/main-menu");
+  gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
+  gtk_widget_show (menubar);
+
+  /* check if we need to add the root warning */
+  if (G_UNLIKELY (geteuid () == 0))
+    {
+      /* install default settings for the root warning text box */
+      gtk_rc_parse_string ("style\"mousepad-window-root-style\"{bg[NORMAL]=\"#b4254b\"\nfg[NORMAL]=\"#fefefe\"}\n"
+                           "widget\"MousepadWindow.*.root-warning\"style\"mousepad-window-root-style\"\n"
+                           "widget\"MousepadWindow.*.root-warning.GtkLabel\"style\"mousepad-window-root-style\"\n");
+
+      /* add the box for the root warning */
+      ebox = gtk_event_box_new ();
+      gtk_widget_set_name (ebox, "root-warning");
+      gtk_box_pack_start (GTK_BOX (vbox), ebox, FALSE, FALSE, 0);
+      gtk_widget_show (ebox);
+
+      /* add the label with the root warning */
+      label = gtk_label_new (_("Warning, you are using the root account, you may harm your system."));
+      gtk_misc_set_padding (GTK_MISC (label), 6, 3);
+      gtk_container_add (GTK_CONTAINER (ebox), label);
+      gtk_widget_show (label);
+
+      separator = gtk_hseparator_new ();
+      gtk_box_pack_start (GTK_BOX (vbox), separator, FALSE, FALSE, 0);
+      gtk_widget_show (separator);
+    }
+
+  window->notebook = g_object_new (GTK_TYPE_NOTEBOOK,
+                                   "homogeneous", FALSE,
+                                   "scrollable", TRUE,
+                                   "show-border", FALSE,
+                                   "show-tabs", FALSE,
+                                   "tab-hborder", 0,
+                                   "tab-vborder", 0,
+                                   NULL);
+
+  g_signal_connect (G_OBJECT (window->notebook), "notify::page",
+                    G_CALLBACK (mousepad_window_page_notified), window);
+  g_signal_connect (G_OBJECT (window->notebook), "remove",
+                    G_CALLBACK (mousepad_window_tab_removed), window);
+
+  gtk_box_pack_start (GTK_BOX (vbox), window->notebook, TRUE, TRUE, 0);
+  gtk_widget_show (window->notebook);
+}
+
+
+
+static void
+mousepad_window_dispose (GObject *object)
+{
+  MousepadWindow *window = MOUSEPAD_WINDOW (object);
+
+  /* destroy the save geometry timer source */
+  if (G_UNLIKELY (window->save_geometry_timer_id > 0))
+    g_source_remove (window->save_geometry_timer_id);
+
+  (*G_OBJECT_CLASS (mousepad_window_parent_class)->dispose) (object);
+}
+
+
+
+static void
+mousepad_window_finalize (GObject *object)
+{
+  MousepadWindow *window = MOUSEPAD_WINDOW (object);
+
+  g_object_unref (G_OBJECT (window->ui_manager));
+  g_object_unref (G_OBJECT (window->action_group));
+
+  /* release the preferences reference */
+  g_object_unref (G_OBJECT (window->preferences));
+
+  (*G_OBJECT_CLASS (mousepad_window_parent_class)->finalize) (object);
+}
+
+
+
+static gboolean
+mousepad_window_configure_event (GtkWidget         *widget,
+                                 GdkEventConfigure *event)
+{
+  MousepadWindow *window = MOUSEPAD_WINDOW (widget);
+
+  /* check if we have a new dimension here */
+  if (widget->allocation.width != event->width || widget->allocation.height != event->height)
+    {
+      /* drop any previous timer source */
+      if (window->save_geometry_timer_id > 0)
+        g_source_remove (window->save_geometry_timer_id);
+
+      /* check if we should schedule another save timer */
+      if (GTK_WIDGET_VISIBLE (widget))
+        {
+          /* save the geometry one second after the last configure event */
+          window->save_geometry_timer_id = g_timeout_add_full (G_PRIORITY_LOW, 1000, mousepad_window_save_geometry_timer,
+                                                               window, mousepad_window_save_geometry_timer_destroy);
+        }
+    }
+
+  /* let Gtk+ handle the configure event */
+  return (*GTK_WIDGET_CLASS (mousepad_window_parent_class)->configure_event) (widget, event);
+}
+
+
+
+static gboolean
+mousepad_window_save_geometry_timer (gpointer user_data)
+{
+  GdkWindowState   state;
+  MousepadWindow  *window = MOUSEPAD_WINDOW (user_data);
+  gboolean         remember_geometry;
+  gint             width;
+  gint             height;
+
+  GDK_THREADS_ENTER ();
+
+  /* check if we should remember the window geometry */
+  g_object_get (G_OBJECT (window->preferences), "misc-remember-geometry", &remember_geometry, NULL);
+  if (G_LIKELY (remember_geometry))
+    {
+      /* check if the window is still visible */
+      if (GTK_WIDGET_VISIBLE (window))
+        {
+          /* determine the current state of the window */
+          state = gdk_window_get_state (GTK_WIDGET (window)->window);
+
+          /* don't save geometry for maximized or fullscreen windows */
+          if ((state & (GDK_WINDOW_STATE_MAXIMIZED | GDK_WINDOW_STATE_FULLSCREEN)) == 0)
+            {
+              /* determine the current width/height of the window... */
+              gtk_window_get_size (GTK_WINDOW (window), &width, &height);
+
+              /* ...and remember them as default for new windows */
+              g_object_set (G_OBJECT (window->preferences),
+                            "last-window-width", width,
+                            "last-window-height", height, NULL);
+            }
+        }
+    }
+
+  GDK_THREADS_LEAVE ();
+
+  return FALSE;
+}
+
+
+
+static void
+mousepad_window_save_geometry_timer_destroy (gpointer user_data)
+{
+  MOUSEPAD_WINDOW (user_data)->save_geometry_timer_id = 0;
+}
+
+
+
+static MousepadScreen *
+mousepad_window_get_active (MousepadWindow *window)
+{
+  GtkNotebook *notebook = GTK_NOTEBOOK (window->notebook);
+  gint         page_num;
+
+  page_num = gtk_notebook_get_current_page (notebook);
+
+  if (G_LIKELY (page_num >= 0))
+    return MOUSEPAD_SCREEN (gtk_notebook_get_nth_page (notebook, page_num));
+  else
+    return NULL;
+}
+
+
+
+gboolean
+mousepad_window_open_tab (MousepadWindow *window,
+                          const gchar    *filename)
+{
+  GtkWidget   *screen;
+  GError      *error = NULL;
+  gboolean     succeed = TRUE;
+  gint         npages = 0, i;
+  const gchar *opened_filename;
+
+  /* get the number of page in the notebook */
+  if (filename)
+    npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) - 1;
+
+  /* walk though the tabs */
+  for (i = 0; i < npages; i++)
+    {
+      screen = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), i);
+
+      if (G_LIKELY (screen != NULL))
+        {
+          /* get the filename */
+          opened_filename = mousepad_screen_get_filename (MOUSEPAD_SCREEN (screen));
+
+          /* see if the file is already opened */
+          if (exo_str_is_equal (filename, opened_filename))
+            {
+              /* switch to the tab */
+              gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), i);
+
+              /* and we're done */
+              return TRUE;
+            }
+        }
+    }
+
+  /* new screen */
+  screen = mousepad_screen_new ();
+
+  /* load a file, if there is any */
+  if (filename)
+    succeed = mousepad_screen_open_file (MOUSEPAD_SCREEN (screen), filename, &error);
+
+  if (G_LIKELY (succeed))
+    mousepad_window_add (window, MOUSEPAD_SCREEN (screen));
+  else
+    {
+      /* something went wrong, remove the screen */
+      gtk_widget_destroy (GTK_WIDGET (screen));
+
+      /* show the warning */
+      mousepad_window_error_dialog (GTK_WINDOW (window), error, _("Failed to open file"));
+      g_error_free (error);
+    }
+
+  return succeed;
+}
+
+
+
+void
+mousepad_window_open_files (MousepadWindow  *window,
+                            const gchar     *working_directory,
+                            gchar          **filenames)
+{
+  gint   n;
+  gchar *filename;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window));
+  _mousepad_return_if_fail (working_directory != NULL);
+  _mousepad_return_if_fail (filenames != NULL);
+  _mousepad_return_if_fail (*filenames != NULL);
+
+  /* walk through all the filenames */
+  for (n = 0; filenames[n] != NULL; ++n)
+    {
+      /* check if the filename looks like an uri */
+      if (g_strstr_len (filenames[n], 5, "file:"))
+        {
+          /* convert the uri to an absolute filename */
+          filename = g_filename_from_uri (filenames[n], NULL, NULL);
+        }
+      else if (g_path_is_absolute (filenames[n]) == FALSE)
+        {
+          /* create an absolute file */
+          filename = g_build_filename (working_directory, filenames[n], NULL);
+        }
+
+      /* open a new tab with the file */
+      mousepad_window_open_tab (window, filename ? filename : filenames[n]);
+
+      /* cleanup */
+      g_free (filename);
+      filename = NULL;
+    }
+}
+
+
+
+static GtkFileChooserConfirmation
+mousepad_window_save_as_callback (GtkFileChooser *dialog)
+{
+  gchar                      *filename;
+  GError                     *error = NULL;
+  GtkFileChooserConfirmation  result;
+
+  /* get the filename */
+  filename = gtk_file_chooser_get_filename (dialog);
+
+  if (mousepad_file_is_writable (filename, &error))
+    {
+      /* show the normal confirmation dialog */
+      result = GTK_FILE_CHOOSER_CONFIRMATION_CONFIRM;
+    }
+  else
+    {
+      /* tell the user he cannot write to this file */
+      mousepad_window_error_dialog (GTK_WINDOW (dialog), error, _("Permission denied"));
+      g_error_free (error);
+
+      /* the user doesn't have permission to write to the file */
+      result = GTK_FILE_CHOOSER_CONFIRMATION_SELECT_AGAIN;
+    }
+
+  /* cleanup */
+  g_free (filename);
+
+  return result;
+}
+
+
+
+static gboolean
+mousepad_window_save_as (MousepadWindow *window,
+                         MousepadScreen *screen)
+{
+  GtkWidget   *dialog;
+  gboolean     succeed = FALSE;
+  gchar       *filename;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_WINDOW (window), FALSE);
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), FALSE);
+
+  dialog = gtk_file_chooser_dialog_new (_("Save As"),
+                                        GTK_WINDOW (window),
+                                        GTK_FILE_CHOOSER_ACTION_SAVE,
+                                        GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                        GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+                                        NULL);
+  gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
+  gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+  /* we check if the user is allowed to write to the file */
+  g_signal_connect (G_OBJECT (dialog), "confirm-overwrite",
+                                G_CALLBACK (mousepad_window_save_as_callback), NULL);
+
+  /* set the current file, or the temp name */
+  if (mousepad_screen_get_filename (screen) != NULL)
+    gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (dialog), mousepad_screen_get_filename (screen));
+  else
+    gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), mousepad_screen_get_title (screen, FALSE));
+
+  if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+    {
+      /* get the filename the user has selected */
+      filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
+
+      if (G_LIKELY (filename != NULL))
+        {
+          /* set the filename */
+          mousepad_screen_set_filename (screen, filename);
+
+          /* cleanup */
+          g_free (filename);
+
+          /* it worked */
+          succeed = TRUE;
+        }
+    }
+
+  /* destroy the dialog */
+  gtk_widget_destroy (dialog);
+
+  return succeed;
+}
+
+
+
+static void
+mousepad_window_modified_changed (MousepadScreen *screen,
+                                  MousepadWindow *window)
+{
+  _mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window));
+  _mousepad_return_if_fail (MOUSEPAD_IS_SCREEN (screen));
+
+  mousepad_window_set_title (window, screen);
+}
+
+
+
+static void
+mousepad_window_add (MousepadWindow *window,
+                     MousepadScreen *screen)
+{
+  GtkWidget      *label;
+  gboolean        always_show_tabs;
+  gint            page, npages;
+  MousepadScreen *active;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window));
+  _mousepad_return_if_fail (MOUSEPAD_IS_SCREEN (screen));
+
+  /* connect some bindings to the screen */
+  exo_binding_new (G_OBJECT (window->preferences), "line-numbers", G_OBJECT (screen), "line-numbers");
+  exo_binding_new (G_OBJECT (window->preferences), "word-wrap", G_OBJECT (screen), "word-wrap");
+  exo_binding_new (G_OBJECT (window->preferences), "auto-indent", G_OBJECT (screen), "auto-indent");
+  exo_binding_new (G_OBJECT (window->preferences), "font-name", G_OBJECT (screen), "font-name");
+
+  label = mousepad_tab_label_new ();
+  gtk_widget_show (label);
+
+  /* add the window to the screen */
+  g_object_set_data (G_OBJECT (screen), I_("mousepad-window"), window);
+
+  /* connect some bindings and signals to the tab label */
+  exo_binding_new (G_OBJECT (screen), "title", G_OBJECT (label), "title");
+  exo_binding_new (G_OBJECT (screen), "filename", G_OBJECT (label), "tooltip");
+  g_signal_connect_swapped (G_OBJECT (label), "close-tab", G_CALLBACK (mousepad_window_button_close_tab), screen);
+  g_signal_connect (G_OBJECT (screen), "notify::title", G_CALLBACK (mousepad_window_notify_title), window);
+
+  g_signal_connect (G_OBJECT (screen), "selection-changed", G_CALLBACK (mousepad_window_selection_changed), window);
+  g_signal_connect (G_OBJECT (screen), "modified-changed", G_CALLBACK (mousepad_window_modified_changed), window);
+
+  /* append the page to the window */
+  page = gtk_notebook_append_page (GTK_NOTEBOOK (window->notebook),
+                                   GTK_WIDGET (screen), label);
+
+  /* check if we should always display tabs */
+  g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL);
+
+  /* change the visibility of the tabs accordingly */
+  npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
+  gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), always_show_tabs || (npages > 1));
+
+  /* don't focus the notebook */
+  GTK_WIDGET_UNSET_FLAGS (window->notebook, GTK_CAN_FOCUS);
+
+  /* rebuild the go menu */
+  mousepad_window_rebuild_gomenu (window);
+
+  /* show the screen */
+  gtk_widget_show (GTK_WIDGET (screen));
+
+  /* get the active tab */
+  active = mousepad_window_get_active (window);
+
+  /* switch to the new tab */
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), page);
+
+  /* destroy the (old) active tab if it's empty
+   * and the new tab is not */
+  if (active != NULL &&
+      mousepad_screen_get_modified (active) == FALSE &&
+      mousepad_screen_get_filename (active) == NULL &&
+      mousepad_screen_get_filename (screen) != NULL)
+    gtk_widget_destroy (GTK_WIDGET (active));
+}
+
+
+
+static gboolean
+mousepad_window_close_screen (MousepadWindow *window,
+                              MousepadScreen *screen)
+{
+  GtkWidget *dialog;
+  gint       response;
+  gboolean   succeed = FALSE;
+  GError    *error = NULL;
+
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_WINDOW (window), FALSE);
+  _mousepad_return_val_if_fail (MOUSEPAD_IS_SCREEN (screen), FALSE);
+
+  /* check if the document needs to be saved */
+  if (mousepad_screen_get_modified (screen))
+    {
+      /* create the question dialog */
+      dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+                                       GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                       GTK_MESSAGE_QUESTION,
+                                       GTK_BUTTONS_NONE,
+                                       _("Do you want to save changes to this\ndocument before closing?"));
+      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                                _("If you don't save, your changes will be lost."));
+      gtk_dialog_add_buttons (GTK_DIALOG (dialog),
+                              _("_Don't Save"), GTK_RESPONSE_HELP,
+                              GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                              GTK_STOCK_SAVE, GTK_RESPONSE_OK,
+                              NULL);
+      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+
+      /* run the dialog */
+      response = gtk_dialog_run (GTK_DIALOG (dialog));
+      gtk_widget_destroy (dialog);
+
+      switch (response)
+        {
+          case GTK_RESPONSE_HELP:
+            /* don't save, only destroy the screen */
+            succeed = TRUE;
+            break;
+          case GTK_RESPONSE_CANCEL:
+            /* we do nothing */
+            break;
+          case GTK_RESPONSE_OK:
+            /* save the screen */
+            if (mousepad_screen_get_filename (screen) == NULL)
+              {
+                /* file has no name yet, save as */
+                if (mousepad_window_save_as (window, screen))
+                  succeed = mousepad_screen_save_file (screen, &error);
+              }
+            else
+              {
+                succeed = mousepad_screen_save_file (screen, &error);
+              }
+            break;
+        }
+    }
+  else
+    {
+      /* no changes in the screen, safe to destroy it */
+      succeed = TRUE;
+    }
+
+  /* destroy the screen */
+  if (succeed)
+    {
+      gtk_widget_destroy (GTK_WIDGET (screen));
+    }
+  else if (error != NULL)
+    {
+      /* something went wrong with saving the file */
+      mousepad_window_error_dialog (GTK_WINDOW (window), error, _("Failed to save file"));
+      g_error_free (error);
+    }
+
+  return succeed;
+}
+
+
+
+static void
+mousepad_window_create_recent_menu (MousepadWindow *window)
+{
+  GtkRecentFilter *filter;
+  GtkWidget       *menu;
+  GtkWidget       *item;
+  gint             recent_menu_limit;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_WINDOW (window));
+
+  /* get the recent menu item */
+  item = gtk_ui_manager_get_widget (window->ui_manager, "/main-menu/file-menu/recent-menu");
+
+  /* create a new recent chooser */
+  menu = gtk_recent_chooser_menu_new ();
+
+  /* show only Mousepad items */
+  filter = gtk_recent_filter_new ();
+  gtk_recent_filter_add_application (filter, "Mousepad Text Editor");
+  gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (menu), filter);
+
+  /* get the recent menu limit number */
+  g_object_get (G_OBJECT (window->preferences), "misc-recent-menu-limit", &recent_menu_limit, NULL);
+
+  /* set recent menu properties */
+  gtk_recent_chooser_set_local_only (GTK_RECENT_CHOOSER (menu), TRUE);
+  gtk_recent_chooser_set_limit (GTK_RECENT_CHOOSER (menu), recent_menu_limit);
+  gtk_recent_chooser_set_show_tips (GTK_RECENT_CHOOSER (menu), TRUE);
+
+  g_signal_connect (G_OBJECT (menu), "item-activated",
+                    G_CALLBACK(mousepad_window_action_open_recent), window);
+
+  /* append the recent menu */
+  gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), menu);
+}
+
+
+
+static void
+mousepad_window_add_recent (const gchar *filename)
+{
+  GtkRecentData     info;
+  gchar            *uri;
+  GtkRecentManager *manager = gtk_recent_manager_get_default ();
+
+  _mousepad_return_if_fail (filename != NULL);
+
+  /* create the recent data */
+  info.display_name = NULL;
+  info.description  = NULL;
+  info.mime_type    = "text/plain";
+  info.app_name     = "Mousepad Text Editor";
+  info.app_exec     = "Mousepad %F";
+  info.groups       = NULL;
+  info.is_private   = FALSE;
+
+  /* create an uri from the filename */
+  uri = g_filename_to_uri (filename, NULL, NULL);
+
+  /* add it */
+  if (G_LIKELY (uri != NULL))
+    {
+      gtk_recent_manager_add_full (manager, uri, &info);
+      g_free (uri);
+    }
+}
+
+
+
+static void
+mousepad_window_set_title (MousepadWindow *window,
+                           MousepadScreen *screen)
+{
+  gchar       *string;
+  const gchar *title;
+  gboolean     show_full_path;
+  GtkTextView *textview;
+
+  /* get the active textview */
+  textview = mousepad_screen_get_text_view (screen);
+
+  /* whether to show the full path in the window title */
+  g_object_get (G_OBJECT (window->preferences), "misc-show-full-path-in-title", &show_full_path, NULL);
+
+  /* the window title */
+  title = mousepad_screen_get_title (screen, show_full_path);
+
+  if (!gtk_text_view_get_editable (textview))
+    {
+      string = g_strdup_printf ("%s [%s] - %s",
+                                title, _("Read Only"), PACKAGE_NAME);
+    }
+  else
+    {
+      string = g_strdup_printf ("%s%s - %s",
+                                mousepad_screen_get_modified (screen) ? "*" : "",
+                                title, PACKAGE_NAME);
+    }
+
+  /* get the window title */
+  gtk_window_set_title (GTK_WINDOW (window), string);
+
+  /* cleanup */
+  g_free (string);
+}
+
+
+
+static void
+mousepad_window_notify_title (MousepadScreen *screen,
+                              GParamSpec     *pspec,
+                              MousepadWindow *window)
+{
+  mousepad_window_set_title (window, screen);
+}
+
+
+
+static void
+mousepad_window_page_notified (GtkNotebook    *notebook,
+                               GParamSpec     *pspec,
+                               MousepadWindow *window)
+{
+  MousepadScreen *screen;
+
+  screen = mousepad_window_get_active (window);
+  if (G_LIKELY (screen != NULL))
+    {
+      mousepad_window_set_title (window, screen);
+
+      mousepad_window_update_actions (window);
+    }
+}
+
+
+
+static void
+mousepad_window_tab_removed (GtkNotebook    *notebook,
+                             MousepadScreen *screen,
+                             MousepadWindow *window)
+{
+  gboolean always_show_tabs;
+  gint     npages;
+
+  npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
+
+  if (G_UNLIKELY (npages == 0))
+    {
+      gtk_widget_destroy (GTK_WIDGET (window));
+    }
+  else
+    {
+      /* check tabs should always be visible */
+      g_object_get (G_OBJECT (window->preferences), "misc-always-show-tabs", &always_show_tabs, NULL);
+
+      /* change the visibility of the tabs accordingly */
+      gtk_notebook_set_show_tabs (GTK_NOTEBOOK (window->notebook), always_show_tabs || (npages > 1));
+
+      /* don't focus the notebook */
+      GTK_WIDGET_UNSET_FLAGS (window->notebook, GTK_CAN_FOCUS);
+
+      /* rebuild the go menu */
+      mousepad_window_rebuild_gomenu (window);
+
+      /* update all screen sensitive actions */
+      mousepad_window_update_actions (window);
+    }
+}
+
+
+
+static void
+mousepad_window_error_dialog (GtkWindow   *window,
+                              GError      *error,
+                              const gchar *message)
+{
+  GtkWidget   *dialog;
+
+  _mousepad_return_if_fail (GTK_IS_WINDOW (window));
+
+  /* create the warning dialog */
+  dialog = gtk_message_dialog_new (window,
+                                   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                   GTK_MESSAGE_ERROR,
+                                   GTK_BUTTONS_CLOSE,
+                                   message);
+  gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE);
+
+  /* set the message from GError */
+  if (G_LIKELY (error && error->message))
+    gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
+                                              error->message);
+
+  /* run the dialog */
+  gtk_dialog_run (GTK_DIALOG (dialog));
+
+  /* destroy it */
+  gtk_widget_destroy (dialog);
+
+}
+
+
+
+static void
+mousepad_window_selection_changed (MousepadScreen *screen,
+                                   gboolean        selected,
+                                   MousepadWindow *window)
+{
+  GtkAction *action;
+
+  action = gtk_action_group_get_action (window->action_group, "cut");
+  gtk_action_set_sensitive (action, selected);
+
+  action = gtk_action_group_get_action (window->action_group, "copy");
+  gtk_action_set_sensitive (action, selected);
+
+  action = gtk_action_group_get_action (window->action_group, "delete");
+  gtk_action_set_sensitive (action, selected);
+}
+
+
+
+static void
+mousepad_window_update_actions (MousepadWindow *window)
+{
+  GtkAction        *action;
+  GtkNotebook      *notebook = GTK_NOTEBOOK (window->notebook);
+  MousepadScreen   *screen;
+  GtkTextView      *textview;
+  GtkTextBuffer    *buffer;
+  GtkWidget        *goitem;
+  gboolean          cycle_tabs;
+  gint              n_pages;
+  gint              page_num;
+  gboolean          selected;
+
+  /* determine the number of pages */
+  n_pages = gtk_notebook_get_n_pages (notebook);
+
+  /* set sensitivity for the "Close Tab" action */
+  action = gtk_action_group_get_action (window->action_group, "close-tab");
+  gtk_action_set_sensitive (action, (n_pages > 1));
+
+  /* update the actions for the current terminal screen */
+  screen = mousepad_window_get_active (window);
+  if (G_LIKELY (screen != NULL))
+    {
+      page_num = gtk_notebook_page_num (notebook, GTK_WIDGET (screen));
+
+      textview = mousepad_screen_get_text_view (screen);
+      buffer = mousepad_screen_get_text_buffer (screen);
+
+      g_object_get (G_OBJECT (window->preferences), "misc-cycle-tabs", &cycle_tabs, NULL);
+
+      action = gtk_action_group_get_action (window->action_group, "back");
+      gtk_action_set_sensitive (action, (cycle_tabs && n_pages > 1) || (page_num > 0));
+
+      action = gtk_action_group_get_action (window->action_group, "forward");
+      gtk_action_set_sensitive (action, (cycle_tabs && n_pages > 1 ) || (page_num < n_pages - 1));
+
+      action = gtk_action_group_get_action (window->action_group, "save-file");
+      gtk_action_set_sensitive (action, gtk_text_view_get_editable (textview));
+
+      g_object_get (G_OBJECT (buffer), "has-selection", &selected, NULL);
+      mousepad_window_selection_changed (screen, selected, window);
+
+      /* update the "Go" menu */
+      goitem = g_object_get_data (G_OBJECT (screen), "go-menu-item");
+      if (G_LIKELY (goitem != NULL))
+        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (goitem), TRUE);
+    }
+}
+
+
+static void
+mousepad_window_action_goto (GtkRadioAction *action,
+                             GtkNotebook    *notebook)
+{
+  gint page = gtk_radio_action_get_current_value (action);
+
+  gtk_notebook_set_current_page (notebook, page);
+}
+
+
+
+static void
+mousepad_window_rebuild_gomenu (MousepadWindow *window)
+{
+  GtkWidget      *screen;
+  gint            npages;
+  gint            n;
+  gchar           name[15];
+  gchar           accelerator[7];
+  GtkRadioAction *action;
+  GSList         *group = NULL;
+  const gchar    *go_menu_path;
+  static guint    merge_id = 0;
+
+  /* remove the old merge */
+  if (merge_id > 1)
+    gtk_ui_manager_remove_ui (window->ui_manager, merge_id);
+
+  /* create a new merge id */
+  merge_id = gtk_ui_manager_new_merge_id (window->ui_manager);
+
+  /* the path in the ui where the items will be added */
+  go_menu_path = "/main-menu/go-menu/placeholder-go-items";
+
+  /* walk through the notebook pages */
+  npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
+  for (n = 0; n < npages; ++n)
+    {
+      screen = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), n);
+
+      /* create a new action name */
+      g_snprintf (name, sizeof (name), "document-%d", n);
+
+      /* create the radio action */
+      action = gtk_radio_action_new (name, NULL, NULL, NULL, n);
+      exo_binding_new (G_OBJECT (screen), "title", G_OBJECT (action), "label");
+      gtk_radio_action_set_group (action, group);
+      group = gtk_radio_action_get_group (action);
+      g_signal_connect (G_OBJECT (action), "activate",
+                        G_CALLBACK (mousepad_window_action_goto), window->notebook);
+
+      /* connect the action to the screen to we can easily active it when the user toggled the tabs */
+      g_object_set_data (G_OBJECT (screen), I_("go-menu-item"), action);
+
+      if (G_LIKELY (n < 9))
+        {
+          /* create an accelerator and add it to the menu */
+          g_snprintf (accelerator, sizeof (accelerator), "<Alt>%d", n+1);
+          gtk_action_group_add_action_with_accel (window->action_group, GTK_ACTION (action), accelerator);
+        }
+      else
+        /* add a menu item without accelerator */
+        gtk_action_group_add_action (window->action_group, GTK_ACTION (action));
+
+      /* release the action */
+      g_object_unref (G_OBJECT (action));
+
+      /* add the action to the go menu */
+      gtk_ui_manager_add_ui (window->ui_manager, merge_id,
+                             go_menu_path, name, name,
+                             GTK_UI_MANAGER_MENUITEM, FALSE);
+    }
+
+  /* make sure the ui is up2date to avoid flickering */
+  gtk_ui_manager_ensure_update (window->ui_manager);
+}
+
+
+/**
+ * Menu Actions
+ **/
+static void
+mousepad_window_action_open_new_window (GtkAction      *action,
+                                        MousepadWindow *window)
+{
+  MousepadApplication *application;
+  GdkScreen           *screen;
+
+  screen = gtk_widget_get_screen (GTK_WIDGET (window));
+
+  application = mousepad_application_get ();
+  mousepad_application_open_window (application, screen, NULL, NULL);
+  g_object_unref (G_OBJECT (application));
+}
+
+
+
+static void
+mousepad_window_action_open_new_tab (GtkAction      *action,
+                                     MousepadWindow *window)
+{
+  mousepad_window_open_tab (window, NULL);
+}
+
+
+
+static void
+mousepad_window_action_open_file (GtkAction      *action,
+                                  MousepadWindow *window)
+{
+  GtkWidget *chooser;
+  gchar     *filename;
+  GSList    *filenames, *li;
+
+  /* create new chooser dialog */
+  chooser = gtk_file_chooser_dialog_new (_("Open File"),
+                                         GTK_WINDOW (window),
+                                         GTK_FILE_CHOOSER_ACTION_OPEN,
+                                         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                         GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+                                         NULL);
+  gtk_dialog_set_default_response (GTK_DIALOG (chooser), GTK_RESPONSE_ACCEPT);
+  gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (chooser), TRUE);
+  gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (chooser), TRUE);
+
+  /* run the dialog */
+  if (G_LIKELY (gtk_dialog_run (GTK_DIALOG (chooser)) == GTK_RESPONSE_ACCEPT))
+    {
+      /* open the new file */
+      filenames = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (chooser));
+
+      /* open the selected files */
+      for (li = filenames; li != NULL; li = li->next)
+        {
+          filename = li->data;
+
+          /* open the file in a new tab */
+          mousepad_window_open_tab (window, filename);
+
+          /* add to the recent files */
+          mousepad_window_add_recent (filename);
+
+          /* cleanup */
+          g_free (filename);
+        }
+
+      /* free the list */
+      g_slist_free(filenames);
+    }
+
+  /* destroy dialog */
+  gtk_widget_destroy (chooser);
+}
+
+
+
+static void
+mousepad_window_action_open_recent (GtkRecentChooser *chooser,
+                                    MousepadWindow   *window)
+{
+  gchar            *uri;
+  gchar            *filename;
+  gboolean          succeed;
+  GtkRecentManager *manager;
+
+  /* get the file uri */
+  uri = gtk_recent_chooser_get_current_uri (chooser);
+
+  if (G_LIKELY(uri != NULL))
+    {
+      /* get the filename from the uri */
+      filename = g_filename_from_uri (uri, NULL, NULL);
+
+      if (G_LIKELY (filename != NULL))
+        {
+          /* open a new tab */
+          succeed = mousepad_window_open_tab (window, filename);
+
+          /* remove the file from the recent menu if Mousepad failed to open it */
+          if (G_UNLIKELY (succeed == FALSE))
+            {
+              manager = gtk_recent_manager_get_default ();
+              gtk_recent_manager_remove_item (manager, uri, NULL);
+            }
+
+          /* cleanup */
+          g_free (filename);
+        }
+
+      /* cleanup */
+      g_free (uri);
+    }
+}
+
+
+
+static void
+mousepad_window_action_save_file (GtkAction      *action,
+                                  MousepadWindow *window)
+{
+  MousepadScreen *screen;
+  GError         *error = NULL;
+
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    {
+      if (mousepad_screen_get_filename (screen) != NULL)
+        mousepad_screen_save_file (screen, &error);
+      else
+        {
+          if (mousepad_window_save_as (window, screen))
+            mousepad_screen_save_file (screen, &error);
+        }
+
+      /* check for errors */
+      if (G_UNLIKELY (error != NULL))
+        {
+          mousepad_window_error_dialog (GTK_WINDOW (window), error, _("Failed to save file"));
+          g_error_free (error);
+        }
+    }
+}
+
+
+
+static void
+mousepad_window_action_save_file_as (GtkAction      *action,
+                                     MousepadWindow *window)
+{
+  MousepadScreen *screen;
+  GError         *error = NULL;
+
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    {
+      /* popup the save as dialog, if that worked, save the file, if
+       * that worked too, add the (new) file to the recent menu */
+      if (mousepad_window_save_as (window, screen))
+        if (mousepad_screen_save_file (screen, &error))
+          mousepad_window_add_recent (mousepad_screen_get_filename (screen));
+
+      /* check for errors */
+      if (G_UNLIKELY (error != NULL))
+        {
+          mousepad_window_error_dialog (GTK_WINDOW (window), error,  _("Failed to save file as"));
+          g_error_free (error);
+        }
+      else
+        {
+          /* make sure save-file is sensitive */
+          action = gtk_action_group_get_action (window->action_group, "save-file");
+          gtk_action_set_sensitive (action, TRUE);
+        }
+    }
+}
+
+
+
+static void
+mousepad_window_action_close_tab (GtkAction      *action,
+                                  MousepadWindow *window)
+{
+  MousepadScreen *screen;
+
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    mousepad_window_close_screen (window, screen);
+}
+
+
+
+static void
+mousepad_window_button_close_tab (MousepadScreen *screen)
+{
+  MousepadWindow *window;
+
+  _mousepad_return_if_fail (MOUSEPAD_IS_SCREEN (screen));
+
+  /* get the mousepad window of this screen */
+  window = g_object_get_data (G_OBJECT (screen), I_("mousepad-window"));
+
+  /* close the screen */
+  if (G_LIKELY (window != NULL))
+    mousepad_window_close_screen (window, screen);
+}
+
+
+
+static gboolean
+mousepad_window_delete_event (MousepadWindow *window,
+                              GdkEvent       *event)
+{
+  /* try to close the windows */
+  mousepad_window_action_close (NULL, window);
+
+  /* we will close the window when it's time */
+  return TRUE;
+}
+
+
+
+static void
+mousepad_window_action_close (GtkAction      *action,
+                              MousepadWindow *window)
+{
+  gint       npages, i;
+  GtkWidget *screen;
+
+  /* get the number of page in the notebook */
+  npages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook)) - 1;
+
+  /* close all the tabs, one by one. the window will close
+   * when all the tabs are closed */
+  for (i = npages; i >= 0; --i)
+    {
+      screen = gtk_notebook_get_nth_page (GTK_NOTEBOOK (window->notebook), i);
+
+      if (G_LIKELY (screen != NULL))
+        {
+          /* switch to the tab we're going to close */
+          gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook), i);
+
+          /* ask user what to do, break when he/she hits the cancel button */
+          if (!mousepad_window_close_screen (window, MOUSEPAD_SCREEN (screen)))
+            break;
+        }
+    }
+}
+
+
+
+static void
+mousepad_window_action_close_all_windows (GtkAction      *action,
+                                          MousepadWindow *window)
+{
+  MousepadApplication *application;
+  GList               *windows, *li;
+
+  /* query the list of currently open windows */
+  application = mousepad_application_get ();
+  windows = mousepad_application_get_windows (application);
+  g_object_unref (G_OBJECT (application));
+
+  /* close all open windows */
+  for (li = windows; li != NULL; li = li->next)
+    mousepad_window_action_close (NULL, MOUSEPAD_WINDOW (li->data));
+
+  g_list_free (windows);
+}
+
+
+
+static void
+mousepad_window_action_cut (GtkAction      *action,
+                            MousepadWindow *window)
+{
+  MousepadScreen *screen;
+  GtkTextBuffer  *buffer;
+  GtkClipboard   *clipboard;
+  GtkTextView    *textview;
+
+  /* get the active screen */
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    {
+      /* get the clipboard, textview and the buffer */
+      buffer = mousepad_screen_get_text_buffer (screen);
+      textview = mousepad_screen_get_text_view (screen);
+      clipboard = gtk_widget_get_clipboard (GTK_WIDGET (textview), GDK_SELECTION_CLIPBOARD);
+
+      /* cut the text */
+      gtk_text_buffer_cut_clipboard (buffer, clipboard,
+                                     gtk_text_view_get_editable (textview));
+
+      /* scroll to visible area */
+      gtk_text_view_scroll_to_mark (textview,
+                                    gtk_text_buffer_get_insert (buffer),
+                                    MOUSEPAD_SCROLL_MARGIN,
+                                    FALSE, 0.0, 0.0);
+    }
+}
+
+
+
+static void
+mousepad_window_action_copy (GtkAction      *action,
+                             MousepadWindow *window)
+{
+  MousepadScreen *screen;
+  GtkTextBuffer  *buffer;
+  GtkClipboard   *clipboard;
+
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    {
+      /* get the buffer, textview and the clipboard */
+      buffer = mousepad_screen_get_text_buffer (screen);
+      clipboard = gtk_widget_get_clipboard (GTK_WIDGET (window), GDK_SELECTION_CLIPBOARD);
+
+      /* copy the selected text */
+      gtk_text_buffer_copy_clipboard (buffer, clipboard);
+    }
+}
+
+
+
+static void
+mousepad_window_action_paste (GtkAction      *action,
+                              MousepadWindow *window)
+{
+  MousepadScreen *screen;
+  GtkTextBuffer  *buffer;
+  GtkClipboard   *clipboard;
+  GtkTextView    *textview;
+
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    {
+      /* get the buffer and the clipboard */
+      buffer = mousepad_screen_get_text_buffer (screen);
+      textview = mousepad_screen_get_text_view (screen);
+      clipboard = gtk_widget_get_clipboard (GTK_WIDGET (textview), GDK_SELECTION_CLIPBOARD);
+
+      /* paste the clipboard content */
+      gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL,
+                                       gtk_text_view_get_editable (textview));
+
+      /* scroll to visible area */
+      gtk_text_view_scroll_to_mark (textview,
+                                    gtk_text_buffer_get_insert (buffer),
+                                    MOUSEPAD_SCROLL_MARGIN,
+                                    FALSE, 0.0, 0.0);
+    }
+}
+
+
+
+static void
+mousepad_window_action_delete (GtkAction      *action,
+                               MousepadWindow *window)
+{
+  MousepadScreen *screen;
+  GtkTextBuffer  *buffer;
+  GtkTextView    *textview;
+
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    {
+      /* get the buffer */
+      buffer = mousepad_screen_get_text_buffer (screen);
+      textview = mousepad_screen_get_text_view (screen);
+
+      /* delete the selected text */
+      gtk_text_buffer_delete_selection (buffer, TRUE,
+                                        gtk_text_view_get_editable (textview));
+
+      /* scroll to visible area */
+      gtk_text_view_scroll_to_mark (textview,
+                                    gtk_text_buffer_get_insert (buffer),
+                                    MOUSEPAD_SCROLL_MARGIN,
+                                    FALSE, 0.0, 0.0);
+    }
+}
+
+
+
+static void
+mousepad_window_action_select_all (GtkAction      *action,
+                                   MousepadWindow *window)
+{
+
+  MousepadScreen *screen;
+  GtkTextBuffer  *buffer;
+  GtkTextIter     start, end;
+
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    {
+      /* get the buffer */
+      buffer = mousepad_screen_get_text_buffer (screen);
+
+      /* get the start and end iter */
+      gtk_text_buffer_get_bounds (buffer, &start, &end);
+
+      /* select everything between those iters */
+      gtk_text_buffer_select_range (buffer, &start, &end);
+    }
+}
+
+
+
+static void
+mousepad_window_action_jump_to (GtkAction      *action,
+                                MousepadWindow *window)
+{
+  GtkWidget      *dialog;
+  GtkWidget      *hbox, *label, *button;
+  GtkTextBuffer  *buffer;
+  MousepadScreen *screen;
+  gint            num, num_max;
+  GtkTextIter     iter;
+  GtkAdjustment   *adjustment;
+
+
+  screen = mousepad_window_get_active (window);
+
+  if (G_LIKELY (screen != NULL))
+    {
+      buffer = mousepad_screen_get_text_buffer (screen);
+
+      /* get the current line number */
+      gtk_text_buffer_get_iter_at_mark (buffer, &iter, gtk_text_buffer_get_insert (buffer));
+      num = gtk_text_iter_get_line (&iter) + 1;
+
+      /* get the last line number */
+      gtk_text_buffer_get_end_iter (buffer, &iter);
+      num_max = gtk_text_iter_get_line (&iter) + 1;
+
+      /* build the dialog */
+      dialog = gtk_dialog_new_with_buttons (_("Jump To"),
+                                            GTK_WINDOW (window),
+                                            GTK_DIALOG_MODAL
+                                            | GTK_DIALOG_DESTROY_WITH_PARENT
+                                            | GTK_DIALOG_NO_SEPARATOR,
+                                            GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+                                            GTK_STOCK_JUMP_TO, GTK_RESPONSE_OK,
+                                            NULL);
+      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
+      gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
+
+      hbox = gtk_hbox_new (FALSE, 8);
+      gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, FALSE, FALSE, 0);
+      gtk_container_set_border_width (GTK_CONTAINER (hbox), 8);
+      gtk_widget_show (hbox);
+
+      label = gtk_label_new_with_mnemonic (_("_Line number:"));
+      gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+      gtk_widget_show (label);
+
+      /* the spin button adjustment */
+      adjustment = (GtkAdjustment *) gtk_adjustment_new (num, 1, num_max, 1, 10, 0);
+
+      /* the spin button */
+      button = gtk_spin_button_new (adjustment, 1, 0);
+      gtk_spin_button_set_numeric (GTK_SPIN_BUTTON (button), TRUE);
+      gtk_spin_button_set_snap_to_ticks (GTK_SPIN_BUTTON (button), TRUE);
+      gtk_entry_set_width_chars (GTK_ENTRY (button), 8);
+      gtk_entry_set_activates_default (GTK_ENTRY (button), TRUE);
+      gtk_label_set_mnemonic_widget (GTK_LABEL(label), button);
+      gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+      gtk_widget_show (button);
+
+      if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK)
+        {
+          /* jump to the line */
+          num = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (button)) - 1;
+          gtk_text_buffer_get_iter_at_line (buffer, &iter, num);
+          gtk_text_buffer_place_cursor (buffer, &iter);
+
+          /* scroll to visible area */
+          gtk_text_view_scroll_to_mark (mousepad_screen_get_text_view (screen),
+                                        gtk_text_buffer_get_insert (buffer),
+                                        MOUSEPAD_SCROLL_MARGIN,
+                                        FALSE, 0.0, 0.0);
+        }
+
+      /* destroy the dialog */
+      gtk_widget_destroy (dialog);
+    }
+}
+
+
+
+static void
+mousepad_window_action_select_font (GtkAction      *action,
+                                    MousepadWindow *window)
+{
+  GtkWidget *dialog;
+  gchar     *font_name;
+
+  dialog = gtk_font_selection_dialog_new (_("Choose Mousepad Font"));
+  gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (window));
+
+  /* set the current font */
+  g_object_get (G_OBJECT (window->preferences), "font-name", &font_name, NULL);
+
+  if (G_LIKELY (font_name))
+    {
+      gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (dialog), font_name);
+      g_free (font_name);
+    }
+
+  /* run the dialog */
+  if (G_LIKELY (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK))
+    {
+      /* send the new font to the preferences */
+      font_name = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (dialog));
+      g_object_set (G_OBJECT (window->preferences), "font-name", font_name, NULL);
+      g_free (font_name);
+    }
+
+  /* destroy dialog */
+  gtk_widget_destroy (dialog);
+}
+
+
+
+static void
+mousepad_window_action_prev_tab (GtkAction      *action,
+                                 MousepadWindow *window)
+{
+  gint page_num;
+  gint n_pages;
+
+  /* get notebook info */
+  page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook));
+  n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
+
+  /* switch to the previous tab or cycle to the last tab */
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook),
+                                 (page_num - 1) % n_pages);
+}
+
+
+
+static void
+mousepad_window_action_next_tab (GtkAction      *action,
+                                 MousepadWindow *window)
+{
+  gint page_num;
+  gint n_pages;
+
+  /* get notebook info */
+  page_num = gtk_notebook_get_current_page (GTK_NOTEBOOK (window->notebook));
+  n_pages = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->notebook));
+
+  /* switch to the next tab or cycle to the first tab */
+  gtk_notebook_set_current_page (GTK_NOTEBOOK (window->notebook),
+                                 (page_num + 1) % n_pages);
+}
+
+
+
+static void
+mousepad_window_action_about (GtkAction      *action,
+                              MousepadWindow *window)
+{
+  static const gchar *authors[] =
+  {
+    "Erik Harrison <erikharrison at xfce.org>",
+    "Nick Schermer <nick at xfce.org>",
+    "Benedikt Meurer <benny at xfce.org>",
+    NULL,
+  };
+
+  /* show the dialog */
+  gtk_about_dialog_set_email_hook (exo_url_about_dialog_hook, NULL, NULL);
+  gtk_about_dialog_set_url_hook (exo_url_about_dialog_hook, NULL, NULL);
+  gtk_show_about_dialog (GTK_WINDOW (window),
+                         "authors", authors,
+                         "comments", _("Mousepad is a fast text editor for the Xfce Desktop Environment."),
+                         "copyright", _("Copyright \302\251 2004-2007 Xfce Development Team"),
+                         "destroy-with-parent", TRUE,
+                         "license", XFCE_LICENSE_GPL,
+                         "logo-icon-name", PACKAGE_NAME,
+                         "name", PACKAGE_NAME,
+                         "version", PACKAGE_VERSION,
+                         "translator-credits", _("translator-credits"),
+                         "website", "http://www.xfce.org/projects/mousepad",
+                         NULL);
+}
+
diff --git a/mousepad/mousepad-window.h b/mousepad/mousepad-window.h
new file mode 100644
index 0000000..951d020
--- /dev/null
+++ b/mousepad/mousepad-window.h
@@ -0,0 +1,48 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2007 Nick Schermer <nick at xfce.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __MOUSEPAD_WINDOW_H__
+#define __MOUSEPAD_WINDOW_H__
+
+G_BEGIN_DECLS
+
+#define MOUSEPAD_TYPE_WINDOW            (mousepad_window_get_type ())
+#define MOUSEPAD_WINDOW(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), MOUSEPAD_TYPE_WINDOW, MousepadWindow))
+#define MOUSEPAD_WINDOW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPAD_TYPE_WINDOW, MousepadWindowClass))
+#define MOUSEPAD_IS_WINDOW(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MOUSEPAD_TYPE_WINDOW))
+#define MOUSEPAD_IS_WINDOW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), MOUSEPADL_TYPE_WINDOW))
+#define MOUSEPAD_WINDOW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), MOUSEPAD_TYPE_WINDOW, MousepadWindowClass))
+
+typedef struct _MousepadWindowClass MousepadWindowClass;
+typedef struct _MousepadWindow      MousepadWindow;
+
+GType           mousepad_window_get_type         (void) G_GNUC_CONST;
+
+GtkWidget      *mousepad_window_new              (void);
+
+gboolean        mousepad_window_open_tab         (MousepadWindow  *window,
+                                                  const gchar     *filename);
+
+void            mousepad_window_open_files       (MousepadWindow  *window,
+                                                  const gchar     *working_directory,
+                                                  gchar          **filenames);
+
+G_END_DECLS
+
+#endif /* !__MOUSEPAD_WINDOW_H__ */
diff --git a/po/ChangeLog b/po/ChangeLog
new file mode 100644
index 0000000..e69de29
diff --git a/po/LINGUAS b/po/LINGUAS
new file mode 100644
index 0000000..a0f7499
--- /dev/null
+++ b/po/LINGUAS
@@ -0,0 +1 @@
+# set of available languages (in alphabetic order)
diff --git a/po/Mousepad.pot b/po/Mousepad.pot
new file mode 100644
index 0000000..ea89984
--- /dev/null
+++ b/po/Mousepad.pot
@@ -0,0 +1,225 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL at ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-02-17 12:57+0100\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL at ADDRESS>\n"
+"Language-Team: LANGUAGE <LL at li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: ../mousepad/main.c:47
+msgid "Print version information and exit"
+msgstr ""
+
+#. default application name
+#: ../mousepad/main.c:65
+msgid "Mousepad"
+msgstr ""
+
+#. initialize Gtk+
+#: ../mousepad/main.c:77
+msgid "[FILES...]"
+msgstr ""
+
+#. no error message, the GUI initialization failed
+#: ../mousepad/main.c:83
+msgid "Failed to open display."
+msgstr ""
+
+#: ../mousepad/main.c:100
+msgid "The Xfce development team. All rights reserved."
+msgstr ""
+
+#: ../mousepad/main.c:101
+msgid "Written by Nick Schermer <nick at xfce.org>."
+msgstr ""
+
+#: ../mousepad/main.c:102
+#, c-format
+msgid "Please report bugs to <%s>."
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:29
+msgid "Untitled Document"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:91
+msgid "_File"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:92
+msgid "New _Tab"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:92
+msgid "Open a new Mousepad tab"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:93
+msgid "_New Window"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:93
+msgid "Open a new Mousepad window"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:94
+msgid "_Open File"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:94
+msgid "Open a new document"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:95
+msgid "Open _Recent"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:96
+msgid "_Save"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:96
+msgid "Save current document"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:97
+msgid "Save _As"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:97
+msgid "Save current document as another file"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:98
+msgid "C_lose Tab"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:98
+msgid "Close the current Mousepad tab"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:99
+msgid "_Close Window"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:99
+msgid "Close the Mousepad window"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:100
+msgid "Close _All Windows"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:100
+msgid "Close all Mousepad windows"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:102
+msgid "_Edit"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:103
+msgid "_Undo"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:104
+msgid "_Redo"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:105
+msgid "Cu_t"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:106
+msgid "_Copy"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:107
+msgid "_Paste"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:108
+msgid "_Delete"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:109
+msgid "Select _All"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:111
+msgid "_Search"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:112
+msgid "_Find"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:113
+msgid "Find _Next"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:114
+msgid "Find _Previous"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:115
+msgid "_Replace"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:116
+msgid "_Jump To"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:118
+msgid "_View"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:119
+msgid "_Font"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:121
+msgid "_Go"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:122
+msgid "Back"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:123
+msgid "Forward"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:125
+msgid "_Help"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:126
+msgid "_About"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:126
+msgid "Display information about Mousepad"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:131
+msgid "_Word Wrap"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:132
+msgid "_Line Numbers"
+msgstr ""
+
+#: ../mousepad/mousepad-window.c:133
+msgid "_Auto Indent"
+msgstr ""
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644
index 0000000..b144c68
--- /dev/null
+++ b/po/POTFILES.in
@@ -0,0 +1,6 @@
+mousepad/main.c
+mousepad/mousepad-application.c
+mousepad/mousepad-dbus.c
+mousepad/mousepad-preferences.c
+mousepad/mousepad-textview.c
+mousepad/mousepad-window.c


More information about the Xfce4-commits mailing list